Merge "Catch and log url pattern formatting errors" into feature/zuulv3
diff --git a/doc/source/developer/testing.rst b/doc/source/developer/testing.rst
index 4a813d0..057ab7e 100644
--- a/doc/source/developer/testing.rst
+++ b/doc/source/developer/testing.rst
@@ -9,6 +9,8 @@
access to a number of attributes useful for manipulating or inspecting
the environment being simulated in the test:
+.. autofunction:: tests.base.simple_layout
+
.. autoclass:: tests.base.ZuulTestCase
:members:
diff --git a/requirements.txt b/requirements.txt
index c7e059a..974b77f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,7 +9,7 @@
python-daemon>=2.0.4,<2.1.0
extras
statsd>=1.0.0,<3.0
-voluptuous>=0.7
+voluptuous>=0.10.2
gear>=0.5.7,<1.0.0
apscheduler>=3.0
PrettyTable>=0.6,<0.8
diff --git a/tests/base.py b/tests/base.py
index 1f447da..6d3df8b 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -28,13 +28,17 @@
import select
import shutil
from six.moves import reload_module
-from six import StringIO
+try:
+ from cStringIO import StringIO
+except Exception:
+ from six import StringIO
import socket
import string
import subprocess
import sys
import tempfile
import threading
+import traceback
import time
import uuid
@@ -97,6 +101,31 @@
raise Exception("Timeout waiting for %s" % purpose)
+def simple_layout(path, driver='gerrit'):
+ """Specify a layout file for use by a test method.
+
+ :arg str path: The path to the layout file.
+ :arg str driver: The source driver to use, defaults to gerrit.
+
+ Some tests require only a very simple configuration. For those,
+ establishing a complete config directory hierachy is too much
+ work. In those cases, you can add a simple zuul.yaml file to the
+ test fixtures directory (in fixtures/layouts/foo.yaml) and use
+ this decorator to indicate the test method should use that rather
+ than the tenant config file specified by the test class.
+
+ The decorator will cause that layout file to be added to a
+ config-project called "common-config" and each "project" instance
+ referenced in the layout file will have a git repo automatically
+ initialized.
+ """
+
+ def decorator(test):
+ test.__simple_layout__ = (path, driver)
+ return test
+ return decorator
+
+
class ChangeReference(git.Reference):
_common_path_default = "refs/changes"
_points_to_commits_only = True
@@ -769,6 +798,11 @@
build.release()
super(RecordingExecutorServer, self).stopJob(job)
+ def stop(self):
+ for build in self.running_builds:
+ build.release()
+ super(RecordingExecutorServer, self).stop()
+
class RecordingAnsibleJob(zuul.executor.server.AnsibleJob):
def doMergeChanges(self, items):
@@ -996,6 +1030,7 @@
provider='test-provider',
region='test-region',
az='test-az',
+ interface_ip='127.0.0.1',
public_ipv4='127.0.0.1',
private_ipv4=None,
public_ipv6=None,
@@ -1042,7 +1077,7 @@
class ChrootedKazooFixture(fixtures.Fixture):
- def __init__(self):
+ def __init__(self, test_id):
super(ChrootedKazooFixture, self).__init__()
zk_host = os.environ.get('NODEPOOL_ZK_HOST', 'localhost')
@@ -1059,15 +1094,19 @@
else:
self.zookeeper_port = int(port)
+ self.test_id = test_id
+
def _setUp(self):
# Make sure the test chroot paths do not conflict
random_bits = ''.join(random.choice(string.ascii_lowercase +
string.ascii_uppercase)
for x in range(8))
- rand_test_path = '%s_%s' % (random_bits, os.getpid())
+ rand_test_path = '%s_%s_%s' % (random_bits, os.getpid(), self.test_id)
self.zookeeper_chroot = "/nodepool_test/%s" % rand_test_path
+ self.addCleanup(self._cleanup)
+
# Ensure the chroot path exists and clean up any pre-existing znodes.
_tmp_client = kazoo.client.KazooClient(
hosts='%s:%s' % (self.zookeeper_host, self.zookeeper_port))
@@ -1080,8 +1119,6 @@
_tmp_client.stop()
_tmp_client.close()
- self.addCleanup(self._cleanup)
-
def _cleanup(self):
'''Remove the chroot path.'''
# Need a non-chroot'ed client to remove the chroot path
@@ -1090,6 +1127,7 @@
_tmp_client.start()
_tmp_client.delete(self.zookeeper_chroot, recursive=True)
_tmp_client.stop()
+ _tmp_client.close()
class MySQLSchemaFixture(fixtures.Fixture):
@@ -1131,7 +1169,7 @@
class BaseTestCase(testtools.TestCase):
log = logging.getLogger("zuul.test")
- wait_timeout = 20
+ wait_timeout = 30
def attachLogs(self, *args):
def reader():
@@ -1182,6 +1220,12 @@
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
+ # Make sure we don't carry old handlers around in process state
+ # which slows down test runs
+ self.addCleanup(logger.removeHandler, handler)
+ self.addCleanup(handler.close)
+ self.addCleanup(handler.flush)
+
# NOTE(notmorgan): Extract logging overrides for specific
# libraries from the OS_LOG_DEFAULTS env and create loggers
# for each. This is used to limit the output during test runs
@@ -1222,7 +1266,8 @@
be loaded). It defaults to the value specified in
`config_file` but can be overidden by subclasses to obtain a
different tenant/project layout while using the standard main
- configuration.
+ configuration. See also the :py:func:`simple_layout`
+ decorator.
:cvar bool create_project_keys: Indicates whether Zuul should
auto-generate keys for each project, or whether the test
@@ -1300,23 +1345,6 @@
self.config.set('executor', 'git_dir', self.executor_src_root)
self.config.set('zuul', 'state_dir', self.state_root)
- # For each project in config:
- # TODOv3(jeblair): remove these and replace with new git
- # filesystem fixtures
- self.init_repo("org/project3")
- self.init_repo("org/project4")
- self.init_repo("org/project5")
- self.init_repo("org/project6")
- self.init_repo("org/one-job-project")
- self.init_repo("org/nonvoting-project")
- self.init_repo("org/templated-project")
- self.init_repo("org/layered-project")
- self.init_repo("org/node-project")
- self.init_repo("org/conflict-project")
- self.init_repo("org/noop-project")
- self.init_repo("org/experimental-project")
- self.init_repo("org/no-jobs-project")
-
self.statsd = FakeStatsd()
# note, use 127.0.0.1 rather than localhost to avoid getting ipv6
# see: https://github.com/jsocol/pystatsd/issues/61
@@ -1339,6 +1367,9 @@
self.sched = zuul.scheduler.Scheduler(self.config)
+ self.webapp = zuul.webapp.WebApp(
+ self.sched, port=0, listen_address='127.0.0.1')
+
self.event_queues = [
self.sched.result_event_queue,
self.sched.trigger_event_queue,
@@ -1346,7 +1377,7 @@
]
self.configure_connections()
- self.sched.registerConnections(self.connections)
+ self.sched.registerConnections(self.connections, self.webapp)
def URLOpenerFactory(*args, **kw):
if isinstance(args[0], urllib.request.Request):
@@ -1386,23 +1417,20 @@
self.sched.setNodepool(self.nodepool)
self.sched.setZooKeeper(self.zk)
- self.webapp = zuul.webapp.WebApp(
- self.sched, port=0, listen_address='127.0.0.1')
self.rpc = zuul.rpclistener.RPCListener(self.config, self.sched)
self.sched.start()
self.webapp.start()
self.rpc.start()
self.executor_client.gearman.waitForServer()
+ # Cleanups are run in reverse order
+ self.addCleanup(self.assertCleanShutdown)
self.addCleanup(self.shutdown)
+ self.addCleanup(self.assertFinalState)
self.sched.reconfigure(self.config)
self.sched.resume()
- def tearDown(self):
- super(ZuulTestCase, self).tearDown()
- self.assertFinalState()
-
def configure_connections(self):
# Set up gerrit related fakes
# Set a changes database so multiple FakeGerrit's can report back to
@@ -1444,19 +1472,74 @@
# obeys the config_file and tenant_config_file attributes.
self.config = ConfigParser.ConfigParser()
self.config.read(os.path.join(FIXTURE_DIR, self.config_file))
- if hasattr(self, 'tenant_config_file'):
- self.config.set('zuul', 'tenant_config', self.tenant_config_file)
- git_path = os.path.join(
- os.path.dirname(
- os.path.join(FIXTURE_DIR, self.tenant_config_file)),
- 'git')
- if os.path.exists(git_path):
- for reponame in os.listdir(git_path):
- project = reponame.replace('_', '/')
- self.copyDirToRepo(project,
- os.path.join(git_path, reponame))
+
+ if not self.setupSimpleLayout():
+ if hasattr(self, 'tenant_config_file'):
+ self.config.set('zuul', 'tenant_config',
+ self.tenant_config_file)
+ git_path = os.path.join(
+ os.path.dirname(
+ os.path.join(FIXTURE_DIR, self.tenant_config_file)),
+ 'git')
+ if os.path.exists(git_path):
+ for reponame in os.listdir(git_path):
+ project = reponame.replace('_', '/')
+ self.copyDirToRepo(project,
+ os.path.join(git_path, reponame))
self.setupAllProjectKeys()
+ def setupSimpleLayout(self):
+ # If the test method has been decorated with a simple_layout,
+ # use that instead of the class tenant_config_file. Set up a
+ # single config-project with the specified layout, and
+ # initialize repos for all of the 'project' entries which
+ # appear in the layout.
+ test_name = self.id().split('.')[-1]
+ test = getattr(self, test_name)
+ if hasattr(test, '__simple_layout__'):
+ path, driver = getattr(test, '__simple_layout__')
+ else:
+ return False
+
+ files = {}
+ path = os.path.join(FIXTURE_DIR, path)
+ with open(path) as f:
+ data = f.read()
+ layout = yaml.safe_load(data)
+ files['zuul.yaml'] = data
+ untrusted_projects = []
+ for item in layout:
+ if 'project' in item:
+ name = item['project']['name']
+ untrusted_projects.append(name)
+ self.init_repo(name)
+ self.addCommitToRepo(name, 'initial commit',
+ files={'README': ''},
+ branch='master', tag='init')
+ if 'job' in item:
+ jobname = item['job']['name']
+ files['playbooks/%s.yaml' % jobname] = ''
+
+ root = os.path.join(self.test_root, "config")
+ if not os.path.exists(root):
+ os.makedirs(root)
+ f = tempfile.NamedTemporaryFile(dir=root, delete=False)
+ config = [{'tenant':
+ {'name': 'tenant-one',
+ 'source': {driver:
+ {'config-projects': ['common-config'],
+ 'untrusted-projects': untrusted_projects}}}}]
+ f.write(yaml.dump(config))
+ f.close()
+ self.config.set('zuul', 'tenant_config',
+ os.path.join(FIXTURE_DIR, f.name))
+
+ self.init_repo('common-config')
+ self.addCommitToRepo('common-config', 'add content from fixture',
+ files, branch='master', tag='init')
+
+ return True
+
def setupAllProjectKeys(self):
if self.create_project_keys:
return
@@ -1467,9 +1550,9 @@
for tenant in tenant_config:
sources = tenant['tenant']['source']
for source, conf in sources.items():
- for project in conf.get('config-repos', []):
+ for project in conf.get('config-projects', []):
self.setupProjectKeys(source, project)
- for project in conf.get('project-repos', []):
+ for project in conf.get('untrusted-projects', []):
self.setupProjectKeys(source, project)
def setupProjectKeys(self, source, project):
@@ -1490,7 +1573,8 @@
o.write(i.read())
def setupZK(self):
- self.zk_chroot_fixture = self.useFixture(ChrootedKazooFixture())
+ self.zk_chroot_fixture = self.useFixture(
+ ChrootedKazooFixture(self.id()))
self.zk_config = '%s:%s%s' % (
self.zk_chroot_fixture.zookeeper_host,
self.zk_chroot_fixture.zookeeper_port,
@@ -1540,6 +1624,9 @@
self.assertEqual(test_key, f.read())
def assertFinalState(self):
+ self.log.debug("Assert final state")
+ # Make sure no jobs are running
+ self.assertEqual({}, self.executor_server.job_workers)
# Make sure that git.Repo objects have been garbage collected.
repos = []
gc.collect()
@@ -1575,12 +1662,23 @@
self.gearman_server.shutdown()
self.fake_nodepool.stop()
self.zk.disconnect()
- threads = threading.enumerate()
- if len(threads) > 1:
- self.log.error("More than one thread is running: %s" % threads)
self.printHistory()
+ # we whitelist watchdog threads as they have relatively long delays
+ # before noticing they should exit, but they should exit on their own.
+ threads = [t for t in threading.enumerate()
+ if t.name != 'executor-watchdog']
+ if len(threads) > 1:
+ log_str = ""
+ for thread_id, stack_frame in sys._current_frames().items():
+ log_str += "Thread: %s\n" % thread_id
+ log_str += "".join(traceback.format_stack(stack_frame))
+ self.log.debug(log_str)
+ raise Exception("More than one thread is running: %s" % threads)
- def init_repo(self, project):
+ def assertCleanShutdown(self):
+ pass
+
+ def init_repo(self, project, tag=None):
parts = project.split('/')
path = os.path.join(self.upstream_root, *parts[:-1])
if not os.path.exists(path):
@@ -1594,6 +1692,8 @@
repo.index.commit('initial commit')
master = repo.create_head('master')
+ if tag:
+ repo.create_tag(tag)
repo.head.reference = master
zuul.merger.merger.reset_repo_to_head(repo)
@@ -1627,11 +1727,15 @@
commit = repo.index.commit('Creating a fake commit')
return commit.hexsha
- def orderedRelease(self):
+ def orderedRelease(self, count=None):
# Run one build at a time to ensure non-race order:
+ i = 0
while len(self.builds):
self.release(self.builds[0])
self.waitUntilSettled()
+ i += 1
+ if count is not None and i >= count:
+ break
def release(self, job):
if isinstance(job, FakeBuild):
@@ -1670,7 +1774,9 @@
def areAllBuildsWaiting(self):
builds = self.executor_client.builds.values()
+ seen_builds = set()
for build in builds:
+ seen_builds.add(build.uuid)
client_job = None
for conn in self.executor_client.gearman.active_connections:
for j in conn.related_jobs.values():
@@ -1708,6 +1814,11 @@
else:
self.log.debug("%s is unassigned" % server_job)
return False
+ for (build_uuid, job_worker) in \
+ self.executor_server.job_workers.items():
+ if build_uuid not in seen_builds:
+ self.log.debug("%s is not finalized" % build_uuid)
+ return False
return True
def areAllNodeRequestsComplete(self):
@@ -1911,9 +2022,12 @@
name: openstack
source:
gerrit:
- config-repos:
+ config-projects:
- %s
- """ % path)
+ untrusted-projects:
+ - org/project
+ - org/project1
+ - org/project2\n""" % path)
f.close()
self.config.set('zuul', 'tenant_config',
os.path.join(FIXTURE_DIR, f.name))
@@ -1944,23 +2058,37 @@
repo.create_tag(tag)
return before
- def commitLayoutUpdate(self, orig_name, source_name):
- source_path = os.path.join(self.test_root, 'upstream',
- source_name)
- to_copy = ['zuul.yaml']
- for playbook in os.listdir(os.path.join(source_path, 'playbooks')):
- to_copy.append('playbooks/{}'.format(playbook))
- commit_data = {}
- for source_file in to_copy:
- source_file_path = os.path.join(source_path, source_file)
- with open(source_file_path, 'r') as nt:
- commit_data[source_file] = nt.read()
+ def commitConfigUpdate(self, project_name, source_name):
+ """Commit an update to zuul.yaml
+
+ This overwrites the zuul.yaml in the specificed project with
+ the contents specified.
+
+ :arg str project_name: The name of the project containing
+ zuul.yaml (e.g., common-config)
+
+ :arg str source_name: The path to the file (underneath the
+ test fixture directory) whose contents should be used to
+ replace zuul.yaml.
+ """
+
+ source_path = os.path.join(FIXTURE_DIR, source_name)
+ files = {}
+ with open(source_path, 'r') as f:
+ data = f.read()
+ layout = yaml.safe_load(data)
+ files['zuul.yaml'] = data
+ for item in layout:
+ if 'job' in item:
+ jobname = item['job']['name']
+ files['playbooks/%s.yaml' % jobname] = ''
before = self.addCommitToRepo(
- orig_name, 'Pulling content from %s' % source_name,
- commit_data)
+ project_name, 'Pulling content from %s' % source_name,
+ files)
return before
def addEvent(self, connection, event):
+
"""Inject a Fake (Gerrit) event.
This method accepts a JSON-encoded event and simulates Zuul
diff --git a/tests/fixtures/config/ansible/git/common-config/zuul.yaml b/tests/fixtures/config/ansible/git/common-config/zuul.yaml
index 0980bc1..f9be158 100644
--- a/tests/fixtures/config/ansible/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/ansible/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
allow-secrets: true
trigger:
gerrit:
@@ -17,7 +16,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -50,6 +48,7 @@
Z3QSO1NjbBxWnaHKZYT7nkrJm8AMCgZU0ZArFLpaufKCeiK5ECSsDxic4FIsY1OkWT42qEUfL0Wd
+150AKGNZpPJnnP3QYY4W/MWcKH/zdO400+zWN52WevbSqZy90tqKDJrBkMl1ydqbuw1E4ZHvIs=
+
- job:
name: python27
pre-run: pre
diff --git a/tests/fixtures/config/ansible/main.yaml b/tests/fixtures/config/ansible/main.yaml
index 8df99f4..9ccece9 100644
--- a/tests/fixtures/config/ansible/main.yaml
+++ b/tests/fixtures/config/ansible/main.yaml
@@ -2,8 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- project-repos:
+ untrusted-projects:
- org/project
- bare-role
diff --git a/tests/fixtures/config/broken/git/common-config/zuul.yaml b/tests/fixtures/config/broken/git/common-config/zuul.yaml
index 6abb87f..162a982 100644
--- a/tests/fixtures/config/broken/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/broken/git/common-config/zuul.yaml
@@ -1,8 +1,6 @@
- pipeline:
name: check
manager: independent
- source:
- gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/broken/main.yaml b/tests/fixtures/config/broken/main.yaml
index a22ed5c..9d01f54 100644
--- a/tests/fixtures/config/broken/main.yaml
+++ b/tests/fixtures/config/broken/main.yaml
@@ -2,5 +2,5 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
diff --git a/tests/fixtures/config/dependency-graph/git/common-config/zuul.yaml b/tests/fixtures/config/dependency-graph/git/common-config/zuul.yaml
index 60f3651..cdf989e 100644
--- a/tests/fixtures/config/dependency-graph/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/dependency-graph/git/common-config/zuul.yaml
@@ -2,7 +2,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/dependency-graph/main.yaml b/tests/fixtures/config/dependency-graph/main.yaml
index d9868fa..208e274 100644
--- a/tests/fixtures/config/dependency-graph/main.yaml
+++ b/tests/fixtures/config/dependency-graph/main.yaml
@@ -2,7 +2,7 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- project-repos:
+ untrusted-projects:
- org/project
diff --git a/tests/fixtures/config/duplicate-pipeline/git/common-config/zuul.yaml b/tests/fixtures/config/duplicate-pipeline/git/common-config/zuul.yaml
index 5005108..60d7363 100755
--- a/tests/fixtures/config/duplicate-pipeline/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/duplicate-pipeline/git/common-config/zuul.yaml
@@ -2,7 +2,6 @@
name: dup1
manager: independent
success-message: Build succeeded (dup1).
- source: gerrit
trigger:
gerrit:
- event: change-restored
@@ -17,7 +16,6 @@
name: dup2
manager: independent
success-message: Build succeeded (dup2).
- source: gerrit
trigger:
gerrit:
- event: change-restored
diff --git a/tests/fixtures/config/duplicate-pipeline/main.yaml b/tests/fixtures/config/duplicate-pipeline/main.yaml
index ba2d8f5..d28df0d 100755
--- a/tests/fixtures/config/duplicate-pipeline/main.yaml
+++ b/tests/fixtures/config/duplicate-pipeline/main.yaml
@@ -2,5 +2,7 @@
name: tenant-duplicate
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project
diff --git a/tests/fixtures/config/git-driver/git/common-config/zuul.yaml b/tests/fixtures/config/git-driver/git/common-config/zuul.yaml
index 0e332e4..8fe8749 100644
--- a/tests/fixtures/config/git-driver/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/git-driver/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/git-driver/main.yaml b/tests/fixtures/config/git-driver/main.yaml
index 5b9b3d9..2a2b204 100644
--- a/tests/fixtures/config/git-driver/main.yaml
+++ b/tests/fixtures/config/git-driver/main.yaml
@@ -2,8 +2,8 @@
name: tenant-one
source:
git:
- config-repos:
+ config-projects:
- common-config
gerrit:
- project-repos:
+ untrusted-projects:
- org/project
diff --git a/tests/fixtures/config/in-repo/git/common-config/zuul.yaml b/tests/fixtures/config/in-repo/git/common-config/zuul.yaml
index 55169ce..1fdaf2e 100644
--- a/tests/fixtures/config/in-repo/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/in-repo/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -16,7 +15,6 @@
name: tenant-one-gate
manager: dependent
success-message: Build succeeded (tenant-one-gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/in-repo/main.yaml b/tests/fixtures/config/in-repo/main.yaml
index d9868fa..208e274 100644
--- a/tests/fixtures/config/in-repo/main.yaml
+++ b/tests/fixtures/config/in-repo/main.yaml
@@ -2,7 +2,7 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- project-repos:
+ untrusted-projects:
- org/project
diff --git a/tests/fixtures/config/merges/git/common-config/zuul.yaml b/tests/fixtures/config/merges/git/common-config/zuul.yaml
index ab4e24c..1309b3f 100644
--- a/tests/fixtures/config/merges/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/merges/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -16,7 +15,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/merges/main.yaml b/tests/fixtures/config/merges/main.yaml
index a22ed5c..3ec47ea 100644
--- a/tests/fixtures/config/merges/main.yaml
+++ b/tests/fixtures/config/merges/main.yaml
@@ -2,5 +2,11 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project-cherry-pick
+ - org/project-merge
+ - org/project-merge-branches
+ - org/project-merge-resolve
+
diff --git a/tests/fixtures/config/multi-tenant-semaphore/git/common-config/zuul.yaml b/tests/fixtures/config/multi-tenant-semaphore/git/common-config/zuul.yaml
index d18ed46..ba91fb5 100644
--- a/tests/fixtures/config/multi-tenant-semaphore/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/multi-tenant-semaphore/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/multi-tenant-semaphore/main.yaml b/tests/fixtures/config/multi-tenant-semaphore/main.yaml
index b1c47b1..59422a0 100644
--- a/tests/fixtures/config/multi-tenant-semaphore/main.yaml
+++ b/tests/fixtures/config/multi-tenant-semaphore/main.yaml
@@ -2,14 +2,20 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- tenant-one-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
- tenant:
name: tenant-two
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- tenant-two-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/multi-tenant/git/common-config/zuul.yaml b/tests/fixtures/config/multi-tenant/git/common-config/zuul.yaml
index 004f2df..ec9c6dd 100644
--- a/tests/fixtures/config/multi-tenant/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/multi-tenant/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/multi-tenant/git/tenant-one-config/zuul.yaml b/tests/fixtures/config/multi-tenant/git/tenant-one-config/zuul.yaml
index 5769cf5..63a19e2 100644
--- a/tests/fixtures/config/multi-tenant/git/tenant-one-config/zuul.yaml
+++ b/tests/fixtures/config/multi-tenant/git/tenant-one-config/zuul.yaml
@@ -2,7 +2,6 @@
name: tenant-one-gate
manager: dependent
success-message: Build succeeded (tenant-one-gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/multi-tenant/git/tenant-two-config/zuul.yaml b/tests/fixtures/config/multi-tenant/git/tenant-two-config/zuul.yaml
index 19782ce..4feb9f5 100644
--- a/tests/fixtures/config/multi-tenant/git/tenant-two-config/zuul.yaml
+++ b/tests/fixtures/config/multi-tenant/git/tenant-two-config/zuul.yaml
@@ -2,7 +2,6 @@
name: tenant-two-gate
manager: dependent
success-message: Build succeeded (tenant-two-gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/multi-tenant/main.yaml b/tests/fixtures/config/multi-tenant/main.yaml
index b1c47b1..3ae7756 100644
--- a/tests/fixtures/config/multi-tenant/main.yaml
+++ b/tests/fixtures/config/multi-tenant/main.yaml
@@ -2,14 +2,18 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- tenant-one-config
+ untrusted-projects:
+ - org/project1
- tenant:
name: tenant-two
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- tenant-two-config
+ untrusted-projects:
+ - org/project2
diff --git a/tests/fixtures/config/one-job-project/git/common-config/playbooks/one-job-project-merge.yaml b/tests/fixtures/config/one-job-project/git/common-config/playbooks/one-job-project-merge.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/one-job-project/git/common-config/playbooks/one-job-project-merge.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/one-job-project/git/common-config/playbooks/one-job-project-post.yaml b/tests/fixtures/config/one-job-project/git/common-config/playbooks/one-job-project-post.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/one-job-project/git/common-config/playbooks/one-job-project-post.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/one-job-project/git/org_one-job-project/README b/tests/fixtures/config/one-job-project/git/org_one-job-project/README
deleted file mode 100644
index 9daeafb..0000000
--- a/tests/fixtures/config/one-job-project/git/org_one-job-project/README
+++ /dev/null
@@ -1 +0,0 @@
-test
diff --git a/tests/fixtures/config/one-job-project/main.yaml b/tests/fixtures/config/one-job-project/main.yaml
deleted file mode 100644
index a22ed5c..0000000
--- a/tests/fixtures/config/one-job-project/main.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-- tenant:
- name: tenant-one
- source:
- gerrit:
- config-repos:
- - common-config
diff --git a/tests/fixtures/config/openstack/git/project-config/zuul.yaml b/tests/fixtures/config/openstack/git/project-config/zuul.yaml
index 760adb8..5d0c774 100644
--- a/tests/fixtures/config/openstack/git/project-config/zuul.yaml
+++ b/tests/fixtures/config/openstack/git/project-config/zuul.yaml
@@ -2,7 +2,6 @@
name: check
manager: independent
success-message: Build succeeded (check).
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -17,7 +16,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/openstack/main.yaml b/tests/fixtures/config/openstack/main.yaml
index 95a0952..f794093 100644
--- a/tests/fixtures/config/openstack/main.yaml
+++ b/tests/fixtures/config/openstack/main.yaml
@@ -2,5 +2,8 @@
name: openstack
source:
gerrit:
- config-repos:
+ config-projects:
- project-config
+ untrusted-projects:
+ - openstack/nova
+ - openstack/keystone
\ No newline at end of file
diff --git a/tests/fixtures/config/requirements/email/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/email/git/common-config/zuul.yaml
index 78d2a18..1a5baed 100644
--- a/tests/fixtures/config/requirements/email/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/email/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: pipeline
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -18,7 +17,6 @@
- pipeline:
name: trigger
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/requirements/email/main.yaml b/tests/fixtures/config/requirements/email/main.yaml
index a22ed5c..950b117 100644
--- a/tests/fixtures/config/requirements/email/main.yaml
+++ b/tests/fixtures/config/requirements/email/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/requirements/newer-than/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/newer-than/git/common-config/zuul.yaml
index 1e84e18..fa230de 100644
--- a/tests/fixtures/config/requirements/newer-than/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/newer-than/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: pipeline
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -19,7 +18,6 @@
- pipeline:
name: trigger
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/requirements/newer-than/main.yaml b/tests/fixtures/config/requirements/newer-than/main.yaml
index a22ed5c..950b117 100644
--- a/tests/fixtures/config/requirements/newer-than/main.yaml
+++ b/tests/fixtures/config/requirements/newer-than/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/requirements/older-than/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/older-than/git/common-config/zuul.yaml
index efbd79a..14541b6 100644
--- a/tests/fixtures/config/requirements/older-than/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/older-than/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: pipeline
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -19,7 +18,6 @@
- pipeline:
name: trigger
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/requirements/older-than/main.yaml b/tests/fixtures/config/requirements/older-than/main.yaml
index a22ed5c..950b117 100644
--- a/tests/fixtures/config/requirements/older-than/main.yaml
+++ b/tests/fixtures/config/requirements/older-than/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/requirements/reject-username/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/reject-username/git/common-config/zuul.yaml
index 7212944..61f3819 100644
--- a/tests/fixtures/config/requirements/reject-username/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/reject-username/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: pipeline
manager: independent
- source: gerrit
reject:
approval:
- username: jenkins
@@ -18,7 +17,6 @@
- pipeline:
name: trigger
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/requirements/reject-username/main.yaml b/tests/fixtures/config/requirements/reject-username/main.yaml
index a22ed5c..950b117 100644
--- a/tests/fixtures/config/requirements/reject-username/main.yaml
+++ b/tests/fixtures/config/requirements/reject-username/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/requirements/reject/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/reject/git/common-config/zuul.yaml
index 9f5b125..32a7582 100644
--- a/tests/fixtures/config/requirements/reject/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/reject/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: pipeline
manager: independent
- source: gerrit
require:
approval:
- username: jenkins
@@ -26,7 +25,6 @@
- pipeline:
name: trigger
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/requirements/reject/main.yaml b/tests/fixtures/config/requirements/reject/main.yaml
index a22ed5c..950b117 100644
--- a/tests/fixtures/config/requirements/reject/main.yaml
+++ b/tests/fixtures/config/requirements/reject/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/requirements/state/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/state/git/common-config/zuul.yaml
index 01ceb46..ffc3453 100644
--- a/tests/fixtures/config/requirements/state/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/state/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: current-check
manager: independent
- source: gerrit
require:
current-patchset: true
trigger:
@@ -18,7 +17,6 @@
- pipeline:
name: open-check
manager: independent
- source: gerrit
require:
open: true
trigger:
@@ -35,7 +33,6 @@
- pipeline:
name: status-check
manager: independent
- source: gerrit
require:
status: NEW
trigger:
diff --git a/tests/fixtures/config/requirements/state/main.yaml b/tests/fixtures/config/requirements/state/main.yaml
index a22ed5c..99756fb 100644
--- a/tests/fixtures/config/requirements/state/main.yaml
+++ b/tests/fixtures/config/requirements/state/main.yaml
@@ -2,5 +2,9 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - current-project
+ - open-project
+ - status-project
diff --git a/tests/fixtures/config/requirements/username/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/username/git/common-config/zuul.yaml
index 9789e71..bc1083a 100644
--- a/tests/fixtures/config/requirements/username/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/username/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: pipeline
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -18,7 +17,6 @@
- pipeline:
name: trigger
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/requirements/username/main.yaml b/tests/fixtures/config/requirements/username/main.yaml
index a22ed5c..950b117 100644
--- a/tests/fixtures/config/requirements/username/main.yaml
+++ b/tests/fixtures/config/requirements/username/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/requirements/vote1/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/vote1/git/common-config/zuul.yaml
index 7989363..7d9164d 100644
--- a/tests/fixtures/config/requirements/vote1/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/vote1/git/common-config/zuul.yaml
@@ -5,7 +5,6 @@
approval:
- username: jenkins
verified: 1
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -19,7 +18,6 @@
- pipeline:
name: trigger
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/requirements/vote1/main.yaml b/tests/fixtures/config/requirements/vote1/main.yaml
index a22ed5c..950b117 100644
--- a/tests/fixtures/config/requirements/vote1/main.yaml
+++ b/tests/fixtures/config/requirements/vote1/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/requirements/vote2/git/common-config/zuul.yaml b/tests/fixtures/config/requirements/vote2/git/common-config/zuul.yaml
index 9348afb..7308c8a 100644
--- a/tests/fixtures/config/requirements/vote2/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/requirements/vote2/git/common-config/zuul.yaml
@@ -7,7 +7,6 @@
verified:
- 1
- 2
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -21,7 +20,6 @@
- pipeline:
name: trigger
manager: independent
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/requirements/vote2/main.yaml b/tests/fixtures/config/requirements/vote2/main.yaml
index a22ed5c..950b117 100644
--- a/tests/fixtures/config/requirements/vote2/main.yaml
+++ b/tests/fixtures/config/requirements/vote2/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/single-tenant/git/layout-idle/playbooks/project-test1.yaml b/tests/fixtures/config/semaphore/git/common-config/playbooks/project-test1.yaml
similarity index 100%
rename from tests/fixtures/config/single-tenant/git/layout-idle/playbooks/project-test1.yaml
rename to tests/fixtures/config/semaphore/git/common-config/playbooks/project-test1.yaml
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/semaphore-one-test1.yaml b/tests/fixtures/config/semaphore/git/common-config/playbooks/semaphore-one-test1.yaml
similarity index 100%
rename from tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/semaphore-one-test1.yaml
rename to tests/fixtures/config/semaphore/git/common-config/playbooks/semaphore-one-test1.yaml
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/semaphore-one-test2.yaml b/tests/fixtures/config/semaphore/git/common-config/playbooks/semaphore-one-test2.yaml
similarity index 100%
rename from tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/semaphore-one-test2.yaml
rename to tests/fixtures/config/semaphore/git/common-config/playbooks/semaphore-one-test2.yaml
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/semaphore-two-test1.yaml b/tests/fixtures/config/semaphore/git/common-config/playbooks/semaphore-two-test1.yaml
similarity index 100%
rename from tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/semaphore-two-test1.yaml
rename to tests/fixtures/config/semaphore/git/common-config/playbooks/semaphore-two-test1.yaml
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/semaphore-two-test2.yaml b/tests/fixtures/config/semaphore/git/common-config/playbooks/semaphore-two-test2.yaml
similarity index 100%
rename from tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/semaphore-two-test2.yaml
rename to tests/fixtures/config/semaphore/git/common-config/playbooks/semaphore-two-test2.yaml
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore/zuul.yaml b/tests/fixtures/config/semaphore/git/common-config/zuul.yaml
similarity index 85%
rename from tests/fixtures/config/single-tenant/git/layout-semaphore/zuul.yaml
rename to tests/fixtures/config/semaphore/git/common-config/zuul.yaml
index f935112..9d1cacf 100644
--- a/tests/fixtures/config/single-tenant/git/layout-semaphore/zuul.yaml
+++ b/tests/fixtures/config/semaphore/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -12,6 +11,14 @@
gerrit:
verified: -1
+# TODOv3(jeblair, tobiash): make semaphore definitions required, which
+# will cause these tests to fail until we define test-semaphore
+# here.
+
+- semaphore:
+ name: test-semaphore-two
+ max: 2
+
- job:
name: project-test1
@@ -46,7 +53,3 @@
- project-test1
- semaphore-two-test1
- semaphore-two-test2
-
-- semaphore:
- name: test-semaphore-two
- max: 2
diff --git a/tests/fixtures/config/single-tenant/git/org_noop-project/README b/tests/fixtures/config/semaphore/git/org_project/README
similarity index 100%
rename from tests/fixtures/config/single-tenant/git/org_noop-project/README
rename to tests/fixtures/config/semaphore/git/org_project/README
diff --git a/tests/fixtures/config/single-tenant/git/org_unknown/README b/tests/fixtures/config/semaphore/git/org_project1/README
similarity index 100%
rename from tests/fixtures/config/single-tenant/git/org_unknown/README
rename to tests/fixtures/config/semaphore/git/org_project1/README
diff --git a/tests/fixtures/config/semaphore/main.yaml b/tests/fixtures/config/semaphore/main.yaml
new file mode 100644
index 0000000..5f57245
--- /dev/null
+++ b/tests/fixtures/config/semaphore/main.yaml
@@ -0,0 +1,9 @@
+- tenant:
+ name: tenant-one
+ source:
+ gerrit:
+ config-projects:
+ - common-config
+ untrusted-projects:
+ - org/project
+ - org/project1
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/zuul.yaml b/tests/fixtures/config/semaphore/zuul-reconfiguration.yaml
similarity index 93%
rename from tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/zuul.yaml
rename to tests/fixtures/config/semaphore/zuul-reconfiguration.yaml
index 0e332e4..8fe8749 100644
--- a/tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/zuul.yaml
+++ b/tests/fixtures/config/semaphore/zuul-reconfiguration.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/single-tenant/git/common-config/playbooks/experimental-project-test.yaml b/tests/fixtures/config/single-tenant/git/common-config/playbooks/experimental-project-test.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/common-config/playbooks/experimental-project-test.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
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 dff18de..34bd9cd 100644
--- a/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -16,7 +15,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -37,24 +35,11 @@
- pipeline:
name: post
manager: independent
- source: gerrit
trigger:
gerrit:
- event: ref-updated
ref: ^(?!refs/).*$
-- pipeline:
- name: experimental
- manager: independent
- source: gerrit
- trigger:
- gerrit:
- - event: patchset-created
- success:
- gerrit: {}
- failure:
- gerrit: {}
-
- job:
name: project-merge
hold-following-changes: true
@@ -87,20 +72,6 @@
queue-name: integration
- job:
- name: experimental-project-test
-
-- job:
- name: nonvoting-project-merge
- hold-following-changes: true
-
-- job:
- name: nonvoting-project-test1
-
-- job:
- name: nonvoting-project-test2
- voting: false
-
-- job:
name: project-testfile
files:
- .*-requires
@@ -170,68 +141,3 @@
dependencies: project-merge
- project1-project2-integration:
dependencies: project-merge
-
-- project:
- name: org/project3
- check:
- jobs:
- - project-merge
- - project-test1:
- dependencies: project-merge
- - project-test2:
- dependencies: project-merge
- - project1-project2-integration:
- dependencies: project-merge
- gate:
- queue: integrated
- jobs:
- - project-merge
- - project-test1:
- dependencies: project-merge
- - project-test2:
- dependencies: project-merge
- - project1-project2-integration:
- dependencies: project-merge
- post:
- jobs:
- - project-post
-
-- project:
- name: org/experimental-project
- experimental:
- jobs:
- - project-merge
- - experimental-project-test:
- dependencies: project-merge
-
-- project:
- name: org/noop-project
- check:
- jobs:
- - noop
- gate:
- jobs:
- - noop
-
-- project:
- name: org/nonvoting-project
- check:
- jobs:
- - nonvoting-project-merge
- - nonvoting-project-test1:
- dependencies: nonvoting-project-merge
- - nonvoting-project-test2:
- dependencies: nonvoting-project-merge
- gate:
- jobs:
- - nonvoting-project-merge
- - nonvoting-project-test1:
- dependencies: nonvoting-project-merge
- - nonvoting-project-test2:
- dependencies: nonvoting-project-merge
-
-- project:
- name: org/no-jobs-project
- check:
- jobs:
- - project-testfile
diff --git a/tests/fixtures/config/single-tenant/git/layout-disabled-at/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-disabled-at/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-disabled-at/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-dont-ignore-ref-deletes/playbooks/project-post.yaml b/tests/fixtures/config/single-tenant/git/layout-dont-ignore-ref-deletes/playbooks/project-post.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-dont-ignore-ref-deletes/playbooks/project-post.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-footer-message/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-footer-message/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-footer-message/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-idle/playbooks/project-bitrot-stable-old.yaml b/tests/fixtures/config/single-tenant/git/layout-idle/playbooks/project-bitrot-stable-old.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-idle/playbooks/project-bitrot-stable-old.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-idle/playbooks/project-bitrot-stable-older.yaml b/tests/fixtures/config/single-tenant/git/layout-idle/playbooks/project-bitrot-stable-older.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-idle/playbooks/project-bitrot-stable-older.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-irrelevant-starts-empty.yaml b/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-irrelevant-starts-empty.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-irrelevant-starts-empty.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-irrelevant-starts-full.yaml b/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-irrelevant-starts-full.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-irrelevant-starts-full.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-nomatch-starts-empty.yaml b/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-nomatch-starts-empty.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-nomatch-starts-empty.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-nomatch-starts-full.yaml b/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-nomatch-starts-full.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-inheritance/playbooks/project-test-nomatch-starts-full.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-irrelevant-files/playbooks/project-test-irrelevant-files.yaml b/tests/fixtures/config/single-tenant/git/layout-irrelevant-files/playbooks/project-test-irrelevant-files.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-irrelevant-files/playbooks/project-test-irrelevant-files.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-merge.yaml b/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-merge.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-merge.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-test2.yaml b/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-test2.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-test2.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-testfile.yaml b/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-testfile.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/playbooks/project-testfile.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-no-jobs/playbooks/gate-noop.yaml b/tests/fixtures/config/single-tenant/git/layout-no-jobs/playbooks/gate-noop.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-no-jobs/playbooks/gate-noop.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-bitrot-stable-old.yaml b/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-bitrot-stable-old.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-bitrot-stable-old.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-bitrot-stable-older.yaml b/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-bitrot-stable-older.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-bitrot-stable-older.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-no-timer/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-merge.yaml b/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-merge.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-merge.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-test2.yaml b/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-test2.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-rate-limit/playbooks/project-test2.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-merge.yaml b/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-merge.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-merge.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-test2.yaml b/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-test2.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/playbooks/project-test2.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-semaphore/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/experimental-project-test.yaml b/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/experimental-project-test.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/experimental-project-test.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-merge.yaml b/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-merge.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-merge.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-test2.yaml b/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-test2.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-smtp/playbooks/project-test2.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/integration.yaml b/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/integration.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/integration.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/merge.yaml b/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/merge.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/merge.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/test1.yaml b/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/test2.yaml b/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/test2.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-tags/playbooks/test2.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-tags/zuul.yaml b/tests/fixtures/config/single-tenant/git/layout-tags/zuul.yaml
deleted file mode 100644
index 07f0657..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-tags/zuul.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-- pipeline:
- name: check
- manager: independent
- source: gerrit
- trigger:
- gerrit:
- - event: patchset-created
- success:
- gerrit:
- verified: 1
- failure:
- gerrit:
- verified: -1
-
-- job:
- name: merge
- failure-message: Unable to merge change
- hold-following-changes: true
- tags:
- - merge
-
-- job:
- name: test1
-
-- job:
- name: test2
-
-- job:
- name: integration
-
-- project:
- name: org/project1
- check:
- jobs:
- - merge:
- tags:
- - extratag
- - test1:
- dependencies: merge
- - test2:
- dependencies: merge
- - integration:
- dependencies: merge
-
-- project:
- name: org/project2
- check:
- jobs:
- - merge
- - test1:
- dependencies: merge
- - test2:
- dependencies: merge
- - integration:
- dependencies: merge
diff --git a/tests/fixtures/config/single-tenant/git/layout-timer-smtp/playbooks/project-bitrot-stable-old.yaml b/tests/fixtures/config/single-tenant/git/layout-timer-smtp/playbooks/project-bitrot-stable-old.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-timer-smtp/playbooks/project-bitrot-stable-old.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-timer-smtp/playbooks/project-bitrot-stable-older.yaml b/tests/fixtures/config/single-tenant/git/layout-timer-smtp/playbooks/project-bitrot-stable-older.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-timer-smtp/playbooks/project-bitrot-stable-older.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-bitrot-stable-old.yaml b/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-bitrot-stable-old.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-bitrot-stable-old.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-bitrot-stable-older.yaml b/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-bitrot-stable-older.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-bitrot-stable-older.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-test1.yaml b/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-test1.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-test1.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-test2.yaml b/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-test2.yaml
deleted file mode 100644
index f679dce..0000000
--- a/tests/fixtures/config/single-tenant/git/layout-timer/playbooks/project-test2.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-- hosts: all
- tasks: []
diff --git a/tests/fixtures/config/single-tenant/git/org_delete-project/README b/tests/fixtures/config/single-tenant/git/org_delete-project/README
deleted file mode 100644
index 9daeafb..0000000
--- a/tests/fixtures/config/single-tenant/git/org_delete-project/README
+++ /dev/null
@@ -1 +0,0 @@
-test
diff --git a/tests/fixtures/config/single-tenant/git/org_experimental-project/README b/tests/fixtures/config/single-tenant/git/org_experimental-project/README
deleted file mode 100644
index 9daeafb..0000000
--- a/tests/fixtures/config/single-tenant/git/org_experimental-project/README
+++ /dev/null
@@ -1 +0,0 @@
-test
diff --git a/tests/fixtures/config/single-tenant/git/org_no-jobs-project/README b/tests/fixtures/config/single-tenant/git/org_no-jobs-project/README
deleted file mode 100644
index 44f3bac..0000000
--- a/tests/fixtures/config/single-tenant/git/org_no-jobs-project/README
+++ /dev/null
@@ -1 +0,0 @@
-staypuft
diff --git a/tests/fixtures/config/single-tenant/git/org_nonvoting-project/README b/tests/fixtures/config/single-tenant/git/org_nonvoting-project/README
deleted file mode 100644
index 2cc3865..0000000
--- a/tests/fixtures/config/single-tenant/git/org_nonvoting-project/README
+++ /dev/null
@@ -1 +0,0 @@
-dont tread on me
diff --git a/tests/fixtures/config/single-tenant/git/org_project3/README b/tests/fixtures/config/single-tenant/git/org_project3/README
deleted file mode 100644
index 234496b..0000000
--- a/tests/fixtures/config/single-tenant/git/org_project3/README
+++ /dev/null
@@ -1 +0,0 @@
-third
diff --git a/tests/fixtures/config/single-tenant/main.yaml b/tests/fixtures/config/single-tenant/main.yaml
index d9868fa..83ed092 100644
--- a/tests/fixtures/config/single-tenant/main.yaml
+++ b/tests/fixtures/config/single-tenant/main.yaml
@@ -2,7 +2,9 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- project-repos:
+ untrusted-projects:
- org/project
+ - org/project1
+ - org/project2
diff --git a/tests/fixtures/config/sql-driver/git/common-config/zuul.yaml b/tests/fixtures/config/sql-driver/git/common-config/zuul.yaml
index 36c7602..dd80d08 100644
--- a/tests/fixtures/config/sql-driver/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/sql-driver/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/sql-driver/main.yaml b/tests/fixtures/config/sql-driver/main.yaml
index d9868fa..208e274 100644
--- a/tests/fixtures/config/sql-driver/main.yaml
+++ b/tests/fixtures/config/sql-driver/main.yaml
@@ -2,7 +2,7 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
- project-repos:
+ untrusted-projects:
- org/project
diff --git a/tests/fixtures/config/success-url/git/common-config/zuul.yaml b/tests/fixtures/config/success-url/git/common-config/zuul.yaml
index b3ecf6d..7082b8c 100644
--- a/tests/fixtures/config/success-url/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/success-url/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/success-url/main.yaml b/tests/fixtures/config/success-url/main.yaml
index a22ed5c..0027ae1 100644
--- a/tests/fixtures/config/success-url/main.yaml
+++ b/tests/fixtures/config/success-url/main.yaml
@@ -2,5 +2,7 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/docs
diff --git a/tests/fixtures/config/templated-project/git/common-config/zuul.yaml b/tests/fixtures/config/templated-project/git/common-config/zuul.yaml
index 8d2c8a0..251a3cd 100644
--- a/tests/fixtures/config/templated-project/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/templated-project/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -16,7 +15,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -37,7 +35,6 @@
- pipeline:
name: post
manager: independent
- source: gerrit
trigger:
gerrit:
- event: ref-updated
diff --git a/tests/fixtures/config/templated-project/main.yaml b/tests/fixtures/config/templated-project/main.yaml
index a22ed5c..e59b396 100644
--- a/tests/fixtures/config/templated-project/main.yaml
+++ b/tests/fixtures/config/templated-project/main.yaml
@@ -2,5 +2,8 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/templated-project
+ - org/layered-project
diff --git a/tests/fixtures/config/zuul-connections-multiple-gerrits/git/common-config/zuul.yaml b/tests/fixtures/config/zuul-connections-multiple-gerrits/git/common-config/zuul.yaml
index 302dfcf..961ff06 100644
--- a/tests/fixtures/config/zuul-connections-multiple-gerrits/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/zuul-connections-multiple-gerrits/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: review_check
manager: independent
- source: review_gerrit
trigger:
review_gerrit:
- event: patchset-created
@@ -15,7 +14,6 @@
- pipeline:
name: another_check
manager: independent
- source: another_gerrit
trigger:
another_gerrit:
- event: patchset-created
@@ -33,10 +31,13 @@
name: project-test2
- project:
- name: org/project1
+ name: review.example.com/org/project1
review_check:
jobs:
- project-test1
+
+- project:
+ name: another.example.com/org/project1
another_check:
jobs:
- project-test2
diff --git a/tests/fixtures/config/zuul-connections-multiple-gerrits/main.yaml b/tests/fixtures/config/zuul-connections-multiple-gerrits/main.yaml
index 730cc7e..f5bff21 100644
--- a/tests/fixtures/config/zuul-connections-multiple-gerrits/main.yaml
+++ b/tests/fixtures/config/zuul-connections-multiple-gerrits/main.yaml
@@ -2,5 +2,10 @@
name: tenant-one
source:
review_gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project1
+ another_gerrit:
+ untrusted-projects:
+ - org/project1
diff --git a/tests/fixtures/config/zuul-connections-same-gerrit/git/common-config/zuul.yaml b/tests/fixtures/config/zuul-connections-same-gerrit/git/common-config/zuul.yaml
index 114a4a3..adc61a3 100644
--- a/tests/fixtures/config/zuul-connections-same-gerrit/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/zuul-connections-same-gerrit/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: review_gerrit
trigger:
review_gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/zuul-connections-same-gerrit/main.yaml b/tests/fixtures/config/zuul-connections-same-gerrit/main.yaml
index 90297fb..9b2fc83 100644
--- a/tests/fixtures/config/zuul-connections-same-gerrit/main.yaml
+++ b/tests/fixtures/config/zuul-connections-same-gerrit/main.yaml
@@ -2,7 +2,7 @@
name: tenant-one
source:
review_gerrit:
- config-repos:
+ config-projects:
- common-config
- project-repos:
+ untrusted-projects:
- org/project
diff --git a/tests/fixtures/config/zuultrigger/parent-change-enqueued/git/common-config/zuul.yaml b/tests/fixtures/config/zuultrigger/parent-change-enqueued/git/common-config/zuul.yaml
index 8d63576..2b21c9b 100644
--- a/tests/fixtures/config/zuultrigger/parent-change-enqueued/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/zuultrigger/parent-change-enqueued/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
require:
approval:
- verified: -1
@@ -21,7 +20,6 @@
- pipeline:
name: gate
manager: dependent
- source: gerrit
require:
approval:
- verified: 1
diff --git a/tests/fixtures/config/zuultrigger/parent-change-enqueued/main.yaml b/tests/fixtures/config/zuultrigger/parent-change-enqueued/main.yaml
index a22ed5c..208e274 100644
--- a/tests/fixtures/config/zuultrigger/parent-change-enqueued/main.yaml
+++ b/tests/fixtures/config/zuultrigger/parent-change-enqueued/main.yaml
@@ -2,5 +2,7 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
+ untrusted-projects:
+ - org/project
diff --git a/tests/fixtures/config/zuultrigger/project-change-merged/git/common-config/zuul.yaml b/tests/fixtures/config/zuultrigger/project-change-merged/git/common-config/zuul.yaml
index eb6bf1c..48fdffe 100644
--- a/tests/fixtures/config/zuultrigger/project-change-merged/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/zuultrigger/project-change-merged/git/common-config/zuul.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -16,7 +15,6 @@
name: gate
manager: dependent
failure-message: Build failed. For information on how to proceed, see http://wiki.example.org/Test_Failures
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -37,7 +35,6 @@
- pipeline:
name: merge-check
manager: independent
- source: gerrit
ignore-dependencies: true
trigger:
zuul:
diff --git a/tests/fixtures/config/zuultrigger/project-change-merged/main.yaml b/tests/fixtures/config/zuultrigger/project-change-merged/main.yaml
index a22ed5c..9d01f54 100644
--- a/tests/fixtures/config/zuultrigger/project-change-merged/main.yaml
+++ b/tests/fixtures/config/zuultrigger/project-change-merged/main.yaml
@@ -2,5 +2,5 @@
name: tenant-one
source:
gerrit:
- config-repos:
+ config-projects:
- common-config
diff --git a/tests/fixtures/config/single-tenant/git/layout-disabled-at/zuul.yaml b/tests/fixtures/layouts/disable_at.yaml
similarity index 95%
rename from tests/fixtures/config/single-tenant/git/layout-disabled-at/zuul.yaml
rename to tests/fixtures/layouts/disable_at.yaml
index bdc19ac..2956ebf 100644
--- a/tests/fixtures/config/single-tenant/git/layout-disabled-at/zuul.yaml
+++ b/tests/fixtures/layouts/disable_at.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/single-tenant/git/layout-dont-ignore-ref-deletes/zuul.yaml b/tests/fixtures/layouts/dont-ignore-ref-deletes.yaml
similarity index 93%
rename from tests/fixtures/config/single-tenant/git/layout-dont-ignore-ref-deletes/zuul.yaml
rename to tests/fixtures/layouts/dont-ignore-ref-deletes.yaml
index 334d9ac..aee5ac6 100644
--- a/tests/fixtures/config/single-tenant/git/layout-dont-ignore-ref-deletes/zuul.yaml
+++ b/tests/fixtures/layouts/dont-ignore-ref-deletes.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: post
manager: independent
- source: gerrit
trigger:
gerrit:
- event: ref-updated
diff --git a/tests/fixtures/config/single-tenant/git/layout-footer-message/zuul.yaml b/tests/fixtures/layouts/footer-message.yaml
similarity index 97%
rename from tests/fixtures/config/single-tenant/git/layout-footer-message/zuul.yaml
rename to tests/fixtures/layouts/footer-message.yaml
index c698378..1261902 100644
--- a/tests/fixtures/config/single-tenant/git/layout-footer-message/zuul.yaml
+++ b/tests/fixtures/layouts/footer-message.yaml
@@ -2,7 +2,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
failure-message: Build failed. For information on how to proceed, see http://wiki.example.org/Test_Failures
footer-message: For CI problems and help debugging, contact ci@example.org
trigger:
@@ -29,6 +28,7 @@
- job:
name: project-test1
# success-url: http://logs.exxxample.com/{change.number}/{change.patchset}/{pipeline.name}/{job.name}
+
- project:
name: org/project
gate:
diff --git a/tests/fixtures/config/single-tenant/git/layout-idle/zuul.yaml b/tests/fixtures/layouts/idle.yaml
similarity index 95%
rename from tests/fixtures/config/single-tenant/git/layout-idle/zuul.yaml
rename to tests/fixtures/layouts/idle.yaml
index d1fa04b..ff33842 100644
--- a/tests/fixtures/config/single-tenant/git/layout-idle/zuul.yaml
+++ b/tests/fixtures/layouts/idle.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: periodic
manager: independent
- source: gerrit
trigger:
timer:
- time: '* * * * * */1'
diff --git a/tests/fixtures/config/single-tenant/git/layout-ignore-dependencies/zuul.yaml b/tests/fixtures/layouts/ignore-dependencies.yaml
similarity index 97%
rename from tests/fixtures/config/single-tenant/git/layout-ignore-dependencies/zuul.yaml
rename to tests/fixtures/layouts/ignore-dependencies.yaml
index 4010372..02aea36 100644
--- a/tests/fixtures/config/single-tenant/git/layout-ignore-dependencies/zuul.yaml
+++ b/tests/fixtures/layouts/ignore-dependencies.yaml
@@ -2,7 +2,6 @@
name: check
manager: independent
ignore-dependencies: true
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/single-tenant/git/layout-inheritance/zuul.yaml b/tests/fixtures/layouts/inheritance.yaml
similarity index 97%
rename from tests/fixtures/config/single-tenant/git/layout-inheritance/zuul.yaml
rename to tests/fixtures/layouts/inheritance.yaml
index ab8c9a5..65dddab 100644
--- a/tests/fixtures/config/single-tenant/git/layout-inheritance/zuul.yaml
+++ b/tests/fixtures/layouts/inheritance.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/single-tenant/git/layout-irrelevant-files/zuul.yaml b/tests/fixtures/layouts/irrelevant-files.yaml
similarity index 95%
rename from tests/fixtures/config/single-tenant/git/layout-irrelevant-files/zuul.yaml
rename to tests/fixtures/layouts/irrelevant-files.yaml
index 5d72fc0..3d086dc 100644
--- a/tests/fixtures/config/single-tenant/git/layout-irrelevant-files/zuul.yaml
+++ b/tests/fixtures/layouts/irrelevant-files.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/zuul.yaml b/tests/fixtures/layouts/live-reconfiguration-del-project.yaml
similarity index 96%
rename from tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/zuul.yaml
rename to tests/fixtures/layouts/live-reconfiguration-del-project.yaml
index a6d6599..299c612 100644
--- a/tests/fixtures/config/single-tenant/git/layout-live-reconfiguration-del-project/zuul.yaml
+++ b/tests/fixtures/layouts/live-reconfiguration-del-project.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
diff --git a/tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/zuul.yaml b/tests/fixtures/layouts/no-jobs-project.yaml
similarity index 68%
copy from tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/zuul.yaml
copy to tests/fixtures/layouts/no-jobs-project.yaml
index 0e332e4..803e5a0 100644
--- a/tests/fixtures/config/single-tenant/git/layout-semaphore-reconfiguration/zuul.yaml
+++ b/tests/fixtures/layouts/no-jobs-project.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -13,10 +12,12 @@
verified: -1
- job:
- name: project-test1
+ name: project-testfile
+ files:
+ - .*-requires
- project:
- name: org/project
+ name: org/no-jobs-project
check:
jobs:
- - project-test1
+ - project-testfile
diff --git a/tests/fixtures/config/single-tenant/git/layout-no-jobs/zuul.yaml b/tests/fixtures/layouts/no-jobs.yaml
similarity index 93%
rename from tests/fixtures/config/single-tenant/git/layout-no-jobs/zuul.yaml
rename to tests/fixtures/layouts/no-jobs.yaml
index 5894440..66193b0 100644
--- a/tests/fixtures/config/single-tenant/git/layout-no-jobs/zuul.yaml
+++ b/tests/fixtures/layouts/no-jobs.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -16,8 +15,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source:
- gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/single-tenant/git/layout-no-timer/zuul.yaml b/tests/fixtures/layouts/no-timer.yaml
similarity index 95%
rename from tests/fixtures/config/single-tenant/git/layout-no-timer/zuul.yaml
rename to tests/fixtures/layouts/no-timer.yaml
index ab919a4..c8ced62 100644
--- a/tests/fixtures/config/single-tenant/git/layout-no-timer/zuul.yaml
+++ b/tests/fixtures/layouts/no-timer.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -17,7 +16,6 @@
manager: independent
# Trigger is required, set it to one that is a noop
# during tests that check the timer trigger.
- source: gerrit
trigger:
gerrit:
- event: ref-updated
diff --git a/tests/fixtures/layouts/nonvoting-job.yaml b/tests/fixtures/layouts/nonvoting-job.yaml
new file mode 100644
index 0000000..fee5043
--- /dev/null
+++ b/tests/fixtures/layouts/nonvoting-job.yaml
@@ -0,0 +1,41 @@
+- pipeline:
+ name: gate
+ manager: dependent
+ success-message: Build succeeded (gate).
+ 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: nonvoting-project-merge
+ hold-following-changes: true
+
+- job:
+ name: nonvoting-project-test1
+
+- job:
+ name: nonvoting-project-test2
+ voting: false
+
+- project:
+ name: org/nonvoting-project
+ gate:
+ jobs:
+ - nonvoting-project-merge
+ - nonvoting-project-test1:
+ dependencies: nonvoting-project-merge
+ - nonvoting-project-test2:
+ dependencies: nonvoting-project-merge
diff --git a/tests/fixtures/layouts/nonvoting-pipeline.yaml b/tests/fixtures/layouts/nonvoting-pipeline.yaml
new file mode 100644
index 0000000..be5d5af
--- /dev/null
+++ b/tests/fixtures/layouts/nonvoting-pipeline.yaml
@@ -0,0 +1,25 @@
+- pipeline:
+ name: experimental
+ manager: independent
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit: {}
+ failure:
+ gerrit: {}
+
+- job:
+ name: project-merge
+ hold-following-changes: true
+
+- job:
+ name: experimental-project-test
+
+- project:
+ name: org/experimental-project
+ experimental:
+ jobs:
+ - project-merge
+ - experimental-project-test:
+ dependencies: project-merge
diff --git a/tests/fixtures/layouts/noop-job.yaml b/tests/fixtures/layouts/noop-job.yaml
new file mode 100644
index 0000000..8081216
--- /dev/null
+++ b/tests/fixtures/layouts/noop-job.yaml
@@ -0,0 +1,26 @@
+- pipeline:
+ name: gate
+ manager: dependent
+ success-message: Build succeeded (gate).
+ trigger:
+ gerrit:
+ - event: comment-added
+ approval:
+ - approved: 1
+ success:
+ gerrit:
+ verified: 2
+ submit: true
+ failure:
+ gerrit:
+ verified: -2
+ start:
+ gerrit:
+ verified: 0
+ precedence: high
+
+- project:
+ name: org/noop-project
+ gate:
+ jobs:
+ - noop
diff --git a/tests/fixtures/config/one-job-project/git/common-config/zuul.yaml b/tests/fixtures/layouts/one-job-project.yaml
similarity index 94%
rename from tests/fixtures/config/one-job-project/git/common-config/zuul.yaml
rename to tests/fixtures/layouts/one-job-project.yaml
index 4579062..b293269 100644
--- a/tests/fixtures/config/one-job-project/git/common-config/zuul.yaml
+++ b/tests/fixtures/layouts/one-job-project.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -16,7 +15,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -37,7 +35,6 @@
- pipeline:
name: post
manager: independent
- source: gerrit
trigger:
gerrit:
- event: ref-updated
diff --git a/tests/fixtures/config/single-tenant/git/layout-rate-limit/zuul.yaml b/tests/fixtures/layouts/rate-limit.yaml
similarity index 97%
rename from tests/fixtures/config/single-tenant/git/layout-rate-limit/zuul.yaml
rename to tests/fixtures/layouts/rate-limit.yaml
index c4e00f6..283354e 100644
--- a/tests/fixtures/config/single-tenant/git/layout-rate-limit/zuul.yaml
+++ b/tests/fixtures/layouts/rate-limit.yaml
@@ -2,7 +2,6 @@
name: gate
manager: dependent
failure-message: Build failed. For information on how to proceed, see http://wiki.example.org/Test_Failures
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/zuul.yaml b/tests/fixtures/layouts/repo-deleted.yaml
similarity index 96%
rename from tests/fixtures/config/single-tenant/git/layout-repo-deleted/zuul.yaml
rename to tests/fixtures/layouts/repo-deleted.yaml
index 5851d75..a33da77 100644
--- a/tests/fixtures/config/single-tenant/git/layout-repo-deleted/zuul.yaml
+++ b/tests/fixtures/layouts/repo-deleted.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -16,7 +15,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
diff --git a/tests/fixtures/config/single-tenant/git/layout-smtp/zuul.yaml b/tests/fixtures/layouts/smtp.yaml
similarity index 93%
rename from tests/fixtures/config/single-tenant/git/layout-smtp/zuul.yaml
rename to tests/fixtures/layouts/smtp.yaml
index be90d48..8f53d02 100644
--- a/tests/fixtures/config/single-tenant/git/layout-smtp/zuul.yaml
+++ b/tests/fixtures/layouts/smtp.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -22,7 +21,6 @@
name: gate
manager: dependent
success-message: Build succeeded (gate).
- source: gerrit
trigger:
gerrit:
- event: comment-added
@@ -60,9 +58,6 @@
- job:
name: project-test2
-- job:
- name: experimental-project-test
-
- project:
name: org/project
check:
diff --git a/tests/fixtures/layouts/tags.yaml b/tests/fixtures/layouts/tags.yaml
new file mode 100644
index 0000000..422eca2
--- /dev/null
+++ b/tests/fixtures/layouts/tags.yaml
@@ -0,0 +1,31 @@
+- pipeline:
+ name: check
+ manager: independent
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit:
+ verified: 1
+ failure:
+ gerrit:
+ verified: -1
+
+- job:
+ name: merge
+ tags:
+ - merge
+
+- project:
+ name: org/project1
+ check:
+ jobs:
+ - merge:
+ tags:
+ - extratag
+
+- project:
+ name: org/project2
+ check:
+ jobs:
+ - merge
diff --git a/tests/fixtures/layouts/three-projects.yaml b/tests/fixtures/layouts/three-projects.yaml
new file mode 100644
index 0000000..5d10276
--- /dev/null
+++ b/tests/fixtures/layouts/three-projects.yaml
@@ -0,0 +1,112 @@
+- pipeline:
+ name: check
+ manager: independent
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit:
+ verified: 1
+ failure:
+ gerrit:
+ verified: -1
+
+- pipeline:
+ name: gate
+ manager: dependent
+ success-message: Build succeeded (gate).
+ 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
+
+- job:
+ name: project-test2
+
+- job:
+ name: project1-project2-integration
+
+- project:
+ name: org/project1
+ check:
+ jobs:
+ - project-merge
+ - project-test1:
+ dependencies: project-merge
+ - project-test2:
+ dependencies: project-merge
+ - project1-project2-integration:
+ dependencies: project-merge
+ gate:
+ queue: integrated
+ jobs:
+ - project-merge
+ - project-test1:
+ dependencies: project-merge
+ - project-test2:
+ dependencies: project-merge
+ - project1-project2-integration:
+ dependencies: project-merge
+
+- project:
+ name: org/project2
+ check:
+ jobs:
+ - project-merge
+ - project-test1:
+ dependencies: project-merge
+ - project-test2:
+ dependencies: project-merge
+ - project1-project2-integration:
+ dependencies: project-merge
+ gate:
+ queue: integrated
+ jobs:
+ - project-merge
+ - project-test1:
+ dependencies: project-merge
+ - project-test2:
+ dependencies: project-merge
+ - project1-project2-integration:
+ dependencies: project-merge
+
+- project:
+ name: org/project3
+ check:
+ jobs:
+ - project-merge
+ - project-test1:
+ dependencies: project-merge
+ - project-test2:
+ dependencies: project-merge
+ - project1-project2-integration:
+ dependencies: project-merge
+ gate:
+ queue: integrated
+ jobs:
+ - project-merge
+ - project-test1:
+ dependencies: project-merge
+ - project-test2:
+ dependencies: project-merge
+ - project1-project2-integration:
+ dependencies: project-merge
diff --git a/tests/fixtures/config/single-tenant/git/layout-timer-smtp/zuul.yaml b/tests/fixtures/layouts/timer-smtp.yaml
similarity index 96%
rename from tests/fixtures/config/single-tenant/git/layout-timer-smtp/zuul.yaml
rename to tests/fixtures/layouts/timer-smtp.yaml
index 2a2eca5..66e9aaf 100644
--- a/tests/fixtures/config/single-tenant/git/layout-timer-smtp/zuul.yaml
+++ b/tests/fixtures/layouts/timer-smtp.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: periodic
manager: independent
- source: gerrit
trigger:
timer:
- time: '* * * * * */1'
diff --git a/tests/fixtures/config/single-tenant/git/layout-timer/zuul.yaml b/tests/fixtures/layouts/timer.yaml
similarity index 94%
rename from tests/fixtures/config/single-tenant/git/layout-timer/zuul.yaml
rename to tests/fixtures/layouts/timer.yaml
index 8072644..95199e7 100644
--- a/tests/fixtures/config/single-tenant/git/layout-timer/zuul.yaml
+++ b/tests/fixtures/layouts/timer.yaml
@@ -1,7 +1,6 @@
- pipeline:
name: check
manager: independent
- source: gerrit
trigger:
gerrit:
- event: patchset-created
@@ -15,7 +14,6 @@
- pipeline:
name: periodic
manager: independent
- source: gerrit
trigger:
timer:
- time: '* * * * * */1'
diff --git a/tests/nodepool/test_nodepool_integration.py b/tests/nodepool/test_nodepool_integration.py
index 2c9a9b3..9c87a10 100644
--- a/tests/nodepool/test_nodepool_integration.py
+++ b/tests/nodepool/test_nodepool_integration.py
@@ -28,9 +28,10 @@
# fake scheduler.
def setUp(self):
- super(BaseTestCase, self).setUp()
+ super(TestNodepoolIntegration, self).setUp()
self.zk = zuul.zk.ZooKeeper()
+ self.addCleanup(self.zk.disconnect)
self.zk.connect('localhost:2181')
self.hostname = socket.gethostname()
diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py
index ee9a0b0..db32938 100644
--- a/tests/unit/test_connection.py
+++ b/tests/unit/test_connection.py
@@ -147,9 +147,6 @@
def test_multiple_sql_connections(self):
"Test putting results in different databases"
- self.updateConfigLayout(
- 'tests/fixtures/layout-sql-reporter.yaml')
-
# Add a successful result
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
diff --git a/tests/unit/test_gerrit.py b/tests/unit/test_gerrit.py
index 999e55d..a369aff 100644
--- a/tests/unit/test_gerrit.py
+++ b/tests/unit/test_gerrit.py
@@ -22,6 +22,7 @@
import tests.base
from tests.base import BaseTestCase
+from zuul.driver.gerrit import GerritDriver
from zuul.driver.gerrit.gerritconnection import GerritConnection
FIXTURE_DIR = os.path.join(tests.base.FIXTURE_DIR, 'gerrit')
@@ -53,7 +54,8 @@
'user': 'gerrit',
'server': 'localhost',
}
- gerrit = GerritConnection(None, 'review_gerrit', gerrit_config)
+ driver = GerritDriver()
+ gerrit = GerritConnection(driver, 'review_gerrit', gerrit_config)
calls, values = read_fixtures(files)
_ssh_mock.side_effect = values
diff --git a/tests/unit/test_git_driver.py b/tests/unit/test_git_driver.py
index 4d75944..1cfadf4 100644
--- a/tests/unit/test_git_driver.py
+++ b/tests/unit/test_git_driver.py
@@ -27,10 +27,10 @@
tenant = self.sched.abide.tenants.get('tenant-one')
# Check that we have the git source for common-config and the
# gerrit source for the project.
- self.assertEqual('git', tenant.config_repos[0][0].name)
- self.assertEqual('common-config', tenant.config_repos[0][1].name)
- self.assertEqual('gerrit', tenant.project_repos[0][0].name)
- self.assertEqual('org/project', tenant.project_repos[0][1].name)
+ self.assertEqual('git', tenant.config_projects[0].source.name)
+ self.assertEqual('common-config', tenant.config_projects[0].name)
+ self.assertEqual('gerrit', tenant.untrusted_projects[0].source.name)
+ self.assertEqual('org/project', tenant.untrusted_projects[0].name)
# The configuration for this test is accessed via the git
# driver (in common-config), rather than the gerrit driver, so
diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py
index 2167a3b..d8480ea 100644
--- a/tests/unit/test_model.py
+++ b/tests/unit/test_model.py
@@ -27,20 +27,22 @@
from tests.base import BaseTestCase, FIXTURE_DIR
-class FakeSource(object):
- def __init__(self, name):
- self.name = name
+class Dummy(object):
+ def __init__(self, **kw):
+ for k, v in kw.items():
+ setattr(self, k, v)
class TestJob(BaseTestCase):
-
def setUp(self):
super(TestJob, self).setUp()
+ self.connection = Dummy(connection_name='dummy_connection')
+ self.source = Dummy(canonical_hostname='git.example.com',
+ connection=self.connection)
self.tenant = model.Tenant('tenant')
self.layout = model.Layout()
- self.project = model.Project('project', 'connection')
- self.source = FakeSource('connection')
- self.tenant.addProjectRepo(self.source, self.project)
+ self.project = model.Project('project', self.source)
+ self.tenant.addUntrustedProject(self.project)
self.pipeline = model.Pipeline('gate', self.layout)
self.layout.addPipeline(self.pipeline)
self.queue = model.ChangeQueue(self.pipeline)
@@ -162,7 +164,8 @@
pipeline = model.Pipeline('gate', layout)
layout.addPipeline(pipeline)
queue = model.ChangeQueue(pipeline)
- project = model.Project('project', None)
+ project = model.Project('project', self.source)
+ tenant.addUntrustedProject(project)
base = configloader.JobParser.fromYaml(tenant, layout, {
'_source_context': self.context,
@@ -429,6 +432,7 @@
def test_job_inheritance_job_tree(self):
tenant = model.Tenant('tenant')
layout = model.Layout()
+ tenant.addUntrustedProject(self.project)
pipeline = model.Pipeline('gate', layout)
layout.addPipeline(pipeline)
@@ -508,7 +512,8 @@
pipeline = model.Pipeline('gate', layout)
layout.addPipeline(pipeline)
queue = model.ChangeQueue(pipeline)
- project = model.Project('project', None)
+ project = model.Project('project', self.source)
+ tenant.addUntrustedProject(project)
base = configloader.JobParser.fromYaml(tenant, layout, {
'_source_context': self.context,
@@ -554,7 +559,7 @@
def test_job_source_project(self):
tenant = model.Tenant('tenant')
layout = model.Layout()
- base_project = model.Project('base_project', None)
+ base_project = model.Project('base_project', self.source)
base_context = model.SourceContext(base_project, 'master',
'test', True)
@@ -565,7 +570,7 @@
})
layout.addJob(base)
- other_project = model.Project('other_project', None)
+ other_project = model.Project('other_project', self.source)
other_context = model.SourceContext(other_project, 'master',
'test', True)
base2 = configloader.JobParser.fromYaml(tenant, layout, {
@@ -588,7 +593,8 @@
})
self.layout.addJob(job)
- project2 = model.Project('project2', None)
+ project2 = model.Project('project2', self.source)
+ self.tenant.addUntrustedProject(project2)
context2 = model.SourceContext(project2, 'master',
'test', True)
@@ -778,3 +784,137 @@
graph.addJob(jobs[3])
jobs[6].dependencies = frozenset([jobs[2].name])
graph.addJob(jobs[6])
+
+
+class TestTenant(BaseTestCase):
+ def test_add_project(self):
+ tenant = model.Tenant('tenant')
+ connection1 = Dummy(connection_name='dummy_connection1')
+ source1 = Dummy(canonical_hostname='git1.example.com',
+ name='dummy', # TODOv3(jeblair): remove
+ connection=connection1)
+
+ source1_project1 = model.Project('project1', source1)
+ tenant.addConfigProject(source1_project1)
+ d = {'project1':
+ {'git1.example.com': source1_project1}}
+ self.assertEqual(d, tenant.projects)
+ self.assertEqual((True, source1_project1),
+ tenant.getProject('project1'))
+ self.assertEqual((True, source1_project1),
+ tenant.getProject('git1.example.com/project1'))
+
+ source1_project2 = model.Project('project2', source1)
+ tenant.addUntrustedProject(source1_project2)
+ d = {'project1':
+ {'git1.example.com': source1_project1},
+ 'project2':
+ {'git1.example.com': source1_project2}}
+ self.assertEqual(d, tenant.projects)
+ self.assertEqual((False, source1_project2),
+ tenant.getProject('project2'))
+ self.assertEqual((False, source1_project2),
+ tenant.getProject('git1.example.com/project2'))
+
+ connection2 = Dummy(connection_name='dummy_connection2')
+ source2 = Dummy(canonical_hostname='git2.example.com',
+ name='dummy', # TODOv3(jeblair): remove
+ connection=connection2)
+
+ source2_project1 = model.Project('project1', source2)
+ tenant.addUntrustedProject(source2_project1)
+ d = {'project1':
+ {'git1.example.com': source1_project1,
+ 'git2.example.com': source2_project1},
+ 'project2':
+ {'git1.example.com': source1_project2}}
+ self.assertEqual(d, tenant.projects)
+ with testtools.ExpectedException(
+ Exception,
+ "Project name 'project1' is ambiguous"):
+ tenant.getProject('project1')
+ self.assertEqual((False, source1_project2),
+ tenant.getProject('project2'))
+ self.assertEqual((True, source1_project1),
+ tenant.getProject('git1.example.com/project1'))
+ self.assertEqual((False, source2_project1),
+ tenant.getProject('git2.example.com/project1'))
+
+ source2_project2 = model.Project('project2', source2)
+ tenant.addConfigProject(source2_project2)
+ d = {'project1':
+ {'git1.example.com': source1_project1,
+ 'git2.example.com': source2_project1},
+ 'project2':
+ {'git1.example.com': source1_project2,
+ 'git2.example.com': source2_project2}}
+ self.assertEqual(d, tenant.projects)
+ with testtools.ExpectedException(
+ Exception,
+ "Project name 'project1' is ambiguous"):
+ tenant.getProject('project1')
+ with testtools.ExpectedException(
+ Exception,
+ "Project name 'project2' is ambiguous"):
+ tenant.getProject('project2')
+ self.assertEqual((True, source1_project1),
+ tenant.getProject('git1.example.com/project1'))
+ self.assertEqual((False, source2_project1),
+ tenant.getProject('git2.example.com/project1'))
+ self.assertEqual((False, source1_project2),
+ tenant.getProject('git1.example.com/project2'))
+ self.assertEqual((True, source2_project2),
+ tenant.getProject('git2.example.com/project2'))
+
+ source1_project2b = model.Project('subpath/project2', source1)
+ tenant.addConfigProject(source1_project2b)
+ d = {'project1':
+ {'git1.example.com': source1_project1,
+ 'git2.example.com': source2_project1},
+ 'project2':
+ {'git1.example.com': source1_project2,
+ 'git2.example.com': source2_project2},
+ 'subpath/project2':
+ {'git1.example.com': source1_project2b}}
+ self.assertEqual(d, tenant.projects)
+ self.assertEqual((False, source1_project2),
+ tenant.getProject('git1.example.com/project2'))
+ self.assertEqual((True, source2_project2),
+ tenant.getProject('git2.example.com/project2'))
+ self.assertEqual((True, source1_project2b),
+ tenant.getProject('subpath/project2'))
+ self.assertEqual(
+ (True, source1_project2b),
+ tenant.getProject('git1.example.com/subpath/project2'))
+
+ source2_project2b = model.Project('subpath/project2', source2)
+ tenant.addConfigProject(source2_project2b)
+ d = {'project1':
+ {'git1.example.com': source1_project1,
+ 'git2.example.com': source2_project1},
+ 'project2':
+ {'git1.example.com': source1_project2,
+ 'git2.example.com': source2_project2},
+ 'subpath/project2':
+ {'git1.example.com': source1_project2b,
+ 'git2.example.com': source2_project2b}}
+ self.assertEqual(d, tenant.projects)
+ self.assertEqual((False, source1_project2),
+ tenant.getProject('git1.example.com/project2'))
+ self.assertEqual((True, source2_project2),
+ tenant.getProject('git2.example.com/project2'))
+ with testtools.ExpectedException(
+ Exception,
+ "Project name 'subpath/project2' is ambiguous"):
+ tenant.getProject('subpath/project2')
+ self.assertEqual(
+ (True, source1_project2b),
+ tenant.getProject('git1.example.com/subpath/project2'))
+ self.assertEqual(
+ (True, source2_project2b),
+ tenant.getProject('git2.example.com/subpath/project2'))
+
+ with testtools.ExpectedException(
+ Exception,
+ "Project project1 is already in project index"):
+ tenant._addProject(source1_project1)
diff --git a/tests/unit/test_nodepool.py b/tests/unit/test_nodepool.py
index 0a55f9f..ba7523c 100644
--- a/tests/unit/test_nodepool.py
+++ b/tests/unit/test_nodepool.py
@@ -27,15 +27,17 @@
# scheduler.
def setUp(self):
- super(BaseTestCase, self).setUp()
+ super(TestNodepool, self).setUp()
- self.zk_chroot_fixture = self.useFixture(ChrootedKazooFixture())
+ self.zk_chroot_fixture = self.useFixture(
+ ChrootedKazooFixture(self.id()))
self.zk_config = '%s:%s%s' % (
self.zk_chroot_fixture.zookeeper_host,
self.zk_chroot_fixture.zookeeper_port,
self.zk_chroot_fixture.zookeeper_chroot)
self.zk = zuul.zk.ZooKeeper()
+ self.addCleanup(self.zk.disconnect)
self.zk.connect(self.zk_config)
self.hostname = 'nodepool-test-hostname'
@@ -48,6 +50,7 @@
self.zk_chroot_fixture.zookeeper_host,
self.zk_chroot_fixture.zookeeper_port,
self.zk_chroot_fixture.zookeeper_chroot)
+ self.addCleanup(self.fake_nodepool.stop)
def waitForRequests(self):
# Wait until all requests are complete.
diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py
index 43a8ddf..3c38045 100755
--- a/tests/unit/test_scheduler.py
+++ b/tests/unit/test_scheduler.py
@@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import gc
import json
import textwrap
@@ -35,6 +36,7 @@
from tests.base import (
ZuulTestCase,
repack_repo,
+ simple_layout,
)
@@ -905,7 +907,8 @@
# TODO: move to test_gerrit (this is a unit test!)
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
tenant = self.sched.abide.tenants.get('tenant-one')
- source = tenant.layout.pipelines['gate'].source
+ (trusted, project) = tenant.getProject('org/project')
+ source = project.source
# TODO(pabelanger): As we add more source / trigger APIs we should make
# it easier for users to create events for testing.
@@ -1103,12 +1106,9 @@
self.assertEqual(len(self.history), 0)
self.assertNotIn('project-post', job_names)
+ @simple_layout('layouts/dont-ignore-ref-deletes.yaml')
def test_post_ignore_deletes_negative(self):
"Test that deleting refs does trigger post jobs"
-
- self.updateConfigLayout('layout-dont-ignore-ref-deletes')
- self.sched.reconfigure(self.config)
-
e = {
"type": "ref-updated",
"submitter": {
@@ -1245,16 +1245,15 @@
# aborted jobs.
self.executor_server.hold_jobs_in_build = True
- A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
- B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
- C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+ B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
+ C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
A.addApproval('code-review', 2)
B.addApproval('code-review', 2)
C.addApproval('code-review', 2)
self.executor_server.failJob('project-test1', A)
self.executor_server.failJob('project-test2', A)
- self.executor_server.failJob('project1-project2-integration', A)
self.fake_gerrit.addEvent(A.addApproval('approved', 1))
self.fake_gerrit.addEvent(B.addApproval('approved', 1))
@@ -1273,29 +1272,26 @@
self.executor_server.release('.*-merge')
self.waitUntilSettled()
- self.assertEqual(len(self.builds), 9)
+ self.assertEqual(len(self.builds), 6)
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, '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, 'project-test1')
- self.assertEqual(self.builds[7].name, 'project-test2')
- self.assertEqual(self.builds[8].name, 'project1-project2-integration')
+ self.assertEqual(self.builds[2].name, 'project-test1')
+ self.assertEqual(self.builds[3].name, 'project-test2')
+ self.assertEqual(self.builds[4].name, 'project-test1')
+ self.assertEqual(self.builds[5].name, 'project-test2')
self.release(self.builds[0])
self.waitUntilSettled()
- self.assertEqual(len(self.builds), 3) # test2,integration, merge for B
- self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 6)
+ self.assertEqual(len(self.builds), 2) # test2, merge for B
+ self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 4)
self.executor_server.hold_jobs_in_build = False
self.executor_server.release()
self.waitUntilSettled()
self.assertEqual(len(self.builds), 0)
- self.assertEqual(len(self.history), 20)
+ self.assertEqual(len(self.history), 15)
self.assertEqual(A.data['status'], 'NEW')
self.assertEqual(B.data['status'], 'MERGED')
@@ -1304,6 +1300,7 @@
self.assertEqual(B.reported, 2)
self.assertEqual(C.reported, 2)
+ @simple_layout('layouts/nonvoting-job.yaml')
def test_nonvoting_job(self):
"Test that non-voting jobs don't vote."
@@ -1365,10 +1362,11 @@
self.assertEqual(self.getJobFromHistory('project-test2').result,
'FAILURE')
+ @simple_layout('layouts/three-projects.yaml')
def test_dependent_behind_dequeue(self):
# This particular test does a large amount of merges and needs a little
# more time to complete
- self.wait_timeout = 90
+ self.wait_timeout = 120
"test that dependent changes behind dequeued changes work"
# This complicated test is a reproduction of a real life bug
self.sched.reconfigure(self.config)
@@ -1497,17 +1495,17 @@
# https://bugs.executepad.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(
- tenant.layout.project_configs.get('org/project1'))
- self.merge_server.merger.addProject('org/project1', url)
- A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
+ trusted, project = tenant.getProject('org/project')
+ url = self.fake_gerrit.getGitUrl(project)
+ self.merge_server.merger.addProject('org/project', url)
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
A.addPatchset(large=True)
- path = os.path.join(self.upstream_root, "org/project1")
+ path = os.path.join(self.upstream_root, "org/project")
repack_repo(path)
- path = os.path.join(self.merger_src_root, "org/project1")
+ path = os.path.join(self.merger_src_root, "org/project")
if os.path.exists(path):
repack_repo(path)
- path = os.path.join(self.executor_src_root, "org/project1")
+ path = os.path.join(self.executor_src_root, "org/project")
if os.path.exists(path):
repack_repo(path)
@@ -1744,11 +1742,13 @@
def test_abandoned_not_timer(self):
"Test that an abandoned change does not cancel timer jobs"
-
+ # This test can not use simple_layout because it must start
+ # with a configuration which does not include a
+ # timer-triggered job so that we have an opportunity to set
+ # the hold flag before the first job.
self.executor_server.hold_jobs_in_build = True
-
# Start timer trigger - also org/project
- self.updateConfigLayout('layout-idle')
+ self.commitConfigUpdate('common-config', 'layouts/idle.yaml')
self.sched.reconfigure(self.config)
# The pipeline triggers every second, so we should have seen
# several by now.
@@ -1757,9 +1757,9 @@
# Stop queuing timer triggered jobs so that the assertions
# below don't race against more jobs being queued.
# Must be in same repo, so overwrite config with another one
- self.commitLayoutUpdate('layout-idle', 'layout-no-timer')
-
+ self.commitConfigUpdate('common-config', 'layouts/no-timer.yaml')
self.sched.reconfigure(self.config)
+
self.assertEqual(len(self.builds), 2, "Two timer jobs")
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
@@ -1895,6 +1895,7 @@
self.assertEqual(len(self.history), 10)
self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
+ @simple_layout('layouts/noop-job.yaml')
def test_noop_job(self):
"Test that the internal noop job works"
A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
@@ -1908,6 +1909,7 @@
self.assertEqual(A.data['status'], 'MERGED')
self.assertEqual(A.reported, 2)
+ @simple_layout('layouts/no-jobs-project.yaml')
def test_no_job_project(self):
"Test that reports with no jobs don't get sent"
A = self.fake_gerrit.addFakeChange('org/no-jobs-project',
@@ -2051,7 +2053,7 @@
# The assertion is that we have one job in the queue, project-merge
self.assertEqual(len(self.gearman_server.getQueue()), 1)
- self.commitLayoutUpdate('common-config', 'layout-no-jobs')
+ self.commitConfigUpdate('common-config', 'layouts/no-jobs.yaml')
self.sched.reconfigure(self.config)
self.waitUntilSettled()
@@ -2112,9 +2114,6 @@
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)
-
if should_skip:
files = {'ignoreme': 'ignored\n'}
else:
@@ -2135,16 +2134,16 @@
else:
self.assertIn(change.data['number'], tested_change_ids)
+ @simple_layout('layouts/irrelevant-files.yaml')
def test_irrelevant_files_match_skips_job(self):
self._test_irrelevant_files_jobs(should_skip=True)
+ @simple_layout('layouts/irrelevant-files.yaml')
def test_irrelevant_files_no_match_runs_job(self):
self._test_irrelevant_files_jobs(should_skip=False)
+ @simple_layout('layouts/inheritance.yaml')
def test_inherited_jobs_keep_matchers(self):
- self.updateConfigLayout('layout-inheritance')
- self.sched.reconfigure(self.config)
-
files = {'ignoreme': 'ignored\n'}
change = self.fake_gerrit.addFakeChange('org/project',
@@ -2168,9 +2167,8 @@
def test_queue_names(self):
"Test shared change queue names"
tenant = self.sched.abide.tenants.get('tenant-one')
- source = tenant.layout.pipelines['gate'].source
- project1 = source.getProject('org/project1')
- project2 = source.getProject('org/project2')
+ (trusted, project1) = tenant.getProject('org/project1')
+ (trusted, project2) = tenant.getProject('org/project2')
q1 = tenant.layout.pipelines['gate'].getQueue(project1)
q2 = tenant.layout.pipelines['gate'].getQueue(project2)
self.assertEqual(q1.name, 'integrated')
@@ -2266,246 +2264,6 @@
self.assertEqual('https://server/job/project-test2/0/',
status_jobs[2]['report_url'])
- def test_semaphore_one(self):
- "Test semaphores with max=1 (mutex)"
- self.updateConfigLayout('layout-semaphore')
- self.sched.reconfigure(self.config)
-
- self.waitUntilSettled()
- tenant = self.sched.abide.tenants.get('openstack')
-
- self.executor_server.hold_jobs_in_build = True
-
- A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
- B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
- self.assertFalse('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
- self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 3)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'semaphore-one-test1')
- self.assertEqual(self.builds[2].name, 'project-test1')
-
- self.executor_server.release('semaphore-one-test1')
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 3)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'project-test1')
- self.assertEqual(self.builds[2].name, 'semaphore-one-test2')
- self.assertTrue('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.executor_server.release('semaphore-one-test2')
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 3)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'project-test1')
- self.assertEqual(self.builds[2].name, 'semaphore-one-test1')
- self.assertTrue('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.executor_server.release('semaphore-one-test1')
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 3)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'project-test1')
- self.assertEqual(self.builds[2].name, 'semaphore-one-test2')
- self.assertTrue('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.executor_server.release('semaphore-one-test2')
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 2)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'project-test1')
- self.assertFalse('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.executor_server.hold_jobs_in_build = False
- self.executor_server.release()
-
- self.waitUntilSettled()
- self.assertEqual(len(self.builds), 0)
-
- self.assertEqual(A.reported, 1)
- self.assertEqual(B.reported, 1)
- self.assertFalse('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- def test_semaphore_two(self):
- "Test semaphores with max>1"
- self.updateConfigLayout('layout-semaphore')
- self.sched.reconfigure(self.config)
-
- self.waitUntilSettled()
- tenant = self.sched.abide.tenants.get('openstack')
-
- self.executor_server.hold_jobs_in_build = True
- A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
- B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
- self.assertFalse('test-semaphore-two' in
- tenant.semaphore_handler.semaphores)
-
- self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
- self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 4)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'semaphore-two-test1')
- self.assertEqual(self.builds[2].name, 'semaphore-two-test2')
- self.assertEqual(self.builds[3].name, 'project-test1')
- self.assertTrue('test-semaphore-two' in
- tenant.semaphore_handler.semaphores)
- self.assertEqual(len(tenant.semaphore_handler.semaphores.get(
- 'test-semaphore-two', [])), 2)
-
- self.executor_server.release('semaphore-two-test1')
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 4)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'semaphore-two-test2')
- self.assertEqual(self.builds[2].name, 'project-test1')
- self.assertEqual(self.builds[3].name, 'semaphore-two-test1')
- self.assertTrue('test-semaphore-two' in
- tenant.semaphore_handler.semaphores)
- self.assertEqual(len(tenant.semaphore_handler.semaphores.get(
- 'test-semaphore-two', [])), 2)
-
- self.executor_server.release('semaphore-two-test2')
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 4)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'project-test1')
- self.assertEqual(self.builds[2].name, 'semaphore-two-test1')
- self.assertEqual(self.builds[3].name, 'semaphore-two-test2')
- self.assertTrue('test-semaphore-two' in
- tenant.semaphore_handler.semaphores)
- self.assertEqual(len(tenant.semaphore_handler.semaphores.get(
- 'test-semaphore-two', [])), 2)
-
- self.executor_server.release('semaphore-two-test1')
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 3)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'project-test1')
- self.assertEqual(self.builds[2].name, 'semaphore-two-test2')
- self.assertTrue('test-semaphore-two' in
- tenant.semaphore_handler.semaphores)
- self.assertEqual(len(tenant.semaphore_handler.semaphores.get(
- 'test-semaphore-two', [])), 1)
-
- self.executor_server.release('semaphore-two-test2')
- self.waitUntilSettled()
-
- self.assertEqual(len(self.builds), 2)
- self.assertEqual(self.builds[0].name, 'project-test1')
- self.assertEqual(self.builds[1].name, 'project-test1')
- self.assertFalse('test-semaphore-two' in
- tenant.semaphore_handler.semaphores)
-
- self.executor_server.hold_jobs_in_build = False
- self.executor_server.release()
-
- self.waitUntilSettled()
- self.assertEqual(len(self.builds), 0)
-
- self.assertEqual(A.reported, 1)
- self.assertEqual(B.reported, 1)
-
- def test_semaphore_abandon(self):
- "Test abandon with job semaphores"
- self.updateConfigLayout('layout-semaphore')
- self.sched.reconfigure(self.config)
-
- self.waitUntilSettled()
- tenant = self.sched.abide.tenants.get('openstack')
-
- self.executor_server.hold_jobs_in_build = True
-
- tenant = self.sched.abide.tenants.get('openstack')
- check_pipeline = tenant.layout.pipelines['check']
-
- A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
- self.assertFalse('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
- self.waitUntilSettled()
-
- self.assertTrue('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
- self.waitUntilSettled()
-
- # The check pipeline should be empty
- items = check_pipeline.getAllItems()
- self.assertEqual(len(items), 0)
-
- # The semaphore should be released
- self.assertFalse('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.executor_server.hold_jobs_in_build = False
- self.executor_server.release()
- self.waitUntilSettled()
-
- def test_semaphore_reconfigure(self):
- "Test reconfigure with job semaphores"
- self.updateConfigLayout('layout-semaphore')
- self.sched.reconfigure(self.config)
-
- self.waitUntilSettled()
- tenant = self.sched.abide.tenants.get('openstack')
-
- self.executor_server.hold_jobs_in_build = True
-
- A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
- self.assertFalse('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
- self.waitUntilSettled()
-
- self.assertTrue('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- # reconfigure without layout change
- self.sched.reconfigure(self.config)
- self.waitUntilSettled()
- tenant = self.sched.abide.tenants.get('openstack')
-
- # semaphore still must be held
- self.assertTrue('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
- self.updateConfigLayout('layout-semaphore-reconfiguration')
- self.sched.reconfigure(self.config)
- self.waitUntilSettled()
- tenant = self.sched.abide.tenants.get('openstack')
-
- self.executor_server.release('project-test1')
- self.waitUntilSettled()
-
- # There should be no builds anymore
- self.assertEqual(len(self.builds), 0)
-
- # The semaphore should be released
- self.assertFalse('test-semaphore' in
- tenant.semaphore_handler.semaphores)
-
def test_live_reconfiguration(self):
"Test that live reconfiguration works"
self.executor_server.hold_jobs_in_build = True
@@ -2828,8 +2586,9 @@
self.assertEqual(len(self.builds), 5)
# This layout defines only org/project, not org/project1
- self.commitLayoutUpdate('common-config',
- 'layout-live-reconfiguration-del-project')
+ self.commitConfigUpdate(
+ 'common-config',
+ 'layouts/live-reconfiguration-del-project.yaml')
self.sched.reconfigure(self.config)
self.waitUntilSettled()
@@ -2879,10 +2638,8 @@
self.assertEqual(A.data['status'], 'MERGED')
self.assertEqual(A.reported, 2)
+ @simple_layout('layouts/repo-deleted.yaml')
def test_repo_deleted(self):
- self.updateConfigLayout('layout-repo-deleted')
- self.sched.reconfigure(self.config)
-
self.init_repo("org/delete-project")
A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
@@ -2919,18 +2676,16 @@
self.assertEqual(B.data['status'], 'MERGED')
self.assertEqual(B.reported, 2)
+ @simple_layout('layouts/tags.yaml')
def test_tags(self):
"Test job tags"
- self.updateConfigLayout('layout-tags')
- self.sched.reconfigure(self.config)
-
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
- self.assertEqual(len(self.history), 8)
+ self.assertEqual(len(self.history), 2)
results = {self.getJobFromHistory('merge',
project='org/project1').uuid: 'extratag merge',
@@ -2943,8 +2698,12 @@
def test_timer(self):
"Test that a periodic job is triggered"
+ # This test can not use simple_layout because it must start
+ # with a configuration which does not include a
+ # timer-triggered job so that we have an opportunity to set
+ # the hold flag before the first job.
self.executor_server.hold_jobs_in_build = True
- self.updateConfigLayout('layout-timer')
+ self.commitConfigUpdate('common-config', 'layouts/timer.yaml')
self.sched.reconfigure(self.config)
# The pipeline triggers every second, so we should have seen
@@ -2957,14 +2716,14 @@
port = self.webapp.server.socket.getsockname()[1]
req = urllib.request.Request(
- "http://localhost:%s/openstack/status" % port)
+ "http://localhost:%s/tenant-one/status" % port)
f = urllib.request.urlopen(req)
data = f.read()
self.executor_server.hold_jobs_in_build = False
# Stop queuing timer triggered jobs so that the assertions
# below don't race against more jobs being queued.
- self.commitLayoutUpdate('layout-timer', 'layout-no-timer')
+ self.commitConfigUpdate('common-config', 'layouts/no-timer.yaml')
self.sched.reconfigure(self.config)
self.executor_server.release()
self.waitUntilSettled()
@@ -2987,13 +2746,18 @@
def test_idle(self):
"Test that frequent periodic jobs work"
+ # This test can not use simple_layout because it must start
+ # with a configuration which does not include a
+ # timer-triggered job so that we have an opportunity to set
+ # the hold flag before the first job.
self.executor_server.hold_jobs_in_build = True
- self.updateConfigLayout('layout-idle')
for x in range(1, 3):
# Test that timer triggers periodic jobs even across
# layout config reloads.
# Start timer trigger
+ self.commitConfigUpdate('common-config',
+ 'layouts/idle.yaml')
self.sched.reconfigure(self.config)
self.waitUntilSettled()
@@ -3003,7 +2767,8 @@
# Stop queuing timer triggered jobs so that the assertions
# below don't race against more jobs being queued.
- before = self.commitLayoutUpdate('layout-idle', 'layout-no-timer')
+ self.commitConfigUpdate('common-config',
+ 'layouts/no-timer.yaml')
self.sched.reconfigure(self.config)
self.waitUntilSettled()
self.assertEqual(len(self.builds), 2,
@@ -3012,16 +2777,9 @@
self.waitUntilSettled()
self.assertEqual(len(self.builds), 0)
self.assertEqual(len(self.history), x * 2)
- # Revert back to layout-idle
- repo = git.Repo(os.path.join(self.test_root,
- 'upstream',
- 'layout-idle'))
- repo.git.reset('--hard', before)
+ @simple_layout('layouts/smtp.yaml')
def test_check_smtp_pool(self):
- self.updateConfigLayout('layout-smtp')
- self.sched.reconfigure(self.config)
-
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
self.waitUntilSettled()
@@ -3050,8 +2808,12 @@
def test_timer_smtp(self):
"Test that a periodic job is triggered"
+ # This test can not use simple_layout because it must start
+ # with a configuration which does not include a
+ # timer-triggered job so that we have an opportunity to set
+ # the hold flag before the first job.
self.executor_server.hold_jobs_in_build = True
- self.updateConfigLayout('layout-timer-smtp')
+ self.commitConfigUpdate('common-config', 'layouts/timer-smtp.yaml')
self.sched.reconfigure(self.config)
# The pipeline triggers every second, so we should have seen
@@ -3084,7 +2846,7 @@
# Stop queuing timer triggered jobs and let any that may have
# queued through so that end of test assertions pass.
- self.commitLayoutUpdate('layout-timer-smtp', 'layout-no-timer')
+ self.commitConfigUpdate('common-config', 'layouts/no-timer.yaml')
self.sched.reconfigure(self.config)
self.waitUntilSettled()
self.executor_server.release('.*')
@@ -3142,6 +2904,7 @@
client = zuul.rpcclient.RPCClient('127.0.0.1',
self.gearman_server.port)
+ self.addCleanup(client.shutdown)
r = client.enqueue(tenant='tenant-one',
pipeline='gate',
project='org/project',
@@ -3163,6 +2926,7 @@
client = zuul.rpcclient.RPCClient('127.0.0.1',
self.gearman_server.port)
+ self.addCleanup(client.shutdown)
r = client.enqueue_ref(
tenant='tenant-one',
pipeline='post',
@@ -3181,6 +2945,7 @@
"Test that the RPC client returns errors"
client = zuul.rpcclient.RPCClient('127.0.0.1',
self.gearman_server.port)
+ self.addCleanup(client.shutdown)
with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
"Invalid tenant"):
r = client.enqueue(tenant='tenant-foo',
@@ -3188,7 +2953,6 @@
project='org/project',
trigger='gerrit',
change='1,1')
- client.shutdown()
self.assertEqual(r, False)
with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
@@ -3198,7 +2962,6 @@
project='project-does-not-exist',
trigger='gerrit',
change='1,1')
- client.shutdown()
self.assertEqual(r, False)
with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
@@ -3208,7 +2971,6 @@
project='org/project',
trigger='gerrit',
change='1,1')
- client.shutdown()
self.assertEqual(r, False)
with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
@@ -3218,7 +2980,6 @@
project='org/project',
trigger='trigger-does-not-exist',
change='1,1')
- client.shutdown()
self.assertEqual(r, False)
with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
@@ -3228,7 +2989,6 @@
project='org/project',
trigger='gerrit',
change='1,1')
- client.shutdown()
self.assertEqual(r, False)
self.waitUntilSettled()
@@ -3259,6 +3019,7 @@
client = zuul.rpcclient.RPCClient('127.0.0.1',
self.gearman_server.port)
+ self.addCleanup(client.shutdown)
r = client.promote(tenant='tenant-one',
pipeline='gate',
change_ids=['2,1', '3,1'])
@@ -3307,7 +3068,6 @@
self.assertEqual(C.data['status'], 'MERGED')
self.assertEqual(C.reported, 2)
- client.shutdown()
self.assertEqual(r, True)
def test_client_promote_dependent(self):
@@ -3333,6 +3093,7 @@
client = zuul.rpcclient.RPCClient('127.0.0.1',
self.gearman_server.port)
+ self.addCleanup(client.shutdown)
r = client.promote(tenant='tenant-one',
pipeline='gate',
change_ids=['3,1'])
@@ -3375,7 +3136,6 @@
self.assertEqual(C.data['status'], 'MERGED')
self.assertEqual(C.reported, 2)
- client.shutdown()
self.assertEqual(r, True)
def test_client_promote_negative(self):
@@ -3388,29 +3148,27 @@
client = zuul.rpcclient.RPCClient('127.0.0.1',
self.gearman_server.port)
+ self.addCleanup(client.shutdown)
with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
r = client.promote(tenant='tenant-one',
pipeline='nonexistent',
change_ids=['2,1', '3,1'])
- client.shutdown()
self.assertEqual(r, False)
with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
r = client.promote(tenant='tenant-one',
pipeline='gate',
change_ids=['4,1'])
- client.shutdown()
self.assertEqual(r, False)
self.executor_server.hold_jobs_in_build = False
self.executor_server.release()
self.waitUntilSettled()
+ @simple_layout('layouts/rate-limit.yaml')
def test_queue_rate_limiting(self):
"Test that DependentPipelines are rate limited with dep across window"
- self.updateConfigLayout('layout-rate-limit')
- self.sched.reconfigure(self.config)
self.executor_server.hold_jobs_in_build = True
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
@@ -3434,9 +3192,10 @@
self.assertEqual(self.builds[0].name, 'project-merge')
self.assertEqual(self.builds[1].name, 'project-merge')
- self.executor_server.release('.*-merge')
+ # Release the merge jobs one at a time.
+ self.builds[0].release()
self.waitUntilSettled()
- self.executor_server.release('.*-merge')
+ self.builds[0].release()
self.waitUntilSettled()
# Only A and B will have their test jobs queued because
@@ -3450,7 +3209,7 @@
self.executor_server.release('project-.*')
self.waitUntilSettled()
- tenant = self.sched.abide.tenants.get('openstack')
+ tenant = self.sched.abide.tenants.get('tenant-one')
queue = tenant.layout.pipelines['gate'].queues[0]
# A failed so window is reduced by 1 to 1.
self.assertEqual(queue.window, 1)
@@ -3498,10 +3257,9 @@
self.assertEqual(queue.window_floor, 1)
self.assertEqual(C.data['status'], 'MERGED')
+ @simple_layout('layouts/rate-limit.yaml')
def test_queue_rate_limiting_dependent(self):
"Test that DependentPipelines are rate limited with dep in window"
- self.updateConfigLayout('layout-rate-limit')
- self.sched.reconfigure(self.config)
self.executor_server.hold_jobs_in_build = True
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
@@ -3526,10 +3284,7 @@
self.assertEqual(self.builds[0].name, 'project-merge')
self.assertEqual(self.builds[1].name, 'project-merge')
- self.executor_server.release('.*-merge')
- self.waitUntilSettled()
- self.executor_server.release('.*-merge')
- self.waitUntilSettled()
+ self.orderedRelease(2)
# Only A and B will have their test jobs queued because
# window is 2.
@@ -3542,7 +3297,7 @@
self.executor_server.release('project-.*')
self.waitUntilSettled()
- tenant = self.sched.abide.tenants.get('openstack')
+ tenant = self.sched.abide.tenants.get('tenant-one')
queue = tenant.layout.pipelines['gate'].queues[0]
# A failed so window is reduced by 1 to 1.
self.assertEqual(queue.window, 1)
@@ -3555,8 +3310,7 @@
self.assertEqual(len(self.builds), 1)
self.assertEqual(self.builds[0].name, 'project-merge')
- self.executor_server.release('.*-merge')
- self.waitUntilSettled()
+ self.orderedRelease(1)
# Only C's test jobs are queued because window is still 1.
self.assertEqual(len(self.builds), 2)
@@ -3610,11 +3364,9 @@
self.executor_server.release()
self.waitUntilSettled()
+ @simple_layout('layouts/footer-message.yaml')
def test_footer_message(self):
"Test a pipeline's footer message is correctly added to the report."
- self.updateConfigLayout('layout-footer-message')
- self.sched.reconfigure(self.config)
-
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
A.addApproval('code-review', 2)
self.executor_server.failJob('project-test1', A)
@@ -3758,6 +3510,7 @@
client = zuul.rpcclient.RPCClient('127.0.0.1',
self.gearman_server.port)
+ self.addCleanup(client.shutdown)
# Wait for gearman server to send the initial workData back to zuul
start = time.time()
@@ -3806,6 +3559,7 @@
running_items = client.get_running_jobs()
self.assertEqual(0, len(running_items))
+ @simple_layout('layouts/nonvoting-pipeline.yaml')
def test_nonvoting_pipeline(self):
"Test that a nonvoting pipeline (experimental) can still report"
@@ -4072,7 +3826,7 @@
def test_crd_gate_unknown(self):
"Test unknown projects in dependent pipeline"
- self.init_repo("org/unknown")
+ self.init_repo("org/unknown", tag='init')
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'B')
A.addApproval('code-review', 2)
@@ -4286,13 +4040,12 @@
independent pipelines"""
# It's a hack for fake gerrit,
# as it implies repo creation upon the creation of any change
- self.init_repo("org/unknown")
+ self.init_repo("org/unknown", tag='init')
self._test_crd_check_reconfiguration('org/project1', 'org/unknown')
+ @simple_layout('layouts/ignore-dependencies.yaml')
def test_crd_check_ignore_dependencies(self):
"Test cross-repo dependencies can be ignored"
- self.updateConfigLayout('layout-ignore-dependencies')
- self.sched.reconfigure(self.config)
self.gearman_server.hold_jobs_in_queue = True
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
@@ -4311,7 +4064,7 @@
# Make sure none of the items share a change queue, and all
# are live.
- tenant = self.sched.abide.tenants.get('openstack')
+ tenant = self.sched.abide.tenants.get('tenant-one')
check_pipeline = tenant.layout.pipelines['check']
self.assertEqual(len(check_pipeline.queues), 3)
self.assertEqual(len(check_pipeline.getAllItems()), 3)
@@ -4333,6 +4086,7 @@
for job in self.history:
self.assertEqual(len(job.changes.split()), 1)
+ @simple_layout('layouts/three-projects.yaml')
def test_crd_check_transitive(self):
"Test transitive cross-repo dependencies"
# Specifically, if A -> B -> C, and C gets a new patchset and
@@ -4375,7 +4129,7 @@
def test_crd_check_unknown(self):
"Test unknown projects in independent pipeline"
- self.init_repo("org/unknown")
+ self.init_repo("org/unknown", tag='init')
A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'D')
# A Depends-On: B
@@ -4418,7 +4172,8 @@
# processing.
tenant = self.sched.abide.tenants.get('tenant-one')
- source = tenant.layout.pipelines['gate'].source
+ (trusted, project) = tenant.getProject('org/project')
+ source = project.source
# TODO(pabelanger): As we add more source / trigger APIs we should make
# it easier for users to create events for testing.
@@ -4441,13 +4196,11 @@
event.change_number = '2'
source.getChange(event, True)
+ @simple_layout('layouts/disable_at.yaml')
def test_disable_at(self):
"Test a pipeline will only report to the disabled trigger when failing"
- self.updateConfigLayout('layout-disabled-at')
- self.sched.reconfigure(self.config)
-
- tenant = self.sched.abide.tenants.get('openstack')
+ tenant = self.sched.abide.tenants.get('tenant-one')
self.assertEqual(3, tenant.layout.pipelines['check'].disable_at)
self.assertEqual(
0, tenant.layout.pipelines['check']._consecutive_failures)
@@ -4545,7 +4298,7 @@
# comes out of disabled
self.sched.reconfigure(self.config)
- tenant = self.sched.abide.tenants.get('openstack')
+ tenant = self.sched.abide.tenants.get('tenant-one')
self.assertEqual(3, tenant.layout.pipelines['check'].disable_at)
self.assertEqual(
@@ -4568,6 +4321,24 @@
# No more messages reported via smtp
self.assertEqual(3, len(self.smtp_messages))
+ @simple_layout('layouts/one-job-project.yaml')
+ def test_one_job_project(self):
+ "Test that queueing works with one job"
+ A = self.fake_gerrit.addFakeChange('org/one-job-project',
+ 'master', 'A')
+ B = self.fake_gerrit.addFakeChange('org/one-job-project',
+ 'master', 'B')
+ A.addApproval('code-review', 2)
+ B.addApproval('code-review', 2)
+ self.fake_gerrit.addEvent(A.addApproval('approved', 1))
+ self.fake_gerrit.addEvent(B.addApproval('approved', 1))
+ self.waitUntilSettled()
+
+ self.assertEqual(A.data['status'], 'MERGED')
+ self.assertEqual(A.reported, 2)
+ self.assertEqual(B.data['status'], 'MERGED')
+ self.assertEqual(B.reported, 2)
+
def test_rerun_on_abort(self):
"Test that if a execute server fails to run a job, it is run again"
@@ -4638,6 +4409,39 @@
self.assertIn('project-test2 : SKIPPED', A.messages[1])
+class TestExecutor(ZuulTestCase):
+ tenant_config_file = 'config/single-tenant/main.yaml'
+
+ def assertFinalState(self):
+ # In this test, we expect to shut down in a non-final state,
+ # so skip these checks.
+ pass
+
+ def assertCleanShutdown(self):
+ self.log.debug("Assert clean shutdown")
+
+ # After shutdown, make sure no jobs are running
+ self.assertEqual({}, self.executor_server.job_workers)
+
+ # Make sure that git.Repo objects have been garbage collected.
+ repos = []
+ gc.collect()
+ for obj in gc.get_objects():
+ if isinstance(obj, git.Repo):
+ self.log.debug("Leaked git repo object: %s" % repr(obj))
+ repos.append(obj)
+ self.assertEqual(len(repos), 0)
+
+ def test_executor_shutdown(self):
+ "Test that the executor can shut down with jobs running"
+
+ self.executor_server.hold_jobs_in_build = True
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+ A.addApproval('code-review', 2)
+ self.fake_gerrit.addEvent(A.addApproval('approved', 1))
+ self.waitUntilSettled()
+
+
class TestDependencyGraph(ZuulTestCase):
tenant_config_file = 'config/dependency-graph/main.yaml'
@@ -4784,27 +4588,6 @@
self.assertIn('project-test1', A.messages[0])
-class TestSchedulerOneJobProject(ZuulTestCase):
- tenant_config_file = 'config/one-job-project/main.yaml'
-
- def test_one_job_project(self):
- "Test that queueing works with one job"
- A = self.fake_gerrit.addFakeChange('org/one-job-project',
- 'master', 'A')
- B = self.fake_gerrit.addFakeChange('org/one-job-project',
- 'master', 'B')
- A.addApproval('code-review', 2)
- B.addApproval('code-review', 2)
- self.fake_gerrit.addEvent(A.addApproval('approved', 1))
- self.fake_gerrit.addEvent(B.addApproval('approved', 1))
- self.waitUntilSettled()
-
- self.assertEqual(A.data['status'], 'MERGED')
- self.assertEqual(A.reported, 2)
- self.assertEqual(B.data['status'], 'MERGED')
- self.assertEqual(B.reported, 2)
-
-
class TestSchedulerTemplatedProject(ZuulTestCase):
tenant_config_file = 'config/templated-project/main.yaml'
@@ -5077,6 +4860,231 @@
self.waitUntilSettled()
+class TestSemaphore(ZuulTestCase):
+ tenant_config_file = 'config/semaphore/main.yaml'
+
+ def test_semaphore_one(self):
+ "Test semaphores with max=1 (mutex)"
+ tenant = self.sched.abide.tenants.get('tenant-one')
+
+ self.executor_server.hold_jobs_in_build = True
+
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+ B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
+ self.assertFalse('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+ self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 3)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'semaphore-one-test1')
+ self.assertEqual(self.builds[2].name, 'project-test1')
+
+ self.executor_server.release('semaphore-one-test1')
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 3)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'project-test1')
+ self.assertEqual(self.builds[2].name, 'semaphore-one-test2')
+ self.assertTrue('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.executor_server.release('semaphore-one-test2')
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 3)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'project-test1')
+ self.assertEqual(self.builds[2].name, 'semaphore-one-test1')
+ self.assertTrue('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.executor_server.release('semaphore-one-test1')
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 3)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'project-test1')
+ self.assertEqual(self.builds[2].name, 'semaphore-one-test2')
+ self.assertTrue('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.executor_server.release('semaphore-one-test2')
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 2)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'project-test1')
+ self.assertFalse('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.executor_server.hold_jobs_in_build = False
+ self.executor_server.release()
+
+ self.waitUntilSettled()
+ self.assertEqual(len(self.builds), 0)
+
+ self.assertEqual(A.reported, 1)
+ self.assertEqual(B.reported, 1)
+ self.assertFalse('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ def test_semaphore_two(self):
+ "Test semaphores with max>1"
+ tenant = self.sched.abide.tenants.get('tenant-one')
+
+ self.executor_server.hold_jobs_in_build = True
+ A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
+ B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
+ self.assertFalse('test-semaphore-two' in
+ tenant.semaphore_handler.semaphores)
+
+ self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+ self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 4)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'semaphore-two-test1')
+ self.assertEqual(self.builds[2].name, 'semaphore-two-test2')
+ self.assertEqual(self.builds[3].name, 'project-test1')
+ self.assertTrue('test-semaphore-two' in
+ tenant.semaphore_handler.semaphores)
+ self.assertEqual(len(tenant.semaphore_handler.semaphores.get(
+ 'test-semaphore-two', [])), 2)
+
+ self.executor_server.release('semaphore-two-test1')
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 4)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'semaphore-two-test2')
+ self.assertEqual(self.builds[2].name, 'project-test1')
+ self.assertEqual(self.builds[3].name, 'semaphore-two-test1')
+ self.assertTrue('test-semaphore-two' in
+ tenant.semaphore_handler.semaphores)
+ self.assertEqual(len(tenant.semaphore_handler.semaphores.get(
+ 'test-semaphore-two', [])), 2)
+
+ self.executor_server.release('semaphore-two-test2')
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 4)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'project-test1')
+ self.assertEqual(self.builds[2].name, 'semaphore-two-test1')
+ self.assertEqual(self.builds[3].name, 'semaphore-two-test2')
+ self.assertTrue('test-semaphore-two' in
+ tenant.semaphore_handler.semaphores)
+ self.assertEqual(len(tenant.semaphore_handler.semaphores.get(
+ 'test-semaphore-two', [])), 2)
+
+ self.executor_server.release('semaphore-two-test1')
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 3)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'project-test1')
+ self.assertEqual(self.builds[2].name, 'semaphore-two-test2')
+ self.assertTrue('test-semaphore-two' in
+ tenant.semaphore_handler.semaphores)
+ self.assertEqual(len(tenant.semaphore_handler.semaphores.get(
+ 'test-semaphore-two', [])), 1)
+
+ self.executor_server.release('semaphore-two-test2')
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.builds), 2)
+ self.assertEqual(self.builds[0].name, 'project-test1')
+ self.assertEqual(self.builds[1].name, 'project-test1')
+ self.assertFalse('test-semaphore-two' in
+ tenant.semaphore_handler.semaphores)
+
+ self.executor_server.hold_jobs_in_build = False
+ self.executor_server.release()
+
+ self.waitUntilSettled()
+ self.assertEqual(len(self.builds), 0)
+
+ self.assertEqual(A.reported, 1)
+ self.assertEqual(B.reported, 1)
+
+ def test_semaphore_abandon(self):
+ "Test abandon with job semaphores"
+ self.executor_server.hold_jobs_in_build = True
+ tenant = self.sched.abide.tenants.get('tenant-one')
+ check_pipeline = tenant.layout.pipelines['check']
+
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+ self.assertFalse('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+
+ self.assertTrue('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
+ self.waitUntilSettled()
+
+ # The check pipeline should be empty
+ items = check_pipeline.getAllItems()
+ self.assertEqual(len(items), 0)
+
+ # The semaphore should be released
+ self.assertFalse('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.executor_server.hold_jobs_in_build = False
+ self.executor_server.release()
+ self.waitUntilSettled()
+
+ def test_semaphore_reconfigure(self):
+ "Test reconfigure with job semaphores"
+ self.executor_server.hold_jobs_in_build = True
+ tenant = self.sched.abide.tenants.get('tenant-one')
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+ self.assertFalse('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+
+ self.assertTrue('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ # reconfigure without layout change
+ self.sched.reconfigure(self.config)
+ self.waitUntilSettled()
+ tenant = self.sched.abide.tenants.get('tenant-one')
+
+ # semaphore still must be held
+ self.assertTrue('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+ self.commitConfigUpdate(
+ 'common-config',
+ 'config/semaphore/zuul-reconfiguration.yaml')
+ self.sched.reconfigure(self.config)
+ self.waitUntilSettled()
+ tenant = self.sched.abide.tenants.get('tenant-one')
+
+ self.executor_server.release('project-test1')
+ self.waitUntilSettled()
+
+ # There should be no builds anymore
+ self.assertEqual(len(self.builds), 0)
+
+ # The semaphore should be released
+ self.assertFalse('test-semaphore' in
+ tenant.semaphore_handler.semaphores)
+
+
class TestSemaphoreMultiTenant(ZuulTestCase):
tenant_config_file = 'config/multi-tenant-semaphore/main.yaml'
diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py
index 678b957..3919418 100644
--- a/tests/unit/test_v3.py
+++ b/tests/unit/test_v3.py
@@ -264,7 +264,7 @@
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
build = self.getJobFromHistory('timeout')
- self.assertEqual(build.result, 'ABORTED')
+ self.assertEqual(build.result, 'TIMED_OUT')
build = self.getJobFromHistory('faillocal')
self.assertEqual(build.result, 'FAILURE')
build = self.getJobFromHistory('check-vars')
diff --git a/tests/unit/test_webapp.py b/tests/unit/test_webapp.py
index 8791a25..4511ec7 100644
--- a/tests/unit/test_webapp.py
+++ b/tests/unit/test_webapp.py
@@ -19,6 +19,7 @@
import json
from six.moves import urllib
+import webob
from tests.base import ZuulTestCase, FIXTURE_DIR
@@ -96,3 +97,16 @@
self.port)
f = urllib.request.urlopen(req)
self.assertEqual(f.read(), public_pem)
+
+ def test_webapp_custom_handler(self):
+ def custom_handler(path, tenant_name, request):
+ return webob.Response(body='ok')
+
+ self.webapp.register_path('/custom', custom_handler)
+ req = urllib.request.Request(
+ "http://localhost:%s/custom" % self.port)
+ f = urllib.request.urlopen(req)
+ self.assertEqual('ok', f.read())
+
+ self.webapp.unregister_path('/custom')
+ self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, req)
diff --git a/tox.ini b/tox.ini
index 9c0d949..8235483 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,14 +8,14 @@
setenv = STATSD_HOST=127.0.0.1
STATSD_PORT=8125
VIRTUAL_ENV={envdir}
- OS_TEST_TIMEOUT=90
+ OS_TEST_TIMEOUT=120
passenv = ZUUL_TEST_ROOT OS_STDOUT_CAPTURE OS_STDERR_CAPTURE OS_LOG_CAPTURE OS_LOG_DEFAULTS
usedevelop = True
install_command = pip install {opts} {packages}
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
- python setup.py testr --slowest --testr-args='{posargs}'
+ python setup.py test --slowest --testr-args='{posargs}'
[testenv:bindep]
# Do not install any requirements. We want this to be fast and work even if
@@ -32,7 +32,7 @@
[testenv:cover]
commands =
- python setup.py testr --coverage
+ python setup.py test --coverage
[testenv:docs]
commands = python setup.py build_sphinx
@@ -46,7 +46,7 @@
[testenv:nodepool]
setenv =
OS_TEST_PATH = ./tests/nodepool
-commands = python setup.py testr --slowest --testr-args='--concurrency=1 {posargs}'
+commands = python setup.py test --slowest --testr-args='--concurrency=1 {posargs}'
[flake8]
# These are ignored intentionally in openstack-infra projects;
diff --git a/zuul/cmd/scheduler.py b/zuul/cmd/scheduler.py
index ff4e1f4..f1d1015 100755
--- a/zuul/cmd/scheduler.py
+++ b/zuul/cmd/scheduler.py
@@ -182,7 +182,7 @@
self.log.info('Starting scheduler')
try:
self.sched.start()
- self.sched.registerConnections(self.connections)
+ self.sched.registerConnections(self.connections, webapp)
self.sched.reconfigure(self.config)
self.sched.resume()
except Exception:
diff --git a/zuul/configloader.py b/zuul/configloader.py
index 5e88ee7..9ef33ea 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -46,6 +46,17 @@
pass
+class ProjectNotFoundError(Exception):
+ def __init__(self, project):
+ message = textwrap.dedent("""\
+ The project {project} was not found. All projects
+ referenced within a Zuul configuration must first be
+ added to the main configuration file by the Zuul
+ administrator.""")
+ message = textwrap.fill(message.format(project=project))
+ super(ProjectNotFoundError, self).__init__(message)
+
+
def indent(s):
return '\n'.join([' ' + x for x in s.split('\n')])
@@ -54,7 +65,7 @@
def configuration_exceptions(stanza, conf):
try:
yield
- except vs.Invalid as e:
+ except Exception as e:
conf = copy.deepcopy(conf)
context = conf.pop('_source_context')
start_mark = conf.pop('_start_mark')
@@ -227,7 +238,7 @@
'tags': to_list(str),
'branches': to_list(str),
'files': to_list(str),
- 'auth': to_list(auth),
+ 'auth': auth,
'irrelevant-files': to_list(str),
'nodes': vs.Any([node], str),
'timeout': int,
@@ -355,10 +366,7 @@
if allowed_projects:
allowed = []
for p in as_list(allowed_projects):
- # TODOv3(jeblair): this limits allowed_projects to the same
- # source; we should remove that limitation.
- source = job.source_context.project.connection_name
- (trusted, project) = tenant.getRepo(source, p)
+ (trusted, project) = tenant.getProject(p)
if project is None:
raise Exception("Unknown project %s" % (p,))
allowed.append(project.name)
@@ -394,14 +402,12 @@
def _makeZuulRole(tenant, job, role):
name = role['zuul'].split('/')[-1]
- # TODOv3(jeblair): this limits roles to the same
- # source; we should remove that limitation.
- source = job.source_context.project.connection_name
- (trusted, project) = tenant.getRepo(source, role['zuul'])
+ (trusted, project) = tenant.getProject(role['zuul'])
if project is None:
return None
- return model.ZuulRole(role.get('name', name), source,
+ return model.ZuulRole(role.get('name', name),
+ project.connection_name,
project.name, trusted)
@@ -493,7 +499,13 @@
for conf in conf_list:
with configuration_exceptions('project', conf):
ProjectParser.getSchema(layout)(conf)
- project = model.ProjectConfig(conf_list[0]['name'])
+
+ with configuration_exceptions('project', conf_list[0]):
+ project_name = conf_list[0]['name']
+ (trusted, project) = tenant.getProject(project_name)
+ if project is None:
+ raise ProjectNotFoundError(project_name)
+ project_config = model.ProjectConfig(project.canonical_name)
configs = []
for conf in conf_list:
@@ -509,14 +521,14 @@
for name in conf_templates])
configs.append(project_template)
mode = conf.get('merge-mode')
- if mode and project.merge_mode is None:
+ if mode and project_config.merge_mode is None:
# Set the merge mode to the first one that we find and
# ignore subsequent settings.
- project.merge_mode = model.MERGER_MAP[mode]
- if project.merge_mode is None:
+ project_config.merge_mode = model.MERGER_MAP[mode]
+ if project_config.merge_mode is None:
# If merge mode was not specified in any project stanza,
# set it to the default.
- project.merge_mode = model.MERGER_MAP['merge-resolve']
+ project_config.merge_mode = model.MERGER_MAP['merge-resolve']
for pipeline in layout.pipelines.values():
project_pipeline = model.ProjectPipelineConfig()
queue_name = None
@@ -537,9 +549,8 @@
if queue_name:
project_pipeline.queue_name = queue_name
if pipeline_defined:
- project.pipelines[pipeline.name] = project_pipeline
-
- return project
+ project_config.pipelines[pipeline.name] = project_pipeline
+ return project_config
class PipelineParser(object):
@@ -582,7 +593,7 @@
'email': str,
'older-than': str,
'newer-than': str,
- }, extra=True)
+ }, extra=vs.ALLOW_EXTRA)
require = {'approval': to_list(approval),
'open': bool,
@@ -598,7 +609,6 @@
pipeline = {vs.Required('name'): str,
vs.Required('manager'): manager,
- 'source': str,
'precedence': precedence,
'description': str,
'require': require,
@@ -636,8 +646,6 @@
pipeline = model.Pipeline(conf['name'], layout)
pipeline.description = conf.get('description')
- pipeline.source = connections.getSource(conf['source'])
-
precedence = model.PRECEDENCE_MAP[conf.get('precedence')]
pipeline.precedence = precedence
pipeline.failure_message = conf.get('failure-message',
@@ -743,8 +751,8 @@
class TenantParser(object):
log = logging.getLogger("zuul.TenantParser")
- tenant_source = vs.Schema({'config-repos': [str],
- 'project-repos': [str]})
+ tenant_source = vs.Schema({'config-projects': [str],
+ 'untrusted-projects': [str]})
@staticmethod
def validateTenantSources(connections):
@@ -774,25 +782,24 @@
tenant = model.Tenant(conf['name'])
tenant.unparsed_config = conf
unparsed_config = model.UnparsedTenantConfig()
- tenant.config_repos, tenant.project_repos = \
- TenantParser._loadTenantConfigRepos(
+ config_projects, untrusted_projects = \
+ TenantParser._loadTenantProjects(
project_key_dir, connections, conf)
- for source, repo in tenant.config_repos:
- tenant.addConfigRepo(source, repo)
- for source, repo in tenant.project_repos:
- tenant.addProjectRepo(source, repo)
- tenant.config_repos_config, tenant.project_repos_config = \
+ for project in config_projects:
+ tenant.addConfigProject(project)
+ for project in untrusted_projects:
+ tenant.addUntrustedProject(project)
+ tenant.config_projects_config, tenant.untrusted_projects_config = \
TenantParser._loadTenantInRepoLayouts(merger, connections,
- tenant.config_repos,
- tenant.project_repos,
+ tenant.config_projects,
+ tenant.untrusted_projects,
cached)
- unparsed_config.extend(tenant.config_repos_config)
- unparsed_config.extend(tenant.project_repos_config)
+ unparsed_config.extend(tenant.config_projects_config)
+ unparsed_config.extend(tenant.untrusted_projects_config)
tenant.layout = TenantParser._parseLayout(base, tenant,
unparsed_config,
scheduler,
connections)
- tenant.layout.tenant = tenant
return tenant
@staticmethod
@@ -842,73 +849,73 @@
encryption.deserialize_rsa_keypair(f.read())
@staticmethod
- def _loadTenantConfigRepos(project_key_dir, connections, conf_tenant):
- config_repos = []
- project_repos = []
+ def _loadTenantProjects(project_key_dir, connections, conf_tenant):
+ config_projects = []
+ untrusted_projects = []
for source_name, conf_source in conf_tenant.get('source', {}).items():
source = connections.getSource(source_name)
- for conf_repo in conf_source.get('config-repos', []):
+ for conf_repo in conf_source.get('config-projects', []):
project = source.getProject(conf_repo)
TenantParser._loadProjectKeys(
project_key_dir, source_name, project)
- config_repos.append((source, project))
+ config_projects.append(project)
- for conf_repo in conf_source.get('project-repos', []):
+ for conf_repo in conf_source.get('untrusted-projects', []):
project = source.getProject(conf_repo)
TenantParser._loadProjectKeys(
project_key_dir, source_name, project)
- project_repos.append((source, project))
+ untrusted_projects.append(project)
- return config_repos, project_repos
+ return config_projects, untrusted_projects
@staticmethod
- def _loadTenantInRepoLayouts(merger, connections, config_repos,
- project_repos, cached):
- config_repos_config = model.UnparsedTenantConfig()
- project_repos_config = model.UnparsedTenantConfig()
+ def _loadTenantInRepoLayouts(merger, connections, config_projects,
+ untrusted_projects, cached):
+ config_projects_config = model.UnparsedTenantConfig()
+ untrusted_projects_config = model.UnparsedTenantConfig()
jobs = []
- for (source, project) in config_repos:
+ for project in config_projects:
# If we have cached data (this is a reconfiguration) use it.
if cached and project.unparsed_config:
TenantParser.log.info(
"Loading previously parsed configuration from %s" %
(project,))
- config_repos_config.extend(project.unparsed_config)
+ config_projects_config.extend(project.unparsed_config)
continue
# Otherwise, prepare an empty unparsed config object to
# hold cached data later.
project.unparsed_config = model.UnparsedTenantConfig()
# Get main config files. These files are permitted the
# full range of configuration.
- url = source.getGitUrl(project)
+ url = project.source.getGitUrl(project)
job = merger.getFiles(project.name, url, 'master',
files=['zuul.yaml', '.zuul.yaml'])
job.source_context = model.SourceContext(project, 'master',
'', True)
jobs.append(job)
- for (source, project) in project_repos:
+ for project in untrusted_projects:
# If we have cached data (this is a reconfiguration) use it.
if cached and project.unparsed_config:
TenantParser.log.info(
"Loading previously parsed configuration from %s" %
(project,))
- project_repos_config.extend(project.unparsed_config)
+ untrusted_projects_config.extend(project.unparsed_config)
continue
# Otherwise, prepare an empty unparsed config object to
# hold cached data later.
project.unparsed_config = model.UnparsedTenantConfig()
# Get in-project-repo config files which have a restricted
# set of options.
- url = source.getGitUrl(project)
+ url = project.source.getGitUrl(project)
# For each branch in the repo, get the zuul.yaml for that
# branch. Remember the branch and then implicitly add a
# branch selector to each job there. This makes the
# in-repo configuration apply only to that branch.
- for branch in source.getProjectBranches(project):
+ for branch in project.source.getProjectBranches(project):
project.unparsed_branch_config[branch] = \
model.UnparsedTenantConfig()
job = merger.getFiles(project.name, url, branch,
@@ -941,27 +948,27 @@
project = job.source_context.project
branch = job.source_context.branch
if job.source_context.trusted:
- incdata = TenantParser._parseConfigRepoLayout(
+ incdata = TenantParser._parseConfigProjectLayout(
job.files[fn], job.source_context)
- config_repos_config.extend(incdata)
+ config_projects_config.extend(incdata)
else:
- incdata = TenantParser._parseProjectRepoLayout(
+ incdata = TenantParser._parseUntrustedProjectLayout(
job.files[fn], job.source_context)
- project_repos_config.extend(incdata)
+ untrusted_projects_config.extend(incdata)
project.unparsed_config.extend(incdata)
if branch in project.unparsed_branch_config:
project.unparsed_branch_config[branch].extend(incdata)
- return config_repos_config, project_repos_config
+ return config_projects_config, untrusted_projects_config
@staticmethod
- def _parseConfigRepoLayout(data, source_context):
+ def _parseConfigProjectLayout(data, source_context):
# This is the top-level configuration for a tenant.
config = model.UnparsedTenantConfig()
config.extend(safe_load_yaml(data, source_context))
return config
@staticmethod
- def _parseProjectRepoLayout(data, source_context):
+ def _parseUntrustedProjectLayout(data, source_context):
# TODOv3(jeblair): this should implement some rules to protect
# aspects of the config that should not be changed in-repo
config = model.UnparsedTenantConfig()
@@ -997,6 +1004,8 @@
layout.addProjectConfig(ProjectParser.fromYaml(
tenant, layout, config_project))
+ layout.tenant = tenant
+
for pipeline in layout.pipelines.values():
pipeline.manager._postConfig(layout)
@@ -1049,42 +1058,44 @@
new_abide.tenants[tenant.name] = new_tenant
return new_abide
- def _loadDynamicProjectData(self, config, source, project, files,
- config_repo):
- for branch in source.getProjectBranches(project):
- data = None
- if config_repo:
- fn = 'zuul.yaml'
- data = files.getFile(project.name, branch, fn)
- if not data:
- fn = '.zuul.yaml'
- data = files.getFile(project.name, branch, fn)
+ def _loadDynamicProjectData(self, config, project, files, trusted):
+ if trusted:
+ branches = ['master']
+ fn = 'zuul.yaml'
+ else:
+ branches = project.source.getProjectBranches(project)
+ fn = '.zuul.yaml'
+
+ for branch in branches:
+ incdata = None
+ data = files.getFile(project.name, branch, fn)
if data:
source_context = model.SourceContext(project, branch,
- fn, config_repo)
- if config_repo:
- incdata = TenantParser._parseConfigRepoLayout(
+ fn, trusted)
+ if trusted:
+ incdata = TenantParser._parseConfigProjectLayout(
data, source_context)
else:
- incdata = TenantParser._parseProjectRepoLayout(
+ incdata = TenantParser._parseUntrustedProjectLayout(
data, source_context)
else:
- incdata = project.unparsed_branch_config.get(branch)
- if not incdata:
- continue
- config.extend(incdata)
+ if trusted:
+ incdata = project.unparsed_config
+ else:
+ incdata = project.unparsed_branch_config.get(branch)
+ if incdata:
+ config.extend(incdata)
- def createDynamicLayout(self, tenant, files, include_config_repos=False):
- if include_config_repos:
+ def createDynamicLayout(self, tenant, files,
+ include_config_projects=False):
+ if include_config_projects:
config = model.UnparsedTenantConfig()
- for source, project in tenant.config_repos:
- self._loadDynamicProjectData(config, source, project,
- files, True)
+ for project in tenant.config_projects:
+ self._loadDynamicProjectData(config, project, files, True)
else:
- config = tenant.config_repos_config.copy()
- for source, project in tenant.project_repos:
- self._loadDynamicProjectData(config, source, project,
- files, False)
+ config = tenant.config_projects_config.copy()
+ for project in tenant.untrusted_projects:
+ self._loadDynamicProjectData(config, project, files, False)
layout = model.Layout()
# NOTE: the actual pipeline objects (complete with queues and
@@ -1101,6 +1112,12 @@
# configuration changes.
layout.semaphores = tenant.layout.semaphores
+ for config_nodeset in config.nodesets:
+ layout.addNodeSet(NodeSetParser.fromYaml(layout, config_nodeset))
+
+ for config_secret in config.secrets:
+ layout.addSecret(SecretParser.fromYaml(layout, config_secret))
+
for config_job in config.jobs:
layout.addJob(JobParser.fromYaml(tenant, layout, config_job))
diff --git a/zuul/connection/__init__.py b/zuul/connection/__init__.py
index 6913294..49624d7 100644
--- a/zuul/connection/__init__.py
+++ b/zuul/connection/__init__.py
@@ -59,3 +59,21 @@
This lets the user supply a list of change objects that are
still in use. Anything in our cache that isn't in the supplied
list should be safe to remove from the cache."""
+
+ def registerWebapp(self, webapp):
+ self.webapp = webapp
+
+ def registerHttpHandler(self, path, handler):
+ """Add connection handler for HTTP URI.
+
+ Connection can use builtin HTTP server for listening on incoming event
+ requests. The resulting path will be /connection/connection_name/path.
+ """
+ self.webapp.register_path(self._connectionPath(path), handler)
+
+ def unregisterHttpHandler(self, path):
+ """Remove the connection handler for HTTP URI."""
+ self.webapp.unregister_path(self._connectionPath(path))
+
+ def _connectionPath(self, path):
+ return '/connection/%s/%s' % (self.connection_name, path)
diff --git a/zuul/driver/__init__.py b/zuul/driver/__init__.py
index 1cc5235..57b5cf9 100644
--- a/zuul/driver/__init__.py
+++ b/zuul/driver/__init__.py
@@ -68,6 +68,17 @@
"""
pass
+ def stop(self):
+ """Stop the driver from running.
+
+ This method is optional; the base implementation does nothing.
+
+ This method is called when the connection registry is stopped
+ allowing you additionally stop any running Driver computation
+ not specific to a connection.
+ """
+ pass
+
@six.add_metaclass(abc.ABCMeta)
class ConnectionInterface(object):
diff --git a/zuul/driver/gerrit/gerritconnection.py b/zuul/driver/gerrit/gerritconnection.py
index e18daa9..73979be 100644
--- a/zuul/driver/gerrit/gerritconnection.py
+++ b/zuul/driver/gerrit/gerritconnection.py
@@ -26,7 +26,7 @@
import voluptuous as v
from zuul.connection import BaseConnection
-from zuul.model import TriggerEvent, Project, Change, Ref
+from zuul.model import TriggerEvent, Change, Ref
from zuul import exceptions
@@ -76,6 +76,7 @@
event.type = data.get('type')
event.trigger_name = 'gerrit'
change = data.get('change')
+ event.project_hostname = self.connection.canonical_hostname
if change:
event.project_name = change.get('project')
event.branch = change.get('branch')
@@ -268,11 +269,13 @@
self._change_cache = {}
self.projects = {}
self.gerrit_event_connector = None
+ self.source = driver.getSource(self)
def getProject(self, name):
- if name not in self.projects:
- self.projects[name] = Project(name, self.connection_name)
- return self.projects[name]
+ return self.projects.get(name)
+
+ def addProject(self, project):
+ self.projects[project.name] = project
def maintainCache(self, relevant):
# This lets the user supply a list of change objects that are
@@ -290,14 +293,14 @@
change = self._getChange(event.change_number, event.patch_number,
refresh=refresh)
elif event.ref:
- project = self.getProject(event.project_name)
+ project = self.source.getProject(event.project_name)
change = Ref(project)
change.ref = event.ref
change.oldrev = event.oldrev
change.newrev = event.newrev
change.url = self._getGitwebUrl(project, sha=event.newrev)
else:
- project = self.getProject(event.project_name)
+ project = self.source.getProject(event.project_name)
change = Ref(project)
branch = event.branch or 'master'
change.ref = 'refs/heads/%s' % branch
@@ -375,7 +378,7 @@
if 'project' not in data:
raise exceptions.ChangeNotFound(change.number, change.patchset)
- change.project = self.getProject(data['project'])
+ change.project = self.source.getProject(data['project'])
change.branch = data['branch']
change.url = data['url']
max_ps = 0
@@ -523,16 +526,16 @@
# Wait for the ref to show up in the repo
start = time.time()
while time.time() - start < self.replication_timeout:
- sha = self.getRefSha(project.name, ref)
+ sha = self.getRefSha(project, ref)
if old_sha != sha:
return True
time.sleep(self.replication_retry_interval)
return False
- def getRefSha(self, project_name, ref):
+ def getRefSha(self, project, ref):
refs = {}
try:
- refs = self.getInfoRefs(project_name)
+ refs = self.getInfoRefs(project)
except:
self.log.exception("Exception looking for ref %s" %
ref)
@@ -594,7 +597,7 @@
return changes
def getProjectBranches(self, project):
- refs = self.getInfoRefs(project.name)
+ refs = self.getInfoRefs(project)
heads = [str(k[len('refs/heads/'):]) for k in refs.keys()
if k.startswith('refs/heads/')]
return heads
@@ -728,9 +731,9 @@
raise Exception("Gerrit error executing %s" % command)
return (out, err)
- def getInfoRefs(self, project_name):
+ def getInfoRefs(self, project):
url = "%s/p/%s/info/refs?service=git-upload-pack" % (
- self.baseurl, project_name)
+ self.baseurl, project.name)
try:
data = urllib.request.urlopen(url).read()
except:
@@ -819,5 +822,5 @@
def getSchema():
- gerrit_connection = v.Any(str, v.Schema({}, extra=True))
+ gerrit_connection = v.Any(str, v.Schema(dict))
return gerrit_connection
diff --git a/zuul/driver/gerrit/gerritreporter.py b/zuul/driver/gerrit/gerritreporter.py
index d132d65..a855db3 100644
--- a/zuul/driver/gerrit/gerritreporter.py
+++ b/zuul/driver/gerrit/gerritreporter.py
@@ -33,7 +33,7 @@
(item.change, self.config, message))
changeid = '%s,%s' % (item.change.number, item.change.patchset)
item.change._ref_sha = source.getRefSha(
- item.change.project.name, 'refs/heads/' + item.change.branch)
+ item.change.project, 'refs/heads/' + item.change.branch)
return self.connection.review(item.change.project.name, changeid,
message, self.config)
@@ -48,5 +48,5 @@
def getSchema():
- gerrit_reporter = v.Any(str, v.Schema({}, extra=True))
+ gerrit_reporter = v.Any(str, v.Schema(dict))
return gerrit_reporter
diff --git a/zuul/driver/gerrit/gerritsource.py b/zuul/driver/gerrit/gerritsource.py
index 2271cde..e6230df 100644
--- a/zuul/driver/gerrit/gerritsource.py
+++ b/zuul/driver/gerrit/gerritsource.py
@@ -14,6 +14,7 @@
import logging
from zuul.source import BaseSource
+from zuul.model import Project
class GerritSource(BaseSource):
@@ -41,7 +42,11 @@
return self.connection.getChange(event, refresh)
def getProject(self, name):
- return self.connection.getProject(name)
+ p = self.connection.getProject(name)
+ if not p:
+ p = Project(name, self)
+ self.connection.addProject(p)
+ return p
def getProjectOpenChanges(self, project):
return self.connection.getProjectOpenChanges(project)
diff --git a/zuul/driver/gerrit/gerrittrigger.py b/zuul/driver/gerrit/gerrittrigger.py
index c678bce..70c65fd 100644
--- a/zuul/driver/gerrit/gerrittrigger.py
+++ b/zuul/driver/gerrit/gerrittrigger.py
@@ -82,14 +82,14 @@
def getSchema():
def toList(x):
return v.Any([x], x)
- variable_dict = v.Schema({}, extra=True)
+ variable_dict = v.Schema(dict)
approval = v.Schema({'username': str,
'email-filter': str,
'email': str,
'older-than': str,
'newer-than': str,
- }, extra=True)
+ }, extra=v.ALLOW_EXTRA)
gerrit_trigger = {
v.Required('event'):
diff --git a/zuul/driver/git/gitconnection.py b/zuul/driver/git/gitconnection.py
index 9c8d658..ca88d3f 100644
--- a/zuul/driver/git/gitconnection.py
+++ b/zuul/driver/git/gitconnection.py
@@ -19,7 +19,6 @@
import voluptuous as v
from zuul.connection import BaseConnection
-from zuul.model import Project
class GitConnection(BaseConnection):
@@ -44,9 +43,10 @@
self.projects = {}
def getProject(self, name):
- if name not in self.projects:
- self.projects[name] = Project(name, self.connection_name)
- return self.projects[name]
+ return self.projects.get(name)
+
+ def addProject(self, project):
+ self.projects[project.name] = project
def getProjectBranches(self, project):
# TODO(jeblair): implement; this will need to handle local or
@@ -59,5 +59,5 @@
def getSchema():
- git_connection = v.Any(str, v.Schema({}, extra=True))
+ git_connection = v.Any(str, v.Schema(dict))
return git_connection
diff --git a/zuul/driver/git/gitsource.py b/zuul/driver/git/gitsource.py
index 076e8b7..485a6e4 100644
--- a/zuul/driver/git/gitsource.py
+++ b/zuul/driver/git/gitsource.py
@@ -14,6 +14,7 @@
import logging
from zuul.source import BaseSource
+from zuul.model import Project
class GitSource(BaseSource):
@@ -38,7 +39,11 @@
raise NotImplemented()
def getProject(self, name):
- return self.connection.getProject(name)
+ p = self.connection.getProject(name)
+ if not p:
+ p = Project(name, self)
+ self.connection.addProject(p)
+ return p
def getProjectBranches(self, project):
return self.connection.getProjectBranches(project)
diff --git a/zuul/driver/smtp/smtpconnection.py b/zuul/driver/smtp/smtpconnection.py
index 6338cd5..56ca240 100644
--- a/zuul/driver/smtp/smtpconnection.py
+++ b/zuul/driver/smtp/smtpconnection.py
@@ -58,5 +58,5 @@
def getSchema():
- smtp_connection = v.Any(str, v.Schema({}, extra=True))
+ smtp_connection = v.Any(str, v.Schema(dict))
return smtp_connection
diff --git a/zuul/driver/sql/sqlconnection.py b/zuul/driver/sql/sqlconnection.py
index 31bc13a..4b1b1a2 100644
--- a/zuul/driver/sql/sqlconnection.py
+++ b/zuul/driver/sql/sqlconnection.py
@@ -101,5 +101,5 @@
def getSchema():
- sql_connection = v.Any(str, v.Schema({}, extra=True))
+ sql_connection = v.Any(str, v.Schema(dict))
return sql_connection
diff --git a/zuul/driver/timer/__init__.py b/zuul/driver/timer/__init__.py
index 3ce0b8d..115e6af 100644
--- a/zuul/driver/timer/__init__.py
+++ b/zuul/driver/timer/__init__.py
@@ -38,6 +38,10 @@
def reconfigure(self, tenant):
self._removeJobs(tenant)
+ if not self.apsched:
+ # Handle possible reuse of the driver without connection objects.
+ self.apsched = BackgroundScheduler()
+ self.apsched.start()
self._addJobs(tenant)
def _removeJobs(self, tenant):
@@ -76,16 +80,20 @@
def _onTrigger(self, tenant, pipeline_name, timespec):
for project_name in tenant.layout.project_configs.keys():
+ project_hostname, project_name = project_name.split('/', 1)
event = TriggerEvent()
event.type = 'timer'
event.timespec = timespec
event.forced_pipeline = pipeline_name
+ event.project_hostname = project_hostname
event.project_name = project_name
self.log.debug("Adding event %s" % event)
self.sched.addEvent(event)
def stop(self):
- self.apsched.shutdown()
+ if self.apsched:
+ self.apsched.shutdown()
+ self.apsched = None
def getTrigger(self, connection_name, config=None):
return timertrigger.TimerTrigger(self, config)
diff --git a/zuul/driver/zuul/__init__.py b/zuul/driver/zuul/__init__.py
index 47ccec0..8c9d795 100644
--- a/zuul/driver/zuul/__init__.py
+++ b/zuul/driver/zuul/__init__.py
@@ -76,6 +76,7 @@
event = TriggerEvent()
event.type = PROJECT_CHANGE_MERGED
event.trigger_name = self.name
+ event.project_hostname = change.project.canonical_hostname
event.project_name = change.project.name
event.change_number = change.number
event.branch = change.branch
@@ -97,6 +98,7 @@
event.type = PARENT_CHANGE_ENQUEUED
event.trigger_name = self.name
event.pipeline_name = pipeline.name
+ event.project_hostname = change.project.canonical_hostname
event.project_name = change.project.name
event.change_number = change.number
event.branch = change.branch
diff --git a/zuul/driver/zuul/zuultrigger.py b/zuul/driver/zuul/zuultrigger.py
index bb7c04e..c0c2fb3 100644
--- a/zuul/driver/zuul/zuultrigger.py
+++ b/zuul/driver/zuul/zuultrigger.py
@@ -63,7 +63,7 @@
'email': str,
'older-than': str,
'newer-than': str,
- }, extra=True)
+ }, extra=v.ALLOW_EXTRA)
zuul_trigger = {
v.Required('event'):
diff --git a/zuul/executor/client.py b/zuul/executor/client.py
index 90cfa9b..55f6874 100644
--- a/zuul/executor/client.py
+++ b/zuul/executor/client.py
@@ -45,14 +45,14 @@
oldrev = None
newrev = None
branch = None
- connection_name = item.pipeline.source.connection.connection_name
+ source = item.change.project.source
+ connection_name = source.connection.connection_name
project = item.change.project.name
return dict(project=project,
- url=item.pipeline.source.getGitUrl(
- item.change.project),
+ url=source.getGitUrl(item.change.project),
connection_name=connection_name,
- merge_mode=item.current_build_set.getMergeMode(project),
+ merge_mode=item.current_build_set.getMergeMode(),
refspec=refspec,
branch=branch,
ref=item.current_build_set.ref,
@@ -209,6 +209,7 @@
return False
def execute(self, job, item, pipeline, dependent_items=[]):
+ tenant = pipeline.layout.tenant
uuid = str(uuid4().hex)
self.log.info(
"Execute job %s (uuid: %s) on nodes %s for change %s "
@@ -307,6 +308,7 @@
host_keys=node.host_keys,
provider=node.provider,
region=node.region,
+ interface_ip=node.interface_ip,
public_ipv6=node.public_ipv6,
public_ipv4=node.public_ipv4))
params['nodes'] = nodes
@@ -318,18 +320,22 @@
projects = set()
if job.repos:
for repo in job.repos:
- project = item.pipeline.source.getProject(repo)
+ (trusted, project) = tenant.getProject(repo)
+ connection = project.source.connection
params['projects'].append(
- dict(name=repo,
- url=item.pipeline.source.getGitUrl(project)))
+ dict(name=project.name,
+ connection_name=connection.connection_name,
+ url=project.source.getGitUrl(project)))
projects.add(project)
for item in all_items:
if item.change.project not in projects:
+ project = item.change.project
+ connection = item.change.project.source.connection
params['projects'].append(
- dict(name=item.change.project.name,
- url=item.pipeline.source.getGitUrl(
- item.change.project)))
- projects.add(item.change.project)
+ dict(name=project.name,
+ connection_name=connection.connection_name,
+ url=project.source.getGitUrl(project)))
+ projects.add(project)
build = Build(job, uuid)
build.parameters = params
diff --git a/zuul/executor/server.py b/zuul/executor/server.py
index 0adb6de..c1e2d48 100644
--- a/zuul/executor/server.py
+++ b/zuul/executor/server.py
@@ -46,7 +46,8 @@
self.timeout = timeout
self.function = function
self.args = args
- self.thread = threading.Thread(target=self._run)
+ self.thread = threading.Thread(target=self._run,
+ name='executor-watchdog')
self.thread.daemon = True
self.timed_out = None
@@ -56,7 +57,11 @@
if self._running:
self.timed_out = True
self.function(*self.args)
- self.timed_out = False
+ else:
+ # Only set timed_out to false if we aren't _running
+ # anymore. This means that we stopped running not because
+ # of a timeout but because normal execution ended.
+ self.timed_out = False
def start(self):
self._running = True
@@ -344,10 +349,17 @@
def stop(self):
self.log.debug("Stopping")
self._running = False
- self.worker.shutdown()
self._command_running = False
self.command_socket.stop()
self.update_queue.put(None)
+
+ for job_worker in self.job_workers.values():
+ try:
+ job_worker.stop()
+ except Exception:
+ self.log.exception("Exception sending stop command "
+ "to worker:")
+ self.worker.shutdown()
self.log.debug("Stopped")
def pause(self):
diff --git a/zuul/lib/connections.py b/zuul/lib/connections.py
index 9964ba9..403aca6 100644
--- a/zuul/lib/connections.py
+++ b/zuul/lib/connections.py
@@ -58,6 +58,13 @@
if load:
connection.onLoad()
+ def registerWebapp(self, webapp):
+ for driver_name, driver in self.drivers.items():
+ if hasattr(driver, 'registerWebapp'):
+ driver.registerWebapp(webapp)
+ for connection_name, connection in self.connections.items():
+ connection.registerWebapp(webapp)
+
def reconfigureDrivers(self, tenant):
for driver in self.drivers.values():
if hasattr(driver, 'reconfigure'):
@@ -66,10 +73,11 @@
def stop(self):
for connection_name, connection in self.connections.items():
connection.onStop()
+ for driver in self.drivers.values():
+ driver.stop()
def configure(self, config):
# Register connections from the config
- # TODO(jhesketh): import connection modules dynamically
connections = {}
for section_name in config.sections():
diff --git a/zuul/manager/__init__.py b/zuul/manager/__init__.py
index 9507d15..3a4ea6a 100644
--- a/zuul/manager/__init__.py
+++ b/zuul/manager/__init__.py
@@ -54,7 +54,6 @@
def _postConfig(self, layout):
self.log.info("Configured Pipeline Manager %s" % self.pipeline.name)
- self.log.info(" Source: %s" % self.pipeline.source)
self.log.info(" Requirements:")
for f in self.changeish_filters:
self.log.info(" %s" % f)
@@ -147,11 +146,12 @@
def reportStart(self, item):
if not self.pipeline._disabled:
+ source = item.change.project.source
try:
self.log.info("Reporting start, action %s item %s" %
(self.pipeline.start_actions, item))
ret = self.sendReport(self.pipeline.start_actions,
- self.pipeline.source, item)
+ source, item)
if ret:
self.log.error("Reporting item start %s received: %s" %
(item, ret))
@@ -454,14 +454,14 @@
elif hasattr(item.change, 'newrev'):
oldrev = item.change.oldrev
newrev = item.change.newrev
- connection_name = self.pipeline.source.connection.connection_name
+ source = item.change.project.source
+ connection_name = source.connection.connection_name
project = item.change.project.name
return dict(project=project,
- url=self.pipeline.source.getGitUrl(
- item.change.project),
+ url=source.getGitUrl(item.change.project),
connection_name=connection_name,
- merge_mode=item.current_build_set.getMergeMode(project),
+ merge_mode=item.current_build_set.getMergeMode(),
refspec=refspec,
branch=branch,
ref=item.current_build_set.ref,
@@ -487,14 +487,14 @@
loader.createDynamicLayout(
item.pipeline.layout.tenant,
build_set.files,
- include_config_repos=True)
+ include_config_projects=True)
# Then create the config a second time but without changes
# to config repos so that we actually use this config.
layout = loader.createDynamicLayout(
item.pipeline.layout.tenant,
build_set.files,
- include_config_repos=False)
+ include_config_projects=False)
except zuul.configloader.ConfigurationSyntaxError as e:
self.log.info("Configuration syntax error "
"in dynamic layout %s" %
@@ -742,9 +742,9 @@
if self.changes_merge:
succeeded = item.didAllJobsSucceed()
merged = item.reported
+ source = item.change.project.source
if merged:
- merged = self.pipeline.source.isMerged(item.change,
- item.change.branch)
+ merged = source.isMerged(item.change, item.change.branch)
self.log.info("Reported change %s status: all-succeeded: %s, "
"merged: %s" % (item.change, succeeded, merged))
change_queue = item.queue
@@ -763,11 +763,11 @@
zuul_driver = self.sched.connections.drivers['zuul']
tenant = self.pipeline.layout.tenant
- zuul_driver.onChangeMerged(tenant, item.change,
- self.pipeline.source)
+ zuul_driver.onChangeMerged(tenant, item.change, source)
def _reportItem(self, item):
self.log.debug("Reporting change %s" % item.change)
+ source = item.change.project.source
ret = True # Means error as returned by trigger.report
if item.getConfigError():
self.log.debug("Invalid config for change %s" % item.change)
@@ -802,7 +802,7 @@
try:
self.log.info("Reporting item %s, actions: %s" %
(item, actions))
- ret = self.sendReport(actions, self.pipeline.source, item)
+ ret = self.sendReport(actions, source, item)
if ret:
self.log.error("Reporting item %s received: %s" %
(item, ret))
diff --git a/zuul/manager/dependent.py b/zuul/manager/dependent.py
index 4c48568..6c56a30 100644
--- a/zuul/manager/dependent.py
+++ b/zuul/manager/dependent.py
@@ -38,13 +38,14 @@
self.log.debug("Building shared change queues")
change_queues = {}
project_configs = self.pipeline.layout.project_configs
+ tenant = self.pipeline.layout.tenant
for project_config in project_configs.values():
project_pipeline_config = project_config.pipelines.get(
self.pipeline.name)
if project_pipeline_config is None:
continue
- project = self.pipeline.source.getProject(project_config.name)
+ (trusted, project) = tenant.getProject(project_config.name)
queue_name = project_pipeline_config.queue_name
if queue_name and queue_name in change_queues:
change_queue = change_queues[queue_name]
@@ -78,16 +79,17 @@
self.pipeline.getQueue(change.project))
def isChangeReadyToBeEnqueued(self, change):
- if not self.pipeline.source.canMerge(change,
- self.getSubmitAllowNeeds()):
+ source = change.project.source
+ if not source.canMerge(change, self.getSubmitAllowNeeds()):
self.log.debug("Change %s can not merge, ignoring" % change)
return False
return True
def enqueueChangesBehind(self, change, quiet, ignore_requirements,
change_queue):
- to_enqueue = []
self.log.debug("Checking for changes needing %s:" % change)
+ to_enqueue = []
+ source = change.project.source
if not hasattr(change, 'needed_by_changes'):
self.log.debug(" %s does not support dependencies" % type(change))
return
@@ -99,8 +101,7 @@
(other_change, other_change.project,
change_queue))
continue
- if self.pipeline.source.canMerge(other_change,
- self.getSubmitAllowNeeds()):
+ if source.canMerge(other_change, self.getSubmitAllowNeeds()):
self.log.debug(" Change %s needs %s and is ready to merge" %
(other_change, change))
to_enqueue.append(other_change)
@@ -130,6 +131,7 @@
def checkForChangesNeededBy(self, change, change_queue):
self.log.debug("Checking for changes needed by %s:" % change)
+ source = change.project.source
# Return true if okay to proceed enqueing this change,
# false if the change should not be enqueued.
if not hasattr(change, 'needs_changes'):
@@ -163,8 +165,7 @@
self.log.debug(" Needed change is already ahead "
"in the queue")
continue
- if self.pipeline.source.canMerge(needed_change,
- self.getSubmitAllowNeeds()):
+ if source.canMerge(needed_change, self.getSubmitAllowNeeds()):
self.log.debug(" Change %s is needed" % needed_change)
if needed_change not in changes_needed:
changes_needed.append(needed_change)
diff --git a/zuul/model.py b/zuul/model.py
index 0128610..4880be1 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -105,11 +105,7 @@
class Pipeline(object):
- """A configuration that ties triggers, reporters, managers and sources.
-
- Source
- Where changes should come from. It is a named connection to
- an external service defined in zuul.conf
+ """A configuration that ties together triggers, reporters and managers
Trigger
A description of which events should be processed
@@ -135,7 +131,6 @@
self.manager = None
self.queues = []
self.precedence = PRECEDENCE_NORMAL
- self.source = None
self.triggers = []
self.start_actions = []
self.success_actions = []
@@ -350,9 +345,12 @@
# This makes a Project instance a unique identifier for a given
# project from a given source.
- def __init__(self, name, connection_name, foreign=False):
+ def __init__(self, name, source, foreign=False):
self.name = name
- self.connection_name = connection_name
+ self.source = source
+ self.connection_name = source.connection.connection_name
+ self.canonical_hostname = source.canonical_hostname
+ self.canonical_name = source.canonical_hostname + '/' + name
# foreign projects are those referenced in dependencies
# of layout projects, this should matter
# when deciding whether to enqueue their changes
@@ -383,6 +381,7 @@
# Attributes from Nodepool
self._state = 'unknown'
self.state_time = time.time()
+ self.interface_ip = None
self.public_ipv4 = None
self.private_ipv4 = None
self.public_ipv6 = None
@@ -1234,10 +1233,14 @@
def getTries(self, job_name):
return self.tries.get(job_name)
- def getMergeMode(self, job_name):
- if not self.layout or job_name not in self.layout.project_configs:
- return MERGER_MERGE_RESOLVE
- return self.layout.project_configs[job_name].merge_mode
+ def getMergeMode(self):
+ if self.layout:
+ project = self.item.change.project
+ project_config = self.layout.project_configs.get(
+ project.canonical_name)
+ if project_config:
+ return project_config.merge_mode
+ return MERGER_MERGE_RESOLVE
class QueueItem(object):
@@ -1824,6 +1827,7 @@
self.type = None
# For management events (eg: enqueue / promote)
self.tenant_name = None
+ self.project_hostname = None
self.project_name = None
self.trigger_name = None
# Representation of the user account that performed the event.
@@ -1848,8 +1852,12 @@
# an admin command, etc):
self.forced_pipeline = None
+ @property
+ def canonical_project_name(self):
+ return self.project_hostname + '/' + self.project_name
+
def __repr__(self):
- ret = '<TriggerEvent %s %s' % (self.type, self.project_name)
+ ret = '<TriggerEvent %s %s' % (self.type, self.canonical_project_name)
if self.branch:
ret += " %s" % self.branch
@@ -2407,7 +2415,7 @@
def createJobGraph(self, item):
project_config = self.project_configs.get(
- item.change.project.name, None)
+ item.change.project.canonical_name, None)
ret = JobGraph()
# NOTE(pabelanger): It is possible for a foreign project not to have a
# configured pipeline, if so return an empty JobGraph.
@@ -2514,51 +2522,88 @@
# The unparsed configuration from the main zuul config for
# this tenant.
self.unparsed_config = None
- # The list of repos from which we will read main
- # configuration. (source, project)
- self.config_repos = []
- # The unparsed config from those repos.
- self.config_repos_config = None
- # The list of projects from which we will read in-repo
- # configuration. (source, project)
- self.project_repos = []
- # The unparsed config from those repos.
- self.project_repos_config = None
- # A mapping of source -> {config_repos: {}, project_repos: {}}
- self.sources = {}
-
+ # The list of projects from which we will read full
+ # configuration.
+ self.config_projects = []
+ # The unparsed config from those projects.
+ self.config_projects_config = None
+ # The list of projects from which we will read untrusted
+ # in-repo configuration.
+ self.untrusted_projects = []
+ # The unparsed config from those projects.
+ self.untrusted_projects_config = None
self.semaphore_handler = SemaphoreHandler()
- def addConfigRepo(self, source, project):
- sd = self.sources.setdefault(source.name,
- {'config_repos': {},
- 'project_repos': {}})
- sd['config_repos'][project.name] = project
+ # A mapping of project names to projects. project_name ->
+ # VALUE where VALUE is a further dictionary of
+ # canonical_hostname -> Project.
+ self.projects = {}
+ self.canonical_hostnames = set()
- def addProjectRepo(self, source, project):
- sd = self.sources.setdefault(source.name,
- {'config_repos': {},
- 'project_repos': {}})
- sd['project_repos'][project.name] = project
+ def _addProject(self, project):
+ """Add a project to the project index
- def getRepo(self, source, project_name):
- """Get a project given a source and project name
+ :arg Project project: The project to add.
+ """
+ self.canonical_hostnames.add(project.canonical_hostname)
+ hostname_dict = self.projects.setdefault(project.name, {})
+ if project.canonical_hostname in hostname_dict:
+ raise Exception("Project %s is already in project index" %
+ (project,))
+ hostname_dict[project.canonical_hostname] = project
- Returns a tuple (trusted, project) or (None, None) if the
- project is not found.
+ def getProject(self, name):
+ """Return a project given its name.
- Trusted indicates the project is a config repo.
+ :arg str name: The name of the project. It may be fully
+ qualified (E.g., "git.example.com/subpath/project") or may
+ contain only the project name name may be supplied (E.g.,
+ "subpath/project").
+
+ :returns: A tuple (trusted, project) or (None, None) if the
+ project is not found or ambiguous. The "trusted" boolean
+ indicates whether or not the project is trusted by this
+ tenant.
+ :rtype: (bool, Project)
"""
-
- sd = self.sources.get(source)
- if not sd:
+ path = name.split('/', 1)
+ if path[0] in self.canonical_hostnames:
+ hostname = path[0]
+ project_name = path[1]
+ else:
+ hostname = None
+ project_name = name
+ hostname_dict = self.projects.get(project_name)
+ project = None
+ if hostname_dict:
+ if hostname:
+ project = hostname_dict.get(hostname)
+ else:
+ values = hostname_dict.values()
+ if len(values) == 1:
+ project = values[0]
+ else:
+ raise Exception("Project name '%s' is ambiguous, "
+ "please fully qualify the project "
+ "with a hostname" % (name,))
+ if project is None:
return (None, None)
- if project_name in sd['config_repos']:
- return (True, sd['config_repos'][project_name])
- if project_name in sd['project_repos']:
- return (False, sd['project_repos'][project_name])
- return (None, None)
+ if project in self.config_projects:
+ return (True, project)
+ if project in self.untrusted_projects:
+ return (False, project)
+ # This should never happen:
+ raise Exception("Project %s is neither trusted nor untrusted" %
+ (project,))
+
+ def addConfigProject(self, project):
+ self.config_projects.append(project)
+ self._addProject(project)
+
+ def addUntrustedProject(self, project):
+ self.untrusted_projects.append(project)
+ self._addProject(project)
class Abide(object):
diff --git a/zuul/rpclistener.py b/zuul/rpclistener.py
index 0fb557c..105c34b 100644
--- a/zuul/rpclistener.py
+++ b/zuul/rpclistener.py
@@ -98,9 +98,10 @@
if tenant:
event.tenant_name = args['tenant']
- project = tenant.layout.project_configs.get(args['project'])
+ (trusted, project) = tenant.getProject(args['project'])
if project:
- event.project_name = args['project']
+ event.project_hostname = project.canonical_hostname
+ event.project_name = project.name
else:
errors += 'Invalid project: %s\n' % (args['project'],)
@@ -119,15 +120,15 @@
else:
errors += 'Invalid tenant: %s\n' % (args['tenant'],)
- return (args, event, errors, pipeline, project)
+ return (args, event, errors, project)
def handle_enqueue(self, job):
- (args, event, errors, pipeline, project) = self._common_enqueue(job)
+ (args, event, errors, project) = self._common_enqueue(job)
if not errors:
event.change_number, event.patch_number = args['change'].split(',')
try:
- pipeline.source.getChange(event, project)
+ project.source.getChange(event, project)
except Exception:
errors += 'Invalid change: %s\n' % (args['change'],)
@@ -138,7 +139,7 @@
job.sendWorkComplete()
def handle_enqueue_ref(self, job):
- (args, event, errors, pipeline, project) = self._common_enqueue(job)
+ (args, event, errors, project) = self._common_enqueue(job)
if not errors:
event.ref = args['ref']
diff --git a/zuul/scheduler.py b/zuul/scheduler.py
index 0fa1763..53ca4c1 100644
--- a/zuul/scheduler.py
+++ b/zuul/scheduler.py
@@ -232,10 +232,11 @@
self.stopConnections()
self.wake_event.set()
- def registerConnections(self, connections, load=True):
+ def registerConnections(self, connections, webapp, load=True):
# load: whether or not to trigger the onLoad for the connection. This
# is useful for not doing a full load during layout validation.
self.connections = connections
+ self.connections.registerWebapp(webapp)
self.connections.registerScheduler(self, load)
def stopConnections(self):
@@ -486,6 +487,41 @@
finally:
self.layout_lock.release()
+ def _reenqueueGetProject(self, tenant, item):
+ project = item.change.project
+ # Attempt to get the same project as the one passed in. If
+ # the project is now found on a different connection, return
+ # the new version of the project. If it is no longer
+ # available (due to a connection being removed), return None.
+ (trusted, new_project) = tenant.getProject(project.canonical_name)
+ if new_project:
+ return new_project
+ # If this is a non-live item we may be looking at a
+ # "foreign" project, ie, one which is not defined in the
+ # config but is constructed ad-hoc to satisfy a
+ # cross-repo-dependency. Find the corresponding live item
+ # and use its source.
+ child = item
+ while child and not child.live:
+ # This assumes that the queue does not branch behind this
+ # item, which is currently true for non-live items; if
+ # that changes, this traversal will need to be more
+ # complex.
+ if child.items_behind:
+ child = child.items_behind[0]
+ else:
+ child = None
+ if child is item:
+ return None
+ if child and child.live:
+ (child_trusted, child_project) = tenant.getProject(
+ child.change.project.canonical_name)
+ if child_project:
+ source = child_project.source
+ new_project = source.getProject(project.name)
+ return new_project
+ return None
+
def _reenqueueTenant(self, old_tenant, tenant):
for name, new_pipeline in tenant.layout.pipelines.items():
old_pipeline = old_tenant.layout.pipelines.get(name)
@@ -501,15 +537,15 @@
for item in shared_queue.queue:
if not item.item_ahead:
last_head = item
- item.item_ahead = None
- item.items_behind = []
item.pipeline = None
item.queue = None
- project_name = item.change.project.name
- item.change.project = new_pipeline.source.getProject(
- project_name)
- if new_pipeline.manager.reEnqueueItem(item,
- last_head):
+ item.change.project = self._reenqueueGetProject(
+ tenant, item)
+ item.item_ahead = None
+ item.items_behind = []
+ if (item.change.project and
+ new_pipeline.manager.reEnqueueItem(item,
+ last_head)):
for build in item.current_build_set.getBuilds():
new_job = item.getJob(build.job.name)
if new_job:
@@ -553,7 +589,6 @@
# TODOv3(jeblair): remove postconfig calls?
for pipeline in tenant.layout.pipelines.values():
- pipeline.source.postConfig()
for trigger in pipeline.triggers:
trigger.postConfig(pipeline)
for reporter in pipeline.actions:
@@ -611,9 +646,9 @@
def _doEnqueueEvent(self, event):
tenant = self.abide.tenants.get(event.tenant_name)
- project = tenant.layout.project_configs.get(event.project_name)
+ (trusted, project) = tenant.getProject(event.project_name)
pipeline = tenant.layout.pipelines[event.forced_pipeline]
- change = pipeline.source.getChange(event, project)
+ change = project.source.getChange(event, project)
self.log.debug("Event %s for change %s was directly assigned "
"to pipeline %s" % (event, change, self))
pipeline.manager.addChange(change, ignore_requirements=True)
@@ -702,31 +737,28 @@
event = self.trigger_event_queue.get()
self.log.debug("Processing trigger event %s" % event)
try:
+ full_project_name = ('/'.join([event.project_hostname,
+ event.project_name]))
for tenant in self.abide.tenants.values():
- reconfigured_tenant = False
+ (trusted, project) = tenant.getProject(full_project_name)
+ if project is None:
+ continue
+ try:
+ change = project.source.getChange(event)
+ except exceptions.ChangeNotFound as e:
+ self.log.debug("Unable to get change %s from "
+ "source %s",
+ e.change, project.source)
+ continue
+ if (event.type == 'change-merged' and
+ hasattr(change, 'files') and
+ change.updatesConfig()):
+ # The change that just landed updates the config.
+ # Clear out cached data for this project and
+ # perform a reconfiguration.
+ change.project.unparsed_config = None
+ self.reconfigureTenant(tenant)
for pipeline in tenant.layout.pipelines.values():
- # Get the change even if the project is unknown to
- # us for the use of updating the cache if there is
- # another change depending on this foreign one.
- try:
- change = pipeline.source.getChange(event)
- except exceptions.ChangeNotFound as e:
- self.log.debug("Unable to get change %s from "
- "source %s (most likely looking "
- "for a change from another "
- "connection trigger)",
- e.change, pipeline.source)
- continue
- if (event.type == 'change-merged' and
- hasattr(change, 'files') and
- not reconfigured_tenant and
- change.updatesConfig()):
- # The change that just landed updates the config.
- # Clear out cached data for this project and
- # perform a reconfiguration.
- change.project.unparsed_config = None
- self.reconfigureTenant(tenant)
- reconfigured_tenant = True
if event.type == 'patchset-created':
pipeline.manager.removeOldVersionsOfChange(change)
elif event.type == 'change-abandoned':
diff --git a/zuul/webapp.py b/zuul/webapp.py
index 4f040fa..f5a7373 100644
--- a/zuul/webapp.py
+++ b/zuul/webapp.py
@@ -45,6 +45,7 @@
class WebApp(threading.Thread):
log = logging.getLogger("zuul.WebApp")
+ change_path_regexp = '/status/change/(\d+,\d+)$'
def __init__(self, scheduler, port=8001, cache_expiry=1,
listen_address='0.0.0.0'):
@@ -56,10 +57,16 @@
self.cache_time = 0
self.cache = {}
self.daemon = True
+ self.routes = {}
+ self._init_default_routes()
self.server = httpserver.serve(
dec.wsgify(self.app), host=self.listen_address, port=self.port,
start_loop=False)
+ def _init_default_routes(self):
+ self.register_path('/(status\.json|status)$', self.status)
+ self.register_path(self.change_path_regexp, self.change)
+
def run(self):
self.server.serve_forever()
@@ -90,14 +97,13 @@
return change['id'] == rev
return self._changes_by_func(func, tenant_name)
- def _normalize_path(self, path):
- # support legacy status.json as well as new /status
- if path == '/status.json' or path == '/status':
- return "status"
- m = re.match('/status/change/(\d+,\d+)$', path)
- if m:
- return m.group(1)
- return None
+ def register_path(self, path, handler):
+ path_re = re.compile(path)
+ self.routes[path] = (path_re, handler)
+
+ def unregister_path(self, path):
+ if self.routes.get(path):
+ del self.routes[path]
def _handle_keys(self, request, path):
m = re.match('/keys/(.*?)/(.*?).pub', path)
@@ -120,14 +126,43 @@
return response.conditional_response_app
def app(self, request):
+ # Try registered paths without a tenant_name first
+ path = request.path
+ for path_re, handler in self.routes.itervalues():
+ if path_re.match(path):
+ return handler(path, '', request)
+
+ # Now try with a tenant_name stripped
tenant_name = request.path.split('/')[1]
path = request.path.replace('/' + tenant_name, '')
+ # Handle keys
if path.startswith('/keys'):
return self._handle_keys(request, path)
- path = self._normalize_path(path)
- if path is None:
+ for path_re, handler in self.routes.itervalues():
+ if path_re.match(path):
+ return handler(path, tenant_name, request)
+ else:
raise webob.exc.HTTPNotFound()
+ def status(self, path, tenant_name, request):
+ def func():
+ return webob.Response(body=self.cache[tenant_name],
+ content_type='application/json')
+ return self._response_with_status_cache(func, tenant_name)
+
+ def change(self, path, tenant_name, request):
+ def func():
+ m = re.match(self.change_path_regexp, path)
+ change_id = m.group(1)
+ status = self._status_for_change(change_id, tenant_name)
+ if status:
+ return webob.Response(body=status,
+ content_type='application/json')
+ else:
+ raise webob.exc.HTTPNotFound()
+ return self._response_with_status_cache(func, tenant_name)
+
+ def _refresh_status_cache(self, tenant_name):
if (tenant_name not in self.cache or
(time.time() - self.cache_time) > self.cache_expiry):
try:
@@ -140,16 +175,10 @@
self.log.exception("Exception formatting status:")
raise
- if path == 'status':
- response = webob.Response(body=self.cache[tenant_name],
- content_type='application/json')
- else:
- status = self._status_for_change(path, tenant_name)
- if status:
- response = webob.Response(body=status,
- content_type='application/json')
- else:
- raise webob.exc.HTTPNotFound()
+ def _response_with_status_cache(self, func, tenant_name):
+ self._refresh_status_cache(tenant_name)
+
+ response = func()
response.headers['Access-Control-Allow-Origin'] = '*'