zuul/tests/unit/test_git_driver.py
James E. Blair 185b970bad Stabilize git driver tests
These tests relied on sleeps which can cause races when running
the full test suite in parallel.  Instead, wait for the events
we know will happen to happen.

Also remove the dependency on yarl now that aiohttp has made a
release which works with yarl 1.0 (however, it does not work with
<1.0 which is why this needs to be combined with this change to
fix tests).

Change-Id: Ib1c626cdd3f083dd1d23a3c6547bd7163b66567e
2018-01-17 09:53:18 -08:00

187 lines
7.2 KiB
Python

# Copyright 2016 Red Hat, Inc.
#
# 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 os
import time
import yaml
from tests.base import ZuulTestCase, simple_layout
class TestGitDriver(ZuulTestCase):
config_file = 'zuul-git-driver.conf'
tenant_config_file = 'config/git-driver/main.yaml'
def setUp(self):
super(TestGitDriver, self).setUp()
self.git_connection = self.sched.connections.getSource('git').\
connection
def setup_config(self):
super(TestGitDriver, self).setup_config()
self.config.set('connection git', 'baseurl', self.upstream_root)
def test_basic(self):
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_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
# if the job runs, it worked.
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertEqual(len(self.history), 1)
self.assertEqual(A.reported, 1)
def test_config_refreshed(self):
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertEqual(len(self.history), 1)
self.assertEqual(A.reported, 1)
self.assertEqual(self.history[0].name, 'project-test1')
# Update zuul.yaml to force a tenant reconfiguration
path = os.path.join(self.upstream_root, 'common-config', 'zuul.yaml')
config = yaml.load(open(path, 'r').read())
change = {
'name': 'org/project',
'check': {
'jobs': [
'project-test2'
]
}
}
config[4]['project'] = change
files = {'zuul.yaml': yaml.dump(config)}
self.addCommitToRepo(
'common-config', 'Change zuul.yaml configuration', files)
# Wait for the tenant reconfiguration to happen
count = self.waitForEvent()
self.waitUntilSettled()
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertEqual(len(self.history), 2)
self.assertEqual(A.reported, 1)
# We make sure the new job has run
self.assertEqual(self.history[1].name, 'project-test2')
# Let's stop the git Watcher to let us merge some changes commits
# We want to verify that config changes are detected for commits
# on the range oldrev..newrev
self.sched.connections.getSource('git').connection.w_pause = True
# Add a config change
change = {
'name': 'org/project',
'check': {
'jobs': [
'project-test1'
]
}
}
config[4]['project'] = change
files = {'zuul.yaml': yaml.dump(config)}
self.addCommitToRepo(
'common-config', 'Change zuul.yaml configuration', files)
# Add two other changes
self.addCommitToRepo(
'common-config', 'Adding f1',
{'f1': "Content"})
self.addCommitToRepo(
'common-config', 'Adding f2',
{'f2': "Content"})
# Restart the git watcher
self.sched.connections.getSource('git').connection.w_pause = False
# Wait for the tenant reconfiguration to happen
self.waitForEvent(count)
self.waitUntilSettled()
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertEqual(len(self.history), 3)
self.assertEqual(A.reported, 1)
# We make sure the new job has run
self.assertEqual(self.history[2].name, 'project-test1')
def ensure_watcher_has_context(self):
# Make sure watcher have read initial refs shas
delay = 0.1
max_delay = 1
while not self.git_connection.projects_refs:
time.sleep(delay)
max_delay -= delay
if max_delay <= 0:
raise Exception("Timeout waiting for initial read")
return self.git_connection.watcher_thread._event_count
def waitForEvent(self, initial_count=0):
delay = 0.1
max_delay = 1
while self.git_connection.watcher_thread._event_count <= initial_count:
time.sleep(delay)
max_delay -= delay
if max_delay <= 0:
raise Exception("Timeout waiting for event")
return self.git_connection.watcher_thread._event_count
@simple_layout('layouts/basic-git.yaml', driver='git')
def test_ref_updated_event(self):
count = self.ensure_watcher_has_context()
# Add a commit to trigger a ref-updated event
self.addCommitToRepo(
'org/project', 'A change for ref-updated', {'f1': 'Content'})
# Wait for the git watcher to detect the ref-update event
self.waitForEvent(count)
self.waitUntilSettled()
self.assertEqual(len(self.history), 1)
self.assertEqual('SUCCESS',
self.getJobFromHistory('post-job').result)
@simple_layout('layouts/basic-git.yaml', driver='git')
def test_ref_created(self):
count = self.ensure_watcher_has_context()
# Tag HEAD to trigger a ref-updated event
self.addTagToRepo(
'org/project', 'atag', 'HEAD')
# Wait for the git watcher to detect the ref-update event
self.waitForEvent(count)
self.waitUntilSettled()
self.assertEqual(len(self.history), 1)
self.assertEqual('SUCCESS',
self.getJobFromHistory('tag-job').result)
@simple_layout('layouts/basic-git.yaml', driver='git')
def test_ref_deleted(self):
count = self.ensure_watcher_has_context()
# Delete default tag init to trigger a ref-updated event
self.delTagFromRepo(
'org/project', 'init')
# Wait for the git watcher to detect the ref-update event
self.waitForEvent(count)
self.waitUntilSettled()
# Make sure no job as run as ignore-delete is True by default
self.assertEqual(len(self.history), 0)