[IMP] *: cleanup status contexts in tests

For historical reasons pretty much all tests used to use the contexts
legal/cla and ci/runbot. While there are a few tests where we need the
interactions of multiple contexts and that makes sense, on the vast
majority of tests that's just extra traffic and noise in the
test (from needing to send multiple statuses unnecessarily).

In fact on the average PR where everything passes by default we could
even remove the required statuses entirely...
This commit is contained in:
Xavier Morel 2025-02-06 14:33:40 +01:00
parent 6d5c539c77
commit e3b4d2bb40
13 changed files with 296 additions and 546 deletions

View File

@ -122,10 +122,6 @@ def pytest_configure(config: pytest.Config) -> None:
"markers",
"expect_log_errors(reason): allow and require tracebacks in the log",
)
config.addinivalue_line(
"markers",
"defaultstatuses: use the statuses `default` rather than `ci/runbot,legal/cla`",
)
def pytest_unconfigure(config):
if not is_manager(config):

View File

@ -1,6 +1,4 @@
import re
from utils import Commit, make_basic, to_pr, seen, matches
from utils import Commit, make_basic, to_pr, seen
def test_single_updated(env, config, make_repo):
@ -9,28 +7,24 @@ def test_single_updated(env, config, make_repo):
See test_update_pr for a simpler (single-PR) version
"""
r1, _ = make_basic(env, config, make_repo, reponame='repo-1')
r2, _ = make_basic(env, config, make_repo, reponame='repo-2')
r1, _ = make_basic(env, config, make_repo, reponame='repo-1', statuses='default')
r2, _ = make_basic(env, config, make_repo, reponame='repo-2', statuses='default')
with r1:
r1.make_commits('a', Commit('1', tree={'1': '0'}), ref='heads/aref')
pr1 = r1.make_pr(target='a', head='aref')
r1.post_status('aref', 'success', 'legal/cla')
r1.post_status('aref', 'success', 'ci/runbot')
r1.post_status('aref', 'success')
pr1.post_comment('hansen r+', config['role_reviewer']['token'])
with r2:
r2.make_commits('a', Commit('2', tree={'2': '0'}), ref='heads/aref')
pr2 = r2.make_pr(target='a', head='aref')
r2.post_status('aref', 'success', 'legal/cla')
r2.post_status('aref', 'success', 'ci/runbot')
r2.post_status('aref', 'success')
pr2.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with r1, r2:
r1.post_status('staging.a', 'success', 'legal/cla')
r1.post_status('staging.a', 'success', 'ci/runbot')
r2.post_status('staging.a', 'success', 'legal/cla')
r2.post_status('staging.a', 'success', 'ci/runbot')
r1.post_status('staging.a', 'success')
r2.post_status('staging.a', 'success')
env.run_crons()
pr1_id, pr11_id, pr2_id, pr21_id = pr_ids = env['runbot_merge.pull_requests'].search([]).sorted('display_name')
@ -60,11 +54,9 @@ def test_single_updated(env, config, make_repo):
assert not pr21_id.parent_id
with r1, r2:
r1.post_status(pr11_id.head, 'success', 'legal/cla')
r1.post_status(pr11_id.head, 'success', 'ci/runbot')
r1.post_status(pr11_id.head, 'success')
r1.get_pr(pr11_id.number).post_comment('hansen r+', config['role_reviewer']['token'])
r2.post_status(pr21_id.head, 'success', 'legal/cla')
r2.post_status(pr21_id.head, 'success', 'ci/runbot')
r2.post_status(pr21_id.head, 'success')
r2.get_pr(pr21_id.number).post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
@ -74,10 +66,8 @@ def test_single_updated(env, config, make_repo):
"(%s)" % prs_again.mapped('display_name')
with r1, r2:
r1.post_status('staging.b', 'success', 'legal/cla')
r1.post_status('staging.b', 'success', 'ci/runbot')
r2.post_status('staging.b', 'success', 'legal/cla')
r2.post_status('staging.b', 'success', 'ci/runbot')
r1.post_status('staging.b', 'success')
r2.post_status('staging.b', 'success')
env.run_crons()
new_prs = env['runbot_merge.pull_requests'].search([]).sorted('display_name') - pr_ids
@ -94,9 +84,8 @@ def test_closing_during_fp(env, config, make_repo, users):
""" Closing a PR after it's been ported once should not port it further, but
the rest of the batch should carry on
"""
r1, _ = make_basic(env, config, make_repo)
r2, _ = make_basic(env, config, make_repo)
env['runbot_merge.repository'].search([]).required_statuses = 'default'
r1, _ = make_basic(env, config, make_repo, statuses='default')
r2, _ = make_basic(env, config, make_repo, statuses='default')
with r1, r2:
r1.make_commits('a', Commit('1', tree={'1': '0'}), ref='heads/aref')

View File

@ -3,8 +3,6 @@ import re
import time
from operator import itemgetter
import pytest
from utils import make_basic, Commit, validate_all, matches, seen, REF_PATTERN, to_pr
@ -12,7 +10,7 @@ def test_conflict(env, config, make_repo, users):
""" Create a PR to A which will (eventually) conflict with C when
forward-ported.
"""
prod, other = make_basic(env, config, make_repo)
prod, _other = make_basic(env, config, make_repo, statuses='default')
# create a d branch
with prod:
prod.make_commits('c', Commit('1111', tree={'i': 'a'}), ref='heads/d')
@ -30,14 +28,12 @@ def test_conflict(env, config, make_repo, users):
ref='heads/conflicting'
)
pr = prod.make_pr(target='a', head='conflicting')
prod.post_status(p_0, 'success', 'legal/cla')
prod.post_status(p_0, 'success', 'ci/runbot')
prod.post_status(p_0, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
pra_id, prb_id = env['runbot_merge.pull_requests'].search([], order='number')
# mark pr b as OK so it gets ported to c
@ -144,15 +140,13 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
# check that merging the fixed PR fixes the flow and restarts a forward
# port process
with prod:
prod.post_status(prc.head, 'success', 'legal/cla')
prod.post_status(prc.head, 'success', 'ci/runbot')
prod.post_status(prc.head, 'success')
prc.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
assert prc_id.staging_id
with prod:
prod.post_status('staging.c', 'success', 'legal/cla')
prod.post_status('staging.c', 'success', 'ci/runbot')
prod.post_status('staging.c', 'success')
env.run_crons()
*_, prd_id = env['runbot_merge.pull_requests'].search([], order='number')
@ -264,7 +258,7 @@ def test_massive_conflict(env, config, make_repo):
def test_conflict_deleted(env, config, make_repo):
prod, other = make_basic(env, config, make_repo, statuses="default")
prod, _other = make_basic(env, config, make_repo, statuses="default")
# remove f from b
with prod:
prod.make_commits(
@ -431,7 +425,7 @@ def test_multiple_commits_same_authorship(env, config, make_repo):
"""
author = {'name': 'George Pearce', 'email': 'gp@example.org'}
committer = {'name': 'G. P. W. Meredith', 'email': 'gpwm@example.org'}
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
with prod:
# conflict: create `g` in `a`, using two commits
prod.make_commits(
@ -445,8 +439,7 @@ def test_multiple_commits_same_authorship(env, config, make_repo):
ref='heads/conflicting'
)
pr = prod.make_pr(target='a', head='conflicting')
prod.post_status('conflicting', 'success', 'legal/cla')
prod.post_status('conflicting', 'success', 'ci/runbot')
prod.post_status('conflicting', 'success')
pr.post_comment('hansen r+ rebase-ff', config['role_reviewer']['token'])
env.run_crons()
@ -455,8 +448,7 @@ def test_multiple_commits_same_authorship(env, config, make_repo):
assert pr_id.staging_id
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
for _ in range(20):
@ -480,7 +472,7 @@ def test_multiple_commits_different_authorship(env, config, make_repo, users, ro
"""
author = {'name': 'George Pearce', 'email': 'gp@example.org'}
committer = {'name': 'G. P. W. Meredith', 'email': 'gpwm@example.org'}
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
with prod:
# conflict: create `g` in `a`, using two commits
# just swap author and committer in the commits
@ -495,8 +487,7 @@ def test_multiple_commits_different_authorship(env, config, make_repo, users, ro
ref='heads/conflicting'
)
pr = prod.make_pr(target='a', head='conflicting')
prod.post_status('conflicting', 'success', 'legal/cla')
prod.post_status('conflicting', 'success', 'ci/runbot')
prod.post_status('conflicting', 'success')
pr.post_comment('hansen r+ rebase-ff', config['role_reviewer']['token'])
env.run_crons()
@ -505,8 +496,7 @@ def test_multiple_commits_different_authorship(env, config, make_repo, users, ro
assert pr_id.staging_id
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
for _ in range(20):
@ -543,8 +533,7 @@ b
pr2 = prod.get_pr(pr2_id.number)
with prod:
prod.post_status(pr2_id.head, 'success', 'legal/cla')
prod.post_status(pr2_id.head, 'success', 'ci/runbot')
prod.post_status(pr2_id.head, 'success')
pr2.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()

View File

@ -10,7 +10,7 @@ from utils import seen, Commit, make_basic, to_pr
pytest.param('b', 'a', 0, id='earlier'),
])
def test_configure_fp_limit(env, config, make_repo, source, limit, count, page):
prod, other = make_basic(env, config, make_repo, statuses="default")
prod, _other = make_basic(env, config, make_repo, statuses="default")
with prod:
[c] = prod.make_commits(
source, Commit('c', tree={'f': 'g'}),
@ -170,25 +170,21 @@ def test_disable(env, config, make_repo, users):
* forward-port over a disabled branch
* request a disabled target as limit
"""
prod, other = make_basic(env, config, make_repo)
project = env['runbot_merge.project'].search([])
prod, _other = make_basic(env, config, make_repo, statuses='default')
with prod:
[c] = prod.make_commits('a', Commit('c 0', tree={'0': '0'}), ref='heads/branch0')
pr = prod.make_pr(target='a', head='branch0')
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr.post_comment('hansen r+ up to b', config['role_reviewer']['token'])
[c] = prod.make_commits('a', Commit('c 1', tree={'1': '1'}), ref='heads/branch1')
pr = prod.make_pr(target='a', head='branch1')
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
# disable branch b
env['runbot_merge.branch'].search([('name', '=', 'b')]).active = False
env.run_crons()
@ -201,8 +197,7 @@ def test_disable(env, config, make_repo, users):
with prod:
[c] = prod.make_commits('a', Commit('c 2', tree={'2': '2'}), ref='heads/branch2')
pr = prod.make_pr(target='a', head='branch2')
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr.post_comment('hansen r+ up to', config['role_reviewer']['token'])
pr.post_comment('hansen up to b', config['role_reviewer']['token'])
pr.post_comment('hansen up to foo', config['role_reviewer']['token'])
@ -255,21 +250,18 @@ Note: this help text is dynamic and will change with the state of the PR.
def test_limit_after_merge(env, config, make_repo, users):
prod, other = make_basic(env, config, make_repo)
prod, other = make_basic(env, config, make_repo, statuses='default')
reviewer = config['role_reviewer']['token']
branch_b = env['runbot_merge.branch'].search([('name', '=', 'b')])
branch_c = env['runbot_merge.branch'].search([('name', '=', 'c')])
with prod:
[c] = prod.make_commits('a', Commit('c', tree={'0': '0'}), ref='heads/abranch')
pr1 = prod.make_pr(target='a', head='abranch')
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr1.post_comment('hansen r+', reviewer)
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
p1, p2 = env['runbot_merge.pull_requests'].search([], order='number')
@ -321,13 +313,11 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
(users['user'], "Forward-porting to 'c'."),
]
with prod:
prod.post_status(p2.head, 'success', 'legal/cla')
prod.post_status(p2.head, 'success', 'ci/runbot')
prod.post_status(p2.head, 'success')
pr2.post_comment('hansen r+', reviewer)
env.run_crons()
with prod:
prod.post_status('staging.b', 'success', 'legal/cla')
prod.post_status('staging.b', 'success', 'ci/runbot')
prod.post_status('staging.b', 'success')
env.run_crons()
_, _, p3 = env['runbot_merge.pull_requests'].search([], order='number')
@ -371,7 +361,7 @@ def test_post_merge(
limit: int,
):
PRs = env['runbot_merge.pull_requests']
project, prod, _ = post_merge
_project, prod, _ = post_merge
reviewer = config['role_reviewer']['token']
# fetch source PR
@ -435,7 +425,7 @@ def test_resume_fw(env, post_merge, users, config, branches, mode):
"""
PRs = env['runbot_merge.pull_requests']
project, prod, _ = post_merge
_project, prod, _ = post_merge
reviewer = config['role_reviewer']['token']
# fetch source PR
@ -467,7 +457,6 @@ def test_resume_fw(env, post_merge, users, config, branches, mode):
env.run_crons()
with prod:
for target in numbers:
pr = PRs.search([('target.name', '=', str(target))])
prod.post_status(f'staging.{target}', 'success')
env.run_crons()
for number in numbers:

View File

@ -11,9 +11,8 @@ def statuses(pr):
def test_override_inherited(env, config, make_repo, users):
""" A forwardport should inherit its parents' overrides, until it's edited.
"""
repo, other = make_basic(env, config, make_repo)
repo, _other = make_basic(env, config, make_repo, statuses='default')
project = env['runbot_merge.project'].search([])
project.repo_ids.status_ids = [(5, 0, 0), (0, 0, {'context': 'default'})]
env['res.partner'].search([('github_login', '=', users['reviewer'])])\
.write({'override_rights': [(0, 0, {
'repository_id': project.repo_ids.id,
@ -73,7 +72,7 @@ def test_override_inherited(env, config, make_repo, users):
def test_override_combination(env, config, make_repo, users):
""" A forwardport should inherit its parents' overrides, until it's edited.
"""
repo, other = make_basic(env, config, make_repo)
repo, _other = make_basic(env, config, make_repo, statuses='ci/runbot,legal/cla')
project = env['runbot_merge.project'].search([])
env['res.partner'].search([('github_login', '=', users['reviewer'])]) \
.write({'override_rights': [

View File

@ -31,7 +31,7 @@ def test_straightforward_flow(env, config, make_repo, users):
('github_login', '=', users['reviewer'])
]).name
prod, other = make_basic(env, config, make_repo)
prod, other = make_basic(env, config, make_repo, statuses='default')
other_user = config['role_other']
other_user_repo = prod.fork(token=other_user['token'])
@ -50,8 +50,7 @@ def test_straightforward_flow(env, config, make_repo, users):
head=other_user['user'] + ':hugechange',
token=other_user['token']
)
prod.post_status(p_1, 'success', 'legal/cla')
prod.post_status(p_1, 'success', 'ci/runbot')
prod.post_status(p_1, 'success')
# use rebase-ff (instead of rebase-merge) so we don't have to dig in
# parents of the merge commit to find the cherrypicks
pr.post_comment('hansen r+ rebase-ff', config['role_reviewer']['token'])
@ -61,8 +60,7 @@ def test_straightforward_flow(env, config, make_repo, users):
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
# should merge the staging then create the FP PR
env.run_crons()
@ -116,8 +114,7 @@ def test_straightforward_flow(env, config, make_repo, users):
'x': '1'
}
with prod:
prod.post_status(pr1.head, 'success', 'ci/runbot')
prod.post_status(pr1.head, 'success', 'legal/cla')
prod.post_status(pr1.head, 'success')
env.run_crons()
pr0_, pr1_, pr2 = env['runbot_merge.pull_requests'].search([], order='number')
@ -176,8 +173,7 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
))
]
with prod:
prod.post_status(pr2.head, 'success', 'ci/runbot')
prod.post_status(pr2.head, 'success', 'legal/cla')
prod.post_status(pr2.head, 'success')
pr2_remote.post_comment('hansen r+', config['role_reviewer']['token'])
@ -189,10 +185,8 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
assert pr1.staging_id != pr2.staging_id
# validate
with prod:
prod.post_status('staging.b', 'success', 'ci/runbot')
prod.post_status('staging.b', 'success', 'legal/cla')
prod.post_status('staging.c', 'success', 'ci/runbot')
prod.post_status('staging.c', 'success', 'legal/cla')
prod.post_status('staging.b', 'success')
prod.post_status('staging.c', 'success')
# and trigger merge
env.run_crons()
@ -249,7 +243,7 @@ def test_empty(env, config, make_repo, users):
""" Cherrypick of an already cherrypicked (or separately implemented)
commit -> conflicting pr.
"""
prod, other = make_basic(env, config, make_repo, statuses="default")
prod, _other = make_basic(env, config, make_repo, statuses="default")
# merge change to b
with prod:
[p_0] = prod.make_commits(
@ -405,7 +399,7 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
def test_partially_empty(env, config, make_repo):
""" Check what happens when only some commits of the PR are now empty
"""
prod, other = make_basic(env, config, make_repo)
prod, _other = make_basic(env, config, make_repo, statuses='default')
# merge change to b
with prod:
[p_0] = prod.make_commits(
@ -413,13 +407,11 @@ def test_partially_empty(env, config, make_repo):
ref='heads/early'
)
pr0 = prod.make_pr(target='b', head='early')
prod.post_status(p_0, 'success', 'legal/cla')
prod.post_status(p_0, 'success', 'ci/runbot')
prod.post_status(p_0, 'success')
pr0.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.b', 'success', 'legal/cla')
prod.post_status('staging.b', 'success', 'ci/runbot')
prod.post_status('staging.b', 'success')
# merge same change to a afterwards
with prod:
@ -431,13 +423,11 @@ def test_partially_empty(env, config, make_repo):
ref='heads/late'
)
pr1 = prod.make_pr(target='a', head='late')
prod.post_status(p_1, 'success', 'legal/cla')
prod.post_status(p_1, 'success', 'ci/runbot')
prod.post_status(p_1, 'success')
pr1.post_comment('hansen r+ rebase-merge', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
assert prod.read_tree(prod.commit('a')) == {
@ -490,7 +480,7 @@ def test_access_rights(env, config, make_repo, users, author, reviewer, delegate
"""Validates the review rights *for the forward-port sequence*, the original
PR is always reviewed by `user`.
"""
prod, other = make_basic(env, config, make_repo)
prod, _other = make_basic(env, config, make_repo, statuses='default')
project = env['runbot_merge.project'].search([])
# create a partner for `user`
@ -521,29 +511,25 @@ def test_access_rights(env, config, make_repo, users, author, reviewer, delegate
head=users[author] + ':accessrights',
token=author_token,
)
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr.post_comment('hansen r+', token=config['github']['token'])
if delegate:
pr.post_comment('hansen delegate=%s' % users[delegate], token=config['github']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
pr0, pr1 = env['runbot_merge.pull_requests'].search([], order='number')
assert pr0.state == 'merged'
with prod:
prod.post_status(pr1.head, 'success', 'ci/runbot')
prod.post_status(pr1.head, 'success', 'legal/cla')
prod.post_status(pr1.head, 'success')
env.run_crons()
_, _, pr2 = env['runbot_merge.pull_requests'].search([], order='number')
with prod:
prod.post_status(pr2.head, 'success', 'ci/runbot')
prod.post_status(pr2.head, 'success', 'legal/cla')
prod.post_status(pr2.head, 'success')
prod.get_pr(pr2.number).post_comment(
'hansen r+',
token=config['role_' + reviewer]['token']
@ -645,7 +631,7 @@ def test_delegate_fw(env, config, make_repo, users):
"""If a user is delegated *on a forward port* they should be able to approve
*the followup*.
"""
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
# create a partner for `other` so we can put an email on it
env['res.partner'].create({
'name': users['other'],
@ -661,14 +647,12 @@ def test_delegate_fw(env, config, make_repo, users):
head=users['self_reviewer'] + ':accessrights',
token=author_token,
)
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr.post_comment('hansen r+', token=config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
# ensure pr1 has to be approved to be forward-ported
@ -679,29 +663,26 @@ def test_delegate_fw(env, config, make_repo, users):
'detach_reason': "Detached for testing.",
})
with prod:
prod.post_status(pr1_id.head, 'success', 'legal/cla')
prod.post_status(pr1_id.head, 'success', 'ci/runbot')
prod.post_status(pr1_id.head, 'success')
env.run_crons()
pr1 = prod.get_pr(pr1_id.number)
# delegate review to "other" consider PR fixed, and have "other" approve it
with prod:
pr1.post_comment('hansen delegate=' + users['other'],
token=config['role_reviewer']['token'])
prod.post_status(pr1_id.head, 'success', 'ci/runbot')
prod.post_status(pr1_id.head, 'success')
pr1.post_comment('hansen r+', token=config['role_other']['token'])
env.run_crons()
with prod:
prod.post_status('staging.b', 'success', 'legal/cla')
prod.post_status('staging.b', 'success', 'ci/runbot')
prod.post_status('staging.b', 'success')
env.run_crons()
_, _, pr2_id = env['runbot_merge.pull_requests'].search([], order='number')
pr2 = prod.get_pr(pr2_id.number)
# make "other" also approve this one
with prod:
prod.post_status(pr2_id.head, 'success', 'ci/runbot')
prod.post_status(pr2_id.head, 'success', 'legal/cla')
prod.post_status(pr2_id.head, 'success')
pr2.post_comment('hansen r+', token=config['role_other']['token'])
env.run_crons()
@ -723,26 +704,22 @@ def test_redundant_approval(env, config, make_repo, users):
"""If a forward port sequence has been partially approved, fw-bot r+ should
not perform redundant approval as that triggers warning messages.
"""
prod, _ = make_basic(env, config, make_repo)
[project] = env['runbot_merge.project'].search([])
prod, _ = make_basic(env, config, make_repo, statuses='default')
with prod:
prod.make_commits(
'a', Commit('p', tree={'x': '0'}),
ref='heads/early'
)
pr0 = prod.make_pr(target='a', head='early')
prod.post_status('heads/early', 'success', 'legal/cla')
prod.post_status('heads/early', 'success', 'ci/runbot')
prod.post_status('heads/early', 'success')
pr0.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
pr0_id, pr1_id = env['runbot_merge.pull_requests'].search([], order='number asc')
with prod:
prod.post_status(pr1_id.head, 'success', 'legal/cla')
prod.post_status(pr1_id.head, 'success', 'ci/runbot')
prod.post_status(pr1_id.head, 'success')
env.run_crons()
_, _, pr2_id = env['runbot_merge.pull_requests'].search([], order='number asc')
@ -770,8 +747,8 @@ def test_batched(env, config, make_repo, users):
""" Tests for projects with multiple repos & sync'd branches. Batches
should be FP'd to batches
"""
main1, _ = make_basic(env, config, make_repo, reponame='main1')
main2, _ = make_basic(env, config, make_repo, reponame='main2')
main1, _ = make_basic(env, config, make_repo, reponame='main1', statuses='default')
main2, _ = make_basic(env, config, make_repo, reponame='main2', statuses='default')
main1.unsubscribe(config['role_reviewer']['token'])
main2.unsubscribe(config['role_reviewer']['token'])
@ -862,7 +839,6 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
assert pr1c.label == pr2c.label, "batched source should yield batched FP"
assert pr1b.label != pr1c.label
project = env['runbot_merge.project'].search([])
# ok main1 PRs
with main1:
validate_all([main1], [pr1c.head])
@ -894,7 +870,7 @@ class TestClosing:
def test_closing_before_fp(self, env, config, make_repo, users):
""" Closing a PR should preclude its forward port
"""
prod, other = make_basic(env, config, make_repo)
prod, _other = make_basic(env, config, make_repo, statuses='default')
with prod:
[p_1] = prod.make_commits(
'a',
@ -902,14 +878,12 @@ class TestClosing:
ref='heads/hugechange'
)
pr = prod.make_pr(target='a', head='hugechange')
prod.post_status(p_1, 'success', 'legal/cla')
prod.post_status(p_1, 'success', 'ci/runbot')
prod.post_status(p_1, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
# should merge the staging then create the FP PR
env.run_crons()
@ -921,8 +895,7 @@ class TestClosing:
assert pr1_id.state == 'closed'
assert not pr1_id.parent_id, "closed PR should should be detached from its parent"
with prod:
prod.post_status(pr1_id.head, 'success', 'legal/cla')
prod.post_status(pr1_id.head, 'success', 'ci/runbot')
prod.post_status(pr1_id.head, 'success')
env.run_crons()
env.run_crons('forwardport.reminder')
@ -941,8 +914,7 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
""" Closing a PR which has been forward-ported should not touch the
followups
"""
prod, other = make_basic(env, config, make_repo)
project = env['runbot_merge.project'].search([])
prod, _other = make_basic(env, config, make_repo, statuses='default')
with prod:
[p_1] = prod.make_commits(
'a',
@ -950,22 +922,19 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
ref='heads/hugechange'
)
pr = prod.make_pr(target='a', head='hugechange')
prod.post_status(p_1, 'success', 'legal/cla')
prod.post_status(p_1, 'success', 'ci/runbot')
prod.post_status(p_1, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
# should merge the staging then create the FP PR
env.run_crons()
pr0_id, pr1_id = env['runbot_merge.pull_requests'].search([], order='number')
with prod:
prod.post_status(pr1_id.head, 'success', 'legal/cla')
prod.post_status(pr1_id.head, 'success', 'ci/runbot')
prod.post_status(pr1_id.head, 'success')
# should create the second staging
env.run_crons()
@ -995,8 +964,7 @@ More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
be nodified if already merged, also there should not be recursive
notifications (odoo/odoo#145969, odoo/odoo#145984)
"""
repo, _ = make_basic(env, config, make_repo)
env['runbot_merge.repository'].search([]).required_statuses = 'default'
repo, _ = make_basic(env, config, make_repo, statuses='default')
# prep: merge PR, create two forward ports
with repo:
[c1] = repo.make_commits('a', Commit('first', tree={'m': 'c1'}))
@ -1072,21 +1040,19 @@ class TestBranchDeletion:
""" Regular PRs should get their branch deleted as long as they're
created in the fp repository
"""
prod, other = make_basic(env, config, make_repo)
prod, other = make_basic(env, config, make_repo, statuses='default')
with prod, other:
[c] = other.make_commits(prod.commit('a').id, Commit('c', tree={'0': '0'}), ref='heads/abranch')
pr = prod.make_pr(
target='a', head='%s:abranch' % other.owner,
title="a pr",
)
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
pr_id = to_pr(env, pr)
@ -1103,13 +1069,12 @@ class TestBranchDeletion:
""" The branches of PRs which are still open or have been closed (rather
than merged) should not get deleted
"""
prod, other = make_basic(env, config, make_repo)
prod, other = make_basic(env, config, make_repo, statuses='default')
with prod, other:
a_ref = prod.commit('a').id
[c] = other.make_commits(a_ref, Commit('c1', tree={'1': '0'}), ref='heads/abranch')
pr1 = prod.make_pr(target='a', head='%s:abranch' % other.owner, title='a')
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr1.post_comment('hansen r+', config['role_reviewer']['token'])
other.make_commits(a_ref, Commit('c2', tree={'2': '0'}), ref='heads/bbranch')
@ -1118,8 +1083,7 @@ class TestBranchDeletion:
[c] = other.make_commits(a_ref, Commit('c3', tree={'3': '0'}), ref='heads/cbranch')
pr3 = prod.make_pr(target='a', head='%s:cbranch' % other.owner, title='c')
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
other.make_commits(a_ref, Commit('c3', tree={'4': '0'}), ref='heads/dbranch')
pr4 = prod.make_pr(target='a', head='%s:dbranch' % other.owner, title='d')
@ -1155,7 +1119,7 @@ def test_spengbab():
class TestRecognizeCommands:
def make_pr(self, env, config, make_repo):
r, _ = make_basic(env, config, make_repo)
r, _ = make_basic(env, config, make_repo, statuses='default')
with r:
r.make_commits('c', Commit('p', tree={'x': '0'}), ref='heads/testbranch')

