|
40 | 40 | from ..test.bench_list import TestBenchList |
41 | 41 | from ..test.report import TestReport |
42 | 42 | from ..test.runner import TestRunner |
| 43 | +from ..test.list import TestList |
43 | 44 | from ..dependency_graph import CircularDependencyException |
44 | 45 |
|
45 | 46 | from .common import LOGGER, TEST_OUTPUT_PATH, select_vhdl_standard, check_not_empty |
@@ -176,8 +177,10 @@ def __init__( |
176 | 177 | self._builtins = Builtins(self, self._vhdl_standard, simulator_class) |
177 | 178 |
|
178 | 179 | self._dependency_graph = None |
179 | | - self._include_in_test_pattern: Optional[List[Union[str, Path]]] = [] |
180 | | - self._exclude_from_test_pattern: Optional[List[Union[str, Path]]] = [] |
| 180 | + self._include_in_test_pattern: Optional[List[Union[str, Path]]] = None |
| 181 | + self._exclude_from_test_pattern: Optional[List[Union[str, Path]]] = None |
| 182 | + self._latest_dependency_updates = None |
| 183 | + self._test_history = None |
181 | 184 |
|
182 | 185 | def _create_database(self): |
183 | 186 | """ |
@@ -806,14 +809,14 @@ def get_dependent_files(dependencies): |
806 | 809 |
|
807 | 810 | dependent_files = get_dependent_files(include_dependencies) - get_dependent_files(exclude_dependencies) |
808 | 811 |
|
809 | | - # Extract testbenches from dependent files and create corresponding test patterns: |
810 | | - # lib_name.tb_name* |
811 | | - test_patterns = [] |
812 | | - for dependent_file in dependent_files: |
813 | | - library_name = dependent_file.library.name |
814 | | - for testbench in self._test_bench_list.get_test_benches_in_library(library_name): |
815 | | - if testbench.design_unit.source_file == dependent_file: |
816 | | - test_patterns.append(f"{library_name}.{testbench.name}*") |
| 812 | + # Extract testbenches from dependent files |
| 813 | + dependent_testbenches = [] |
| 814 | + for testbench in self._test_bench_list.get_test_benches(): |
| 815 | + if testbench.design_unit.source_file in dependent_files: |
| 816 | + dependent_testbenches.append(testbench) |
| 817 | + |
| 818 | + # Create test patterns for remaining testbenches: lib_name.tb_name* |
| 819 | + test_patterns = [f"{testbench.library_name}.{testbench.name}*" for testbench in dependent_testbenches] |
817 | 820 |
|
818 | 821 | # Update test filter to match test patterns |
819 | 822 | if isinstance(self._args.test_patterns, list): |
@@ -877,6 +880,12 @@ def _get_latest_dependency_updates(self): |
877 | 880 |
|
878 | 881 | source_files_in_order = self._dependency_graph.toposort() |
879 | 882 | source_file_timestamps = self._project.get_compile_timestamps(source_files_in_order) |
| 883 | + for source_file in source_files_in_order: |
| 884 | + hash_file_name = self._project.hash_file_name_of(source_file) |
| 885 | + if not ostools.file_exists(hash_file_name) or ( |
| 886 | + ostools.read_file(hash_file_name) != source_file.content_hash |
| 887 | + ): |
| 888 | + source_file_timestamps[source_file] = 10e9 |
880 | 889 |
|
881 | 890 | for source_file, timestamp in source_file_timestamps.items(): |
882 | 891 | dependency_time_stamps = [ |
@@ -982,12 +991,41 @@ def _update_test_history(self, report, simulator_if): |
982 | 991 |
|
983 | 992 | self._database[b"test_history"] = test_history |
984 | 993 |
|
| 994 | + def _get_test_list_depending_on_change(self, test_list): |
| 995 | + if self._latest_dependency_updates is None: |
| 996 | + self._latest_dependency_updates = self._get_latest_dependency_updates() |
| 997 | + |
| 998 | + if self._test_history is None: |
| 999 | + self._test_history = self._get_test_history(simulator_if=None) |
| 1000 | + |
| 1001 | + def depending_on_change(test_suite): |
| 1002 | + latest_dependency_update = self._latest_dependency_updates[test_suite.file_name] |
| 1003 | + test_suite_history = self._test_history.get(test_suite.name, None) |
| 1004 | + if test_suite_history: |
| 1005 | + test_start_times = [test_data["start_time"] for test_data in test_suite_history.values()] |
| 1006 | + if None in test_start_times: |
| 1007 | + return True |
| 1008 | + |
| 1009 | + return min(test_start_times) < latest_dependency_update |
| 1010 | + else: |
| 1011 | + return True |
| 1012 | + |
| 1013 | + new_test_list = TestList() |
| 1014 | + for test_suite in test_list: |
| 1015 | + if depending_on_change(test_suite): |
| 1016 | + new_test_list.add_suite(test_suite) |
| 1017 | + |
| 1018 | + return new_test_list |
| 1019 | + |
985 | 1020 | def _main_run(self, post_run): |
986 | 1021 | """ |
987 | 1022 | Main with running tests |
988 | 1023 | """ |
989 | 1024 | simulator_if = self._create_simulator_if() |
990 | 1025 | test_list = self._create_tests(simulator_if) |
| 1026 | + if self._args.changed: |
| 1027 | + test_list = self._get_test_list_depending_on_change(test_list) |
| 1028 | + |
991 | 1029 | self._compile(simulator_if) |
992 | 1030 | print() |
993 | 1031 |
|
@@ -1022,6 +1060,9 @@ def _main_list_only(self): |
1022 | 1060 | Main function when only listing test cases |
1023 | 1061 | """ |
1024 | 1062 | test_list = self._create_tests(simulator_if=None) |
| 1063 | + if self._args.changed: |
| 1064 | + test_list = self._get_test_list_depending_on_change(test_list) |
| 1065 | + |
1025 | 1066 | for test_name in test_list.test_names: |
1026 | 1067 | print(test_name) |
1027 | 1068 | print(f"Listed {test_list.num_tests} tests") |
|
0 commit comments