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