| #!/usr/bin/env python3 | |
| # Copyright lowRISC contributors. | |
| # Licensed under the Apache License, Version 2.0, see LICENSE for details. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| import unittest | |
| from unittest.mock import ( | |
| MagicMock, | |
| patch, | |
| ) | |
| from pathlib import Path | |
| from io import BytesIO | |
| import functest_coverage | |
| class AnyStringWith(str): | |
| def __eq__(self, other): | |
| return self in other | |
| class TestFunc(unittest.TestCase): | |
| def test_handle_libs(self): | |
| device_libs_all = [ | |
| "//foo/a", "//foo/b_on_host_do_not", "//foo/c_on_host", "//foo/d" | |
| ] | |
| device_libs = ["//foo/a", "//foo/d"] | |
| self.assertEqual(functest_coverage.handle_libs(device_libs_all), | |
| device_libs) | |
| @patch("functest_coverage.LLD_TARGET", "<lld_target>") | |
| @patch("functest_coverage.run") | |
| def test_handle_objs(self, mock_run): | |
| merged_library = Path("/foo/merged.so") | |
| obj_files = ["//foo/a.o", "//foo/d.o"] | |
| functest_coverage.handle_objs(merged_library, obj_files) | |
| mock_run.assert_called_once_with("<lld_target>", | |
| AnyStringWith("unresolved"), | |
| "-zmuldefs", "-o", | |
| str(merged_library), *obj_files) | |
| @patch("functest_coverage.run") | |
| def test_handle_test_targets(self, mock_run): | |
| test_targets = [ | |
| "//foo/test", "//bar/test_cw310_test_rom", | |
| "//qux/long_wycheproof_test" | |
| ] | |
| mock_run.side_effect = ( | |
| None, | |
| ["workspace_path"], | |
| ["bitstream_file.bit"], | |
| None, | |
| ) | |
| res = functest_coverage.handle_test_targets(test_targets) | |
| self.assertEqual(res, ["//bar/test_cw310_test_rom"]) | |
| calls_mock_run = mock_run.call_args_list | |
| self.assertEqual(len(calls_mock_run), 4) | |
| self.assertEqual(calls_mock_run[0][0], | |
| (functest_coverage.BAZEL, "build", | |
| functest_coverage.BITSTREAM_TARGET)) | |
| self.assertEqual(calls_mock_run[1][0], | |
| (functest_coverage.BAZEL, "info", "workspace")) | |
| self.assertEqual( | |
| calls_mock_run[2][0], | |
| (functest_coverage.BAZEL, "cquery", "--output=starlark", | |
| "--starlark:expr", "target.files.to_list()[0].path", | |
| functest_coverage.BITSTREAM_TARGET)) | |
| self.assertEqual( | |
| calls_mock_run[3][0], | |
| (functest_coverage.BAZEL, "run", "//sw/host/opentitantool", "--", | |
| "fpga", "load-bitstream", "workspace_path/bitstream_file.bit")) | |
| def mock_binary_file(self: unittest.TestCase, | |
| name: str, | |
| contents: bytes = None) -> MagicMock: | |
| mock_file = MagicMock(autospec=BytesIO) | |
| mock_file.__enter__.side_effect = [mock_file] | |
| mock_file.name = name | |
| if contents: | |
| mock_file.read.side_effect = [contents] | |
| return mock_file | |
| @patch("pathlib.Path.open", autospec=True) | |
| @patch("functest_coverage.extract_profile_data") | |
| @patch("pathlib.Path.__truediv__", | |
| side_effect=Path.__truediv__, | |
| autospec=True) | |
| def test_handle_test_log_dirs(self, mock_path_div, | |
| mock_extract_profile_data, mock_path_open): | |
| test_log_dirs = [Path("/testlogs/foo"), Path("/testlogs/bar")] | |
| test_logs = [ | |
| Path("/testlogs/foo/test.log"), | |
| Path("/testlogs/bar/test.log") | |
| ] | |
| profiles = [ | |
| Path("/testlogs/foo/prof.raw"), | |
| Path("/testlogs/bar/prof.raw") | |
| ] | |
| mock_files = [ | |
| self.mock_binary_file(name=test_logs[0], contents=b"<log_0>"), | |
| self.mock_binary_file(name=profiles[0]), | |
| self.mock_binary_file(name=test_logs[1], contents=b"<log_1>"), | |
| self.mock_binary_file(name=profiles[1]), | |
| ] | |
| mock_path_open.side_effect = mock_files | |
| mock_extract_profile_data.side_effect = (b"<raw_profile_0>", | |
| b"<raw_profile_1>") | |
| self.assertEqual(functest_coverage.handle_test_log_dirs(test_log_dirs), | |
| profiles) | |
| calls_path_div = mock_path_div.call_args_list | |
| self.assertEqual(len(calls_path_div), 4) | |
| self.assertEqual(calls_path_div[0][0], (test_log_dirs[0], "test.log")) | |
| self.assertEqual(calls_path_div[1][0], (test_log_dirs[0], "prof.raw")) | |
| self.assertEqual(calls_path_div[2][0], (test_log_dirs[1], "test.log")) | |
| self.assertEqual(calls_path_div[3][0], (test_log_dirs[1], "prof.raw")) | |
| calls_path_open = mock_path_open.call_args_list | |
| self.assertEqual(len(calls_path_open), 4) | |
| self.assertEqual(calls_path_open[0][0], (test_logs[0], "rb")) | |
| self.assertEqual(calls_path_open[1][0], (profiles[0], "wb")) | |
| self.assertEqual(calls_path_open[2][0], (test_logs[1], "rb")) | |
| self.assertEqual(calls_path_open[3][0], (profiles[1], "wb")) | |
| calls_extract_profile_data = mock_extract_profile_data.call_args_list | |
| self.assertEqual(len(calls_extract_profile_data), 2) | |
| self.assertEqual(calls_extract_profile_data[0][0], ("<log_0>", )) | |
| self.assertEqual(calls_extract_profile_data[1][0], ("<log_1>", )) | |
| mock_files[1].write.assert_called_once_with(b"<raw_profile_0>") | |
| mock_files[3].write.assert_called_once_with(b"<raw_profile_1>") | |
| def test_params(self): | |
| self.assertEqual(functest_coverage.PARAMS.bazel_test_type, | |
| AnyStringWith("sh_test")) | |
| self.assertEqual(functest_coverage.PARAMS.config, | |
| "ot_coverage_on_target") | |
| self.assertEqual(functest_coverage.PARAMS.libs_fn, | |
| functest_coverage.handle_libs) | |
| self.assertEqual(functest_coverage.PARAMS.objs_fn, | |
| functest_coverage.handle_objs) | |
| self.assertEqual(functest_coverage.PARAMS.test_targets_fn, | |
| functest_coverage.handle_test_targets) | |
| self.assertEqual(functest_coverage.PARAMS.test_log_dirs_fn, | |
| functest_coverage.handle_test_log_dirs) | |
| self.assertEqual(functest_coverage.PARAMS.report_title, | |
| AnyStringWith("Functional Test")) | |
| if __name__ == "__main__": | |
| unittest.main() |