diff --git a/tests/fixtures/config/tenant-parser/exclude-all.yaml b/tests/fixtures/config/tenant-parser/exclude-all.yaml new file mode 100644 index 0000000000..e9fb6b5f95 --- /dev/null +++ b/tests/fixtures/config/tenant-parser/exclude-all.yaml @@ -0,0 +1,21 @@ +- tenant: + name: tenant-one + source: + gerrit: + config-projects: + - common-config + untrusted-projects: + - org/project1: + include: [] + - org/project2 + +- tenant: + name: tenant-two + source: + gerrit: + config-projects: + - common-config + untrusted-projects: + - org/project1 + - org/project2 + - org/project5 diff --git a/tests/fixtures/config/tenant-parser/git/org_project5/.zuul.yaml b/tests/fixtures/config/tenant-parser/git/org_project5/.zuul.yaml new file mode 100644 index 0000000000..e6cd45fff6 --- /dev/null +++ b/tests/fixtures/config/tenant-parser/git/org_project5/.zuul.yaml @@ -0,0 +1,3 @@ +- job: + name: project5-job + parent: project1-job diff --git a/tests/unit/test_configloader.py b/tests/unit/test_configloader.py index bb7f98727f..2993aadd8e 100644 --- a/tests/unit/test_configloader.py +++ b/tests/unit/test_configloader.py @@ -312,6 +312,22 @@ class TestTenantUnprotectedBranches(TenantParserTestCase): self.assertIsNone(tpc[project_name].exclude_unprotected_branches) +class TestTenantExcludeAll(TenantParserTestCase): + tenant_config_file = 'config/tenant-parser/exclude-all.yaml' + + def test_tenant_exclude_all(self): + """ + Tests that excluding all configuration of project1 in tenant-one + doesn't remove the configuration of project1 in tenant-two. + """ + # The config in org/project5 depends on config in org/project1 so + # validate that there are no config errors in that tenant. + tenant_two = self.sched.abide.tenants.get('tenant-two') + self.assertEquals( + len(tenant_two.layout.loading_errors), 0, + "No error should have been accumulated") + + class TestSplitConfig(ZuulTestCase): tenant_config_file = 'config/split-config/main.yaml' diff --git a/zuul/configloader.py b/zuul/configloader.py index aab039bc0a..e3d51861b0 100644 --- a/zuul/configloader.py +++ b/zuul/configloader.py @@ -1563,8 +1563,9 @@ class TenantParser(object): # in-repo configuration apply only to that branch. branches = tenant.getProjectBranches(project) for branch in branches: - if abide.getUnparsedConfig(project.canonical_name, - branch): + unparsed_config = abide.getUnparsedConfig( + project.canonical_name, branch) + if unparsed_config and not unparsed_config.load_skipped: # We already have this branch cached. continue if not tpc.load_classes: @@ -1573,7 +1574,7 @@ class TenantParser(object): # data so we know we've looked at this branch. abide.cacheUnparsedConfig( project.canonical_name, - branch, model.UnparsedConfig()) + branch, model.UnparsedConfig(load_skipped=True)) continue job = self.merger.getFiles( project.source.connection.connection_name, diff --git a/zuul/model.py b/zuul/model.py index f766032e28..f0a8d485e3 100644 --- a/zuul/model.py +++ b/zuul/model.py @@ -3218,7 +3218,7 @@ class UnparsedAbideConfig(object): class UnparsedConfig(object): """A collection of yaml lists that has not yet been parsed into objects.""" - def __init__(self): + def __init__(self, load_skipped=False): self.pragmas = [] self.pipelines = [] self.jobs = [] @@ -3228,6 +3228,10 @@ class UnparsedConfig(object): self.secrets = [] self.semaphores = [] + # This indicates wether this is empty because we skipped loading + # earlier because all config items have been excluded. + self.load_skipped = load_skipped + def copy(self, trusted=None): # If trusted is not None, update the source context of each # object in the copy.