Merge "Update zuul-changes script for v3" 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/fixtures/layouts/multiple-templates.yaml b/tests/fixtures/layouts/multiple-templates.yaml
new file mode 100644
index 0000000..7272cad
--- /dev/null
+++ b/tests/fixtures/layouts/multiple-templates.yaml
@@ -0,0 +1,44 @@
+- pipeline:
+ name: check
+ manager: independent
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit:
+ Verified: 1
+ failure:
+ gerrit:
+ Verified: -1
+
+- job:
+ name: base
+ parent: null
+
+- job:
+ name: py27
+
+- project-template:
+ name: python-jobs
+ check:
+ jobs:
+ - py27
+
+- project-template:
+ name: python-trusty-jobs
+ check:
+ jobs:
+ - py27:
+ tags:
+ - trusty
+
+- project:
+ name: org/project1
+ templates:
+ - python-jobs
+ - python-trusty-jobs
+
+- project:
+ name: org/project2
+ templates:
+ - python-jobs
diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py
index 2dcd9bf..7f8c0a3 100755
--- a/tests/unit/test_scheduler.py
+++ b/tests/unit/test_scheduler.py
@@ -4613,6 +4613,56 @@
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
+ # doesn't alter them when used for a second project.
+ A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
+ self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+
+ build = self.getJobFromHistory('py27')
+ self.assertEqual(build.parameters['zuul']['jobtags'], [])
+
class TestExecutor(ZuulTestCase):
tenant_config_file = 'config/single-tenant/main.yaml'
diff --git a/zuul/configloader.py b/zuul/configloader.py
index d597ee0..97dfd21 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -486,6 +486,7 @@
job = model.Job(conf['name'])
job.source_context = conf.get('_source_context')
+ job.source_line = conf.get('_start_mark').line +1
is_variant = layout.hasJob(conf['name'])
if 'parent' in conf:
@@ -1403,19 +1404,20 @@
(job.source_context,))
continue
loaded = conf_root
- job.source_context.path = fn
+ source_context = job.source_context.copy()
+ source_context.path = fn
TenantParser.log.info(
"Loading configuration from %s" %
- (job.source_context,))
- project = job.source_context.project
- branch = job.source_context.branch
- if job.source_context.trusted:
+ (source_context,))
+ project = source_context.project
+ branch = source_context.branch
+ if source_context.trusted:
incdata = TenantParser._parseConfigProjectLayout(
- job.files[fn], job.source_context)
+ job.files[fn], source_context)
config_projects_config.extend(incdata)
else:
incdata = TenantParser._parseUntrustedProjectLayout(
- job.files[fn], job.source_context)
+ job.files[fn], source_context)
untrusted_projects_config.extend(incdata)
new_project_unparsed_config[project].extend(incdata)
if branch in new_project_unparsed_branch_config.get(
diff --git a/zuul/model.py b/zuul/model.py
index 4c5a51f..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
@@ -817,6 +827,7 @@
self.other_attributes = dict(
name=None,
source_context=None,
+ source_line=None,
inheritance_path=(),
)
@@ -851,9 +862,11 @@
return self.name
def __repr__(self):
- return '<Job %s branches: %s source: %s>' % (self.name,
- self.branch_matcher,
- self.source_context)
+ return '<Job %s branches: %s source: %s#%s>' % (
+ self.name,
+ self.branch_matcher,
+ self.source_context,
+ self.source_line)
def __getattr__(self, name):
v = self.__dict__.get(name)
@@ -1030,7 +1043,9 @@
if jobname in self.jobs:
self.jobs[jobname].extend(jobs)
else:
- self.jobs[jobname] = jobs
+ # Be sure to make a copy here since this list may be
+ # modified.
+ self.jobs[jobname] = jobs[:]
class JobGraph(object):
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)