View File

@ -2,8 +2,6 @@
Test cases for updating PRs during after the forward-porting process after the
initial merge has succeeded (and forward-porting has started)
"""
import re
import pytest
from utils import seen, matches, Commit, make_basic, to_pr
@ -17,7 +15,7 @@ def test_update_pr(env, config, make_repo, users, merge_parent) -> None:
In this case, all following forward ports should... be detached? Or maybe
only this one and its dependent should be updated?
"""
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='ci/runbot,legal/cla')
# create a branch d from c so we can have 3 forward ports PRs, not just 2,
# for additional checks
env['runbot_merge.project'].search([]).write({
@ -219,7 +217,7 @@ def test_update_merged(env, make_repo, config, users):
* also maybe disable or exponentially backoff the update job after some
number of attempts?
"""
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
# add a 4th branch
with prod:
prod.make_ref('heads/d', prod.commit('c').id)
@ -230,33 +228,28 @@ def test_update_merged(env, make_repo, config, users):
with prod:
[c] = prod.make_commits('a', Commit('p_0', tree={'0': '0'}), ref='heads/hugechange')
pr = prod.make_pr(target='a', head='hugechange')
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
_, pr1_id = env['runbot_merge.pull_requests'].search([], order='number')
with prod:
prod.post_status(pr1_id.head, 'success', 'legal/cla')
prod.post_status(pr1_id.head, 'success', 'ci/runbot')
prod.post_status(pr1_id.head, 'success')
env.run_crons()
pr0_id, pr1_id, pr2_id = env['runbot_merge.pull_requests'].search([], order='number')
pr2 = prod.get_pr(pr2_id.number)
with prod:
pr2.post_comment('hansen r+', config['role_reviewer']['token'])
prod.post_status(pr2_id.head, 'success', 'legal/cla')
prod.post_status(pr2_id.head, 'success', 'ci/runbot')
prod.post_status(pr2_id.head, 'success')
env.run_crons()
assert pr2_id.staging_id
with prod:
prod.post_status('staging.c', 'success', 'legal/cla')
prod.post_status('staging.c', 'success', 'ci/runbot')
prod.post_status('staging.c', 'success')
env.run_crons()
assert pr2_id.state == 'merged'
assert pr2.state == 'closed'
@ -371,7 +364,7 @@ def test_duplicate_fw(env, make_repo, setreviewers, config, users):
env.run_crons()
parent = child
pr_ids = _, prv2_id, prv3_id, prmaster_id = PRs.search([], order='number')
_, prv2, prv3, prmaster = [repo.get_pr(p.number) for p in pr_ids]
_, prv2, _prv3, _prmaster = [repo.get_pr(p.number) for p in pr_ids]
assert pr_ids.mapped('target.name') == ['v1', 'v2', 'v3', 'master']
assert pr_ids.mapped('state') == ['merged', 'validated', 'validated', 'validated']
assert repo.read_tree(repo.commit(prmaster_id.head)) == {'f': 'e', 'z': 'a'}
@ -404,19 +397,17 @@ def test_subsequent_conflict(env, make_repo, config, users):
""" Test for updating an fw PR in the case where it produces a conflict in
the followup. Cf #467.
"""
repo, fork = make_basic(env, config, make_repo)
repo, fork = make_basic(env, config, make_repo, statuses='default')
# create a PR in branch A which adds a new file
with repo:
repo.make_commits('a', Commit('newfile', tree={'x': '0'}), ref='heads/pr1')
pr_1 = repo.make_pr(target='a', head='pr1')
repo.post_status('pr1', 'success', 'legal/cla')
repo.post_status('pr1', 'success', 'ci/runbot')
repo.post_status('pr1', 'success')
pr_1.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with repo:
repo.post_status('staging.a', 'success', 'legal/cla')
repo.post_status('staging.a', 'success', 'ci/runbot')
repo.post_status('staging.a', 'success')
env.run_crons()
pr1_id = to_pr(env, pr_1)
assert pr1_id.state == 'merged'
@ -424,8 +415,7 @@ def test_subsequent_conflict(env, make_repo, config, users):
pr2_id = env['runbot_merge.pull_requests'].search([('source_id', '=', pr1_id.id)])
assert pr2_id
with repo:
repo.post_status(pr2_id.head, 'success', 'legal/cla')
repo.post_status(pr2_id.head, 'success', 'ci/runbot')
repo.post_status(pr2_id.head, 'success')
env.run_crons()
pr3_id = env['runbot_merge.pull_requests'].search([('parent_id', '=', pr2_id.id)])

View File

@ -11,21 +11,19 @@ def test_no_token(env, config, make_repo):
log
"""
# create project configured with remotes on the repo but no token
prod, _ = make_basic(env, config, make_repo, fp_token=False, fp_remote=True)
prod, _ = make_basic(env, config, make_repo, fp_token=False, fp_remote=True, statuses='default')
with prod:
prod.make_commits(
'a', Commit('c0', tree={'a': '0'}), ref='heads/abranch'
)
pr = prod.make_pr(target='a', head='abranch')
prod.post_status(pr.head, 'success', 'legal/cla')
prod.post_status(pr.head, 'success', 'ci/runbot')
prod.post_status(pr.head, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
# wanted to use capfd, however it's not compatible with the subprocess
# being created beforehand and server() depending on capfd() would remove
@ -41,85 +39,75 @@ def test_no_token(env, config, make_repo):
"should not have created forward port"
def test_remove_token(env, config, make_repo):
prod, _ = make_basic(env, config, make_repo)
env['runbot_merge.project'].search([]).fp_github_token = False
prod, _ = make_basic(env, config, make_repo, statuses='default', fp_token=False)
with prod:
prod.make_commits(
'a', Commit('c0', tree={'a': '0'}), ref='heads/abranch'
)
pr = prod.make_pr(target='a', head='abranch')
prod.post_status(pr.head, 'success', 'legal/cla')
prod.post_status(pr.head, 'success', 'ci/runbot')
prod.post_status(pr.head, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
assert len(env['runbot_merge.pull_requests'].search([], order='number')) == 1,\
"should not have created forward port"
def test_no_target(env, config, make_repo):
prod, _ = make_basic(env, config, make_repo, fp_remote=False)
prod, _ = make_basic(env, config, make_repo, fp_remote=False, statuses='default')
with prod:
prod.make_commits(
'a', Commit('c0', tree={'a': '0'}), ref='heads/abranch'
)
pr = prod.make_pr(target='a', head='abranch')
prod.post_status(pr.head, 'success', 'legal/cla')
prod.post_status(pr.head, 'success', 'ci/runbot')
prod.post_status(pr.head, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
assert len(env['runbot_merge.pull_requests'].search([], order='number')) == 1,\
"should not have created forward port"
def test_failed_staging(env, config, make_repo):
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
reviewer = config['role_reviewer']['token']
with prod:
prod.make_commits('a', Commit('c', tree={'a': '0'}), ref='heads/abranch')
pr1 = prod.make_pr(target='a', head='abranch')
prod.post_status(pr1.head, 'success', 'legal/cla')
prod.post_status(pr1.head, 'success', 'ci/runbot')
prod.post_status(pr1.head, 'success')
pr1.post_comment('hansen r+', reviewer)
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
pr1_id, pr2_id = env['runbot_merge.pull_requests'].search([], order='number')
assert pr2_id.parent_id == pr2_id.source_id == pr1_id
with prod:
prod.post_status(pr2_id.head, 'success', 'legal/cla')
prod.post_status(pr2_id.head, 'success', 'ci/runbot')
prod.post_status(pr2_id.head, 'success')
env.run_crons()
pr1_id, pr2_id, pr3_id = env['runbot_merge.pull_requests'].search([], order='number')
_pr1_id, _pr2_id, pr3_id = env['runbot_merge.pull_requests'].search([], order='number')
pr3 = prod.get_pr(pr3_id.number)
with prod:
prod.post_status(pr3_id.head, 'success', 'legal/cla')
prod.post_status(pr3_id.head, 'success', 'ci/runbot')
prod.post_status(pr3_id.head, 'success')
pr3.post_comment('hansen r+', reviewer)
env.run_crons()
prod.commit('staging.c')
with prod:
prod.post_status('staging.b', 'success', 'legal/cla')
prod.post_status('staging.b', 'success', 'ci/runbot')
prod.post_status('staging.c', 'failure', 'ci/runbot')
prod.post_status('staging.b', 'success')
prod.post_status('staging.c', 'failure')
env.run_crons()
pr3_head = env['runbot_merge.commit'].search([('sha', '=', pr3_id.head)])
@ -128,8 +116,7 @@ def test_failed_staging(env, config, make_repo):
# send a new status to the PR, as if somebody had rebuilt it or something
with prod:
pr3.post_comment('hansen retry', reviewer)
prod.post_status(pr3_id.head, 'success', 'foo/bar')
prod.post_status(pr3_id.head, 'success', 'legal/cla')
prod.post_status(pr3_id.head, 'success')
assert pr3_head.to_check, "check that the commit was updated as to process"
env.run_crons()
assert not pr3_head.to_check, "check that the commit was processed"
@ -255,13 +242,13 @@ class TestNotAllBranches:
repo_a = env['runbot_merge.repository'].create({
'project_id': project.id,
'name': a.name,
'required_statuses': 'ci/runbot',
'required_statuses': 'default',
'fp_remote_target': a_dev.name,
})
repo_b = env['runbot_merge.repository'].create({
'project_id': project.id,
'name': b.name,
'required_statuses': 'ci/runbot',
'required_statuses': 'default',
'fp_remote_target': b_dev.name,
'branch_filter': '[("name", "in", ["a", "c"])]',
})
@ -272,32 +259,32 @@ class TestNotAllBranches:
def test_single_first(self, env, repos, config):
""" A merge in A.a should be forward-ported to A.b and A.c
"""
project, a, a_dev, b, _ = repos
_project, a, a_dev, b, _ = repos
with a, a_dev:
[c] = a_dev.make_commits(a.commit('a').id, Commit('pr', tree={'pr': '1'}), ref='heads/change')
pr = a.make_pr(target='a', title="a pr", head=a_dev.owner + ':change')
a.post_status(c, 'success', 'ci/runbot')
a.post_status(c, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
p = to_pr(env, pr)
env.run_crons()
assert p.staging_id
with a, b:
for repo in a, b:
repo.post_status('staging.a', 'success', 'ci/runbot')
a.post_status('staging.a', 'success')
b.post_status('staging.a', 'success')
env.run_crons()
a_head = a.commit('a')
assert a_head.message.startswith('pr\n\n')
assert a.read_tree(a_head) == {'a': '2', 'pr': '1'}
pr0, pr1 = env['runbot_merge.pull_requests'].search([], order='number')
_pr0, pr1 = env['runbot_merge.pull_requests'].search([], order='number')
with a:
a.post_status(pr1.head, 'success', 'ci/runbot')
a.post_status(pr1.head, 'success')
env.run_crons()
pr0, pr1, pr2 = env['runbot_merge.pull_requests'].search([], order='number')
with a:
a.post_status(pr2.head, 'success', 'ci/runbot')
a.post_status(pr2.head, 'success')
a.get_pr(pr2.number).post_comment(
'hansen r+',
config['role_reviewer']['token'])
@ -305,9 +292,9 @@ class TestNotAllBranches:
assert pr1.staging_id
assert pr2.staging_id
with a, b:
a.post_status('staging.b', 'success', 'ci/runbot')
a.post_status('staging.c', 'success', 'ci/runbot')
b.post_status('staging.c', 'success', 'ci/runbot')
a.post_status('staging.b', 'success')
a.post_status('staging.c', 'success')
b.post_status('staging.c', 'success')
env.run_crons()
assert pr0.state == 'merged'
@ -319,31 +306,31 @@ class TestNotAllBranches:
def test_single_second(self, env, repos, config):
""" A merge in B.a should "skip ahead" to B.c
"""
project, a, _, b, b_dev = repos
_project, a, _, b, b_dev = repos
with b, b_dev:
[c] = b_dev.make_commits(b.commit('a').id, Commit('pr', tree={'pr': '1'}), ref='heads/change')
pr = b.make_pr(target='a', title="a pr", head=b_dev.owner + ':change')
b.post_status(c, 'success', 'ci/runbot')
b.post_status(c, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with a, b:
a.post_status('staging.a', 'success', 'ci/runbot')
b.post_status('staging.a', 'success', 'ci/runbot')
a.post_status('staging.a', 'success')
b.post_status('staging.a', 'success')
env.run_crons()
assert b.read_tree(b.commit('a')) == {'a': 'z', 'pr': '1'}
pr0, pr1 = env['runbot_merge.pull_requests'].search([], order='number')
with b:
b.post_status(pr1.head, 'success', 'ci/runbot')
b.post_status(pr1.head, 'success')
b.get_pr(pr1.number).post_comment(
'hansen r+',
config['role_reviewer']['token'])
env.run_crons()
with a, b:
a.post_status('staging.c', 'success', 'ci/runbot')
b.post_status('staging.c', 'success', 'ci/runbot')
a.post_status('staging.c', 'success')
b.post_status('staging.c', 'success')
env.run_crons()
assert pr0.state == 'merged'
@ -353,22 +340,22 @@ class TestNotAllBranches:
def test_both_first(self, env, repos, config, users):
""" A merge in A.a, B.a should... not be forward-ported at all?
"""
project, a, a_dev, b, b_dev = repos
_project, a, a_dev, b, b_dev = repos
with a, a_dev:
[c_a] = a_dev.make_commits(a.commit('a').id, Commit('pr a', tree={'pr': 'a'}), ref='heads/change')
pr_a = a.make_pr(target='a', title='a pr', head=a_dev.owner + ':change')
a.post_status(c_a, 'success', 'ci/runbot')
a.post_status(c_a, 'success')
pr_a.post_comment('hansen r+', config['role_reviewer']['token'])
with b, b_dev:
[c_b] = b_dev.make_commits(b.commit('a').id, Commit('pr b', tree={'pr': 'b'}), ref='heads/change')
pr_b = b.make_pr(target='a', title='b pr', head=b_dev.owner + ':change')
b.post_status(c_b, 'success', 'ci/runbot')
b.post_status(c_b, 'success')
pr_b.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with a, b:
for repo in a, b:
repo.post_status('staging.a', 'success', 'ci/runbot')
repo.post_status('staging.a', 'success')
env.run_crons()
pr_a_id = to_pr(env, pr_a)
@ -404,11 +391,8 @@ def test_new_intermediate_branch(env, config, make_repo):
1.0, 2.0 and master, if a branch 3.0 is forked off from master and inserted
before it, we need to create a new *intermediate* forward port PR
"""
def validate(repo, commit):
repo.post_status(commit, 'success', 'ci/runbot')
repo.post_status(commit, 'success', 'legal/cla')
prod, _ = make_basic(env, config, make_repo)
prod2, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
prod2, _ = make_basic(env, config, make_repo, statuses='default')
project = env['runbot_merge.project'].search([])
assert len(project.repo_ids) == 2
@ -419,7 +403,7 @@ def test_new_intermediate_branch(env, config, make_repo):
prod.make_commits('a', Commit(i, tree={i:i}), ref='heads/branch%s' % i)
pr = prod.make_pr(target='a', head='branch%s' % i)
prs.append(pr)
validate(prod, pr.head)
prod.post_status(pr.head, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
# also add a PR targeting b forward-ported to c, in order to check
@ -429,15 +413,15 @@ def test_new_intermediate_branch(env, config, make_repo):
prod2.make_commits('b', Commit('x2', tree={'x': 'x2'}), ref='heads/branchx')
prx = prod.make_pr(target='b', head='branchx')
prx2 = prod2.make_pr(target='b', head='branchx')
validate(prod, prx.head)
validate(prod2, prx2.head)
prod.post_status(prx.head, 'success')
prod2.post_status(prx2.head, 'success')
prx.post_comment('hansen r+', config['role_reviewer']['token'])
prx2.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod, prod2:
for r in [prod, prod2]:
validate(r, 'staging.a')
validate(r, 'staging.b')
r.post_status('staging.a', 'success')
r.post_status('staging.b', 'success')
env.run_crons()
# should have merged pr1, pr2 and prx and created their forward ports, now
@ -450,7 +434,7 @@ def test_new_intermediate_branch(env, config, make_repo):
assert pr0_fp_id
assert pr0_fp_id.target.name == 'b'
with prod:
validate(prod, pr0_fp_id.head)
prod.post_status(pr0_fp_id.head, 'success')
env.run_crons()
assert pr0_fp_id.state == 'validated'
original0 = PRs.search([('parent_id', '=', pr0_fp_id.id)])
@ -549,7 +533,8 @@ def test_new_intermediate_branch(env, config, make_repo):
fps = PRs.search([('source_id', 'in', sources), ('target.name', '=', ['new', 'c'])])
with prod, prod2:
for fp in fps:
validate(get_repo(fp), fp.head)
repo = get_repo(fp)
repo.post_status(fp.head, 'success')
env.run_crons()
# now fps should be the last PR of each sequence, and thus r+-able (via
# fwbot so preceding PR is also r+'d)
@ -568,8 +553,8 @@ def test_new_intermediate_branch(env, config, make_repo):
"enabled branches should have been staged"
with prod, prod2:
for target in ['new', 'c']:
validate(prod, f'staging.{target}')
validate(prod2, f'staging.{target}')
prod.post_status(f'staging.{target}', 'success')
prod2.post_status(f'staging.{target}', 'success')
env.run_crons()
assert all(p.state == 'merged' for p in PRs.search([('target.name', '!=', 'b')])), \
"All PRs except disabled branch should be merged now"
@ -586,7 +571,7 @@ def test_new_intermediate_branch(env, config, make_repo):
}, "check that new got all the updates (should be in the same state as c really)"
def test_author_can_close_via_fwbot(env, config, make_repo):
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
other_user = config['role_other']
other_token = other_user['token']
other = prod.fork(token=other_token)
@ -601,16 +586,14 @@ def test_author_can_close_via_fwbot(env, config, make_repo):
# should be able to close and open own PR
pr.close(other_token)
pr.open(other_token)
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success')
pr.post_comment('hansen close', other_token)
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
assert pr.state == 'open'
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
pr0_id, pr1_id = env['runbot_merge.pull_requests'].search([], order='number')
@ -629,21 +612,19 @@ def test_author_can_close_via_fwbot(env, config, make_repo):
assert pr1_id.state == 'closed'
def test_skip_ci_all(env, config, make_repo):
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
with prod:
prod.make_commits('a', Commit('x', tree={'x': '0'}), ref='heads/change')
pr = prod.make_pr(target='a', head='change')
prod.post_status(pr.head, 'success', 'legal/cla')
prod.post_status(pr.head, 'success', 'ci/runbot')
prod.post_status(pr.head, 'success')
pr.post_comment('hansen fw=skipci', config['role_reviewer']['token'])
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
assert to_pr(env, pr).batch_id.fw_policy == 'skipci'
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
# run cron a few more times for the fps
@ -658,19 +639,17 @@ def test_skip_ci_all(env, config, make_repo):
assert pr2_id.source_id == pr0_id
def test_skip_ci_next(env, config, make_repo):
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
with prod:
prod.make_commits('a', Commit('x', tree={'x': '0'}), ref='heads/change')
pr = prod.make_pr(target='a', head='change')
prod.post_status(pr.head, 'success', 'legal/cla')
prod.post_status(pr.head, 'success', 'ci/runbot')
prod.post_status(pr.head, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.a', 'success', 'legal/cla')
prod.post_status('staging.a', 'success', 'ci/runbot')
prod.post_status('staging.a', 'success')
env.run_crons()
pr0_id, pr1_id = env['runbot_merge.pull_requests'].search([], order='number')
@ -696,13 +675,12 @@ def test_retarget_after_freeze(env, config, make_repo, users):
latter port. In that case the reinsertion task should just do nothing, and
the retargeted PR should be forward-ported normally once merged.
"""
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
project = env['runbot_merge.project'].search([])
with prod:
[c] = prod.make_commits('b', Commit('thing', tree={'x': '1'}), ref='heads/mypr')
pr = prod.make_pr(target='b', head='mypr')
prod.post_status(c, 'success', 'ci/runbot')
prod.post_status(c, 'success', 'legal/cla')
prod.post_status(c, 'success')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
@ -711,8 +689,7 @@ def test_retarget_after_freeze(env, config, make_repo, users):
assert original_pr_id.staging_id
with prod:
prod.post_status('staging.b', 'success', 'ci/runbot')
prod.post_status('staging.b', 'success', 'legal/cla')
prod.post_status('staging.b', 'success')
env.run_crons()
# should have created a pr targeted to C
port_id = env['runbot_merge.pull_requests'].search([('state', 'not in', ('merged', 'closed'))])
@ -755,13 +732,11 @@ def test_retarget_after_freeze(env, config, make_repo, users):
# merge the retargered PR
with prod:
prod.post_status(port_pr.head, 'success', 'ci/runbot')
prod.post_status(port_pr.head, 'success', 'legal/cla')
prod.post_status(port_pr.head, 'success')
port_pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons()
with prod:
prod.post_status('staging.bprime', 'success', 'ci/runbot')
prod.post_status('staging.bprime', 'success', 'legal/cla')
prod.post_status('staging.bprime', 'success')
env.run_crons()
# #2 batch 6 (???)
@ -773,7 +748,7 @@ def test_retarget_after_freeze(env, config, make_repo, users):
assert new_pr_id.target == branch_c
def test_approve_draft(env, config, make_repo, users):
prod, _ = make_basic(env, config, make_repo)
prod, _ = make_basic(env, config, make_repo, statuses='default')
with prod:
prod.make_commits('a', Commit('x', tree={'x': '0'}), ref='heads/change')

View File

@ -24,7 +24,7 @@ class Commit:
self.tree = tree
self.reset = reset
def validate_all(repos, refs, contexts=('ci/runbot', 'legal/cla')):
def validate_all(repos, refs, contexts=('default',)):
""" Post a "success" status for each context on each ref of each repo
"""
for repo, branch, context in itertools.product(repos, refs, contexts):
@ -76,7 +76,7 @@ def make_basic(
*,
project_name='myproject',
reponame='proj',
statuses='legal/cla,ci/runbot',
statuses,
fp_token=True,
fp_remote=True,
):

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,6 @@ import pytest
from utils import seen, Commit, pr_page, to_pr
pytestmark = pytest.mark.defaultstatuses
def test_existing_pr_disabled_branch(env, project, repo, config, users, page):
""" PRs to disabled branches are ignored, but what if the PR exists *before*
the branch is disabled?
@ -37,7 +35,7 @@ def test_existing_pr_disabled_branch(env, project, repo, config, users, page):
assert staging_id == pr_id.staging_id
# staging of `pr` should have generated a staging branch
_ = repo.get_ref('heads/staging.other')
_ = repo.get_ref('staging.other')
# disable branch "other"
branch_id.active = False
@ -46,7 +44,7 @@ def test_existing_pr_disabled_branch(env, project, repo, config, users, page):
# triggered cleanup should have deleted the staging for the disabled `other`
# target branch
with pytest.raises(AssertionError, match=r'Not Found'):
repo.get_ref('heads/staging.other')
repo.get_ref('staging.other')
# the PR should not have been closed implicitly
assert pr_id.state == 'ready'

View File

@ -1,4 +1,3 @@
import datetime
import functools
from itertools import repeat

View File

@ -1,4 +1,4 @@
from utils import Commit, to_pr, make_basic, prevent_unstaging
from utils import Commit, to_pr, prevent_unstaging
def test_staging_disabled_branch(env, project, repo, config):