mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 23:45:44 +07:00
[IMP] runbot_merge: pluginify github mock
This is the preparation of an attempt to make these tests work with both a local github mock (in-memory) and a remote actual github. Move a bunch of fixtures relying on the specific github implementation (and odoo-as-library access) to the "local" plugin, including splitting the "repo" fixture. The specific fixtures will likely have to be adjusted as the remote endpoint is fleshed out.
This commit is contained in:
parent
5e64f79730
commit
d98d40389d
@ -1,57 +1,5 @@
|
||||
import odoo
|
||||
|
||||
import pytest
|
||||
|
||||
import fake_github
|
||||
|
||||
@pytest.fixture
|
||||
def gh():
|
||||
with fake_github.Github() as gh:
|
||||
yield gh
|
||||
pytest_plugins = ["local"]
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption("--db", action="store", help="Odoo DB to run tests with")
|
||||
parser.addoption('--addons-path', action='store', help="Odoo's addons path")
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def registry(request):
|
||||
""" Set up Odoo & yields a registry to the specified db
|
||||
"""
|
||||
db = request.config.getoption('--db')
|
||||
addons = request.config.getoption('--addons-path')
|
||||
odoo.tools.config.parse_config(['--addons-path', addons, '-d', db, '--db-filter', db])
|
||||
try:
|
||||
odoo.service.db._create_empty_database(db)
|
||||
except odoo.service.db.DatabaseExists:
|
||||
pass
|
||||
|
||||
#odoo.service.server.load_server_wide_modules()
|
||||
#odoo.service.server.preload_registries([db])
|
||||
|
||||
with odoo.api.Environment.manage():
|
||||
# ensure module is installed
|
||||
r0 = odoo.registry(db)
|
||||
with r0.cursor() as cr:
|
||||
env = odoo.api.Environment(cr, 1, {})
|
||||
[mod] = env['ir.module.module'].search([('name', '=', 'runbot_merge')])
|
||||
mod.button_immediate_install()
|
||||
|
||||
yield odoo.registry(db)
|
||||
|
||||
@pytest.fixture
|
||||
def env(request, registry):
|
||||
"""Generates an environment, can be parameterized on a user's login
|
||||
"""
|
||||
with registry.cursor() as cr:
|
||||
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
||||
login = getattr(request, 'param', 'admin')
|
||||
if login != 'admin':
|
||||
user = env['res.users'].search([('login', '=', login)], limit=1)
|
||||
env = odoo.api.Environment(cr, user.id, {})
|
||||
ctx = env['res.users'].context_get()
|
||||
registry.enter_test_mode(cr)
|
||||
yield env(context=ctx)
|
||||
registry.leave_test_mode()
|
||||
|
||||
cr.rollback()
|
||||
|
||||
|
@ -192,6 +192,12 @@ class Repo(object):
|
||||
return handler(self, request, **m.groupdict())
|
||||
return (404, {'message': "No match for {} {}".format(request.method, path)})
|
||||
|
||||
def read_tree(self, commit):
|
||||
return git.read_object(self.objects, commit.tree)
|
||||
|
||||
def is_ancestor(self, sha, of):
|
||||
assert not git.is_ancestor(self.objects, sha, of=of)
|
||||
|
||||
def _read_ref(self, r, ref):
|
||||
obj = self.refs.get(ref)
|
||||
if obj is None:
|
||||
|
84
runbot_merge/tests/local.py
Normal file
84
runbot_merge/tests/local.py
Normal file
@ -0,0 +1,84 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import odoo
|
||||
import pytest
|
||||
import fake_github
|
||||
|
||||
@pytest.fixture
|
||||
def gh():
|
||||
with fake_github.Github() as gh:
|
||||
yield gh
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def registry(request):
|
||||
""" Set up Odoo & yields a registry to the specified db
|
||||
"""
|
||||
db = request.config.getoption('--db')
|
||||
addons = request.config.getoption('--addons-path')
|
||||
odoo.tools.config.parse_config(['--addons-path', addons, '-d', db, '--db-filter', db])
|
||||
try:
|
||||
odoo.service.db._create_empty_database(db)
|
||||
except odoo.service.db.DatabaseExists:
|
||||
pass
|
||||
|
||||
#odoo.service.server.load_server_wide_modules()
|
||||
#odoo.service.server.preload_registries([db])
|
||||
|
||||
with odoo.api.Environment.manage():
|
||||
# ensure module is installed
|
||||
r0 = odoo.registry(db)
|
||||
with r0.cursor() as cr:
|
||||
env = odoo.api.Environment(cr, 1, {})
|
||||
[mod] = env['ir.module.module'].search([('name', '=', 'runbot_merge')])
|
||||
mod.button_immediate_install()
|
||||
|
||||
yield odoo.registry(db)
|
||||
|
||||
@pytest.fixture
|
||||
def env(registry):
|
||||
with registry.cursor() as cr:
|
||||
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
||||
ctx = env['res.users'].context_get()
|
||||
registry.enter_test_mode(cr)
|
||||
yield env(context=ctx)
|
||||
registry.leave_test_mode()
|
||||
|
||||
cr.rollback()
|
||||
|
||||
@pytest.fixture
|
||||
def project(env):
|
||||
env['res.partner'].create({
|
||||
'name': "Reviewer",
|
||||
'github_login': 'reviewer',
|
||||
'reviewer': True,
|
||||
})
|
||||
env['res.partner'].create({
|
||||
'name': "Self Reviewer",
|
||||
'github_login': 'self-reviewer',
|
||||
'self_reviewer': True,
|
||||
})
|
||||
env['res.partner'].create({
|
||||
'name': "Other",
|
||||
'github_login': 'other',
|
||||
})
|
||||
return env['runbot_merge.project'].create({
|
||||
'name': 'odoo',
|
||||
'github_token': 'okokok',
|
||||
'github_prefix': 'hansen',
|
||||
'branch_ids': [(0, 0, {'name': 'master'})],
|
||||
'required_statuses': 'legal/cla,ci/runbot',
|
||||
})
|
||||
|
||||
@pytest.fixture
|
||||
def make_repo(gh, project):
|
||||
def make_repo(name):
|
||||
fullname = 'org/' + name
|
||||
project.write({'repo_ids': [(0, 0, {'name': fullname})]})
|
||||
return gh.repo(fullname, hooks=[
|
||||
((odoo.http.root, '/runbot_merge/hooks'), [
|
||||
'pull_request', 'issue_comment', 'status', 'pull_request_review'
|
||||
])
|
||||
])
|
||||
return make_repo
|
||||
# TODO: project fixture
|
||||
# TODO: repos (indirect/parameterize?) w/ WS hook
|
||||
# + repo proxy object
|
@ -7,35 +7,8 @@ import odoo
|
||||
from fake_github import git
|
||||
|
||||
@pytest.fixture
|
||||
def repo(gh, env):
|
||||
env['res.partner'].create({
|
||||
'name': "Reviewer",
|
||||
'github_login': 'reviewer',
|
||||
'reviewer': True,
|
||||
})
|
||||
env['res.partner'].create({
|
||||
'name': "Self Reviewer",
|
||||
'github_login': 'self-reviewer',
|
||||
'self_reviewer': True,
|
||||
})
|
||||
env['res.partner'].create({
|
||||
'name': "Other",
|
||||
'github_login': 'other',
|
||||
})
|
||||
env['runbot_merge.project'].create({
|
||||
'name': 'odoo',
|
||||
'github_token': 'okokok',
|
||||
'github_prefix': 'hansen',
|
||||
'repo_ids': [(0, 0, {'name': 'odoo/odoo'})],
|
||||
'branch_ids': [(0, 0, {'name': 'master'})],
|
||||
'required_statuses': 'legal/cla,ci/runbot',
|
||||
})
|
||||
# need to create repo & branch in env so hook will allow processing them
|
||||
return gh.repo('odoo/odoo', hooks=[
|
||||
((odoo.http.root, '/runbot_merge/hooks'), [
|
||||
'pull_request', 'issue_comment', 'status', 'pull_request_review',
|
||||
])
|
||||
])
|
||||
def repo(make_repo):
|
||||
return make_repo('repo')
|
||||
|
||||
def test_trivial_flow(env, repo):
|
||||
# create base branch
|
||||
@ -48,7 +21,7 @@ def test_trivial_flow(env, repo):
|
||||
pr1 = repo.make_pr("gibberish", "blahblah", target='master', ctid=c1, user='user')
|
||||
|
||||
[pr] = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', pr1.number),
|
||||
])
|
||||
assert pr.state == 'opened'
|
||||
@ -83,7 +56,7 @@ def test_trivial_flow(env, repo):
|
||||
master = repo.commit('heads/master')
|
||||
assert master.parents == [m, pr1.head],\
|
||||
"master's parents should be the old master & the PR head"
|
||||
assert git.read_object(repo.objects, master.tree) == {
|
||||
assert repo.read_tree(master) == {
|
||||
'a': b'some other content',
|
||||
'b': b'a second file',
|
||||
}
|
||||
@ -103,7 +76,7 @@ def test_staging_conflict(env, repo):
|
||||
pr1.post_comment("hansen r+", "reviewer")
|
||||
env['runbot_merge.project']._check_progress()
|
||||
pr1 = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', 1)
|
||||
])
|
||||
assert pr1.staging_id
|
||||
@ -117,7 +90,7 @@ def test_staging_conflict(env, repo):
|
||||
pr2.post_comment('hansen r+', "reviewer")
|
||||
env['runbot_merge.project']._check_progress()
|
||||
p_2 = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', 2)
|
||||
])
|
||||
assert p_2.state == 'ready', "PR2 should not have been staged since there is a pending staging for master"
|
||||
@ -162,12 +135,12 @@ def test_staging_concurrent(env, repo):
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
pr1 = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', pr1.number)
|
||||
])
|
||||
assert pr1.staging_id
|
||||
pr2 = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', pr2.number)
|
||||
])
|
||||
assert pr2.staging_id
|
||||
@ -188,7 +161,7 @@ def test_staging_merge_fail(env, repo):
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
pr1 = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
])
|
||||
assert pr1.state == 'error'
|
||||
@ -214,7 +187,7 @@ def test_staging_ci_timeout(env, repo):
|
||||
env['runbot_merge.project']._check_progress()
|
||||
|
||||
pr1 = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
])
|
||||
assert pr1.staging_id
|
||||
@ -238,7 +211,7 @@ def test_staging_ci_failure_single(env, repo):
|
||||
prx.post_comment('hansen r+', "reviewer")
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id
|
||||
|
||||
@ -247,7 +220,7 @@ def test_staging_ci_failure_single(env, repo):
|
||||
repo.post_status(staging_head.id, 'failure', 'ci/runbot') # stable genius
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'error'
|
||||
|
||||
@ -269,7 +242,7 @@ def test_ff_failure(env, repo):
|
||||
prx.post_comment('hansen r+', "reviewer")
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id
|
||||
|
||||
@ -283,7 +256,7 @@ def test_ff_failure(env, repo):
|
||||
env['runbot_merge.project']._check_progress()
|
||||
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id, "merge should not have succeeded"
|
||||
assert repo.commit('heads/staging.master').id != staging.id,\
|
||||
@ -310,7 +283,7 @@ def test_edit(env, repo):
|
||||
c2 = repo.make_commit(c1, 'second', None, tree={'m': 'c2'})
|
||||
prx = repo.make_pr('title', 'body', target='master', ctid=c2, user='user')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
])
|
||||
assert pr.message == 'title\n\nbody'
|
||||
@ -326,7 +299,7 @@ def test_edit(env, repo):
|
||||
|
||||
prx.base = '1.0'
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).target == branch_1
|
||||
|
||||
@ -355,7 +328,7 @@ def test_close_staged(env, repo):
|
||||
repo.post_status(prx.head, 'success', 'ci/runbot')
|
||||
prx.post_comment('hansen r+', user='reviewer')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
env['runbot_merge.project']._check_progress()
|
||||
@ -381,7 +354,7 @@ class TestRetry:
|
||||
prx.post_comment('hansen r+', "reviewer")
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id
|
||||
|
||||
@ -390,7 +363,7 @@ class TestRetry:
|
||||
repo.post_status(staging_head.id, 'failure', 'ci/runbot')
|
||||
env['runbot_merge.project']._check_progress()
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
])
|
||||
assert pr.state == 'error'
|
||||
@ -427,7 +400,7 @@ class TestRetry:
|
||||
prx.post_comment('hansen r+ delegate=other', "reviewer")
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id
|
||||
|
||||
@ -436,13 +409,13 @@ class TestRetry:
|
||||
repo.post_status(staging_head.id, 'failure', 'ci/runbot')
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'error'
|
||||
|
||||
prx.post_comment('hansen retry', retrier)
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'ready'
|
||||
env['runbot_merge.project']._check_progress()
|
||||
@ -453,7 +426,7 @@ class TestRetry:
|
||||
repo.post_status(staging_head2.id, 'success', 'ci/runbot')
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'merged'
|
||||
|
||||
@ -470,7 +443,7 @@ class TestRetry:
|
||||
prx.post_comment('hansen r+ delegate=other', "reviewer")
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id
|
||||
|
||||
@ -479,7 +452,7 @@ class TestRetry:
|
||||
repo.post_status(staging_head.id, 'failure', 'ci/runbot')
|
||||
env['runbot_merge.project']._check_progress()
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
])
|
||||
assert pr.state == 'error'
|
||||
@ -508,22 +481,22 @@ class TestSquashing(object):
|
||||
repo.post_status(prx.head, 'success', 'ci/runbot')
|
||||
prx.post_comment('hansen r+', "reviewer")
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).squash
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id
|
||||
|
||||
staging = repo.commit('heads/staging.master')
|
||||
assert not git.is_ancestor(repo.objects, prx.head, of=staging.id),\
|
||||
assert not repo.is_ancestor(prx.head, of=staging.id),\
|
||||
"the pr head should not be an ancestor of the staging branch in a squash merge"
|
||||
assert staging.parents == [m2],\
|
||||
"the previous master's tip should be the sole parent of the staging commit"
|
||||
assert git.read_object(repo.objects, staging.tree) == {
|
||||
assert repo.read_tree(staging) == {
|
||||
'm': b'c1', 'm2': b'm2',
|
||||
}, "the tree should still be correctly merged"
|
||||
|
||||
@ -531,7 +504,7 @@ class TestSquashing(object):
|
||||
repo.post_status(staging.id, 'success', 'ci/runbot')
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'merged'
|
||||
assert prx.state == 'closed'
|
||||
@ -548,7 +521,7 @@ class TestSquashing(object):
|
||||
c1 = repo.make_commit(m, 'first', None, tree={'m': 'c1'})
|
||||
prx = repo.make_pr('title', 'body', target='master', ctid=c1, user='user')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
assert pr.squash, "a PR with a single commit should be squashed"
|
||||
@ -569,7 +542,7 @@ class TestSquashing(object):
|
||||
c2 = repo.make_commit(c1, 'second2', None, tree={'m': 'c2'})
|
||||
prx = repo.make_pr('title', 'body', target='master', ctid=c2, user='user')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
assert not pr.squash, "a PR with a single commit should not be squashed"
|
||||
@ -590,22 +563,22 @@ class TestSquashing(object):
|
||||
repo.post_status(prx.head, 'success', 'ci/runbot')
|
||||
prx.post_comment('hansen r+ squash+', "reviewer")
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).squash
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id
|
||||
|
||||
staging = repo.commit('heads/staging.master')
|
||||
assert not git.is_ancestor(repo.objects, prx.head, of=staging.id),\
|
||||
assert not repo.is_ancestor(prx.head, of=staging.id),\
|
||||
"the pr head should not be an ancestor of the staging branch in a squash merge"
|
||||
assert staging.parents == [m2],\
|
||||
"the previous master's tip should be the sole parent of the staging commit"
|
||||
assert git.read_object(repo.objects, staging.tree) == {
|
||||
assert repo.read_tree(staging) == {
|
||||
'm': b'c2', 'm2': b'm2',
|
||||
}, "the tree should still be correctly merged"
|
||||
|
||||
@ -613,7 +586,7 @@ class TestSquashing(object):
|
||||
repo.post_status(staging.id, 'success', 'ci/runbot')
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'merged'
|
||||
assert prx.state == 'closed'
|
||||
@ -630,20 +603,20 @@ class TestSquashing(object):
|
||||
repo.post_status(prx.head, 'success', 'ci/runbot')
|
||||
prx.post_comment('hansen r+ squash-', "reviewer")
|
||||
assert not env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).squash
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).staging_id
|
||||
|
||||
staging = repo.commit('heads/staging.master')
|
||||
assert git.is_ancestor(repo.objects, prx.head, of=staging.id)
|
||||
assert repo.is_ancestor(prx.head, of=staging.id)
|
||||
assert staging.parents == [m2, c1]
|
||||
assert git.read_object(repo.objects, staging.tree) == {
|
||||
assert repo.read_tree(staging) == {
|
||||
'm': b'c1', 'm2': b'm2',
|
||||
}
|
||||
|
||||
@ -651,7 +624,7 @@ class TestSquashing(object):
|
||||
repo.post_status(staging.id, 'success', 'ci/runbot')
|
||||
env['runbot_merge.project']._check_progress()
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'merged'
|
||||
assert prx.state == 'closed'
|
||||
@ -668,7 +641,7 @@ class TestPRUpdate(object):
|
||||
c = repo.make_commit(m, 'fist', None, tree={'m': 'c1'})
|
||||
prx = repo.make_pr('title', 'body', target='master', ctid=c, user='user')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
assert pr.head == c
|
||||
@ -686,7 +659,7 @@ class TestPRUpdate(object):
|
||||
c = repo.make_commit(m, 'fist', None, tree={'m': 'c1'})
|
||||
prx = repo.make_pr('title', 'body', target='master', ctid=c, user='user')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
prx.close()
|
||||
@ -707,7 +680,7 @@ class TestPRUpdate(object):
|
||||
c = repo.make_commit(m, 'fist', None, tree={'m': 'c1'})
|
||||
prx = repo.make_pr('title', 'body', target='master', ctid=c, user='user')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
prx.close()
|
||||
@ -732,7 +705,7 @@ class TestPRUpdate(object):
|
||||
repo.post_status(prx.head, 'success', 'legal/cla')
|
||||
repo.post_status(prx.head, 'success', 'ci/runbot')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
assert pr.head == c
|
||||
@ -751,7 +724,7 @@ class TestPRUpdate(object):
|
||||
prx = repo.make_pr('title', 'body', target='master', ctid=c, user='user')
|
||||
prx.post_comment('hansen r+', user='reviewer')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
assert pr.head == c
|
||||
@ -774,7 +747,7 @@ class TestPRUpdate(object):
|
||||
repo.post_status(prx.head, 'success', 'ci/runbot')
|
||||
prx.post_comment('hansen r+', user='reviewer')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
assert pr.head == c
|
||||
@ -797,7 +770,7 @@ class TestPRUpdate(object):
|
||||
repo.post_status(prx.head, 'success', 'ci/runbot')
|
||||
prx.post_comment('hansen r+', user='reviewer')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
env['runbot_merge.project']._check_progress()
|
||||
@ -825,7 +798,7 @@ class TestPRUpdate(object):
|
||||
env['runbot_merge.project']._check_progress()
|
||||
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
h = repo.commit('heads/staging.master').id
|
||||
@ -854,7 +827,7 @@ class TestPRUpdate(object):
|
||||
repo.post_status(prx.head, 'success', 'ci/runbot')
|
||||
prx.post_comment('hansen r+', user='reviewer')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number),
|
||||
])
|
||||
env['runbot_merge.project']._check_progress()
|
||||
@ -897,6 +870,7 @@ class TestBatching(object):
|
||||
):
|
||||
""" Helper creating a PR from a series of commits on a base
|
||||
|
||||
:type repo: fake_github.Repo
|
||||
:param prefix: a prefix used for commit messages, PR title & PR body
|
||||
:param trees: a list of dicts symbolising the tree for the corresponding commit.
|
||||
each tree is an update on the "current state" of the tree
|
||||
@ -907,7 +881,7 @@ class TestBatching(object):
|
||||
:type statuses: List[(str, str)]
|
||||
"""
|
||||
base = repo.commit('heads/{}'.format(target))
|
||||
tree = dict(repo.objects[base.tree])
|
||||
tree = repo.read_tree(base)
|
||||
c = base.id
|
||||
for i, t in enumerate(trees):
|
||||
tree.update(t)
|
||||
@ -920,9 +894,9 @@ class TestBatching(object):
|
||||
pr.post_comment('hansen r+', reviewer)
|
||||
return pr
|
||||
|
||||
def _get(self, env, number):
|
||||
def _get(self, env, repo, number):
|
||||
return env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', number),
|
||||
])
|
||||
|
||||
@ -937,9 +911,9 @@ class TestBatching(object):
|
||||
pr2 = self._pr(repo, 'PR2', [{'c': 'CCC'}, {'d': 'DDD'}])
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
pr1 = self._get(env, pr1.number)
|
||||
pr1 = self._get(env, repo, pr1.number)
|
||||
assert pr1.staging_id
|
||||
pr2 = self._get(env, pr2.number)
|
||||
pr2 = self._get(env, repo, pr2.number)
|
||||
assert pr1.staging_id
|
||||
assert pr2.staging_id
|
||||
assert pr1.staging_id == pr2.staging_id
|
||||
@ -958,7 +932,7 @@ class TestBatching(object):
|
||||
pr11.post_comment('hansen priority=1', 'reviewer')
|
||||
pr12.post_comment('hansen priority=1', 'reviewer')
|
||||
|
||||
pr21, pr22, pr11, pr12 = prs = [self._get(env, pr.number) for pr in [pr21, pr22, pr11, pr12]]
|
||||
pr21, pr22, pr11, pr12 = prs = [self._get(env, repo, pr.number) for pr in [pr21, pr22, pr11, pr12]]
|
||||
assert pr21.priority == pr22.priority == 2
|
||||
assert pr11.priority == pr12.priority == 1
|
||||
|
||||
@ -986,7 +960,7 @@ class TestBatching(object):
|
||||
# stage PR1
|
||||
env['runbot_merge.project']._check_progress()
|
||||
p_11, p_12, p_21, p_22 = \
|
||||
[self._get(env, pr.number) for pr in [pr11, pr12, pr21, pr22]]
|
||||
[self._get(env, repo, pr.number) for pr in [pr11, pr12, pr21, pr22]]
|
||||
assert not p_21.staging_id or p_22.staging_id
|
||||
assert p_11.staging_id and p_12.staging_id
|
||||
assert p_11.staging_id == p_12.staging_id
|
||||
@ -995,7 +969,7 @@ class TestBatching(object):
|
||||
# no statuses run on PR0s
|
||||
pr01 = self._pr(repo, 'Urgent 1', [{'n': 'n'}, {'o': 'o'}], reviewer=None, statuses=[])
|
||||
pr01.post_comment('hansen priority=0', 'reviewer')
|
||||
p_01 = self._get(env, pr01.number)
|
||||
p_01 = self._get(env, repo, pr01.number)
|
||||
assert p_01.state == 'opened'
|
||||
assert p_01.priority == 0
|
||||
|
||||
@ -1014,9 +988,9 @@ class TestBatching(object):
|
||||
repo.make_ref('heads/master', m)
|
||||
|
||||
pr1 = self._pr(repo, 'PR1', [{'a': 'AAA'}, {'b': 'BBB'}])
|
||||
p_1 = self._get(env, pr1.number)
|
||||
p_1 = self._get(env, repo, pr1.number)
|
||||
pr2 = self._pr(repo, 'PR2', [{'a': 'some_content', 'c': 'CCC'}, {'d': 'DDD'}])
|
||||
p_2 = self._get(env, pr2.number)
|
||||
p_2 = self._get(env, repo, pr2.number)
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
st = env['runbot_merge.stagings'].search([])
|
||||
@ -1038,7 +1012,7 @@ class TestBatching(object):
|
||||
env['runbot_merge.project']._check_progress()
|
||||
# TODO: maybe just deactivate stagings instead of deleting them when canceling?
|
||||
assert not p_1.staging_id
|
||||
assert self._get(env, pr0.number).staging_id
|
||||
assert self._get(env, repo, pr0.number).staging_id
|
||||
|
||||
def test_urgent_failed(self, env, repo):
|
||||
""" Ensure pr[p=0,state=failed] don't get picked up
|
||||
@ -1048,12 +1022,12 @@ class TestBatching(object):
|
||||
|
||||
pr21 = self._pr(repo, 'PR1', [{'a': 'AAA'}, {'b': 'BBB'}])
|
||||
|
||||
p_21 = self._get(env, pr21.number)
|
||||
p_21 = self._get(env, repo, pr21.number)
|
||||
|
||||
# no statuses run on PR0s
|
||||
pr01 = self._pr(repo, 'Urgent 1', [{'n': 'n'}, {'o': 'o'}], reviewer=None, statuses=[])
|
||||
pr01.post_comment('hansen priority=0', 'reviewer')
|
||||
p_01 = self._get(env, pr01.number)
|
||||
p_01 = self._get(env, repo, pr01.number)
|
||||
p_01.state = 'error'
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
@ -1122,12 +1096,12 @@ class TestReviewing(object):
|
||||
prx.post_comment('hansen r+', user='rando')
|
||||
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'validated'
|
||||
prx.post_comment('hansen r+', user='reviewer')
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'ready'
|
||||
|
||||
@ -1146,7 +1120,7 @@ class TestReviewing(object):
|
||||
|
||||
assert prx.user == 'reviewer'
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'validated'
|
||||
|
||||
@ -1165,7 +1139,7 @@ class TestReviewing(object):
|
||||
|
||||
assert prx.user == 'self-reviewer'
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'ready'
|
||||
|
||||
@ -1186,7 +1160,7 @@ class TestReviewing(object):
|
||||
|
||||
assert prx.user == 'user'
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'ready'
|
||||
|
||||
@ -1207,13 +1181,13 @@ class TestReviewing(object):
|
||||
|
||||
assert prx.user == 'user'
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'validated'
|
||||
|
||||
prx.post_comment('hansen r+', user='jimbob')
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
]).state == 'ready'
|
||||
|
||||
@ -1225,7 +1199,7 @@ class TestReviewing(object):
|
||||
c1 = repo.make_commit(m, 'first', None, tree={'m': 'c1'})
|
||||
prx = repo.make_pr('title', 'body', target='master', ctid=c1, user='user')
|
||||
pr = env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', 'odoo/odoo'),
|
||||
('repository.name', '=', repo.name),
|
||||
('number', '=', prx.number)
|
||||
])
|
||||
|
||||
|
@ -7,50 +7,19 @@ are staged concurrently in all repos
|
||||
"""
|
||||
import json
|
||||
|
||||
import odoo
|
||||
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def project(env):
|
||||
env['res.partner'].create({
|
||||
'name': "Reviewer",
|
||||
'github_login': 'reviewer',
|
||||
'reviewer': True,
|
||||
})
|
||||
env['res.partner'].create({
|
||||
'name': "Self Reviewer",
|
||||
'github_login': 'self-reviewer',
|
||||
'self_reviewer': True,
|
||||
})
|
||||
return env['runbot_merge.project'].create({
|
||||
'name': 'odoo',
|
||||
'github_token': 'okokok',
|
||||
'github_prefix': 'hansen',
|
||||
'branch_ids': [(0, 0, {'name': 'master'})],
|
||||
'required_statuses': 'legal/cla,ci/runbot',
|
||||
})
|
||||
def repo_a(make_repo):
|
||||
return make_repo('a')
|
||||
|
||||
@pytest.fixture
|
||||
def repo_a(gh, project):
|
||||
project.write({'repo_ids': [(0, 0, {'name': "odoo/a"})]})
|
||||
return gh.repo('odoo/a', hooks=[
|
||||
((odoo.http.root, '/runbot_merge/hooks'), ['pull_request', 'issue_comment', 'status', 'pull_request_review'])
|
||||
])
|
||||
def repo_b(make_repo):
|
||||
return make_repo('b')
|
||||
|
||||
@pytest.fixture
|
||||
def repo_b(gh, project):
|
||||
project.write({'repo_ids': [(0, 0, {'name': "odoo/b"})]})
|
||||
return gh.repo('odoo/b', hooks=[
|
||||
((odoo.http.root, '/runbot_merge/hooks'), ['pull_request', 'issue_comment', 'status'])
|
||||
])
|
||||
|
||||
@pytest.fixture
|
||||
def repo_c(gh, project):
|
||||
project.write({'repo_ids': [(0, 0, {'name': "odoo/c"})]})
|
||||
return gh.repo('odoo/c', hooks=[
|
||||
((odoo.http.root, '/runbot_merge/hooks'), ['pull_request', 'issue_comment', 'status'])
|
||||
])
|
||||
def repo_c(make_repo):
|
||||
return make_repo('c')
|
||||
|
||||
def make_pr(repo, prefix, trees, *, target='master', user='user', label=None,
|
||||
statuses=(('ci/runbot', 'success'), ('legal/cla', 'success')),
|
||||
@ -67,7 +36,7 @@ def make_pr(repo, prefix, trees, *, target='master', user='user', label=None,
|
||||
:rtype: fake_github.PR
|
||||
"""
|
||||
base = repo.commit('heads/{}'.format(target))
|
||||
tree = dict(repo.objects[base.tree])
|
||||
tree = repo.read_tree(base)
|
||||
c = base.id
|
||||
for i, t in enumerate(trees):
|
||||
tree.update(t)
|
||||
@ -172,9 +141,9 @@ def test_sub_match(env, project, repo_a, repo_b, repo_c):
|
||||
"branch-matched PRs should be part of the same staging"
|
||||
st = pr_b.staging_id
|
||||
assert json.loads(st.heads) == {
|
||||
'odoo/a': repo_a.commit('heads/master').id,
|
||||
'odoo/b': repo_b.commit('heads/staging.master').id,
|
||||
'odoo/c': repo_c.commit('heads/staging.master').id,
|
||||
repo_a.name: repo_a.commit('heads/master').id,
|
||||
repo_b.name: repo_b.commit('heads/staging.master').id,
|
||||
repo_c.name: repo_c.commit('heads/staging.master').id,
|
||||
}
|
||||
|
||||
def test_merge_fail(env, project, repo_a, repo_b):
|
||||
|
Loading…
Reference in New Issue
Block a user