Don't validate references for excluded config items
Because of the way the exclude options work in tenant project configs, we will still parse the job objects, even if we plan to discard them later. This leads to failed config loading if we validate references of config options we would exclude anyway. This can be fixed by moving the exclude filter into parseConfig where the parsed config (which is tenant specific) is generated. Co-Authored-By: Tobias Henkel <tobias.henkel@bmw.de> Change-Id: I78b68c5a3c8d403f0837d154a4ac47d11876bae5
This commit is contained in:
parent
7d95d0b1cb
commit
5c9072e958
|
@ -0,0 +1,10 @@
|
|||
- job:
|
||||
name: project3-job
|
||||
required-projects:
|
||||
- doesnot/exist
|
||||
|
||||
- project:
|
||||
name: org/project3
|
||||
check:
|
||||
jobs:
|
||||
- project3-job
|
|
@ -10,3 +10,5 @@
|
|||
- org/project1
|
||||
- org/project2:
|
||||
exclude: job
|
||||
- org/project3:
|
||||
exclude: job
|
||||
|
|
|
@ -153,7 +153,7 @@ class TestTenantGroups2(TenantParserTestCase):
|
|||
tenant = self.sched.abide.tenants.get('tenant-one')
|
||||
self.assertEqual(['common-config'],
|
||||
[x.name for x in tenant.config_projects])
|
||||
self.assertEqual(['org/project1', 'org/project2'],
|
||||
self.assertEqual(['org/project1', 'org/project2', 'org/project3'],
|
||||
[x.name for x in tenant.untrusted_projects])
|
||||
project = tenant.config_projects[0]
|
||||
tpc = tenant.project_configs[project.canonical_name]
|
||||
|
|
|
@ -1582,6 +1582,30 @@ class TestInRepoConfig(ZuulTestCase):
|
|||
self.assertIn('nodeset "does-not-exist" was not found', A.messages[0],
|
||||
"A should have a syntax error reported")
|
||||
|
||||
def test_required_project_not_found_error(self):
|
||||
in_repo_conf = textwrap.dedent(
|
||||
"""
|
||||
- job:
|
||||
name: project-test1
|
||||
- job:
|
||||
name: test
|
||||
required-projects:
|
||||
- does-not-exist
|
||||
""")
|
||||
|
||||
file_dict = {'.zuul.yaml': in_repo_conf}
|
||||
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
|
||||
files=file_dict)
|
||||
A.addApproval('Code-Review', 2)
|
||||
self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
|
||||
self.waitUntilSettled()
|
||||
|
||||
self.assertEqual(A.data['status'], 'NEW')
|
||||
self.assertEqual(A.reported, 1,
|
||||
"A should report failure")
|
||||
self.assertIn('Unknown project does-not-exist', A.messages[0],
|
||||
"A should have a syntax error reported")
|
||||
|
||||
def test_template_not_found_error(self):
|
||||
in_repo_conf = textwrap.dedent(
|
||||
"""
|
||||
|
|
|
@ -1563,7 +1563,7 @@ class TenantParser(object):
|
|||
return data.copy(trusted=False)
|
||||
|
||||
def _getLoadClasses(self, tenant, conf_object):
|
||||
project = conf_object.source_context.project
|
||||
project = conf_object.get('_source_context').project
|
||||
tpc = tenant.project_configs[project.canonical_name]
|
||||
return tpc.load_classes
|
||||
|
||||
|
@ -1577,36 +1577,57 @@ class TenantParser(object):
|
|||
pcontext.pragma_parser.fromYaml(config_pragma)
|
||||
|
||||
for config_pipeline in unparsed_config.pipelines:
|
||||
classes = self._getLoadClasses(tenant, config_pipeline)
|
||||
if 'pipeline' not in classes:
|
||||
continue
|
||||
with configuration_exceptions('pipeline', config_pipeline):
|
||||
parsed_config.pipelines.append(
|
||||
pcontext.pipeline_parser.fromYaml(config_pipeline))
|
||||
|
||||
for config_nodeset in unparsed_config.nodesets:
|
||||
classes = self._getLoadClasses(tenant, config_nodeset)
|
||||
if 'nodeset' not in classes:
|
||||
continue
|
||||
with configuration_exceptions('nodeset', config_nodeset):
|
||||
parsed_config.nodesets.append(
|
||||
pcontext.nodeset_parser.fromYaml(config_nodeset))
|
||||
|
||||
for config_secret in unparsed_config.secrets:
|
||||
classes = self._getLoadClasses(tenant, config_secret)
|
||||
if 'secret' not in classes:
|
||||
continue
|
||||
with configuration_exceptions('secret', config_secret):
|
||||
parsed_config.secrets.append(
|
||||
pcontext.secret_parser.fromYaml(config_secret))
|
||||
|
||||
for config_job in unparsed_config.jobs:
|
||||
classes = self._getLoadClasses(tenant, config_job)
|
||||
if 'job' not in classes:
|
||||
continue
|
||||
with configuration_exceptions('job', config_job):
|
||||
parsed_config.jobs.append(
|
||||
pcontext.job_parser.fromYaml(config_job))
|
||||
|
||||
for config_semaphore in unparsed_config.semaphores:
|
||||
classes = self._getLoadClasses(tenant, config_semaphore)
|
||||
if 'semaphore' not in classes:
|
||||
continue
|
||||
with configuration_exceptions('semaphore', config_semaphore):
|
||||
parsed_config.semaphores.append(
|
||||
pcontext.semaphore_parser.fromYaml(config_semaphore))
|
||||
|
||||
for config_template in unparsed_config.project_templates:
|
||||
classes = self._getLoadClasses(tenant, config_template)
|
||||
if 'project-template' not in classes:
|
||||
continue
|
||||
with configuration_exceptions('project-template', config_template):
|
||||
parsed_config.project_templates.append(
|
||||
pcontext.project_template_parser.fromYaml(config_template))
|
||||
|
||||
for config_project in unparsed_config.projects:
|
||||
classes = self._getLoadClasses(tenant, config_project)
|
||||
if 'project' not in classes:
|
||||
continue
|
||||
with configuration_exceptions('project', config_project):
|
||||
# we need to separate the regex projects as they are processed
|
||||
# differently later
|
||||
|
@ -1665,29 +1686,17 @@ class TenantParser(object):
|
|||
# reference_exceptions has it; add tests if needed.
|
||||
if not skip_pipelines:
|
||||
for pipeline in parsed_config.pipelines:
|
||||
classes = self._getLoadClasses(tenant, pipeline)
|
||||
if 'pipeline' not in classes:
|
||||
continue
|
||||
layout.addPipeline(pipeline)
|
||||
|
||||
for nodeset in parsed_config.nodesets:
|
||||
classes = self._getLoadClasses(tenant, nodeset)
|
||||
if 'nodeset' not in classes:
|
||||
continue
|
||||
with reference_exceptions('nodeset', nodeset):
|
||||
layout.addNodeSet(nodeset)
|
||||
|
||||
for secret in parsed_config.secrets:
|
||||
classes = self._getLoadClasses(tenant, secret)
|
||||
if 'secret' not in classes:
|
||||
continue
|
||||
with reference_exceptions('secret', secret):
|
||||
layout.addSecret(secret)
|
||||
|
||||
for job in parsed_config.jobs:
|
||||
classes = self._getLoadClasses(tenant, job)
|
||||
if 'job' not in classes:
|
||||
continue
|
||||
with reference_exceptions('job', job):
|
||||
added = layout.addJob(job)
|
||||
if not added:
|
||||
|
@ -1711,16 +1720,10 @@ class TenantParser(object):
|
|||
else:
|
||||
semaphore_layout = layout
|
||||
for semaphore in parsed_config.semaphores:
|
||||
classes = self._getLoadClasses(tenant, semaphore)
|
||||
if 'semaphore' not in classes:
|
||||
continue
|
||||
with reference_exceptions('semaphore', semaphore):
|
||||
semaphore_layout.addSemaphore(semaphore)
|
||||
|
||||
for template in parsed_config.project_templates:
|
||||
classes = self._getLoadClasses(tenant, template)
|
||||
if 'project-template' not in classes:
|
||||
continue
|
||||
with reference_exceptions('project-template', template):
|
||||
layout.addProjectTemplate(template)
|
||||
|
||||
|
@ -1741,9 +1744,6 @@ class TenantParser(object):
|
|||
parsed_config.projects.append(conf)
|
||||
|
||||
for project in parsed_config.projects:
|
||||
classes = self._getLoadClasses(tenant, project)
|
||||
if 'project' not in classes:
|
||||
continue
|
||||
layout.addProjectConfig(project)
|
||||
|
||||
# Now that all the project pipelines are loaded, fixup and
|
||||
|
|
Loading…
Reference in New Issue