From 6a0452559b6dc6475011098e08eb6fd4105d93cf Mon Sep 17 00:00:00 2001 From: Matt Clay Date: Sat, 12 Jan 2019 00:18:17 -0800 Subject: [PATCH] Handle non-target file deps for integration tests. Some integration test targets have dependencies on files outside the `test/integration/targets/` directory tree. Changes to these dependencies can result in unexpected test failures since they do not trigger integration tests which depend on them. --- .../targets/inventory_foreman_script/aliases | 1 + .../targets/lookup_hashi_vault/aliases | 1 + test/integration/targets/setup_docker/aliases | 1 + test/integration/targets/test_infra/aliases | 2 + test/integration/targets/uri/aliases | 1 + test/runner/lib/classification.py | 42 +++++++++++++++++++ test/runner/lib/target.py | 5 +++ 7 files changed, 53 insertions(+) create mode 100644 test/integration/targets/setup_docker/aliases diff --git a/test/integration/targets/inventory_foreman_script/aliases b/test/integration/targets/inventory_foreman_script/aliases index 64483bbb69b..236bb0768d2 100644 --- a/test/integration/targets/inventory_foreman_script/aliases +++ b/test/integration/targets/inventory_foreman_script/aliases @@ -1,2 +1,3 @@ shippable/cloud/group1 cloud/foreman +needs/file/contrib/inventory/foreman.py diff --git a/test/integration/targets/lookup_hashi_vault/aliases b/test/integration/targets/lookup_hashi_vault/aliases index ffded0edd48..ca01009e65f 100644 --- a/test/integration/targets/lookup_hashi_vault/aliases +++ b/test/integration/targets/lookup_hashi_vault/aliases @@ -1,3 +1,4 @@ shippable/posix/group2 destructive needs/target/setup_openssl +needs/file/test/runner/requirements/constraints.txt diff --git a/test/integration/targets/setup_docker/aliases b/test/integration/targets/setup_docker/aliases new file mode 100644 index 00000000000..f50acb2d6ac --- /dev/null +++ b/test/integration/targets/setup_docker/aliases @@ -0,0 +1 @@ +needs/file/test/runner/requirements/constraints.txt diff --git a/test/integration/targets/test_infra/aliases b/test/integration/targets/test_infra/aliases index b59832142f2..e3073ace3de 100644 --- a/test/integration/targets/test_infra/aliases +++ b/test/integration/targets/test_infra/aliases @@ -1 +1,3 @@ shippable/posix/group3 +needs/file/hacking/test-module +needs/file/lib/ansible/modules/system/ping.py diff --git a/test/integration/targets/uri/aliases b/test/integration/targets/uri/aliases index 90ef161f598..50a839705db 100644 --- a/test/integration/targets/uri/aliases +++ b/test/integration/targets/uri/aliases @@ -1,3 +1,4 @@ destructive shippable/posix/group1 needs/httptester +needs/file/test/runner/requirements/constraints.txt diff --git a/test/runner/lib/classification.py b/test/runner/lib/classification.py index 2071bdf7288..4356dc2a910 100644 --- a/test/runner/lib/classification.py +++ b/test/runner/lib/classification.py @@ -196,7 +196,49 @@ class PathMapper(object): self.powershell_module_utils_imports = {} # populated on first use to reduce overhead when not needed self.csharp_module_utils_imports = {} # populated on first use to reduce overhead when not needed + self.paths_to_dependent_targets = {} + + for target in self.integration_targets: + for path in target.needs_file: + if path not in self.paths_to_dependent_targets: + self.paths_to_dependent_targets[path] = set() + + self.paths_to_dependent_targets[path].add(target) + def get_dependent_paths(self, path): + """ + :type path: str + :rtype: list[str] + """ + unprocessed_paths = set(self.get_dependent_paths_non_recursive(path)) + paths = set() + + while unprocessed_paths: + queued_paths = list(unprocessed_paths) + paths |= unprocessed_paths + unprocessed_paths = set() + + for queued_path in queued_paths: + new_paths = self.get_dependent_paths_non_recursive(queued_path) + + for new_path in new_paths: + if new_path not in paths: + unprocessed_paths.add(new_path) + + return sorted(paths) + + def get_dependent_paths_non_recursive(self, path): + """ + :type path: str + :rtype: list[str] + """ + paths = self.get_dependent_paths_internal(path) + paths += [t.path + '/' for t in self.paths_to_dependent_targets.get(path, set())] + paths = sorted(set(paths)) + + return paths + + def get_dependent_paths_internal(self, path): """ :type path: str :rtype: list[str] diff --git a/test/runner/lib/target.py b/test/runner/lib/target.py index 70fc91abf60..a7e35fdd6ff 100644 --- a/test/runner/lib/target.py +++ b/test/runner/lib/target.py @@ -626,6 +626,11 @@ class IntegrationTarget(CompletionTarget): if self.type not in ('script', 'role'): groups.append('hidden') + # Collect file paths before group expansion to avoid including the directories. + # Ignore references to test targets, as those must be defined using `needs/target/*` or other target references. + self.needs_file = tuple(sorted(set('/'.join(g.split('/')[2:]) for g in groups if + g.startswith('needs/file/') and not g.startswith('needs/file/test/integration/targets/')))) + for group in itertools.islice(groups, 0, len(groups)): if '/' in group: parts = group.split('/')