| |
@@ -10,6 +10,9 @@
|
| |
from blockerbugs import app, db
|
| |
from blockerbugs.controllers import main
|
| |
|
| |
+ pkg_counter = 0
|
| |
+ ''' This makes generated package names different '''
|
| |
+
|
| |
|
| |
def add_release(number=99):
|
| |
test_release = Release(number)
|
| |
@@ -29,7 +32,7 @@
|
| |
|
| |
def add_bug(bugid, summary, milestone):
|
| |
test_bug = Bug(bugid=bugid,
|
| |
- url='https://bugzilla.redhat.com/show_bug.cgi?id=%d' % bugid,
|
| |
+ url=f'https://bugzilla.redhat.com/show_bug.cgi?id={bugid}',
|
| |
summary=summary,
|
| |
status='NEW',
|
| |
component='testcomponent',
|
| |
@@ -43,15 +46,22 @@
|
| |
return test_bug
|
| |
|
| |
|
| |
- def add_update(updateid, release, status, bugs=[]):
|
| |
+ def add_update(updateid, release, status, bugs=None):
|
| |
+ bugs = bugs or []
|
| |
+ nvrs = []
|
| |
+ global pkg_counter
|
| |
+ for i, bug in enumerate(bugs):
|
| |
+ pkg_counter += 1
|
| |
+ nvrs.append(f'pkg{pkg_counter}-{i+1}-1.fc{release.number}')
|
| |
+ title = ' '.join(nvrs) or updateid
|
| |
test_update = Update(updateid=updateid,
|
| |
release=release,
|
| |
status=status,
|
| |
karma=1,
|
| |
- url='http://localhost/update',
|
| |
+ url=f'https://bodhi.fedoraproject.org/updates/{updateid}',
|
| |
date_submitted=datetime.datetime.utcnow(),
|
| |
request=None,
|
| |
- title=None,
|
| |
+ title=title,
|
| |
stable_karma=3,
|
| |
bugs=bugs)
|
| |
db.session.add(test_update)
|
| |
@@ -74,35 +84,45 @@
|
| |
return True
|
| |
|
| |
|
| |
- def split_requests(rendered_requests: str) -> tuple[str, str, str, str, str]:
|
| |
+ def split_requests(rendered_requests: str) -> tuple[str, str, str, str, str, str, str]:
|
| |
"""Take a rendered 'requests.txt' template, split it into parts and return them.
|
| |
|
| |
- :returns: (compose_blockers, compose_fes, push_blockers, push_fes, deps)
|
| |
+ :returns: (compose_blockers, compose_fes, compose_cmds, push_blockers, push_fes, push_cmds,
|
| |
+ deps)
|
| |
"""
|
| |
- index_fp = rendered_requests.index('### FREEZE PUSH ###')
|
| |
+ index_push = rendered_requests.index('## FREEZE PUSH ##')
|
| |
try:
|
| |
- index_deps = rendered_requests.index('### THE ABOVE MIGHT NOT BE COMPLETE')
|
| |
+ index_deps = rendered_requests.index('## THE ABOVE MIGHT NOT BE COMPLETE')
|
| |
except ValueError:
|
| |
# deps section might not be present
|
| |
index_deps = len(rendered_requests)
|
| |
- compose = rendered_requests[:index_fp]
|
| |
- assert '### CANDIDATE COMPOSE ###' in compose
|
| |
- push = rendered_requests[index_fp:index_deps]
|
| |
- assert '### FREEZE PUSH ###' in push
|
| |
+ compose = rendered_requests[:index_push]
|
| |
+ assert '## CANDIDATE COMPOSE ##' in compose
|
| |
+ push = rendered_requests[index_push:index_deps]
|
| |
+ assert '## FREEZE PUSH ##' in push
|
| |
deps = rendered_requests[index_deps:]
|
| |
- assert '### THE ABOVE MIGHT NOT BE COMPLETE' in deps or not deps
|
| |
- index_fe = compose.index('== Freeze exceptions ==')
|
| |
+ assert '## THE ABOVE MIGHT NOT BE COMPLETE' in deps or not deps
|
| |
+
|
| |
+ index_fe = compose.index('#### Freeze exceptions ####')
|
| |
+ index_cmd = compose.index('#### Releng commands ####')
|
| |
compose_blockers = compose[:index_fe]
|
| |
- assert '== Blockers ==' in compose_blockers
|
| |
- compose_fes = compose[index_fe:]
|
| |
- assert '== Freeze exceptions ==' in compose_fes
|
| |
- index_fe = push.index('== Freeze exceptions ==')
|
| |
+ assert '#### Blockers ####' in compose_blockers
|
| |
+ compose_fes = compose[index_fe:index_cmd]
|
| |
+ assert '#### Freeze exceptions ####' in compose_fes
|
| |
+ compose_commands = compose[index_cmd:]
|
| |
+ assert '#### Releng commands ####' in compose_commands
|
| |
+
|
| |
+ index_fe = push.index('#### Freeze exceptions ####')
|
| |
+ index_cmd = push.index('#### Releng commands ####')
|
| |
push_blockers = push[:index_fe]
|
| |
- assert '== Blockers ==' in push_blockers
|
| |
- push_fes = push[index_fe:]
|
| |
- assert '== Freeze exceptions ==' in push_fes
|
| |
-
|
| |
- all_sections = (compose_blockers, compose_fes, push_blockers, push_fes, deps)
|
| |
+ assert '#### Blockers ####' in push_blockers
|
| |
+ push_fes = push[index_fe:index_cmd]
|
| |
+ assert '#### Freeze exceptions ####' in push_fes
|
| |
+ push_commands = push[index_cmd:]
|
| |
+ assert '#### Releng commands ####' in push_commands
|
| |
+
|
| |
+ all_sections = (compose_blockers, compose_fes, compose_commands, push_blockers, push_fes,
|
| |
+ push_commands, deps)
|
| |
assert len(rendered_requests) == len(''.join(all_sections))
|
| |
return all_sections
|
| |
|
| |
@@ -297,20 +317,14 @@
|
| |
|
| |
def test_get_milestone_updates(self):
|
| |
updates = main.get_milestone_updates(self.milestone)
|
| |
- assert set(updates) == set([self.update_pending_stable,
|
| |
- self.update_stable1,
|
| |
- self.update_pending_testing,
|
| |
- self.update_testing1,
|
| |
- self.update_complex,
|
| |
- self.update_complexfe
|
| |
- ])
|
| |
+ assert set(updates) == {self.update_pending_stable, self.update_stable1,
|
| |
+ self.update_pending_testing, self.update_testing1,
|
| |
+ self.update_complex, self.update_complexfe}
|
| |
|
| |
def test_get_updates_nonstable_blockers(self):
|
| |
updates = main.get_updates_nonstable_blockers(self.milestone)
|
| |
- assert set(updates) == set([self.update_pending_stable,
|
| |
- self.update_pending_testing,
|
| |
- self.update_testing1
|
| |
- ])
|
| |
+ assert set(updates) == {self.update_pending_stable, self.update_pending_testing,
|
| |
+ self.update_testing1}
|
| |
|
| |
def test_get_updates_nonstable_FEs(self):
|
| |
updates = main.get_updates_nonstable_FEs(self.milestone)
|
| |
@@ -322,7 +336,7 @@
|
| |
|
| |
def test_requests(self):
|
| |
# we also test the requests template generation here, as it's
|
| |
- # what the get_* queries provide and it makes sense to do it
|
| |
+ # what the get_* queries provide, and it makes sense to do it
|
| |
# with all these bits in place
|
| |
with app.app_context():
|
| |
beta_response = self.client.get(
|
| |
@@ -337,58 +351,115 @@
|
| |
print(beta_requests)
|
| |
# split up the text
|
| |
all_sections = split_requests(beta_requests)
|
| |
- compose_blockers, compose_fes, push_blockers, push_fes, deps = all_sections
|
| |
+ compose_blockers, compose_fes, compose_cmds, push_blockers, push_fes, push_cmds, \
|
| |
+ deps = all_sections
|
| |
|
| |
# check all the right updates and bugs are and are not in the correct sections
|
| |
- assert item_just_in("test-pending-stable", [compose_blockers, push_blockers], all_sections)
|
| |
- assert item_just_in("test-stable1", [], all_sections)
|
| |
- assert item_just_in("test-stable2", [], all_sections)
|
| |
- assert item_just_in("test-pending-testing", [compose_blockers], all_sections)
|
| |
- assert item_just_in("test-testing1", [compose_blockers], all_sections)
|
| |
- assert item_just_in("test-testing2", [], all_sections)
|
| |
- assert item_just_in("test-complex1", [compose_fes], all_sections)
|
| |
- assert item_just_in("test-complexfe", [], all_sections)
|
| |
- # bug 1 id
|
| |
- assert item_just_in("9000", [compose_blockers, push_blockers, deps], all_sections)
|
| |
- # bug 2 id
|
| |
- assert item_just_in("9001", [], all_sections)
|
| |
- # finalbug id
|
| |
- assert item_just_in("9002", [], all_sections)
|
| |
- # betafebug id
|
| |
- assert item_just_in("9003", [compose_fes], all_sections)
|
| |
- # propbetafebug id
|
| |
- assert item_just_in("9004", [], all_sections)
|
| |
- # finalfebug id
|
| |
- assert item_just_in("9005", [], all_sections)
|
| |
+ # self.update_pending_stable
|
| |
+ assert item_just_in(self.update_pending_stable.updateid, [compose_blockers, push_blockers,
|
| |
+ push_cmds], all_sections)
|
| |
+ for build in self.update_pending_stable.title.split(' '):
|
| |
+ assert item_just_in(build, [compose_blockers, compose_cmds, push_blockers],
|
| |
+ all_sections)
|
| |
+ # self.update_stable1
|
| |
+ assert item_just_in(self.update_stable1.updateid, [], all_sections)
|
| |
+ for build in self.update_stable1.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.update_stable2
|
| |
+ assert item_just_in(self.update_stable2.updateid, [], all_sections)
|
| |
+ for build in self.update_stable2.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.update_pending_testing
|
| |
+ assert item_just_in(self.update_pending_testing.updateid, [compose_blockers],
|
| |
+ all_sections)
|
| |
+ for build in self.update_pending_testing.title.split(' '):
|
| |
+ assert item_just_in(build, [compose_blockers, compose_cmds], all_sections)
|
| |
+ # self.update_testing1
|
| |
+ assert item_just_in(self.update_testing1.updateid, [compose_blockers], all_sections)
|
| |
+ for build in self.update_testing1.title.split(' '):
|
| |
+ assert item_just_in(build, [compose_blockers, compose_cmds], all_sections)
|
| |
+ # self.update_testing2
|
| |
+ assert item_just_in(self.update_testing2.updateid, [], all_sections)
|
| |
+ for build in self.update_testing2.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.update_complex
|
| |
+ assert item_just_in(self.update_complex.updateid, [compose_fes], all_sections)
|
| |
+ for build in self.update_complex.title.split(' '):
|
| |
+ assert item_just_in(build, [compose_fes, compose_cmds], all_sections)
|
| |
+ # self.update_complexfe
|
| |
+ assert item_just_in(self.update_complexfe.updateid, [], all_sections)
|
| |
+ for build in self.update_complexfe.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.bug1
|
| |
+ assert item_just_in(str(self.bug1.bugid), [compose_blockers, push_blockers, deps],
|
| |
+ all_sections)
|
| |
+ # self.bug2
|
| |
+ assert item_just_in(str(self.bug2.bugid), [], all_sections)
|
| |
+ # self.finalbug
|
| |
+ assert item_just_in(str(self.finalbug.bugid), [], all_sections)
|
| |
+ # self.betafebug
|
| |
+ assert item_just_in(str(self.betafebug.bugid), [compose_fes], all_sections)
|
| |
+ # self.propbetafebug
|
| |
+ assert item_just_in(str(self.propbetafebug.bugid), [], all_sections)
|
| |
+ # self.finalfebug
|
| |
+ assert item_just_in(str(self.finalfebug.bugid), [], all_sections)
|
| |
|
| |
# === final milestone ===
|
| |
final_requests = final_response.get_data(as_text=True)
|
| |
print(final_requests)
|
| |
# split up the text
|
| |
all_sections = split_requests(final_requests)
|
| |
- compose_blockers, compose_fes, push_blockers, push_fes, deps = all_sections
|
| |
+ compose_blockers, compose_fes, compose_cmds, push_blockers, push_fes, push_cmds, \
|
| |
+ deps = all_sections
|
| |
|
| |
# check all the right updates and bugs are and are not in the correct sections
|
| |
- assert item_just_in("test-pending-stable", [compose_blockers, push_blockers], all_sections)
|
| |
- assert item_just_in("test-stable1", [], all_sections)
|
| |
- assert item_just_in("test-stable2", [], all_sections)
|
| |
- assert item_just_in("test-pending-testing", [], all_sections)
|
| |
- assert item_just_in("test-testing1", [], all_sections)
|
| |
- assert item_just_in("test-testing2", [], all_sections)
|
| |
- assert item_just_in("test-complex1", [compose_blockers], all_sections)
|
| |
- assert item_just_in("test-complexfe", [compose_fes], all_sections)
|
| |
- # bug 1 id
|
| |
- assert item_just_in("9000", [], all_sections)
|
| |
- # bug 2 id
|
| |
- assert item_just_in("9001", [], all_sections)
|
| |
- # finalbug id
|
| |
- assert item_just_in("9002", [compose_blockers, push_blockers], all_sections)
|
| |
- # betafebug id
|
| |
- assert item_just_in("9003", [], all_sections)
|
| |
- # propbetafebug id
|
| |
- assert item_just_in("9004", [], all_sections)
|
| |
- # finalfebug id
|
| |
- assert item_just_in("9005", [compose_fes], all_sections)
|
| |
+ # self.update_pending_stable
|
| |
+ assert item_just_in(self.update_pending_stable.updateid, [compose_blockers, push_blockers,
|
| |
+ push_cmds], all_sections)
|
| |
+ for build in self.update_pending_stable.title.split(' '):
|
| |
+ assert item_just_in(build, [compose_blockers, compose_cmds, push_blockers],
|
| |
+ all_sections)
|
| |
+ # self.update_stable1
|
| |
+ assert item_just_in(self.update_stable1.updateid, [], all_sections)
|
| |
+ for build in self.update_stable1.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.update_stable2
|
| |
+ assert item_just_in(self.update_stable2.updateid, [], all_sections)
|
| |
+ for build in self.update_stable2.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.update_pending_testing
|
| |
+ assert item_just_in(self.update_pending_testing.updateid, [], all_sections)
|
| |
+ for build in self.update_pending_testing.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.update_testing1
|
| |
+ assert item_just_in(self.update_testing1.updateid, [], all_sections)
|
| |
+ for build in self.update_testing1.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.update_testing2
|
| |
+ assert item_just_in(self.update_testing2.updateid, [], all_sections)
|
| |
+ for build in self.update_testing2.title.split(' '):
|
| |
+ assert item_just_in(build, [], all_sections)
|
| |
+ # self.update_complex
|
| |
+ assert item_just_in(self.update_complex.updateid, [compose_blockers], all_sections)
|
| |
+ for build in self.update_complex.title.split(' '):
|
| |
+ assert item_just_in(build, [compose_blockers, compose_cmds], all_sections)
|
| |
+ # self.update_complexfe
|
| |
+ assert item_just_in(self.update_complexfe.updateid, [compose_fes], all_sections)
|
| |
+ for build in self.update_complexfe.title.split(' '):
|
| |
+ assert item_just_in(build, [compose_fes, compose_cmds], all_sections)
|
| |
+ # self.bug1
|
| |
+ assert item_just_in(str(self.bug1.bugid), [], all_sections)
|
| |
+ # self.bug2
|
| |
+ assert item_just_in(str(self.bug2.bugid), [], all_sections)
|
| |
+ # self.finalbug
|
| |
+ assert item_just_in(str(self.finalbug.bugid), [compose_blockers, push_blockers],
|
| |
+ all_sections)
|
| |
+ # self.betafebug
|
| |
+ assert item_just_in(str(self.betafebug.bugid), [], all_sections)
|
| |
+ # self.propbetafebug
|
| |
+ assert item_just_in(str(self.propbetafebug.bugid), [], all_sections)
|
| |
+ # self.finalfebug
|
| |
+ assert item_just_in(str(self.finalfebug.bugid), [compose_fes], all_sections)
|
| |
|
| |
def test_display_bug_updates(self):
|
| |
with app.app_context():
|
| |
Based on releng request, this adds a section to Requests showing the exact
commands releng should run. When creating a releng ticket, QA will have to make
sure the FE and Releng sections match, if any of the FEs are filtered out by QA.
This will only work as long as Bodhi defaults to populate each Bodhi update
title with a space-delimited list of NVRs. If they stop doing that, we'll have
to switch to a more proper approach.
Fixes: https://pagure.io/fedora-qa/blockerbugs/issue/275
Related: https://pagure.io/fedora-qa/blockerbugs/pull-request/271
Co-authored-by: Kevin Fenzi kevin@scrye.com
Co-authored-by: František Zatloukal fzatlouk@redhat.com
Here's an example Requests output with my test data:
https://pastebin.com/raw/R7pi5T27
@kevin @adamwill I'll need you guys to make some choices. In the Releng Commands sections, there are a few
ALTERNATIVE
blocks. I need you to tell me which work best for you. The problem is, I believe Adam doesn't just copy&paste all the available FEs into a compose/freeze push ticket, but handpicks those which look reasonable for that moment. So if we're going to have a Releng Commands section, he would also need to make the same changes there. However, it's not that easy to reliably edit a long bash command with possibly dozens of arguments. So in those ALTERNATIVE sections, I made sure each FE gets its own line. Is that better?Also, in the Freeze Push section, we have an option to work with update aliases or list of builds. The first feels to be more reliable, but the second makes it probably easier to figure out which FE the current line refers to and whether to keep it or erase it. So which style do we want to have in there?
@kevin Please verify whether the bash commands syntax looks OK. I made some changes from your original PR.