diff --git a/tests/fixtures/config/job-pause-priority/git/common-config/zuul.yaml b/tests/fixtures/config/job-pause-priority/git/common-config/zuul.yaml new file mode 100644 index 0000000000..a07342e2ec --- /dev/null +++ b/tests/fixtures/config/job-pause-priority/git/common-config/zuul.yaml @@ -0,0 +1,17 @@ +- pipeline: + name: check + manager: independent + post-review: true + trigger: + gerrit: + - event: patchset-created + success: + gerrit: + Verified: 1 + failure: + gerrit: + Verified: -1 + +- job: + name: base + parent: null diff --git a/tests/fixtures/config/job-pause-priority/git/org_project/README b/tests/fixtures/config/job-pause-priority/git/org_project/README new file mode 100644 index 0000000000..9daeafb986 --- /dev/null +++ b/tests/fixtures/config/job-pause-priority/git/org_project/README @@ -0,0 +1 @@ +test diff --git a/tests/fixtures/config/job-pause-priority/git/org_project/playbooks/compile.yaml b/tests/fixtures/config/job-pause-priority/git/org_project/playbooks/compile.yaml new file mode 100644 index 0000000000..9d6f2dae80 --- /dev/null +++ b/tests/fixtures/config/job-pause-priority/git/org_project/playbooks/compile.yaml @@ -0,0 +1,7 @@ +- hosts: all + tasks: + - name: Pause and let child run + zuul_return: + data: + zuul: + pause: true diff --git a/tests/fixtures/config/job-pause-priority/git/org_project/playbooks/test.yaml b/tests/fixtures/config/job-pause-priority/git/org_project/playbooks/test.yaml new file mode 100644 index 0000000000..f679dceaef --- /dev/null +++ b/tests/fixtures/config/job-pause-priority/git/org_project/playbooks/test.yaml @@ -0,0 +1,2 @@ +- hosts: all + tasks: [] diff --git a/tests/fixtures/config/job-pause-priority/git/org_project/zuul.yaml b/tests/fixtures/config/job-pause-priority/git/org_project/zuul.yaml new file mode 100644 index 0000000000..854b083a32 --- /dev/null +++ b/tests/fixtures/config/job-pause-priority/git/org_project/zuul.yaml @@ -0,0 +1,23 @@ +- job: + name: compile + run: playbooks/compile.yaml + nodeset: + nodes: + - name: compile_node + label: compile_label + +- job: + name: test + run: playbooks/test.yaml + nodeset: + nodes: + - name: test_node + label: test_label + +- project: + check: + jobs: + - compile + - test: + dependencies: + - compile diff --git a/tests/fixtures/config/job-pause-priority/main.yaml b/tests/fixtures/config/job-pause-priority/main.yaml new file mode 100644 index 0000000000..a2130154fd --- /dev/null +++ b/tests/fixtures/config/job-pause-priority/main.yaml @@ -0,0 +1,7 @@ +- tenant: + name: tenant-one + source: + gerrit: + config-projects: + - common-config + - org/project diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py index a30fc26b31..9579e81be7 100644 --- a/tests/unit/test_v3.py +++ b/tests/unit/test_v3.py @@ -31,6 +31,7 @@ from tests.base import ( ZuulDBTestCase, FIXTURE_DIR, simple_layout, + iterate_timeout, ) @@ -4637,7 +4638,7 @@ class TestJobPause(AnsibleZuulTestCase): self.executor_server.verbose = True # Second node request should fail - fail = {'_oid': '200-0000000001'} + fail = {'_oid': '199-0000000001'} self.fake_nodepool.addFailRequest(fail) A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A') @@ -5101,3 +5102,38 @@ class TestForceMergeMissingTemplate(ZuulTestCase): self.assertHistory([ dict(name='other-job', result='SUCCESS', changes='2,1'), ]) + + +class TestJobPausePriority(AnsibleZuulTestCase): + tenant_config_file = 'config/job-pause-priority/main.yaml' + + def test_paused_job_priority(self): + "Test that nodes for children of paused jobs have a higher priority" + + self.fake_nodepool.pause() + self.executor_server.hold_jobs_in_build = True + + A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A') + self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1)) + self.waitUntilSettled() + + reqs = self.fake_nodepool.getNodeRequests() + self.assertEqual(len(reqs), 1) + self.assertEqual(reqs[0]['_oid'], '200-0000000000') + + self.fake_nodepool.unpause() + self.waitUntilSettled() + self.fake_nodepool.pause() + self.executor_server.hold_jobs_in_build = False + self.executor_server.release() + + for x in iterate_timeout(60, 'paused job'): + reqs = self.fake_nodepool.getNodeRequests() + if reqs: + break + + self.assertEqual(len(reqs), 1) + self.assertEqual(reqs[0]['_oid'], '199-0000000001') + + self.fake_nodepool.unpause() + self.waitUntilSettled() diff --git a/zuul/model.py b/zuul/model.py index a6f5be4bf4..90df68449f 100644 --- a/zuul/model.py +++ b/zuul/model.py @@ -723,11 +723,20 @@ class NodeRequest(object): @property def priority(self): + precedence_adjustment = 0 if self.build_set: precedence = self.build_set.item.pipeline.precedence + job_graph = self.build_set.item.job_graph + if job_graph: + for parent in job_graph.getParentJobsRecursively( + self.job.name): + build = self.build_set.getBuild(parent.name) + if build.paused: + precedence_adjustment = -1 else: precedence = PRECEDENCE_NORMAL - return PRIORITY_MAP[precedence] + initial_precedence = PRIORITY_MAP[precedence] + return max(0, initial_precedence + precedence_adjustment) @property def fulfilled(self):