diff --git a/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml b/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml index 14f43f4c1c..2160ef950e 100644 --- a/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml +++ b/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml @@ -39,6 +39,7 @@ gerrit: - event: ref-updated ref: ^(?!refs/).*$ + precedence: low - job: name: base diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py index f9a83ab8ed..7f8c0a33f0 100755 --- a/tests/unit/test_scheduler.py +++ b/tests/unit/test_scheduler.py @@ -4613,6 +4613,45 @@ For CI problems and help debugging, contact ci@example.org""" self.assertIn('project-test1 : SKIPPED', A.messages[1]) self.assertIn('project-test2 : SKIPPED', A.messages[1]) + def test_nodepool_priority(self): + "Test that nodes are requested at the correct priority" + + self.fake_nodepool.paused = True + + A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A') + self.fake_gerrit.addEvent(A.getRefUpdatedEvent()) + + B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B') + self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1)) + + C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C') + C.addApproval('Code-Review', 2) + self.fake_gerrit.addEvent(C.addApproval('Approved', 1)) + + self.waitUntilSettled() + + reqs = self.fake_nodepool.getNodeRequests() + + # The requests come back sorted by oid. Since we have three requests + # for the three changes each with a different priority. + # Also they get a serial number based on order they were received + # so the number on the endof the oid should map to order submitted. + + # * gate first - high priority - change C + self.assertEqual(reqs[0]['_oid'], '100-0000000002') + self.assertEqual(reqs[0]['node_types'], ['label1']) + # * check second - normal priority - change B + self.assertEqual(reqs[1]['_oid'], '200-0000000001') + self.assertEqual(reqs[1]['node_types'], ['label1']) + # * post third - low priority - change A + # additionally, the post job defined uses an ubuntu-xenial node, + # so we include that check just as an extra verification + self.assertEqual(reqs[2]['_oid'], '300-0000000000') + self.assertEqual(reqs[2]['node_types'], ['ubuntu-xenial']) + + self.fake_nodepool.paused = False + self.waitUntilSettled() + @simple_layout('layouts/multiple-templates.yaml') def test_multiple_project_templates(self): # Test that applying multiple project templates to a project diff --git a/zuul/model.py b/zuul/model.py index 5c95cd54a3..5f64c473f1 100644 --- a/zuul/model.py +++ b/zuul/model.py @@ -44,6 +44,12 @@ PRECEDENCE_MAP = { 'high': PRECEDENCE_HIGH, } +PRIORITY_MAP = { + PRECEDENCE_NORMAL: 200, + PRECEDENCE_LOW: 300, + PRECEDENCE_HIGH: 100, +} + # Request states STATE_REQUESTED = 'requested' STATE_PENDING = 'pending' @@ -524,6 +530,10 @@ class NodeRequest(object): self.failed = False self.canceled = False + @property + def priority(self): + return PRIORITY_MAP[self.build_set.item.pipeline.precedence] + @property def fulfilled(self): return (self._state == STATE_FULFILLED) and not self.failed diff --git a/zuul/zk.py b/zuul/zk.py index dcaa172a61..a3efef2090 100644 --- a/zuul/zk.py +++ b/zuul/zk.py @@ -147,12 +147,10 @@ class ZooKeeper(object): from ZooKeeper). The watcher should return False when further updates are no longer necessary. ''' - priority = 100 # TODO(jeblair): integrate into nodereq - data = node_request.toDict() data['created_time'] = time.time() - path = '%s/%s-' % (self.REQUEST_ROOT, priority) + path = '%s/%s-' % (self.REQUEST_ROOT, node_request.priority) path = self.client.create(path, self._dictToStr(data), makepath=True, sequence=True, ephemeral=True)