zuul/tests/unit/test_pagure_driver.py
James E. Blair c224c36b12 Allow early configuration of fake gerrit in tests
A followup change is going to require that we set the submitWholeTopic
value in our fake gerrit at the start of the test setup sequence (instead
of after zuul has already started as we do now).  The best way to do that
is to add a test decorator so that we can set the value for the test methods
that require it.

Because we are plumbing an increasing number of what are effectively per-test
variables to many different places in the tests, let's centralize these values
so that we don't have to pass them all around explicitly.

This adds a TestConfig class which holds some test-specific variables, including
the global fake change database, and passes this new object around instead of
several individual values.

There is room for adding more variables in the future and simplifying the class
and function signatures of many methods, but this is a start.

Change-Id: I514744b1ecca536fd844ed28d29fac3b6ca73a04
2024-06-10 17:54:02 -07:00

1091 lines
40 KiB
Python

# Copyright 2019 Red Hat
#
# 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 re
import git
import yaml
import socket
from testtools.matchers import MatchesRegex
from zuul.lib import strings
from zuul.zk.layout import LayoutState
from tests.base import ZuulTestCase, simple_layout
from tests.base import ZuulWebFixture
EMPTY_LAYOUT_STATE = LayoutState("", "", 0, None, {}, -1)
class TestPagureDriver(ZuulTestCase):
config_file = 'zuul-pagure-driver.conf'
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_pull_request_opened(self):
initial_comment = "This is the\nPR initial_comment."
A = self.fake_pagure.openFakePullRequest(
'org/project', 'master', 'A', initial_comment=initial_comment)
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test1').result)
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test2').result)
job = self.getJobFromHistory('project-test2')
zuulvars = job.parameters['zuul']
self.assertEqual(str(A.number), zuulvars['change'])
self.assertEqual(str(A.commit_stop), zuulvars['patchset'])
self.assertEqual(str(A.commit_stop), zuulvars['commit_id'])
self.assertEqual('master', zuulvars['branch'])
self.assertEquals('https://pagure/org/project/pull-request/1',
zuulvars['items'][0]['change_url'])
self.assertEqual(zuulvars["message"],
strings.b64encode(initial_comment))
self.assertEqual(2, len(self.history))
self.assertEqual(2, len(A.comments))
self.assertEqual(
A.comments[0]['comment'], "Starting check jobs.")
self.assertThat(
A.comments[1]['comment'],
MatchesRegex(r'.*\[project-test1 \]\(.*\).*', re.DOTALL))
self.assertThat(
A.comments[1]['comment'],
MatchesRegex(r'.*\[project-test2 \]\(.*\).*', re.DOTALL))
self.assertEqual(1, len(A.flags))
self.assertEqual('success', A.flags[0]['status'])
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_pull_request_updated(self):
A = self.fake_pagure.openFakePullRequest('org/project', 'master', 'A')
pr_tip1 = A.commit_stop
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual(2, len(self.history))
self.assertHistory(
[
{'name': 'project-test1', 'changes': '1,%s' % pr_tip1},
{'name': 'project-test2', 'changes': '1,%s' % pr_tip1},
], ordered=False
)
self.fake_pagure.emitEvent(A.getPullRequestUpdatedEvent())
pr_tip2 = A.commit_stop
self.waitUntilSettled()
self.assertEqual(4, len(self.history))
self.assertHistory(
[
{'name': 'project-test1', 'changes': '1,%s' % pr_tip1},
{'name': 'project-test2', 'changes': '1,%s' % pr_tip1},
{'name': 'project-test1', 'changes': '1,%s' % pr_tip2},
{'name': 'project-test2', 'changes': '1,%s' % pr_tip2}
], ordered=False
)
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_pull_request_updated_builds_aborted(self):
A = self.fake_pagure.openFakePullRequest('org/project', 'master', 'A')
pr_tip1 = A.commit_stop
self.executor_server.hold_jobs_in_build = True
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.fake_pagure.emitEvent(A.getPullRequestUpdatedEvent())
pr_tip2 = A.commit_stop
self.waitUntilSettled()
self.executor_server.hold_jobs_in_build = False
self.executor_server.release()
self.waitUntilSettled()
self.assertHistory(
[
{'name': 'project-test1', 'result': 'ABORTED',
'changes': '1,%s' % pr_tip1},
{'name': 'project-test2', 'result': 'ABORTED',
'changes': '1,%s' % pr_tip1},
{'name': 'project-test1', 'changes': '1,%s' % pr_tip2},
{'name': 'project-test2', 'changes': '1,%s' % pr_tip2}
], ordered=False
)
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_pull_request_commented(self):
A = self.fake_pagure.openFakePullRequest('org/project', 'master', 'A')
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual(2, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent('I like that change'))
self.waitUntilSettled()
self.assertEqual(2, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent('recheck'))
self.waitUntilSettled()
self.assertEqual(4, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestInitialCommentEvent('Initial comment edited'))
self.waitUntilSettled()
self.assertEqual(6, len(self.history))
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_pull_request_with_dyn_reconf(self):
zuul_yaml = [
{'job': {
'name': 'project-test3',
'run': 'job.yaml'
}},
{'project': {
'check': {
'jobs': [
'project-test3'
]
}
}}
]
playbook = "- hosts: all\n tasks: []"
A = self.fake_pagure.openFakePullRequest(
'org/project', 'master', 'A')
A.addCommit(
{'.zuul.yaml': yaml.dump(zuul_yaml),
'job.yaml': playbook}
)
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test1').result)
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test2').result)
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test3').result)
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_ref_updated(self):
event = self.fake_pagure.getGitReceiveEvent('org/project')
expected_newrev = event[1]['msg']['end_commit']
expected_oldrev = event[1]['msg']['old_commit']
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
self.assertEqual(
'SUCCESS',
self.getJobFromHistory('project-post-job').result)
job = self.getJobFromHistory('project-post-job')
zuulvars = job.parameters['zuul']
self.assertEqual('refs/heads/master', zuulvars['ref'])
self.assertEqual('post', zuulvars['pipeline'])
self.assertEqual('project-post-job', zuulvars['job'])
self.assertEqual('master', zuulvars['branch'])
self.assertEqual(
'https://pagure/org/project/c/%s' % zuulvars['newrev'],
zuulvars['change_url'])
self.assertEqual(expected_newrev, zuulvars['newrev'])
self.assertEqual(expected_oldrev, zuulvars['oldrev'])
self.assertEqual(expected_newrev, zuulvars['commit_id'])
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_ref_created(self):
self.create_branch('org/project', 'stable-1.0')
path = os.path.join(self.upstream_root, 'org/project')
repo = git.Repo(path)
newrev = repo.commit('refs/heads/stable-1.0').hexsha
event = self.fake_pagure.getGitBranchEvent(
'org/project', 'stable-1.0', 'creation', newrev)
old = self.scheds.first.sched.tenant_layout_state.get(
'tenant-one', EMPTY_LAYOUT_STATE)
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
new = self.scheds.first.sched.tenant_layout_state.get(
'tenant-one', EMPTY_LAYOUT_STATE)
# New timestamp should be greater than the old timestamp
self.assertLess(old, new)
self.assertEqual(1, len(self.history))
self.assertEqual(
'SUCCESS',
self.getJobFromHistory('project-post-job').result)
job = self.getJobFromHistory('project-post-job')
zuulvars = job.parameters['zuul']
self.assertEqual('refs/heads/stable-1.0', zuulvars['ref'])
self.assertEqual('post', zuulvars['pipeline'])
self.assertEqual('project-post-job', zuulvars['job'])
self.assertEqual('stable-1.0', zuulvars['branch'])
self.assertEqual(newrev, zuulvars['newrev'])
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_ref_deleted(self):
event = self.fake_pagure.getGitBranchEvent(
'org/project', 'stable-1.0', 'deletion', '0' * 40)
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_ref_updated_and_tenant_reconfigure(self):
self.waitUntilSettled()
old = self.scheds.first.sched.tenant_layout_state.get(
'tenant-one', EMPTY_LAYOUT_STATE)
zuul_yaml = [
{'job': {
'name': 'project-post-job2',
'run': 'job.yaml'
}},
{'project': {
'post': {
'jobs': [
'project-post-job2'
]
}
}}
]
playbook = "- hosts: all\n tasks: []"
self.create_commit(
'org/project',
{'.zuul.yaml': yaml.dump(zuul_yaml),
'job.yaml': playbook},
message='Add InRepo configuration'
)
event = self.fake_pagure.getGitReceiveEvent('org/project')
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
new = self.scheds.first.sched.tenant_layout_state.get(
'tenant-one', EMPTY_LAYOUT_STATE)
# New timestamp should be greater than the old timestamp
self.assertLess(old, new)
self.assertHistory(
[{'name': 'project-post-job'},
{'name': 'project-post-job2'},
], ordered=False
)
@simple_layout('layouts/files-pagure.yaml', driver='pagure')
def test_pull_matched_file_event(self):
A = self.fake_pagure.openFakePullRequest(
'org/project', 'master', 'A',
files={'random.txt': 'test', 'build-requires': 'test'})
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
B = self.fake_pagure.openFakePullRequest('org/project', 'master', 'B',
files={'random.txt': 'test2'})
self.fake_pagure.emitEvent(B.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
C = self.fake_pagure.openFakePullRequest(
'org/project', 'master', 'C',
files={'build-requires': 'test'})
self.fake_pagure.emitEvent(C.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual(2, len(self.history))
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_tag_created(self):
path = os.path.join(self.upstream_root, 'org/project')
repo = git.Repo(path)
repo.create_tag('1.0')
tagsha = repo.tags['1.0'].commit.hexsha
event = self.fake_pagure.getGitTagCreatedEvent(
'org/project', '1.0', tagsha)
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
self.assertEqual(
'SUCCESS',
self.getJobFromHistory('project-tag-job').result)
job = self.getJobFromHistory('project-tag-job')
zuulvars = job.parameters['zuul']
self.assertEqual('refs/tags/1.0', zuulvars['ref'])
self.assertEqual('tag', zuulvars['pipeline'])
self.assertEqual('project-tag-job', zuulvars['job'])
self.assertEqual(tagsha, zuulvars['newrev'])
@simple_layout('layouts/requirements-pagure.yaml', driver='pagure')
def test_pr_score_require_1_vote(self):
A = self.fake_pagure.openFakePullRequest(
'org/project1', 'master', 'A')
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent("I like that change"))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsup:"))
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
self.assertEqual(
'SUCCESS',
self.getJobFromHistory('project-test').result)
@simple_layout('layouts/requirements-pagure.yaml', driver='pagure')
def test_pr_score_require_2_votes(self):
A = self.fake_pagure.openFakePullRequest(
'org/project2', 'master', 'A')
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent("I like that change"))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsup:"))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsdown:"))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsup:"))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsup:"))
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
@simple_layout('layouts/requirements-pagure.yaml', driver='pagure')
def test_status_trigger(self):
A = self.fake_pagure.openFakePullRequest(
'org/project3', 'master', 'A')
self.fake_pagure.emitEvent(
A.getPullRequestStatusSetEvent("failure"))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestStatusSetEvent("success"))
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
@simple_layout('layouts/requirements-pagure.yaml', driver='pagure')
def test_tag_trigger(self):
A = self.fake_pagure.openFakePullRequest(
'org/project4', 'master', 'A')
self.fake_pagure.emitEvent(
A.getPullRequestTagAddedEvent(["lambda"]))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestTagAddedEvent(["gateit", "lambda"]))
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
self.fake_pagure.emitEvent(
A.getPullRequestTagAddedEvent(["mergeit"]))
self.waitUntilSettled()
self.assertEqual(2, len(self.history))
@simple_layout('layouts/requirements-pagure.yaml', driver='pagure')
def test_tag_require(self):
A = self.fake_pagure.openFakePullRequest(
'org/project5', 'master', 'A')
self.fake_pagure.emitEvent(A.getPullRequestUpdatedEvent())
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
A.tags = ["lambda"]
self.fake_pagure.emitEvent(A.getPullRequestUpdatedEvent())
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
A.tags = ["lambda", "gateit"]
self.fake_pagure.emitEvent(A.getPullRequestUpdatedEvent())
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
A.tags = []
self.fake_pagure.emitEvent(A.getPullRequestUpdatedEvent())
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
@simple_layout('layouts/requirements-pagure.yaml', driver='pagure')
def test_flag_require(self):
A = self.fake_pagure.openFakePullRequest(
'org/project7', 'master', 'A')
# CI status from other CIs must not be handled
self.fake_pagure.emitEvent(
A.getPullRequestStatusSetEvent("success", username="notzuul"))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.assertEqual(1, len(A.flags))
self.fake_pagure.emitEvent(
A.getPullRequestStatusSetEvent("failure"))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
self.assertEqual(2, len(A.flags))
self.fake_pagure.emitEvent(
A.getPullRequestStatusSetEvent("success"))
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
self.assertEqual(2, len(A.flags))
@simple_layout('layouts/requirements-pagure.yaml', driver='pagure')
def test_pull_request_closed(self):
A = self.fake_pagure.openFakePullRequest(
'org/project6', 'master', 'A')
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
# Validate a closed but not merged PR does not trigger the pipeline
self.fake_pagure.emitEvent(A.getPullRequestClosedEvent(merged=False))
self.waitUntilSettled()
self.assertEqual(0, len(self.history))
# Reset the status to Open
# Validate a closed and merged PR triggers the pipeline
A.status = 'Open'
A.is_merged = False
self.fake_pagure.emitEvent(A.getPullRequestClosedEvent())
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
@simple_layout('layouts/merging-pagure.yaml', driver='pagure')
def test_merge_action_in_independent(self):
A = self.fake_pagure.openFakePullRequest(
'org/project1', 'master', 'A')
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
self.assertEqual(1, len(self.history))
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test').result)
self.assertEqual('Merged', A.status)
@simple_layout('layouts/merging-pagure.yaml', driver='pagure')
def test_merge_action_in_dependent(self):
A = self.fake_pagure.openFakePullRequest(
'org/project2', 'master', 'A')
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
# connection.canMerge is not validated
self.assertEqual(0, len(self.history))
# Set the mergeable PR flag to a expected value
A.cached_merge_status = 'MERGE'
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
# connection.canMerge is not validated
self.assertEqual(0, len(self.history))
# Set the score threshold as reached
# Here we use None that means no specific score is required
A.threshold_reached = None
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
# connection.canMerge is not validated
self.assertEqual(0, len(self.history))
# Set CI flag as passed CI
A.addFlag('success', 'https://url', 'Build passed')
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
# connection.canMerge is validated
self.assertEqual(1, len(self.history))
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test').result)
self.assertEqual('Merged', A.status)
@simple_layout('layouts/crd-pagure.yaml', driver='pagure')
def test_crd_independent(self):
# Create a change in project1 that a project2 change will depend on
A = self.fake_pagure.openFakePullRequest('org/project1', 'master', 'A')
# Create a commit in B that sets the dependency on A
msg = "Depends-On: %s" % A.url
B = self.fake_pagure.openFakePullRequest(
'org/project2', 'master', 'B', initial_comment=msg)
# Make an event to re-use
event = B.getPullRequestCommentedEvent('A comment')
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
# The changes for the job from project2 should include the project1
# PR content
changes = self.getJobFromHistory(
'project2-test', 'org/project2').changes
self.assertEqual(changes, "%s,%s %s,%s" % (A.number,
A.commit_stop,
B.number,
B.commit_stop))
# There should be no more changes in the queue
tenant = self.scheds.first.sched.abide.tenants.get('tenant-one')
self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
@simple_layout('layouts/crd-pagure.yaml', driver='pagure')
def test_crd_dependent(self):
# Create a change in project3 that a project4 change will depend on
A = self.fake_pagure.openFakePullRequest('org/project3', 'master', 'A')
# Create a commit in B that sets the dependency on A
msg = "Depends-On: %s" % A.url
B = self.fake_pagure.openFakePullRequest(
'org/project4', 'master', 'B', initial_comment=msg)
# Make an event to re-use
event = B.getPullRequestCommentedEvent('A comment')
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
# Neither A and B can't merge (no flag, no score threshold)
self.assertEqual(0, len(self.history))
B.threshold_reached = True
B.addFlag('success', 'https://url', 'Build passed')
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
# B can't merge as A got no flag, no score threshold
self.assertEqual(0, len(self.history))
A.threshold_reached = True
A.addFlag('success', 'https://url', 'Build passed')
self.fake_pagure.emitEvent(event)
self.waitUntilSettled()
# The changes for the job from project4 should include the project3
# PR content
changes = self.getJobFromHistory(
'project4-test', 'org/project4').changes
self.assertEqual(changes, "%s,%s %s,%s" % (A.number,
A.commit_stop,
B.number,
B.commit_stop))
self.assertTrue(A.is_merged)
self.assertTrue(B.is_merged)
@simple_layout('layouts/crd-pagure.yaml', driver='pagure')
def test_crd_needed_changes(self):
# Given change A and B, where B depends on A, when A
# completes B should be enqueued (using a shared queue)
# Create a change in project3 that a project4 change will depend on
A = self.fake_pagure.openFakePullRequest('org/project3', 'master', 'A')
A.threshold_reached = True
A.addFlag('success', 'https://url', 'Build passed')
# Set B to depend on A
msg = "Depends-On: %s" % A.url
B = self.fake_pagure.openFakePullRequest(
'org/project4', 'master', 'B', initial_comment=msg)
# Make the driver aware of change B by sending an event
# At that moment B can't merge
self.fake_pagure.emitEvent(B.getPullRequestCommentedEvent('A comment'))
# Now set B mergeable
B.threshold_reached = True
B.addFlag('success', 'https://url', 'Build passed')
# Enqueue A, which will make the scheduler detect that B is
# depending on so B will be enqueue as well.
self.fake_pagure.emitEvent(A.getPullRequestCommentedEvent('A comment'))
self.waitUntilSettled()
# The changes for the job from project4 should include the project3
# PR content
changes = self.getJobFromHistory(
'project4-test', 'org/project4').changes
self.assertEqual(changes, "%s,%s %s,%s" % (A.number,
A.commit_stop,
B.number,
B.commit_stop))
self.assertTrue(A.is_merged)
self.assertTrue(B.is_merged)
@simple_layout('layouts/files-pagure.yaml', driver='pagure')
def test_changed_file_match_filter(self):
files = {'{:03d}.txt'.format(n): 'test' for n in range(300)}
files["foobar-requires"] = "test"
files["to-be-removed"] = "test"
A = self.fake_pagure.openFakePullRequest(
'org/project', 'master', 'A', files=files)
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
# project-test1 and project-test2 should be run
self.assertEqual(2, len(self.history))
@simple_layout('layouts/files-pagure.yaml', driver='pagure')
def test_changed_and_reverted_file_not_match_filter(self):
files = {'{:03d}.txt'.format(n): 'test' for n in range(3)}
files["foobar-requires"] = "test"
files["to-be-removed"] = "test"
A = self.fake_pagure.openFakePullRequest(
'org/project', 'master', 'A', files=files)
A.addCommit(delete_files=['to-be-removed'])
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent())
self.waitUntilSettled()
# Only project-test1 should be run, because the file to-be-removed
# is reverted and not in changed files to trigger project-test2
self.assertEqual(1, len(self.history))
class TestPagureToGerritCRD(ZuulTestCase):
config_file = 'zuul-crd-pagure.conf'
tenant_config_file = 'config/cross-source-pagure/gerrit.yaml'
def test_crd_gate(self):
"Test cross-repo dependencies"
A = self.fake_pagure.openFakePullRequest('pagure/project2', 'master',
'A')
B = self.fake_gerrit.addFakeChange('gerrit/project1', 'master', 'B')
# A Depends-On: B
A.editInitialComment('Depends-On: %s\n' % (B.data['url']))
A.addFlag('success', 'https://url', 'Build passed')
A.threshold_reached = True
B.addApproval('Code-Review', 2)
# Make A enter the pipeline
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsup:"))
self.waitUntilSettled()
# Expect not merged as B not approved yet
self.assertFalse(A.is_merged)
self.assertEqual(B.data['status'], 'NEW')
for connection in self.scheds.first.connections.connections.values():
connection.maintainCache([], max_age=0)
B.addApproval('Approved', 1)
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsup:"))
self.waitUntilSettled()
self.assertTrue(A.is_merged)
self.assertEqual(B.data['status'], 'MERGED')
self.assertEqual(len(A.comments), 4)
self.assertEqual(B.reported, 2)
changes = self.getJobFromHistory(
'project-merge', 'pagure/project2').changes
self.assertEqual(changes, '1,1 1,%s' % A.commit_stop)
def test_crd_check(self):
"Test cross-repo dependencies in independent pipelines"
A = self.fake_pagure.openFakePullRequest('pagure/project2', 'master',
'A')
B = self.fake_gerrit.addFakeChange(
'gerrit/project1', 'master', 'B')
# A Depends-On: B
A.editInitialComment('Depends-On: %s\n' % (B.data['url'],))
self.executor_server.hold_jobs_in_build = True
self.fake_pagure.emitEvent(A.getPullRequestUpdatedEvent())
self.waitUntilSettled()
self.assertTrue(self.builds[0].hasChanges(A, B))
self.executor_server.hold_jobs_in_build = False
self.executor_server.release()
self.waitUntilSettled()
self.assertFalse(A.is_merged)
self.assertEqual(B.data['status'], 'NEW')
self.assertEqual(len(A.comments), 2)
self.assertEqual(B.reported, 0)
changes = self.getJobFromHistory(
'project-merge', 'pagure/project2').changes
self.assertEqual(changes, '1,1 1,%s' % A.commit_stop)
class TestGerritToPagureCRD(ZuulTestCase):
config_file = 'zuul-crd-pagure.conf'
tenant_config_file = 'config/cross-source-pagure/gerrit.yaml'
def test_crd_gate(self):
"Test cross-repo dependencies"
A = self.fake_gerrit.addFakeChange('gerrit/project1', 'master', 'A')
B = self.fake_pagure.openFakePullRequest('pagure/project2', 'master',
'B')
A.addApproval('Code-Review', 2)
AM2 = self.fake_gerrit.addFakeChange('gerrit/project1', 'master',
'AM2')
AM1 = self.fake_gerrit.addFakeChange('gerrit/project1', 'master',
'AM1')
AM2.setMerged()
AM1.setMerged()
# A -> AM1 -> AM2
# A Depends-On: B
# M2 is here to make sure it is never queried. If it is, it
# means zuul is walking down the entire history of merged
# changes.
A.setDependsOn(AM1, 1)
AM1.setDependsOn(AM2, 1)
A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
A.subject, B.url)
self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
self.waitUntilSettled()
self.assertEqual(A.data['status'], 'NEW')
self.assertFalse(B.is_merged)
for connection in self.scheds.first.connections.connections.values():
connection.maintainCache([], max_age=0)
B.addFlag('success', 'https://url', 'Build passed')
B.threshold_reached = True
self.fake_pagure.emitEvent(
B.getPullRequestCommentedEvent(":thumbsup:"))
self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
self.waitUntilSettled()
self.assertEqual(AM2.queried, 0)
self.assertEqual(A.data['status'], 'MERGED')
self.assertTrue(B.is_merged)
self.assertEqual(A.reported, 2)
self.assertEqual(len(B.comments), 3)
changes = self.getJobFromHistory(
'project-merge', 'gerrit/project1').changes
self.assertEqual(changes, '1,%s 1,1' % B.commit_stop)
def test_crd_check(self):
"Test cross-repo dependencies in independent pipelines"
A = self.fake_gerrit.addFakeChange('gerrit/project1', 'master', 'A')
B = self.fake_pagure.openFakePullRequest(
'pagure/project2', 'master', 'B')
# A Depends-On: B
A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
A.subject, B.url)
self.executor_server.hold_jobs_in_build = True
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertTrue(self.builds[0].hasChanges(A, B))
self.executor_server.hold_jobs_in_build = False
self.executor_server.release()
self.waitUntilSettled()
self.assertEqual(A.data['status'], 'NEW')
self.assertFalse(B.is_merged)
self.assertEqual(A.reported, 1)
self.assertEqual(len(B.comments), 0)
changes = self.getJobFromHistory(
'project-merge', 'gerrit/project1').changes
self.assertEqual(changes, '1,%s 1,1' % B.commit_stop)
class TestPagureToGithubCRD(ZuulTestCase):
config_file = 'zuul-crd-pagure.conf'
tenant_config_file = 'config/cross-source-pagure/github.yaml'
def test_crd_gate(self):
"Test cross-repo dependencies"
A = self.fake_pagure.openFakePullRequest('pagure/project2', 'master',
'A')
B = self.fake_github.openFakePullRequest('github/project1', 'master',
'B')
# A Depends-On: B
A.editInitialComment('Depends-On: %s\n' % (B.url))
A.addFlag('success', 'https://url', 'Build passed')
A.threshold_reached = True
# Make A enter the pipeline
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsup:"))
self.waitUntilSettled()
# Expect not merged as B not approved yet
self.assertFalse(A.is_merged)
self.assertFalse(B.is_merged)
for connection in self.scheds.first.connections.connections.values():
connection.maintainCache([], max_age=0)
B.addLabel('approved')
self.fake_pagure.emitEvent(
A.getPullRequestCommentedEvent(":thumbsup:"))
self.waitUntilSettled()
self.assertTrue(A.is_merged)
self.assertTrue(B.is_merged)
self.assertEqual(len(A.comments), 4)
self.assertEqual(len(B.comments), 2)
changes = self.getJobFromHistory(
'project-merge', 'pagure/project2').changes
self.assertEqual(changes, '1,%s 1,%s' % (B.head_sha, A.commit_stop))
def test_crd_check(self):
"Test cross-repo dependencies in independent pipelines"
A = self.fake_pagure.openFakePullRequest('pagure/project2', 'master',
'A')
B = self.fake_github.openFakePullRequest('github/project1', 'master',
'A')
# A Depends-On: B
A.editInitialComment('Depends-On: %s\n' % B.url)
self.executor_server.hold_jobs_in_build = True
self.fake_pagure.emitEvent(A.getPullRequestUpdatedEvent())
self.waitUntilSettled()
self.assertTrue(self.builds[0].hasChanges(A, B))
self.executor_server.hold_jobs_in_build = False
self.executor_server.release()
self.waitUntilSettled()
self.assertFalse(A.is_merged)
self.assertFalse(B.is_merged)
self.assertEqual(len(A.comments), 2)
self.assertEqual(len(A.comments), 2)
changes = self.getJobFromHistory(
'project-merge', 'pagure/project2').changes
self.assertEqual(changes, '1,%s 1,%s' % (B.head_sha, A.commit_stop))
class TestGithubToPagureCRD(ZuulTestCase):
config_file = 'zuul-crd-pagure.conf'
tenant_config_file = 'config/cross-source-pagure/github.yaml'
# Those tests are also using the fake github implementation which
# means that every scheduler gets a different fake github instance.
# Thus, assertions might fail depending on which scheduler did the
# interaction with Github.
scheduler_count = 1
def test_crd_gate(self):
"Test cross-repo dependencies"
A = self.fake_github.openFakePullRequest('github/project1', 'master',
'A')
B = self.fake_pagure.openFakePullRequest('pagure/project2', 'master',
'B')
# A Depends-On: B
A.editBody('Depends-On: %s\n' % B.url)
event = A.addLabel('approved')
self.fake_github.emitEvent(event)
self.waitUntilSettled()
self.assertFalse(A.is_merged)
self.assertFalse(B.is_merged)
for connection in self.scheds.first.connections.connections.values():
connection.maintainCache([], max_age=0)
B.addFlag('success', 'https://url', 'Build passed')
B.threshold_reached = True
self.fake_pagure.emitEvent(
B.getPullRequestCommentedEvent(":thumbsup:"))
self.fake_github.emitEvent(event)
self.waitUntilSettled()
self.assertTrue(A.is_merged)
self.assertTrue(B.is_merged)
self.assertEqual(len(A.comments), 2)
self.assertEqual(len(B.comments), 3)
changes = self.getJobFromHistory(
'project-merge', 'github/project1').changes
self.assertEqual(changes, '1,%s 1,%s' % (B.commit_stop, A.head_sha))
def test_crd_check(self):
"Test cross-repo dependencies in independent pipelines"
A = self.fake_github.openFakePullRequest(
'github/project1', 'master', 'A')
B = self.fake_pagure.openFakePullRequest(
'pagure/project2', 'master', 'B')
# A Depends-On: B
self.executor_server.hold_jobs_in_build = True
self.fake_github.emitEvent(A.editBody('Depends-On: %s\n' % B.url))
self.waitUntilSettled()
self.assertTrue(self.builds[0].hasChanges(A, B))
self.executor_server.hold_jobs_in_build = False
self.executor_server.release()
self.waitUntilSettled()
self.assertFalse(A.is_merged)
self.assertFalse(B.is_merged)
self.assertEqual(len(A.comments), 1)
self.assertEqual(len(B.comments), 0)
changes = self.getJobFromHistory(
'project-merge', 'github/project1').changes
self.assertEqual(changes, '1,%s 1,%s' % (B.commit_stop, A.head_sha))
class TestPagureWebhook(ZuulTestCase):
config_file = 'zuul-pagure-driver.conf'
def setUp(self):
super(TestPagureWebhook, self).setUp()
# Start the web server
self.web = self.useFixture(
ZuulWebFixture(self.config, self.test_config,
self.additional_event_queues, self.upstream_root,
self.poller_events,
self.git_url_with_auth, self.addCleanup,
self.test_root))
host = '127.0.0.1'
# Wait until web server is started
while True:
port = self.web.port
try:
with socket.create_connection((host, port)):
break
except ConnectionRefusedError:
pass
self.fake_pagure.setZuulWebPort(port)
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_webhook(self):
A = self.fake_pagure.openFakePullRequest(
'org/project', 'master', 'A')
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent(),
use_zuulweb=True,
project='org/project',
wrong_token=True)
self.waitUntilSettled()
self.assertEqual(len(self.history), 0)
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent(),
use_zuulweb=True,
project='org/project')
self.waitUntilSettled()
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test1').result)
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test2').result)
class TestPagureWebhookWhitelist(ZuulTestCase):
config_file = 'zuul-pagure-driver-whitelist.conf'
def setUp(self):
super(TestPagureWebhookWhitelist, self).setUp()
# Start the web server
self.web = self.useFixture(
ZuulWebFixture(self.config, self.test_config,
self.additional_event_queues, self.upstream_root,
self.poller_events,
self.git_url_with_auth, self.addCleanup,
self.test_root))
host = '127.0.0.1'
# Wait until web server is started
while True:
port = self.web.port
try:
with socket.create_connection((host, port)):
break
except ConnectionRefusedError:
pass
self.fake_pagure.setZuulWebPort(port)
@simple_layout('layouts/basic-pagure.yaml', driver='pagure')
def test_webhook_whitelist(self):
A = self.fake_pagure.openFakePullRequest(
'org/project', 'master', 'A')
self.fake_pagure.emitEvent(A.getPullRequestOpenedEvent(),
use_zuulweb=True,
project='org/project',
wrong_token=True)
self.waitUntilSettled()
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test1').result)
self.assertEqual('SUCCESS',
self.getJobFromHistory('project-test2').result)