Use update aliases instead of titles, they are now guaranteed to be
available.
This is needed to have working bodhi comments once again in the future.
lbrabec | |
tflink | |
jskladan |
Use update aliases instead of titles, they are now guaranteed to be
available.
This is needed to have working bodhi comments once again in the future.
test suite works and a manual depcheck run worked as well, but there was a very fresh set of updates and none of them were found in bodhi, so it's very like some code paths were not tested
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Path | Packages | |||
---|---|---|---|---|
M | depcheck/squash_results.py (18 lines) | |||
M | tests/test_squash_results.py (20 lines) |
Commit | Tree | Parents | Author | Summary | Date |
---|---|---|---|---|---|
1c85b27108c8 | fa5ea4f019dc | 7c9eced9b668 | Kamil Páral | adjust to Bodhi 2.0 (Show More…) | Aug 18 2015, 7:49 PM |
Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Line(s) | 46 | def _squash_builds_to_updates(results_nvr, bodhi_client = None): | |||
---|---|---|---|---|---|
53 | """ | 53 | """ | ||
54 | if bodhi_client is None: | 54 | if bodhi_client is None: | ||
55 | bodhi_client = BodhiUtils() | 55 | bodhi_client = BodhiUtils() | ||
56 | 56 | | |||
57 | pending_ok, pending_fail = bodhi_client.build2update(results_nvr.keys(), strict = True) | 57 | pending_ok, pending_fail = bodhi_client.build2update(results_nvr.keys(), strict = True) | ||
58 | 58 | | |||
59 | updates = {} | 59 | updates = {} | ||
60 | for _, update in pending_ok.items(): | 60 | for _, update in pending_ok.items(): | ||
61 | updates[update['title']] = update | 61 | updates[update['alias']] = update | ||
62 | 62 | | |||
63 | for build, update in pending_fail.items(): | 63 | for build, update in pending_fail.items(): | ||
64 | if update is None: | 64 | if update is None: | ||
65 | log.logger.error("Build without an update: %r" % build) | 65 | log.logger.error("Build without an update: %r" % build) | ||
66 | continue | 66 | continue | ||
67 | if update['title'] not in updates: | 67 | if update['alias'] not in updates: | ||
68 | updates[update['title']] = update | 68 | updates[update['alias']] = update | ||
69 | 69 | | |||
70 | updates_results = [] | 70 | updates_results = [] | ||
71 | for update_title, update in updates.items(): | 71 | for update_alias, update in updates.items(): | ||
72 | cd = check.CheckDetail(update_title, check.ReportType.BODHI_UPDATE, outcome = 'PASSED') | 72 | cd = check.CheckDetail(update_alias, check.ReportType.BODHI_UPDATE, outcome = 'PASSED') | ||
73 | updates_results.append(cd) | 73 | updates_results.append(cd) | ||
74 | 74 | | |||
75 | builds = sorted([build['nvr'] for build in update['builds']]) | 75 | builds = sorted([build['nvr'] for build in update['builds']]) | ||
76 | 76 | | |||
77 | if set(builds).intersection(set(pending_fail.keys())): | 77 | if set(builds).intersection(set(pending_fail.keys())): | ||
78 | # A build is in pending_fail either when it has no assigned | 78 | # A build is in pending_fail either when it has no assigned | ||
79 | # update (that can not happen, as we traverse builds of | 79 | # update (that can not happen, as we traverse builds of | ||
80 | # a specific update), or when an update was incomplete | 80 | # a specific update), or when an update was incomplete | ||
Show All 20 Lines | |||||
101 | 101 | | |||
102 | # set summary | 102 | # set summary | ||
103 | if update['request']: | 103 | if update['request']: | ||
104 | target = 'into %s %s' % (update['release']['name'], | 104 | target = 'into %s %s' % (update['release']['name'], | ||
105 | update['request']) | 105 | update['request']) | ||
106 | else: | 106 | else: | ||
107 | target = 'in %s %s' % (update['release']['name'], | 107 | target = 'in %s %s' % (update['release']['name'], | ||
108 | update['status']) | 108 | update['status']) | ||
109 | cd.summary = '%s %s' % (update_title, target) | 109 | cd.summary = '%s %s' % (update_alias, target) | ||
110 | 110 | | |||
111 | return updates_results | 111 | return updates_results | ||
112 | 112 | | |||
113 | 113 | | |||
114 | def squash_results(run_result, bodhi_client = None, koji_client = None): | 114 | def squash_results(run_result, bodhi_client = None, koji_client = None): | ||
115 | per_nvr = _squash_rpms_to_builds(run_result, koji_client) | 115 | per_nvr = _squash_rpms_to_builds(run_result, koji_client) | ||
116 | per_update = _squash_builds_to_updates(per_nvr, bodhi_client) | 116 | per_update = _squash_builds_to_updates(per_nvr, bodhi_client) | ||
117 | 117 | | |||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Line(s) | 163 | try: | |||
166 | 166 | | |||
167 | if not os.path.exists(storedir): | 167 | if not os.path.exists(storedir): | ||
168 | os.makedirs(storedir) | 168 | os.makedirs(storedir) | ||
169 | 169 | | |||
170 | # save logs | 170 | # save logs | ||
171 | for result in results: | 171 | for result in results: | ||
172 | item = result.item | 172 | item = result.item | ||
173 | filename = "%s.%s.log" % (item, result.keyvals['arch']) | 173 | filename = "%s.%s.log" % (item, result.keyvals['arch']) | ||
174 | # Bodhi update titles can be very long, we need to trim them | | |||
175 | if len(filename) > 255: # the max file name length for most Linux filesystems | | |||
176 | exceed_len = len(filename) - 255 | | |||
177 | item = item[:-exceed_len-len('...')] + '...' | | |||
178 | filename = "%s.%s.log" % (item, result.keyvals['arch']) | | |||
179 | assert len(filename) <= 255 | | |||
180 | filepath = os.path.join(storedir, filename) | 174 | filepath = os.path.join(storedir, filename) | ||
181 | fout = open(filepath, 'w') | 175 | fout = open(filepath, 'w') | ||
182 | fout.write(check.export_TAP([result], checkname='depcheck')) | 176 | fout.write(check.export_TAP([result], checkname='depcheck')) | ||
183 | fout.close() | 177 | fout.close() | ||
184 | result.artifact = filepath | 178 | result.artifact = filepath | ||
185 | 179 | | |||
186 | except OSError as e: | 180 | except OSError as e: | ||
187 | log.logger.error('Individual logs not saved into %s, an error occured. ' | 181 | log.logger.error('Individual logs not saved into %s, an error occured. ' | ||
188 | 'Raising.', artifactsdir) | 182 | 'Raising.', artifactsdir) | ||
189 | raise e | 183 | raise e | ||
190 | 184 | |
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Line(s) | 47 | def test__squash_builds_to_updates_all_ok(self): | |||
---|---|---|---|---|---|
49 | Checks whether __squash_builds_to_updates provides correct output | 49 | Checks whether __squash_builds_to_updates provides correct output | ||
50 | when all the builds in an update passed depchecking. | 50 | when all the builds in an update passed depchecking. | ||
51 | """ | 51 | """ | ||
52 | 52 | | |||
53 | run_results = { | 53 | run_results = { | ||
54 | 'nvr1': {'result': Pass, 'details': []}, | 54 | 'nvr1': {'result': Pass, 'details': []}, | ||
55 | 'nvr2': {'result': Pass, 'details': []}, | 55 | 'nvr2': {'result': Pass, 'details': []}, | ||
56 | } | 56 | } | ||
57 | update = {'title': 'update_name', | 57 | update = {'alias': 'update_name', | ||
58 | 'builds': [{'nvr': k} for k in run_results.keys()], | 58 | 'builds': [{'nvr': k} for k in run_results.keys()], | ||
59 | 'release': {'name': 'F20'}, | 59 | 'release': {'name': 'F20'}, | ||
60 | 'request': 'stable', | 60 | 'request': 'stable', | ||
61 | } | 61 | } | ||
62 | build_2_update = ( | 62 | build_2_update = ( | ||
63 | { | 63 | { | ||
64 | 'nvr1': update, | 64 | 'nvr1': update, | ||
65 | 'nvr2': update, | 65 | 'nvr2': update, | ||
66 | }, {}) | 66 | }, {}) | ||
67 | 67 | | |||
68 | fake_bodhi = Dingus(build2update__returns = build_2_update) | 68 | fake_bodhi = Dingus(build2update__returns = build_2_update) | ||
69 | 69 | | |||
70 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | 70 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | ||
71 | assert len(cds) == 1 | 71 | assert len(cds) == 1 | ||
72 | 72 | | |||
73 | detail = cds[0] | 73 | detail = cds[0] | ||
74 | assert detail.item == update['title'] | 74 | assert detail.item == update['alias'] | ||
75 | assert detail.outcome == 'PASSED' | 75 | assert detail.outcome == 'PASSED' | ||
76 | 76 | | |||
77 | def test__squash_builds_to_updates_build_failed(self): | 77 | def test__squash_builds_to_updates_build_failed(self): | ||
78 | """ | 78 | """ | ||
79 | Checks whether __squash_builds_to_updates provides correct output | 79 | Checks whether __squash_builds_to_updates provides correct output | ||
80 | when some of the builds in an update failed depchecking. | 80 | when some of the builds in an update failed depchecking. | ||
81 | """ | 81 | """ | ||
82 | run_results = { | 82 | run_results = { | ||
83 | 'nvr1': {'result': Pass, 'details': []}, | 83 | 'nvr1': {'result': Pass, 'details': []}, | ||
84 | 'nvr2': {'result': Fail, 'details': ['### TEST @@@']}, | 84 | 'nvr2': {'result': Fail, 'details': ['### TEST @@@']}, | ||
85 | } | 85 | } | ||
86 | update = {'title': 'update_name', | 86 | update = {'alias': 'update_name', | ||
87 | 'builds': [{'nvr': k} for k in run_results.keys()], | 87 | 'builds': [{'nvr': k} for k in run_results.keys()], | ||
88 | 'release': {'name': 'F20'}, | 88 | 'release': {'name': 'F20'}, | ||
89 | 'request': 'stable', | 89 | 'request': 'stable', | ||
90 | } | 90 | } | ||
91 | build_2_update = ( | 91 | build_2_update = ( | ||
92 | { | 92 | { | ||
93 | 'nvr1': update, | 93 | 'nvr1': update, | ||
94 | 'nvr2': update, | 94 | 'nvr2': update, | ||
95 | }, {}) | 95 | }, {}) | ||
96 | 96 | | |||
97 | fake_bodhi = Dingus(build2update__returns = build_2_update) | 97 | fake_bodhi = Dingus(build2update__returns = build_2_update) | ||
98 | 98 | | |||
99 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | 99 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | ||
100 | assert len(cds) == 1 | 100 | assert len(cds) == 1 | ||
101 | 101 | | |||
102 | detail = cds[0] | 102 | detail = cds[0] | ||
103 | assert detail.item == update['title'] | 103 | assert detail.item == update['alias'] | ||
104 | assert detail.outcome == 'FAILED' | 104 | assert detail.outcome == 'FAILED' | ||
105 | assert '### TEST @@@' in detail.output | 105 | assert '### TEST @@@' in detail.output | ||
106 | 106 | | |||
107 | def test__squash_builds_to_updates_incomplete_update(self): | 107 | def test__squash_builds_to_updates_incomplete_update(self): | ||
108 | """ | 108 | """ | ||
109 | Checks whether __squash_builds_to_updates provides correct output | 109 | Checks whether __squash_builds_to_updates provides correct output | ||
110 | when some update is incomplete (i.e. present in the second return-value | 110 | when some update is incomplete (i.e. present in the second return-value | ||
111 | from the build2update method). | 111 | from the build2update method). | ||
112 | """ | 112 | """ | ||
113 | run_results = { | 113 | run_results = { | ||
114 | 'nvr1': {'result': Pass, 'details': []}, | 114 | 'nvr1': {'result': Pass, 'details': []}, | ||
115 | 'nvr2': {'result': Pass, 'details': []}, | 115 | 'nvr2': {'result': Pass, 'details': []}, | ||
116 | } | 116 | } | ||
117 | update = {'title': 'update_name', | 117 | update = {'alias': 'update_name', | ||
118 | 'builds': [{'nvr': k} for k in run_results.keys()], | 118 | 'builds': [{'nvr': k} for k in run_results.keys()], | ||
119 | 'release': {'name': 'F20'}, | 119 | 'release': {'name': 'F20'}, | ||
120 | 'request': 'stable', | 120 | 'request': 'stable', | ||
121 | } | 121 | } | ||
122 | update['builds'].append({'nvr':'nvr3'}) | 122 | update['builds'].append({'nvr':'nvr3'}) | ||
123 | build_2_update = ({}, | 123 | build_2_update = ({}, | ||
124 | { | 124 | { | ||
125 | 'nvr1': update, | 125 | 'nvr1': update, | ||
126 | 'nvr2': update, | 126 | 'nvr2': update, | ||
127 | }) | 127 | }) | ||
128 | 128 | | |||
129 | fake_bodhi = Dingus(build2update__returns = build_2_update) | 129 | fake_bodhi = Dingus(build2update__returns = build_2_update) | ||
130 | 130 | | |||
131 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | 131 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | ||
132 | assert len(cds) == 1 | 132 | assert len(cds) == 1 | ||
133 | 133 | | |||
134 | detail = cds[0] | 134 | detail = cds[0] | ||
135 | assert detail.item == update['title'] | 135 | assert detail.item == update['alias'] | ||
136 | assert detail.outcome == 'ABORTED' | 136 | assert detail.outcome == 'ABORTED' | ||
137 | assert any('Update was incomplete' in line for line in detail.output) | 137 | assert any('Update was incomplete' in line for line in detail.output) | ||
138 | 138 | | |||
139 | def test__squash_builds_to_updates_incomplete_update_missing_first(self): | 139 | def test__squash_builds_to_updates_incomplete_update_missing_first(self): | ||
140 | """ | 140 | """ | ||
141 | Checks whether __squash_builds_to_updates provides correct output | 141 | Checks whether __squash_builds_to_updates provides correct output | ||
142 | when some update is incomplete (i.e. present in the second return-value | 142 | when some update is incomplete (i.e. present in the second return-value | ||
143 | from the build2update method) and the missing build is the first one | 143 | from the build2update method) and the missing build is the first one | ||
144 | to process (https://phab.qadevel.cloud.fedoraproject.org/T476). | 144 | to process (https://phab.qadevel.cloud.fedoraproject.org/T476). | ||
145 | """ | 145 | """ | ||
146 | run_results = { | 146 | run_results = { | ||
147 | 'nvr1': {'result': Pass, 'details': []}, | 147 | 'nvr1': {'result': Pass, 'details': []}, | ||
148 | 'nvr2': {'result': Pass, 'details': []}, | 148 | 'nvr2': {'result': Pass, 'details': []}, | ||
149 | } | 149 | } | ||
150 | update = {'title': 'update_name', | 150 | update = {'alias': 'update_name', | ||
151 | 'builds': [{'nvr': k} for k in run_results.keys()], | 151 | 'builds': [{'nvr': k} for k in run_results.keys()], | ||
152 | 'release': {'name': 'F20'}, | 152 | 'release': {'name': 'F20'}, | ||
153 | 'request': 'stable', | 153 | 'request': 'stable', | ||
154 | } | 154 | } | ||
155 | # the builds are processed alphabetically in _squash_build_to_updates(), | 155 | # the builds are processed alphabetically in _squash_build_to_updates(), | ||
156 | # so naming it 'abc1' ensures it is processed before 'nvr*' | 156 | # so naming it 'abc1' ensures it is processed before 'nvr*' | ||
157 | update['builds'].append({'nvr':'abc1'}) | 157 | update['builds'].append({'nvr':'abc1'}) | ||
158 | build_2_update = ({}, | 158 | build_2_update = ({}, | ||
159 | { | 159 | { | ||
160 | 'nvr1': update, | 160 | 'nvr1': update, | ||
161 | 'nvr2': update, | 161 | 'nvr2': update, | ||
162 | }) | 162 | }) | ||
163 | 163 | | |||
164 | fake_bodhi = Dingus(build2update__returns = build_2_update) | 164 | fake_bodhi = Dingus(build2update__returns = build_2_update) | ||
165 | 165 | | |||
166 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | 166 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | ||
167 | assert len(cds) == 1 | 167 | assert len(cds) == 1 | ||
168 | 168 | | |||
169 | detail = cds[0] | 169 | detail = cds[0] | ||
170 | assert detail.item == update['title'] | 170 | assert detail.item == update['alias'] | ||
171 | assert detail.outcome == 'ABORTED' | 171 | assert detail.outcome == 'ABORTED' | ||
172 | assert any('Update was incomplete' in line for line in detail.output) | 172 | assert any('Update was incomplete' in line for line in detail.output) | ||
173 | 173 | | |||
174 | def test__squash_builds_to_updates_missing_update(self): | 174 | def test__squash_builds_to_updates_missing_update(self): | ||
175 | """ | 175 | """ | ||
176 | Checks whether __squash_builds_to_updates provides correct output | 176 | Checks whether __squash_builds_to_updates provides correct output | ||
177 | when there is no update for a certain build. | 177 | when there is no update for a certain build. | ||
178 | """ | 178 | """ | ||
179 | run_results = { | 179 | run_results = { | ||
180 | 'nvr1': {'result': Pass, 'details': []}, | 180 | 'nvr1': {'result': Pass, 'details': []}, | ||
181 | 'nvr2': {'result': Pass, 'details': []}, | 181 | 'nvr2': {'result': Pass, 'details': []}, | ||
182 | } | 182 | } | ||
183 | update = {'title': 'update_name', | 183 | update = {'alias': 'update_name', | ||
184 | 'builds': [{'nvr': 'nvr1'}], | 184 | 'builds': [{'nvr': 'nvr1'}], | ||
185 | 'release': {'name': 'F20'}, | 185 | 'release': {'name': 'F20'}, | ||
186 | 'request': 'stable', | 186 | 'request': 'stable', | ||
187 | } | 187 | } | ||
188 | build_2_update = ( | 188 | build_2_update = ( | ||
189 | { 'nvr1': update, }, | 189 | { 'nvr1': update, }, | ||
190 | { 'nvr2': None, }, | 190 | { 'nvr2': None, }, | ||
191 | ) | 191 | ) | ||
192 | 192 | | |||
193 | fake_bodhi = Dingus(build2update__returns = build_2_update) | 193 | fake_bodhi = Dingus(build2update__returns = build_2_update) | ||
194 | 194 | | |||
195 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | 195 | cds = _squash_builds_to_updates(run_results, fake_bodhi) | ||
196 | # 'nvr2' got ignored (just logged), so only one CheckDetail got returned | 196 | # 'nvr2' got ignored (just logged), so only one CheckDetail got returned | ||
197 | assert len(cds) == 1 | 197 | assert len(cds) == 1 | ||
198 | detail = cds[0] | 198 | detail = cds[0] | ||
199 | assert detail.item == update['title'] | 199 | assert detail.item == update['alias'] | ||
200 | assert detail.outcome == 'PASSED' | 200 | assert detail.outcome == 'PASSED' | ||
201 | 201 | |