mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 23:45:44 +07:00
[ADD] runbot_merge: add tests to try and expose the mystery of staging 13
Staging 13 tried merging 3 PRs (27085, 27083 and 27071) and supposedly succeeded *but* only merged one of the 3 PRs despite marking all three as merged. I tried building a few tests constructing multi-PR graphs and checking them, but the only thing they exposed was the local github implementation not correctly updating merge targets. So fixed that, which is good. Doesn't tell me why the staging didn't work right though.
This commit is contained in:
parent
c2db5659d8
commit
6dbfde0389
@ -465,13 +465,13 @@ class Repo(object):
|
||||
# merging according to read-tree:
|
||||
# get common ancestor (base) of commits
|
||||
try:
|
||||
base = git.merge_base(self.objects, target, sha)
|
||||
merge_base = git.merge_base(self.objects, target, sha)
|
||||
except Exception:
|
||||
return (400, {'message': "No common ancestor between %(base)s and %(head)s" % body})
|
||||
try:
|
||||
tid = git.merge_objects(
|
||||
self.objects,
|
||||
self.objects[base].tree,
|
||||
self.objects[merge_base].tree,
|
||||
self.objects[target].tree,
|
||||
self.objects[sha].tree,
|
||||
)
|
||||
@ -481,6 +481,7 @@ class Repo(object):
|
||||
|
||||
c = Commit(tid, body['commit_message'], author=None, committer=None, parents=[target, sha])
|
||||
self.objects[c.id] = c
|
||||
self.refs[base] = c.id
|
||||
|
||||
return (201, c.to_json())
|
||||
|
||||
|
@ -1226,6 +1226,60 @@ class TestBatching(object):
|
||||
assert pr2.staging_id
|
||||
assert pr1.staging_id == pr2.staging_id
|
||||
|
||||
log = list(repo.log('heads/staging.master'))
|
||||
staging = log_to_node(log)
|
||||
p1 = node(
|
||||
'title PR1\n\nbody PR1\n\ncloses {}#{}'.format(repo.name, pr1.number),
|
||||
node('initial'),
|
||||
node('commit_PR1_01', node('commit_PR1_00', node('initial')))
|
||||
)
|
||||
p2 = node(
|
||||
'title PR2\n\nbody PR2\n\ncloses {}#{}'.format(repo.name, pr2.number),
|
||||
p1,
|
||||
node('commit_PR2_01', node('commit_PR2_00', p1))
|
||||
)
|
||||
expected = (re_matches('^force rebuild'), frozenset([p2]))
|
||||
assert staging == expected
|
||||
|
||||
def test_staging_batch_norebase(self, env, repo):
|
||||
""" If multiple PRs are ready for the same target at the same point,
|
||||
they should be staged together
|
||||
"""
|
||||
m = repo.make_commit(None, 'initial', None, tree={'a': 'some content'})
|
||||
repo.make_ref('heads/master', m)
|
||||
|
||||
pr1 = self._pr(repo, 'PR1', [{'a': 'AAA'}, {'b': 'BBB'}])
|
||||
pr1.post_comment('hansen rebase-', 'reviewer')
|
||||
pr2 = self._pr(repo, 'PR2', [{'c': 'CCC'}, {'d': 'DDD'}])
|
||||
pr2.post_comment('hansen rebase-', 'reviewer')
|
||||
|
||||
env['runbot_merge.project']._check_progress()
|
||||
pr1 = self._get(env, repo, pr1.number)
|
||||
assert pr1.staging_id
|
||||
assert not pr1.rebase
|
||||
pr2 = self._get(env, repo, pr2.number)
|
||||
assert not pr2.rebase
|
||||
assert pr1.staging_id
|
||||
assert pr2.staging_id
|
||||
assert pr1.staging_id == pr2.staging_id
|
||||
|
||||
log = list(repo.log('heads/staging.master'))
|
||||
|
||||
staging = log_to_node(log)
|
||||
|
||||
p1 = node(
|
||||
'title PR1\n\nbody PR1\n\ncloses {}#{}'.format(repo.name, pr1.number),
|
||||
node('initial'),
|
||||
node('commit_PR1_01', node('commit_PR1_00', node('initial')))
|
||||
)
|
||||
p2 = node(
|
||||
'title PR2\n\nbody PR2\n\ncloses {}#{}'.format(repo.name, pr2.number),
|
||||
p1,
|
||||
node('commit_PR2_01', node('commit_PR2_00', node('initial')))
|
||||
)
|
||||
expected = (re_matches('^force rebuild'), frozenset([p2]))
|
||||
assert staging == expected
|
||||
|
||||
def test_batching_pressing(self, env, repo):
|
||||
""" "Pressing" PRs should be selected before normal & batched together
|
||||
"""
|
||||
@ -1581,9 +1635,22 @@ def node(name, *children):
|
||||
def log_to_node(log):
|
||||
log = list(log)
|
||||
nodes = {}
|
||||
for c in reversed(log):
|
||||
nodes[c['sha']] = (c['commit']['message'], frozenset(
|
||||
nodes[p['sha']]
|
||||
for p in (c['parents'])
|
||||
))
|
||||
# check that all parents are present
|
||||
ids = {c['sha'] for c in log}
|
||||
parents = {p['sha'] for c in log for p in c['parents']}
|
||||
missing = parents - ids
|
||||
assert parents, "Didn't find %s in log" % missing
|
||||
|
||||
# github doesn't necessarily log topologically maybe?
|
||||
todo = list(reversed(log))
|
||||
while todo:
|
||||
c = todo.pop(0)
|
||||
if all(p['sha'] in nodes for p in c['parents']):
|
||||
nodes[c['sha']] = (c['commit']['message'], frozenset(
|
||||
nodes[p['sha']]
|
||||
for p in c['parents']
|
||||
))
|
||||
else:
|
||||
todo.append(c)
|
||||
|
||||
return nodes[log[0]['sha']]
|
||||
|
Loading…
Reference in New Issue
Block a user