Merge "Update webapp status json to support tenants" into feature/zuulv3
diff --git a/tests/base.py b/tests/base.py
index 073b8ad..b343655 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -41,7 +41,7 @@
import fixtures
import statsd
import testtools
-from git import GitCommandError
+from git.exc import NoSuchPathError
import zuul.connection.gerrit
import zuul.connection.smtp
@@ -640,17 +640,20 @@
:rtype: bool
"""
- project = self.parameters['ZUUL_PROJECT']
- path = os.path.join(self.jobdir.git_root, project)
- repo = git.Repo(path)
- ref = self.parameters['ZUUL_REF']
- repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
- commit_messages = ['%s-1' % change.subject for change in changes]
- self.log.debug("Checking if build %s has changes; commit_messages %s;"
- " repo_messages %s" % (self, commit_messages,
- repo_messages))
- for msg in commit_messages:
- if msg not in repo_messages:
+ for change in changes:
+ path = os.path.join(self.jobdir.git_root, change.project)
+ try:
+ repo = git.Repo(path)
+ except NoSuchPathError as e:
+ self.log.debug('%s' % e)
+ return False
+ ref = self.parameters['ZUUL_REF']
+ repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
+ commit_message = '%s-1' % change.subject
+ self.log.debug("Checking if build %s has changes; commit_message "
+ "%s; repo_messages %s" % (self, commit_message,
+ repo_messages))
+ if commit_message not in repo_messages:
self.log.debug(" messages do not match")
return False
self.log.debug(" OK")
@@ -1262,19 +1265,6 @@
commit = repo.index.commit('Creating a fake commit')
return commit.hexsha
- def ref_has_change(self, ref, change):
- # TODOv3(jeblair): this should probably be removed in favor of
- # build.hasChanges
- path = os.path.join(self.git_root, change.project)
- repo = git.Repo(path)
- try:
- for commit in repo.iter_commits(ref):
- if commit.message.strip() == ('%s-1' % change.subject):
- return True
- except GitCommandError:
- pass
- return False
-
def orderedRelease(self):
# Run one build at a time to ensure non-race order:
while len(self.builds):
@@ -1540,13 +1530,16 @@
os.makedirs(root)
f = tempfile.NamedTemporaryFile(dir=root, delete=False)
f.write("""
-tenants:
- - name: openstack
- include:
- - %s
- """ % os.path.abspath(path))
+- tenant:
+ name: openstack
+ source:
+ gerrit:
+ config-repos:
+ - %s
+ """ % path)
f.close()
- self.config.set('zuul', 'tenant_config', f.name)
+ self.config.set('zuul', 'tenant_config',
+ os.path.join(FIXTURE_DIR, f.name))
def addCommitToRepo(self, project, message, files,
branch='master', tag=None):
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 20906e6..0ddb6e5 100644
--- a/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml
@@ -70,6 +70,10 @@
name: project-test2
- job:
+ name: project1-project2-integration
+ queue-name: integration
+
+- job:
name: experimental-project-test
- project:
@@ -95,6 +99,7 @@
jobs:
- project-test1
- project-test2
+ - project1-project2-integration
gate:
queue: integrated
jobs:
@@ -102,6 +107,7 @@
jobs:
- project-test1
- project-test2
+ - project1-project2-integration
- project:
name: org/project2
@@ -120,3 +126,12 @@
- project-merge:
jobs:
- experimental-project-test
+
+- project:
+ name: org/noop-project
+ check:
+ jobs:
+ - noop
+ gate:
+ jobs:
+ - noop
diff --git a/tests/fixtures/config/single-tenant/git/layout-disabled-at/zuul.yaml b/tests/fixtures/config/single-tenant/git/layout-disabled-at/zuul.yaml
new file mode 100644
index 0000000..4cf6f16
--- /dev/null
+++ b/tests/fixtures/config/single-tenant/git/layout-disabled-at/zuul.yaml
@@ -0,0 +1,30 @@
+- pipeline:
+ name: check
+ manager: independent
+ source:
+ gerrit
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit:
+ verified: 1
+ failure:
+ gerrit:
+ verified: -1
+ disabled:
+ smtp:
+ to: you@example.com
+ disable-after-consecutive-failures: 3
+
+- job:
+ name: project-test1
+ nodes:
+ - name: controller
+ image: image1
+
+- project:
+ name: org/project
+ check:
+ jobs:
+ - project-test1
diff --git a/tests/fixtures/config/single-tenant/git/layout-irrelevant-files/zuul.yaml b/tests/fixtures/config/single-tenant/git/layout-irrelevant-files/zuul.yaml
new file mode 100644
index 0000000..f243bcc
--- /dev/null
+++ b/tests/fixtures/config/single-tenant/git/layout-irrelevant-files/zuul.yaml
@@ -0,0 +1,27 @@
+- pipeline:
+ name: check
+ manager: independent
+ source:
+ gerrit
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit:
+ verified: 1
+ failure:
+ gerrit:
+ verified: -1
+
+
+- job:
+ name: project-test-irrelevant-files
+
+- project:
+ name: org/project
+ check:
+ jobs:
+ - project-test-irrelevant-files:
+ irrelevant-files:
+ - ^README$
+ - ^ignoreme$
diff --git a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/zuul.yaml b/tests/fixtures/config/single-tenant/git/layout-repo-deleted/zuul.yaml
new file mode 100644
index 0000000..2bffc3e
--- /dev/null
+++ b/tests/fixtures/config/single-tenant/git/layout-repo-deleted/zuul.yaml
@@ -0,0 +1,72 @@
+- pipeline:
+ name: check
+ manager: independent
+ source:
+ gerrit
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit:
+ verified: 1
+ failure:
+ gerrit:
+ verified: -1
+
+- pipeline:
+ name: gate
+ manager: dependent
+ success-message: Build succeeded (gate).
+ source:
+ gerrit
+ trigger:
+ gerrit:
+ - event: comment-added
+ approval:
+ - approved: 1
+ success:
+ gerrit:
+ verified: 2
+ submit: true
+ failure:
+ gerrit:
+ verified: -2
+ start:
+ gerrit:
+ verified: 0
+ precedence: high
+
+- job:
+ name: project-merge
+ hold-following-changes: true
+
+- job:
+ name: project-test1
+ nodes:
+ - name: controller
+ image: image1
+
+- job:
+ name: project-test1
+ branches: stable
+ nodes:
+ - name: controller
+ image: image2
+
+- job:
+ name: project-test2
+
+- project:
+ name: org/delete-project
+ check:
+ jobs:
+ - project-merge:
+ jobs:
+ - project-test1
+ - project-test2
+ gate:
+ jobs:
+ - project-merge:
+ jobs:
+ - project-test1
+ - project-test2
diff --git a/tests/fixtures/config/single-tenant/git/layout-smtp/zuul.yaml b/tests/fixtures/config/single-tenant/git/layout-smtp/zuul.yaml
new file mode 100644
index 0000000..9effb1f
--- /dev/null
+++ b/tests/fixtures/config/single-tenant/git/layout-smtp/zuul.yaml
@@ -0,0 +1,81 @@
+- pipeline:
+ name: check
+ manager: independent
+ source:
+ gerrit
+ trigger:
+ gerrit:
+ - event: patchset-created
+ start:
+ smtp:
+ to: you@example.com
+ success:
+ gerrit:
+ verified: 1
+ smtp:
+ to: alternative_me@example.com
+ from: zuul_from@example.com
+ failure:
+ gerrit:
+ verified: -1
+
+- pipeline:
+ name: gate
+ manager: dependent
+ success-message: Build succeeded (gate).
+ source:
+ gerrit
+ trigger:
+ gerrit:
+ - event: comment-added
+ approval:
+ - approved: 1
+ success:
+ gerrit:
+ verified: 2
+ submit: true
+ failure:
+ gerrit:
+ verified: -2
+ start:
+ gerrit:
+ verified: 0
+ precedence: high
+
+- job:
+ name: project-merge
+ hold-following-changes: true
+
+- job:
+ name: project-test1
+ nodes:
+ - name: controller
+ image: image1
+
+- job:
+ name: project-test1
+ branches: stable
+ nodes:
+ - name: controller
+ image: image2
+
+- job:
+ name: project-test2
+
+- job:
+ name: experimental-project-test
+
+- project:
+ name: org/project
+ check:
+ jobs:
+ - project-merge:
+ jobs:
+ - project-test1
+ - project-test2
+ gate:
+ jobs:
+ - project-merge:
+ jobs:
+ - project-test1
+ - project-test2
diff --git a/tests/fixtures/config/single-tenant/git/org_delete-project/README b/tests/fixtures/config/single-tenant/git/org_delete-project/README
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/tests/fixtures/config/single-tenant/git/org_delete-project/README
@@ -0,0 +1 @@
+test
diff --git a/tests/fixtures/config/single-tenant/git/org_noop-project/README b/tests/fixtures/config/single-tenant/git/org_noop-project/README
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/tests/fixtures/config/single-tenant/git/org_noop-project/README
@@ -0,0 +1 @@
+test
diff --git a/tests/fixtures/config/single-tenant/git/org_unknown/README b/tests/fixtures/config/single-tenant/git/org_unknown/README
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/tests/fixtures/config/single-tenant/git/org_unknown/README
@@ -0,0 +1 @@
+test
diff --git a/tests/fixtures/layout-repo-deleted.yaml b/tests/fixtures/layout-repo-deleted.yaml
deleted file mode 100644
index 967009a..0000000
--- a/tests/fixtures/layout-repo-deleted.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-pipelines:
- - name: check
- manager: IndependentPipelineManager
- trigger:
- gerrit:
- - event: patchset-created
- success:
- gerrit:
- verified: 1
- failure:
- gerrit:
- verified: -1
-
- - name: post
- manager: IndependentPipelineManager
- trigger:
- gerrit:
- - event: ref-updated
- ref: ^(?!refs/).*$
-
- - name: gate
- manager: DependentPipelineManager
- failure-message: Build failed. For information on how to proceed, see http://wiki.example.org/Test_Failures
- trigger:
- gerrit:
- - event: comment-added
- approval:
- - approved: 1
- success:
- gerrit:
- verified: 2
- submit: true
- failure:
- gerrit:
- verified: -2
- start:
- gerrit:
- verified: 0
- precedence: high
-
-projects:
- - name: org/delete-project
- check:
- - project-merge:
- - project-test1
- - project-test2
- gate:
- - project-merge:
- - project-test1
- - project-test2
- post:
- - project-post
diff --git a/tests/fixtures/layout-skip-if.yaml b/tests/fixtures/layout-skip-if.yaml
deleted file mode 100644
index 0cfb445..0000000
--- a/tests/fixtures/layout-skip-if.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-pipelines:
- - name: check
- manager: IndependentPipelineManager
- trigger:
- gerrit:
- - event: patchset-created
- success:
- gerrit:
- verified: 1
- failure:
- gerrit:
- verified: -1
-
-
-jobs:
- # Defining a metajob will validate that the skip-if attribute of the
- # metajob is correctly copied to the job.
- - name: ^.*skip-if$
- skip-if:
- - project: ^org/project$
- branch: ^master$
- all-files-match-any:
- - ^README$
- - name: project-test-skip-if
-
-projects:
- - name: org/project
- check:
- - project-test-skip-if
diff --git a/tests/test_merger_repo.py b/tests/test_merger_repo.py
index 7bf08ee..5062c14 100644
--- a/tests/test_merger_repo.py
+++ b/tests/test_merger_repo.py
@@ -31,14 +31,12 @@
class TestMergerRepo(ZuulTestCase):
log = logging.getLogger("zuul.test.merger.repo")
+ tenant_config_file = 'config/single-tenant/main.yaml'
workspace_root = None
def setUp(self):
- self.skip("Disabled for early v3 development")
-
- # def setUp(self):
- # super(TestMergerRepo, self).setUp()
- # self.workspace_root = os.path.join(self.test_root, 'workspace')
+ super(TestMergerRepo, self).setUp()
+ self.workspace_root = os.path.join(self.test_root, 'workspace')
def test_ensure_cloned(self):
parent_path = os.path.join(self.upstream_root, 'org/project1')
diff --git a/tests/test_requirements.py b/tests/test_requirements.py
index 1cad659..1f179e6 100644
--- a/tests/test_requirements.py
+++ b/tests/test_requirements.py
@@ -16,6 +16,7 @@
import logging
import time
+from unittest import skip
from tests.base import ZuulTestCase
@@ -27,14 +28,13 @@
class TestRequirements(ZuulTestCase):
"""Test pipeline and trigger requirements"""
- def setUp(self):
- self.skip("Disabled for early v3 development")
-
+ @skip("Disabled for early v3 development")
def test_pipeline_require_approval_newer_than(self):
"Test pipeline requirement: approval newer than"
return self._test_require_approval_newer_than('org/project1',
'project1-pipeline')
+ @skip("Disabled for early v3 development")
def test_trigger_require_approval_newer_than(self):
"Test trigger requirement: approval newer than"
return self._test_require_approval_newer_than('org/project2',
@@ -68,11 +68,13 @@
self.assertEqual(len(self.history), 1)
self.assertEqual(self.history[0].name, job)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_approval_older_than(self):
"Test pipeline requirement: approval older than"
return self._test_require_approval_older_than('org/project1',
'project1-pipeline')
+ @skip("Disabled for early v3 development")
def test_trigger_require_approval_older_than(self):
"Test trigger requirement: approval older than"
return self._test_require_approval_older_than('org/project2',
@@ -106,11 +108,13 @@
self.assertEqual(len(self.history), 1)
self.assertEqual(self.history[0].name, job)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_approval_username(self):
"Test pipeline requirement: approval username"
return self._test_require_approval_username('org/project1',
'project1-pipeline')
+ @skip("Disabled for early v3 development")
def test_trigger_require_approval_username(self):
"Test trigger requirement: approval username"
return self._test_require_approval_username('org/project2',
@@ -137,11 +141,13 @@
self.assertEqual(len(self.history), 1)
self.assertEqual(self.history[0].name, job)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_approval_email(self):
"Test pipeline requirement: approval email"
return self._test_require_approval_email('org/project1',
'project1-pipeline')
+ @skip("Disabled for early v3 development")
def test_trigger_require_approval_email(self):
"Test trigger requirement: approval email"
return self._test_require_approval_email('org/project2',
@@ -168,11 +174,13 @@
self.assertEqual(len(self.history), 1)
self.assertEqual(self.history[0].name, job)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_approval_vote1(self):
"Test pipeline requirement: approval vote with one value"
return self._test_require_approval_vote1('org/project1',
'project1-pipeline')
+ @skip("Disabled for early v3 development")
def test_trigger_require_approval_vote1(self):
"Test trigger requirement: approval vote with one value"
return self._test_require_approval_vote1('org/project2',
@@ -205,11 +213,13 @@
self.assertEqual(len(self.history), 1)
self.assertEqual(self.history[0].name, job)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_approval_vote2(self):
"Test pipeline requirement: approval vote with two values"
return self._test_require_approval_vote2('org/project1',
'project1-pipeline')
+ @skip("Disabled for early v3 development")
def test_trigger_require_approval_vote2(self):
"Test trigger requirement: approval vote with two values"
return self._test_require_approval_vote2('org/project2',
@@ -262,6 +272,7 @@
self.assertEqual(len(self.history), 2)
self.assertEqual(self.history[1].name, job)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_current_patchset(self):
"Test pipeline requirement: current-patchset"
self.updateConfigLayout(
@@ -290,6 +301,7 @@
self.waitUntilSettled()
self.assertEqual(len(self.history), 3)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_open(self):
"Test pipeline requirement: open"
self.updateConfigLayout(
@@ -308,6 +320,7 @@
self.waitUntilSettled()
self.assertEqual(len(self.history), 1)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_status(self):
"Test pipeline requirement: status"
self.updateConfigLayout(
@@ -358,11 +371,13 @@
self.waitUntilSettled()
self.assertEqual(len(self.history), 1)
+ @skip("Disabled for early v3 development")
def test_pipeline_reject_username(self):
"Test negative pipeline requirement: no comment from jenkins"
return self._test_require_reject_username('org/project1',
'project1-pipeline')
+ @skip("Disabled for early v3 development")
def test_trigger_reject_username(self):
"Test negative trigger requirement: no comment from jenkins"
return self._test_require_reject_username('org/project2',
@@ -418,10 +433,12 @@
self.assertEqual(len(self.history), 3)
self.assertEqual(self.history[2].name, job)
+ @skip("Disabled for early v3 development")
def test_pipeline_require_reject(self):
"Test pipeline requirement: rejections absent"
return self._test_require_reject('org/project1', 'project1-pipeline')
+ @skip("Disabled for early v3 development")
def test_trigger_require_reject(self):
"Test trigger requirement: rejections absent"
return self._test_require_reject('org/project2', 'project2-trigger')
diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py
index dc479ab..f3ae204 100755
--- a/tests/test_scheduler.py
+++ b/tests/test_scheduler.py
@@ -20,7 +20,6 @@
import re
import shutil
import time
-import yaml
from unittest import skip
import git
@@ -284,6 +283,7 @@
dict(name='project-test2', changes='1,1'),
dict(name='project-test1', changes='2,1'),
dict(name='project-test2', changes='2,1'),
+ dict(name='project1-project2-integration', changes='2,1'),
dict(name='project-test1', changes='2,1 3,1'),
dict(name='project-test2', changes='2,1 3,1'),
])
@@ -297,6 +297,10 @@
dict(name='project-test2', result='SUCCESS', changes='1,1'),
dict(name='project-test1', result='SUCCESS', changes='2,1'),
dict(name='project-test2', result='SUCCESS', changes='2,1'),
+ dict(
+ name='project1-project2-integration',
+ result='SUCCESS',
+ changes='2,1'),
dict(name='project-test1', result='SUCCESS', changes='2,1 3,1'),
dict(name='project-test2', result='SUCCESS', changes='2,1 3,1'),
])
@@ -500,7 +504,6 @@
self.assertEqual(B.reported, 2)
self.assertEqual(C.reported, 2)
- @skip("Disabled for early v3 development")
def test_failed_change_at_head_with_queue(self):
"Test that if a change at the head fails, queued jobs are canceled"
@@ -522,8 +525,10 @@
queue = self.gearman_server.getQueue()
self.assertEqual(len(self.builds), 0)
self.assertEqual(len(queue), 1)
- self.assertEqual(queue[0].name, 'build:project-merge')
- self.assertTrue(self.job_has_changes(queue[0], A))
+ self.assertEqual(queue[0].name, 'launcher:launch')
+ job_args = json.loads(queue[0].arguments)
+ self.assertEqual(job_args['job'], 'project-merge')
+ self.assertEqual(job_args['items'][0]['number'], '%d' % A.number)
self.gearman_server.release('.*-merge')
self.waitUntilSettled()
@@ -535,12 +540,19 @@
self.assertEqual(len(self.builds), 0)
self.assertEqual(len(queue), 6)
- self.assertEqual(queue[0].name, 'build:project-test1')
- self.assertEqual(queue[1].name, 'build:project-test2')
- self.assertEqual(queue[2].name, 'build:project-test1')
- self.assertEqual(queue[3].name, 'build:project-test2')
- self.assertEqual(queue[4].name, 'build:project-test1')
- self.assertEqual(queue[5].name, 'build:project-test2')
+
+ self.assertEqual(
+ json.loads(queue[0].arguments)['job'], 'project-test1')
+ self.assertEqual(
+ json.loads(queue[1].arguments)['job'], 'project-test2')
+ self.assertEqual(
+ json.loads(queue[2].arguments)['job'], 'project-test1')
+ self.assertEqual(
+ json.loads(queue[3].arguments)['job'], 'project-test2')
+ self.assertEqual(
+ json.loads(queue[4].arguments)['job'], 'project-test1')
+ self.assertEqual(
+ json.loads(queue[5].arguments)['job'], 'project-test2')
self.release(queue[0])
self.waitUntilSettled()
@@ -710,37 +722,6 @@
self.assertEqual(B.reported, 2)
self.assertEqual(C.reported, 2)
- @skip("Disabled for early v3 development")
- def test_parse_skip_if(self):
- job_yaml = """
-jobs:
- - name: job_name
- skip-if:
- - project: ^project_name$
- branch: ^stable/icehouse$
- all-files-match-any:
- - ^filename$
- - project: ^project2_name$
- all-files-match-any:
- - ^filename2$
- """.strip()
- data = yaml.load(job_yaml)
- config_job = data.get('jobs')[0]
- cm = zuul.change_matcher
- expected = cm.MatchAny([
- cm.MatchAll([
- cm.ProjectMatcher('^project_name$'),
- cm.BranchMatcher('^stable/icehouse$'),
- cm.MatchAllFiles([cm.FileMatcher('^filename$')]),
- ]),
- cm.MatchAll([
- cm.ProjectMatcher('^project2_name$'),
- cm.MatchAllFiles([cm.FileMatcher('^filename2$')]),
- ]),
- ])
- matcher = self.sched._parseSkipIf(config_job)
- self.assertEqual(expected, matcher)
-
def test_patch_order(self):
"Test that dependent patches are tested in the right order"
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
@@ -1325,7 +1306,6 @@
self.assertIn('Build succeeded', E.messages[1])
self.assertEqual(len(self.history), 18)
- @skip("Disabled for early v3 development")
def test_head_is_dequeued_once(self):
"Test that if a change at the head fails it is dequeued only once"
# If it's dequeued more than once, we should see extra
@@ -1339,8 +1319,8 @@
B.addApproval('code-review', 2)
C.addApproval('code-review', 2)
- self.launch_server.failJob('project1-test1', A)
- self.launch_server.failJob('project1-test2', A)
+ self.launch_server.failJob('project-test1', A)
+ self.launch_server.failJob('project-test2', A)
self.launch_server.failJob('project1-project2-integration', A)
self.fake_gerrit.addEvent(A.addApproval('approved', 1))
@@ -1350,8 +1330,8 @@
self.waitUntilSettled()
self.assertEqual(len(self.builds), 1)
- self.assertEqual(self.builds[0].name, 'project1-merge')
- self.assertTrue(self.job_has_changes(self.builds[0], A))
+ self.assertEqual(self.builds[0].name, 'project-merge')
+ self.assertTrue(self.builds[0].hasChanges(A))
self.launch_server.release('.*-merge')
self.waitUntilSettled()
@@ -1361,14 +1341,14 @@
self.waitUntilSettled()
self.assertEqual(len(self.builds), 9)
- self.assertEqual(self.builds[0].name, 'project1-test1')
- self.assertEqual(self.builds[1].name, 'project1-test2')
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'project-test2')
self.assertEqual(self.builds[2].name, 'project1-project2-integration')
- self.assertEqual(self.builds[3].name, 'project1-test1')
- self.assertEqual(self.builds[4].name, 'project1-test2')
+ self.assertEqual(self.builds[3].name, 'project-test1')
+ self.assertEqual(self.builds[4].name, 'project-test2')
self.assertEqual(self.builds[5].name, 'project1-project2-integration')
- self.assertEqual(self.builds[6].name, 'project1-test1')
- self.assertEqual(self.builds[7].name, 'project1-test2')
+ self.assertEqual(self.builds[6].name, 'project-test1')
+ self.assertEqual(self.builds[7].name, 'project-test2')
self.assertEqual(self.builds[8].name, 'project1-project2-integration')
self.release(self.builds[0])
@@ -1574,13 +1554,13 @@
self.assertEqual(A.data['status'], 'MERGED')
self.assertEqual(A.reported, 2)
- @skip("Disabled for early v3 development")
def test_merger_repack_large_change(self):
"Test that the merger works with large changes after a repack"
# https://bugs.launchpad.net/zuul/+bug/1078946
# This test assumes the repo is already cloned; make sure it is
+ tenant = self.sched.abide.tenants.get('tenant-one')
url = self.fake_gerrit.getGitUrl(
- self.sched.layout.projects['org/project1'])
+ tenant.layout.project_configs.get('org/project1'))
self.merge_server.merger.addProject('org/project1', url)
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
A.addPatchset(large=True)
@@ -1592,11 +1572,11 @@
A.addApproval('code-review', 2)
self.fake_gerrit.addEvent(A.addApproval('approved', 1))
self.waitUntilSettled()
- self.assertEqual(self.getJobFromHistory('project1-merge').result,
+ self.assertEqual(self.getJobFromHistory('project-merge').result,
'SUCCESS')
- self.assertEqual(self.getJobFromHistory('project1-test1').result,
+ self.assertEqual(self.getJobFromHistory('project-test1').result,
'SUCCESS')
- self.assertEqual(self.getJobFromHistory('project1-test2').result,
+ self.assertEqual(self.getJobFromHistory('project-test2').result,
'SUCCESS')
self.assertEqual(A.data['status'], 'MERGED')
self.assertEqual(A.reported, 2)
@@ -2010,7 +1990,6 @@
self.assertEqual(len(self.history), 10)
self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
- @skip("Disabled for early v3 development")
def test_noop_job(self):
"Test that the internal noop job works"
A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
@@ -2042,7 +2021,6 @@
self.assertEqual(len(self.history), 0)
- @skip("Disabled for early v3 development")
def test_zuul_refs(self):
"Test that zuul refs exist and have the right changes"
self.launch_server.hold_jobs_in_build = True
@@ -2075,15 +2053,22 @@
self.waitUntilSettled()
a_zref = b_zref = c_zref = d_zref = None
+ a_build = b_build = c_build = d_build = None
for x in self.builds:
if x.parameters['ZUUL_CHANGE'] == '3':
a_zref = x.parameters['ZUUL_REF']
- if x.parameters['ZUUL_CHANGE'] == '4':
+ a_build = x
+ elif x.parameters['ZUUL_CHANGE'] == '4':
b_zref = x.parameters['ZUUL_REF']
- if x.parameters['ZUUL_CHANGE'] == '5':
+ b_build = x
+ elif x.parameters['ZUUL_CHANGE'] == '5':
c_zref = x.parameters['ZUUL_REF']
- if x.parameters['ZUUL_CHANGE'] == '6':
+ c_build = x
+ elif x.parameters['ZUUL_CHANGE'] == '6':
d_zref = x.parameters['ZUUL_REF']
+ d_build = x
+ if a_build and b_build and c_build and d_build:
+ break
# There are... four... refs.
self.assertIsNotNone(a_zref)
@@ -2095,27 +2080,20 @@
refs = set([a_zref, b_zref, c_zref, d_zref])
self.assertEqual(len(refs), 4)
- # a ref should have a, not b, and should not be in project2
- self.assertTrue(self.ref_has_change(a_zref, A))
- self.assertFalse(self.ref_has_change(a_zref, B))
- self.assertFalse(self.ref_has_change(a_zref, M2))
+ # should have a, not b, and should not be in project2
+ self.assertTrue(a_build.hasChanges(A))
+ self.assertFalse(a_build.hasChanges(B, M2))
- # b ref should have a and b, and should not be in project2
- self.assertTrue(self.ref_has_change(b_zref, A))
- self.assertTrue(self.ref_has_change(b_zref, B))
- self.assertFalse(self.ref_has_change(b_zref, M2))
+ # should have a and b, and should not be in project2
+ self.assertTrue(b_build.hasChanges(A, B))
+ self.assertFalse(b_build.hasChanges(M2))
- # c ref should have a and b in 1, c in 2
- self.assertTrue(self.ref_has_change(c_zref, A))
- self.assertTrue(self.ref_has_change(c_zref, B))
- self.assertTrue(self.ref_has_change(c_zref, C))
- self.assertFalse(self.ref_has_change(c_zref, D))
+ # should have a and b in 1, c in 2
+ self.assertTrue(c_build.hasChanges(A, B, C))
+ self.assertFalse(c_build.hasChanges(D))
- # d ref should have a and b in 1, c and d in 2
- self.assertTrue(self.ref_has_change(d_zref, A))
- self.assertTrue(self.ref_has_change(d_zref, B))
- self.assertTrue(self.ref_has_change(d_zref, C))
- self.assertTrue(self.ref_has_change(d_zref, D))
+ # should have a and b in 1, c and d in 2
+ self.assertTrue(d_build.hasChanges(A, B, C, D))
self.launch_server.hold_jobs_in_build = False
self.launch_server.release()
@@ -2232,35 +2210,36 @@
self.assertEqual(B.data['status'], 'MERGED')
self.assertEqual(B.reported, 2)
- @skip("Disabled for early v3 development")
- def _test_skip_if_jobs(self, branch, should_skip):
- "Test that jobs with a skip-if filter run only when appropriate"
- self.updateConfigLayout(
- 'tests/fixtures/layout-skip-if.yaml')
+ def _test_irrelevant_files_jobs(self, should_skip):
+ "Test that jobs with irrelevant-files filter run only when appropriate"
+ self.updateConfigLayout('layout-irrelevant-files')
self.sched.reconfigure(self.config)
- self.registerJobs()
+
+ if should_skip:
+ files = {'ignoreme': 'ignored\n'}
+ else:
+ files = {'respectme': 'please!\n'}
change = self.fake_gerrit.addFakeChange('org/project',
- branch,
- 'test skip-if')
+ 'master',
+ 'test irrelevant-files',
+ files=files)
self.fake_gerrit.addEvent(change.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
tested_change_ids = [x.changes[0] for x in self.history
- if x.name == 'project-test-skip-if']
+ if x.name == 'project-test-irrelevant-files']
if should_skip:
self.assertEqual([], tested_change_ids)
else:
self.assertIn(change.data['number'], tested_change_ids)
- @skip("Disabled for early v3 development")
- def test_skip_if_match_skips_job(self):
- self._test_skip_if_jobs(branch='master', should_skip=True)
+ def test_irrelevant_files_match_skips_job(self):
+ self._test_irrelevant_files_jobs(should_skip=True)
- @skip("Disabled for early v3 development")
- def test_skip_if_no_match_runs_job(self):
- self._test_skip_if_jobs(branch='mp', should_skip=False)
+ def test_irrelevant_files_no_match_runs_job(self):
+ self._test_irrelevant_files_jobs(should_skip=False)
@skip("Disabled for early v3 development")
def test_test_config(self):
@@ -2463,7 +2442,6 @@
'debian')
self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
- @skip("Disabled for early v3 development")
def test_live_reconfiguration(self):
"Test that live reconfiguration works"
self.launch_server.hold_jobs_in_build = True
@@ -2865,10 +2843,8 @@
self.assertEqual(A.data['status'], 'MERGED')
self.assertEqual(A.reported, 2)
- @skip("Disabled for early v3 development")
def test_repo_deleted(self):
- self.updateConfigLayout(
- 'tests/fixtures/layout-repo-deleted.yaml')
+ self.updateConfigLayout('layout-repo-deleted')
self.sched.reconfigure(self.config)
self.init_repo("org/delete-project")
@@ -3005,10 +2981,8 @@
self.assertEqual(len(self.builds), 0)
self.assertEqual(len(self.history), x * 2)
- @skip("Disabled for early v3 development")
def test_check_smtp_pool(self):
- self.updateConfigLayout(
- 'tests/fixtures/layout-smtp.yaml')
+ self.updateConfigLayout('layout-smtp')
self.sched.reconfigure(self.config)
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
@@ -3816,7 +3790,6 @@
'SUCCESS')
self.assertEqual(A.reported, 1)
- @skip("Disabled for early v3 development")
def test_crd_gate(self):
"Test cross-repo dependencies"
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
@@ -3856,7 +3829,7 @@
self.assertEqual(A.data['status'], 'NEW')
self.assertEqual(B.data['status'], 'NEW')
- for connection in self.connections.values():
+ for connection in self.connections.connections.values():
connection.maintainCache([])
self.launch_server.hold_jobs_in_build = True
@@ -3879,12 +3852,14 @@
self.assertEqual(A.reported, 2)
self.assertEqual(B.reported, 2)
- self.assertEqual(self.getJobFromHistory('project1-merge').changes,
- '2,1 1,1')
+ changes = self.getJobFromHistory(
+ 'project-merge', 'org/project1').changes
+ self.assertEqual(changes, '2,1 1,1')
- @skip("Disabled for early v3 development")
def test_crd_branch(self):
"Test cross-repo dependencies in multiple branches"
+
+ self.create_branch('org/project2', 'mp')
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
C = self.fake_gerrit.addFakeChange('org/project2', 'mp', 'C')
@@ -3920,10 +3895,10 @@
self.assertEqual(B.reported, 2)
self.assertEqual(C.reported, 2)
- self.assertEqual(self.getJobFromHistory('project1-merge').changes,
- '2,1 3,1 1,1')
+ changes = self.getJobFromHistory(
+ 'project-merge', 'org/project1').changes
+ self.assertEqual(changes, '2,1 3,1 1,1')
- @skip("Disabled for early v3 development")
def test_crd_multiline(self):
"Test multiple depends-on lines in commit"
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
@@ -3960,8 +3935,9 @@
self.assertEqual(B.reported, 2)
self.assertEqual(C.reported, 2)
- self.assertEqual(self.getJobFromHistory('project1-merge').changes,
- '2,1 3,1 1,1')
+ changes = self.getJobFromHistory(
+ 'project-merge', 'org/project1').changes
+ self.assertEqual(changes, '2,1 3,1 1,1')
def test_crd_unshared_gate(self):
"Test cross-repo dependencies in unshared gate queues"
@@ -4001,7 +3977,6 @@
self.assertEqual(A.data['status'], 'MERGED')
self.assertEqual(A.reported, 2)
- @skip("Disabled for early v3 development")
def test_crd_gate_reverse(self):
"Test reverse cross-repo dependencies"
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
@@ -4038,8 +4013,9 @@
self.assertEqual(A.reported, 2)
self.assertEqual(B.reported, 2)
- self.assertEqual(self.getJobFromHistory('project1-merge').changes,
- '2,1 1,1')
+ changes = self.getJobFromHistory(
+ 'project-merge', 'org/project1').changes
+ self.assertEqual(changes, '2,1 1,1')
def test_crd_cycle(self):
"Test cross-repo dependency cycles"
@@ -4063,7 +4039,6 @@
self.assertEqual(A.data['status'], 'NEW')
self.assertEqual(B.data['status'], 'NEW')
- @skip("Disabled for early v3 development")
def test_crd_gate_unknown(self):
"Test unknown projects in dependent pipeline"
self.init_repo("org/unknown")
@@ -4106,10 +4081,10 @@
self.assertEqual(B.data['status'], 'MERGED')
self.assertEqual(B.reported, 0)
- @skip("Disabled for early v3 development")
def test_crd_check(self):
"Test cross-repo dependencies in independent pipelines"
+ self.launch_server.hold_jobs_in_build = True
self.gearman_server.hold_jobs_in_queue = True
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
@@ -4127,27 +4102,37 @@
self.gearman_server.release()
self.waitUntilSettled()
- path = os.path.join(self.git_root, "org/project1")
+ self.launch_server.release('.*-merge')
+ self.waitUntilSettled()
+
+ path = os.path.join(self.builds[0].jobdir.git_root, "org/project1")
repo = git.Repo(path)
repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
repo_messages.reverse()
- correct_messages = ['initial commit', 'A-1']
+ correct_messages = [
+ 'initial commit', 'add content from fixture', 'A-1']
self.assertEqual(repo_messages, correct_messages)
- path = os.path.join(self.git_root, "org/project2")
+ path = os.path.join(self.builds[0].jobdir.git_root, "org/project2")
repo = git.Repo(path)
repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
repo_messages.reverse()
- correct_messages = ['initial commit', 'B-1']
+ correct_messages = [
+ 'initial commit', 'add content from fixture', 'B-1']
self.assertEqual(repo_messages, correct_messages)
+ self.launch_server.hold_jobs_in_build = False
+ self.launch_server.release()
+ self.waitUntilSettled()
+
self.assertEqual(A.data['status'], 'NEW')
self.assertEqual(B.data['status'], 'NEW')
self.assertEqual(A.reported, 1)
self.assertEqual(B.reported, 0)
self.assertEqual(self.history[0].changes, '2,1 1,1')
- self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
+ tenant = self.sched.abide.tenants.get('tenant-one')
+ self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
def test_crd_check_git_depends(self):
"Test single-repo dependencies in independent pipelines"
@@ -4223,7 +4208,6 @@
self.assertIn('Build succeeded', A.messages[0])
self.assertIn('Build succeeded', B.messages[0])
- @skip("Disabled for early v3 development")
def _test_crd_check_reconfiguration(self, project1, project2):
"Test cross-repo dependencies re-enqueued in independent pipelines"
@@ -4242,8 +4226,9 @@
# Make sure the items still share a change queue, and the
# first one is not live.
- self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 1)
- queue = self.sched.layout.pipelines['check'].queues[0]
+ tenant = self.sched.abide.tenants.get('tenant-one')
+ self.assertEqual(len(tenant.layout.pipelines['check'].queues), 1)
+ queue = tenant.layout.pipelines['check'].queues[0]
first_item = queue.queue[0]
for item in queue.queue:
self.assertEqual(item.queue, first_item.queue)
@@ -4260,13 +4245,11 @@
self.assertEqual(B.reported, 0)
self.assertEqual(self.history[0].changes, '2,1 1,1')
- self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
+ self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
- @skip("Disabled for early v3 development")
def test_crd_check_reconfiguration(self):
self._test_crd_check_reconfiguration('org/project1', 'org/project2')
- @skip("Disabled for early v3 development")
def test_crd_undefined_project(self):
"""Test that undefined projects in dependencies are handled for
independent pipelines"""
@@ -4362,7 +4345,6 @@
self.waitUntilSettled()
self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
- @skip("Disabled for early v3 development")
def test_crd_check_unknown(self):
"Test unknown projects in independent pipeline"
self.init_repo("org/unknown")
@@ -4382,7 +4364,6 @@
self.assertEqual(B.data['status'], 'NEW')
self.assertEqual(B.reported, 0)
- @skip("Disabled for early v3 development")
def test_crd_cycle_join(self):
"Test an updated change creates a cycle"
A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
@@ -4408,10 +4389,18 @@
# call the method that would ultimately be called by the event
# processing.
- source = self.sched.layout.pipelines['gate'].source
+ tenant = self.sched.abide.tenants.get('tenant-one')
+ source = tenant.layout.pipelines['gate'].source
+
+ # TODO(pabelanger): As we add more source / trigger APIs we should make
+ # it easier for users to create events for testing.
+ event = zuul.model.TriggerEvent()
+ event.trigger_name = 'gerrit'
+ event.change_number = '1'
+ event.patch_number = '2'
with testtools.ExpectedException(
Exception, "Dependency cycle detected"):
- source._getChange(u'1', u'2', True)
+ source.getChange(event, True)
self.log.debug("Got expected dependency cycle exception")
# Now if we update B to remove the depends-on, everything
@@ -4419,21 +4408,22 @@
B.addPatchset()
B.data['commitMessage'] = '%s\n' % (B.subject,)
- source._getChange(u'1', u'2', True)
- source._getChange(u'2', u'2', True)
- @skip("Disabled for early v3 development")
+ source.getChange(event, True)
+ event.change_number = '2'
+ source.getChange(event, True)
+
def test_disable_at(self):
"Test a pipeline will only report to the disabled trigger when failing"
- self.updateConfigLayout(
- 'tests/fixtures/layout-disable-at.yaml')
+ self.updateConfigLayout('layout-disabled-at')
self.sched.reconfigure(self.config)
- self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
+ tenant = self.sched.abide.tenants.get('openstack')
+ self.assertEqual(3, tenant.layout.pipelines['check'].disable_at)
self.assertEqual(
- 0, self.sched.layout.pipelines['check']._consecutive_failures)
- self.assertFalse(self.sched.layout.pipelines['check']._disabled)
+ 0, tenant.layout.pipelines['check']._consecutive_failures)
+ self.assertFalse(tenant.layout.pipelines['check']._disabled)
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
@@ -4464,15 +4454,15 @@
self.waitUntilSettled()
self.assertEqual(
- 2, self.sched.layout.pipelines['check']._consecutive_failures)
- self.assertFalse(self.sched.layout.pipelines['check']._disabled)
+ 2, tenant.layout.pipelines['check']._consecutive_failures)
+ self.assertFalse(tenant.layout.pipelines['check']._disabled)
self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertEqual(
- 0, self.sched.layout.pipelines['check']._consecutive_failures)
- self.assertFalse(self.sched.layout.pipelines['check']._disabled)
+ 0, tenant.layout.pipelines['check']._consecutive_failures)
+ self.assertFalse(tenant.layout.pipelines['check']._disabled)
self.fake_gerrit.addEvent(D.getPatchsetCreatedEvent(1))
self.fake_gerrit.addEvent(E.getPatchsetCreatedEvent(1))
@@ -4481,8 +4471,8 @@
# We should be disabled now
self.assertEqual(
- 3, self.sched.layout.pipelines['check']._consecutive_failures)
- self.assertTrue(self.sched.layout.pipelines['check']._disabled)
+ 3, tenant.layout.pipelines['check']._consecutive_failures)
+ self.assertTrue(tenant.layout.pipelines['check']._disabled)
# We need to wait between each of these patches to make sure the
# smtp messages come back in an expected order
@@ -4512,30 +4502,35 @@
self.assertEqual(3, len(self.smtp_messages))
self.assertEqual(0, len(G.messages))
self.assertIn('Build failed.', self.smtp_messages[0]['body'])
- self.assertIn('/7/1/check', self.smtp_messages[0]['body'])
+ self.assertIn(
+ 'project-test1 https://server/job', self.smtp_messages[0]['body'])
self.assertEqual(0, len(H.messages))
self.assertIn('Build failed.', self.smtp_messages[1]['body'])
- self.assertIn('/8/1/check', self.smtp_messages[1]['body'])
+ self.assertIn(
+ 'project-test1 https://server/job', self.smtp_messages[1]['body'])
self.assertEqual(0, len(I.messages))
self.assertIn('Build succeeded.', self.smtp_messages[2]['body'])
- self.assertIn('/9/1/check', self.smtp_messages[2]['body'])
+ self.assertIn(
+ 'project-test1 https://server/job', self.smtp_messages[2]['body'])
# Now reload the configuration (simulate a HUP) to check the pipeline
# comes out of disabled
self.sched.reconfigure(self.config)
- self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
+ tenant = self.sched.abide.tenants.get('openstack')
+
+ self.assertEqual(3, tenant.layout.pipelines['check'].disable_at)
self.assertEqual(
- 0, self.sched.layout.pipelines['check']._consecutive_failures)
- self.assertFalse(self.sched.layout.pipelines['check']._disabled)
+ 0, tenant.layout.pipelines['check']._consecutive_failures)
+ self.assertFalse(tenant.layout.pipelines['check']._disabled)
self.fake_gerrit.addEvent(J.getPatchsetCreatedEvent(1))
self.fake_gerrit.addEvent(K.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertEqual(
- 2, self.sched.layout.pipelines['check']._consecutive_failures)
- self.assertFalse(self.sched.layout.pipelines['check']._disabled)
+ 2, tenant.layout.pipelines['check']._consecutive_failures)
+ self.assertFalse(tenant.layout.pipelines['check']._disabled)
# J and K went back to gerrit
self.assertEqual(1, len(J.messages))
diff --git a/zuul/model.py b/zuul/model.py
index 77b1259..ddb0dde 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -435,7 +435,7 @@
for k, v in self.attributes.items():
setattr(self, k, v)
- def __equals__(self, other):
+ def __eq__(self, other):
# Compare the name and all inheritable attributes to determine
# whether two jobs with the same name are identically
# configured. Useful upon reconfiguration.
@@ -1771,11 +1771,12 @@
self._createJobTree(change, tree.job_trees, frozen_tree)
def createJobTree(self, item):
- project_config = self.project_configs[item.change.project.name]
+ project_config = self.project_configs.get(
+ item.change.project.name, None)
ret = JobTree(None)
# NOTE(pabelanger): It is possible for a foreign project not to have a
# configured pipeline, if so return an empty JobTree.
- if item.pipeline.name in project_config.pipelines:
+ if project_config and item.pipeline.name in project_config.pipelines:
project_tree = \
project_config.pipelines[item.pipeline.name].job_tree
self._createJobTree(item.change, project_tree.job_trees, ret)
diff --git a/zuul/scheduler.py b/zuul/scheduler.py
index b000a6f..1d27523 100644
--- a/zuul/scheduler.py
+++ b/zuul/scheduler.py
@@ -500,9 +500,9 @@
last_head):
new_jobs = item.getJobs()
for build in item.current_build_set.getBuilds():
- job = item.layout.getJob(build.job.name)
- if job and job in new_jobs:
- build.job = job
+ jobtree = item.job_tree.getJobTreeForJob(build.job)
+ if jobtree and jobtree.job in new_jobs:
+ build.job = jobtree.job
else:
item.removeBuild(build)
builds_to_cancel.append(build)
@@ -601,13 +601,14 @@
self.log.debug("Waiting on merger")
return False
waiting = False
- for pipeline in self.layout.pipelines.values():
- for item in pipeline.getAllItems():
- for build in item.current_build_set.getBuilds():
- if build.result is None:
- self.log.debug("%s waiting on %s" %
- (pipeline.manager, build))
- waiting = True
+ for tenant in self.abide.tenants.values():
+ for pipeline in tenant.layout.pipelines.values():
+ for item in pipeline.getAllItems():
+ for build in item.current_build_set.getBuilds():
+ if build.result is None:
+ self.log.debug("%s waiting on %s" %
+ (pipeline.manager, build))
+ waiting = True
if not waiting:
self.log.debug("All builds are complete")
return True