Files
zuul/tests/unit/test_timer_driver.py
James E. Blair bb53e772d3 Remove the manager attribute from pipelines
This moves the model.Pipeline class closer to being a tenant and
layout-independent configuration object by removing its "manager"
attribute.  Instead, we will consider the Pipeline class an attribute
of the manager.  The PipelineManager will be the root class for all
information about a pipeline.  It will hold the PipelineState and
PipelineSummary ZKObjects, as well as the Pipeline object which
describes its configuration.

This does change a lot of references, probably more than strictly
necessary.  But since, over the years, we built up several helper
methods to get to a pipeline's queues from various objects, it was
becoming unclear how to actually get to the objects we are interested
in after this change.  So to avoid increasing the length of our
object reference chains, this change rips off the bandage and
directly changes many references.

Change-Id: Ied771c56e4fc5a1e032737811a3818168ef36fce
2025-04-02 14:27:15 -07:00

105 lines
4.3 KiB
Python

# Copyright 2021 Acme Gating, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from tests.base import ZuulTestCase, iterate_timeout
class TestTimerTwoTenants(ZuulTestCase):
tenant_config_file = 'config/timer-two-tenant/main.yaml'
def test_timer_two_tenants(self):
# The pipeline triggers every second. Wait until we have 4
# jobs (2 from each tenant).
for _ in iterate_timeout(60, 'jobs started'):
if len(self.history) >= 4:
break
tenant_one_projects = set()
tenant_two_projects = set()
for h in self.history:
if h.parameters['zuul']['tenant'] == 'tenant-one':
tenant_one_projects.add((h.parameters['items'][0]['project']))
if h.parameters['zuul']['tenant'] == 'tenant-two':
tenant_two_projects.add((h.parameters['items'][0]['project']))
# Verify that the right job ran in the right tenant
self.assertEqual(tenant_one_projects, {'org/project1'})
self.assertEqual(tenant_two_projects, {'org/project2'})
# Stop running timer jobs so the assertions don't race.
self.commitConfigUpdate('common-config', 'layouts/no-timer.yaml')
self.scheds.execute(lambda app: app.sched.reconfigure(app.config))
self.waitUntilSettled()
class TestTimerAlwaysDynamicBranches(ZuulTestCase):
tenant_config_file = 'config/dynamic-only-project/dynamic.yaml'
def test_exclude_always_dynamic_branches(self):
# Test that no timer events are emitted for always dynamic branches.
self.create_branch('org/project', 'stable')
self.create_branch('org/project', 'feature/foo')
self.fake_gerrit.addEvent(
self.fake_gerrit.getFakeBranchCreatedEvent(
'org/project', 'stable'))
self.fake_gerrit.addEvent(
self.fake_gerrit.getFakeBranchCreatedEvent(
'org/project', 'feature/foo'))
self.executor_server.hold_jobs_in_build = True
self.commitConfigUpdate('common-config', 'layouts/timer.yaml')
self.scheds.execute(lambda app: app.sched.reconfigure(app.config))
# The pipeline triggers every second, so we should have seen
# several by now.
for _ in iterate_timeout(60, 'jobs started'):
if len(self.builds) > 1:
break
timer = self.scheds.first.sched.connections.drivers['timer']
timer_jobs = timer.apsched.get_jobs()
self.assertEqual(len(timer_jobs), 2)
# Ensure that the status json has the ref so we can render it in the
# web ui.
manager = self.scheds.first.sched.abide.tenants[
'tenant-one'].layout.pipeline_managers['periodic']
self.assertEqual(len(manager.state.queues), 2)
for queue in manager.state.queues:
item = queue.queue[0]
self.assertIn(item.changes[0].branch, ['master', 'stable'])
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.commitConfigUpdate('common-config', 'layouts/no-timer.yaml')
self.scheds.execute(lambda app: app.sched.reconfigure(app.config))
# If APScheduler is in mid-event when we remove the job, we
# can end up with one more event firing, so give it an extra
# second to settle.
time.sleep(3)
self.waitUntilSettled()
self.executor_server.release()
self.waitUntilSettled()
self.assertTrue(len(self.history) > 1)
for job in self.history[:1]:
self.assertEqual(job.result, 'SUCCESS')
self.assertEqual(job.name, 'project-bitrot')
self.assertIn(job.ref, ('refs/heads/stable', 'refs/heads/master'))