Merge "SourceContext improvements" into feature/zuulv3
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 14f43f4..2160ef9 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 f9a83ab..7f8c0a3 100755
--- a/tests/unit/test_scheduler.py
+++ b/tests/unit/test_scheduler.py
@@ -4613,6 +4613,45 @@
         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 2fa3d6a..eff0ae3 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -44,6 +44,12 @@
     'high': PRECEDENCE_HIGH,
 }
 
+PRIORITY_MAP = {
+    PRECEDENCE_NORMAL: 200,
+    PRECEDENCE_LOW: 300,
+    PRECEDENCE_HIGH: 100,
+}
+
 # Request states
 STATE_REQUESTED = 'requested'
 STATE_PENDING = 'pending'
@@ -525,6 +531,10 @@
         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 dcaa172..a3efef2 100644
--- a/zuul/zk.py
+++ b/zuul/zk.py
@@ -147,12 +147,10 @@
             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)