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 | | |||