Merge lp:~robru/cupstream2distro/check-approved-uploaders-for-publish into lp:cupstream2distro
- check-approved-uploaders-for-publish
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Robert Bruce Park |
Approved revision: | 1076 |
Merged at revision: | 1065 |
Proposed branch: | lp:~robru/cupstream2distro/check-approved-uploaders-for-publish |
Merge into: | lp:cupstream2distro |
Diff against target: |
641 lines (+150/-191) 10 files modified
citrain/jenkins-templates/build.xml.tmpl (+1/-1) citrain/jenkins-templates/publish.xml.tmpl (+12/-18) citrain/publisher.py (+2/-60) citrain/recipes/base.py (+44/-1) citrain/recipes/manual.py (+5/-0) cupstream2distro/settings.py (+0/-1) tests/strings.py (+0/-17) tests/unit/test_recipe_base.py (+71/-0) tests/unit/test_recipe_manual.py (+11/-0) tests/unit/test_script_publisher.py (+4/-93) |
To merge this branch: | bzr merge lp:~robru/cupstream2distro/check-approved-uploaders-for-publish |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Bruce Park (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+269806@code.launchpad.net |
Commit message
Call checkUpload to see if publisher has upload rights.
Description of the change
- 1066. By Robert Bruce Park
-
Catch ClientError.
- 1067. By Robert Bruce Park
-
Log PublishError properly.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1068. By Robert Bruce Park
-
Absorb redundant confirm_
publisher_ identity.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1068
http://
Executed test runs:
Click here to trigger a rebuild:
http://
- 1069. By Robert Bruce Park
-
More logging.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1069
http://
Executed test runs:
Click here to trigger a rebuild:
http://
- 1070. By Robert Bruce Park
-
No more honor system for who is acking packages.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1070
http://
Executed test runs:
Click here to trigger a rebuild:
http://
- 1071. By Robert Bruce Park
-
Enforce checkupload for all manual sources but merges only with diffs.
- 1072. By Robert Bruce Park
-
Debug logging.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1072
http://
Executed test runs:
Click here to trigger a rebuild:
http://
- 1073. By Robert Bruce Park
-
Stop generating XML artifacts.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1073
http://
Executed test runs:
Click here to trigger a rebuild:
http://
- 1074. By Robert Bruce Park
-
Fail properly.
- 1075. By Robert Bruce Park
-
-rf
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1075
http://
Executed test runs:
Click here to trigger a rebuild:
http://
- 1076. By Robert Bruce Park
-
Set self.authorized after, just to be sure.
Robert Bruce Park (robru) wrote : | # |
Looking good to me in staging, just waiting for some love from one of the core devs I emailed to double check.
Preview Diff
1 | === modified file 'citrain/jenkins-templates/build.xml.tmpl' |
2 | --- citrain/jenkins-templates/build.xml.tmpl 2015-03-13 04:48:32 +0000 |
3 | +++ citrain/jenkins-templates/build.xml.tmpl 2015-09-02 03:52:46 +0000 |
4 | @@ -85,7 +85,7 @@ |
5 | [ "$DEBUG" = "true" ] && set -x |
6 | |
7 | # Cleanup workspace |
8 | -pwd|grep -q workspace && rm -f * |
9 | +rm -rf $WORKSPACE/* |
10 | |
11 | cd {SILOS_DIR}/{SILO_NAME} |
12 | |
13 | |
14 | === modified file 'citrain/jenkins-templates/publish.xml.tmpl' |
15 | --- citrain/jenkins-templates/publish.xml.tmpl 2015-03-13 04:48:32 +0000 |
16 | +++ citrain/jenkins-templates/publish.xml.tmpl 2015-09-02 03:52:46 +0000 |
17 | @@ -25,11 +25,6 @@ |
18 | <description>Ack packaging changes</description> |
19 | <defaultValue>false</defaultValue> |
20 | </hudson.model.BooleanParameterDefinition> |
21 | - <hudson.model.StringParameterDefinition> |
22 | - <name>PUBLISHER</name> |
23 | - <description>If you sponsor this publishing for someone else, file this entry with his/her launchpad nickname. It defaults to your user id.</description> |
24 | - <defaultValue></defaultValue> |
25 | - </hudson.model.StringParameterDefinition> |
26 | <hudson.model.BooleanParameterDefinition> |
27 | <name>IGNORE_VERSIONDESTINATION</name> |
28 | <description>Ignore if the latest version in destination doesn't match when prepare was started</description> |
29 | @@ -63,32 +58,31 @@ |
30 | |
31 | [ "$DEBUG" = "true" ] && set -x |
32 | |
33 | -# Cleanup workspace |
34 | -pwd|grep -q workspace && rm -f * |
35 | +rm -rf $WORKSPACE/* |
36 | |
37 | cd {SILOS_DIR}/{SILO_NAME} |
38 | |
39 | {BINDIR}/publisher.py |
40 | - |
41 | -# copy artefacts |
42 | -cp *diff publisher.xml packagelist* $WORKSPACE/ 2>/dev/null || true |
43 | - |
44 | -# create rsync out dir |
45 | +RETVAL=$? |
46 | + |
47 | +cp *diff packagelist* $WORKSPACE/ 2>/dev/null || true |
48 | + |
49 | mkdir -p {RSYNC_OUTDIR} |
50 | mv packagelist_rsync_* {RSYNC_OUTDIR} 2>/dev/null || true |
51 | + |
52 | +# ubuntu/ directory only contains distro versions, and only used for diffing. |
53 | +# This cuts our disk usage in half: |
54 | +rm -rf ubuntu/ build-area/ |
55 | + |
56 | +exit $RETVAL |
57 | </command> |
58 | </hudson.tasks.Shell> |
59 | </builders> |
60 | <publishers> |
61 | <hudson.tasks.ArtifactArchiver> |
62 | - <artifacts>*.diff,*xml,packagelist*</artifacts> |
63 | + <artifacts>*</artifacts> |
64 | <latestOnly>false</latestOnly> |
65 | </hudson.tasks.ArtifactArchiver> |
66 | - <hudson.tasks.junit.JUnitResultArchiver> |
67 | - <testResults>*.xml</testResults> |
68 | - <keepLongStdio>false</keepLongStdio> |
69 | - <testDataPublishers/> |
70 | - </hudson.tasks.junit.JUnitResultArchiver> |
71 | </publishers> |
72 | <buildWrappers> |
73 | <org.jenkinsci.plugins.builduser.BuildUser plugin="build-user-vars-plugin@1.3"/> |
74 | |
75 | === modified file 'citrain/publisher.py' |
76 | --- citrain/publisher.py 2015-08-22 04:36:15 +0000 |
77 | +++ citrain/publisher.py 2015-09-02 03:52:46 +0000 |
78 | @@ -22,11 +22,8 @@ |
79 | ACK_PACKAGING |
80 | Publish packaging changes. Only done after manual reviews of the diff. |
81 | |
82 | -PUBLISHER |
83 | - Launchpad nickname of the person publishing that package. |
84 | - |
85 | BUILD_USER_ID |
86 | - This provides a default value if PUBLISHER is unset (Jenkins sets this one) |
87 | + Launchpad nickname of the person running this job. |
88 | |
89 | IGNORE_VERSIONDESTINATION |
90 | Ignore if the latest version in archive doesn't match what was prepared. |
91 | @@ -39,11 +36,9 @@ |
92 | """ |
93 | |
94 | import logging |
95 | -import glob |
96 | import sys |
97 | import os |
98 | |
99 | -from xml.sax.saxutils import escape |
100 | from collections import defaultdict |
101 | |
102 | sys.path.append(os.path.dirname(os.path.dirname(__file__))) |
103 | @@ -59,31 +54,16 @@ |
104 | from cupstream2distro.project import DotProject |
105 | from cupstream2distro.revno import Rev |
106 | from cupstream2distro.settings import ( |
107 | - PUBLISHER_ARTEFACTS_FILENAME, |
108 | - PACKAGING_DIFF, |
109 | STABLE_OVERLAY_PPA, |
110 | ) |
111 | from cupstream2distro.utils import ( |
112 | SILO_DIR, |
113 | env, |
114 | log_value_of, |
115 | - os_path_join_safe, |
116 | run_script, |
117 | - suppress, |
118 | - utf8_open, |
119 | ) |
120 | |
121 | |
122 | -UNSTABLE_XML_STRING = """\ |
123 | -<testsuite errors="0" failures="{}" name="" tests="1" time="0.1"> |
124 | - <testcase classname="MarkUnstable" name="Publisher" time="0.0">{} |
125 | - </testcase> |
126 | -</testsuite> |
127 | -""" |
128 | -FAILURE_TEMPLATE = """ |
129 | - <failure type="exception">{}</failure>""" |
130 | - |
131 | - |
132 | def get_distro_and_series(series): |
133 | """Parse the distro and series name from a series link.""" |
134 | env.DISTRO = series.distribution.name |
135 | @@ -96,8 +76,6 @@ |
136 | """Prevent the publish job from being run simultaneously.""" |
137 | if is_publishing: |
138 | raise PublishError('The publisher job is already running. Skipping.') |
139 | - with suppress(OSError): |
140 | - os.remove(os_path_join_safe(SILO_DIR(), PUBLISHER_ARTEFACTS_FILENAME)) |
141 | |
142 | |
143 | def check_versions_at_destination(dest, source_names): |
144 | @@ -152,31 +130,6 @@ |
145 | raise PublishError('Some merges have unbuilt revisions.') |
146 | |
147 | |
148 | -def confirm_publisher_identity(lp_people): |
149 | - """Identify the person who is running this job.""" |
150 | - nick = env.PUBLISHER or env.BUILD_USER_ID |
151 | - try: |
152 | - logging.debug('lp.people["{}"]: {}'.format(nick, lp_people[nick])) |
153 | - except KeyError: |
154 | - raise PublishError('{} is not a valid launchpad user id.'.format(nick)) |
155 | - logging.info('Publishing the silo as {}.'.format(nick)) |
156 | - env.PUBLISHER = nick |
157 | - |
158 | - |
159 | -def ack_packaging_diffs(): |
160 | - """Prevent publishing silos with packaging diffs without an ACK.""" |
161 | - if env.ACK_PACKAGING != 'true': |
162 | - diffs = glob.glob(SILO_DIR(PACKAGING_DIFF.format('*'))) |
163 | - for diff in diffs: |
164 | - basename = os.path.basename(diff) |
165 | - logging.error('Packaging changes found: {}'.format(basename)) |
166 | - if diffs: |
167 | - generate_xml_artifacts(diffs) |
168 | - raise PublishError('Packaging changes need manual ACKing.') |
169 | - else: |
170 | - logging.warning('Honoring your request to ACK packaging changes.') |
171 | - |
172 | - |
173 | # FIXME: Call this during the build job, so we have access to it sooner. |
174 | def push_branches(mps, lp_load): |
175 | """Push all local branches to Launchpad.""" |
176 | @@ -260,22 +213,14 @@ |
177 | source.source_package_version) |
178 | |
179 | |
180 | -def generate_xml_artifacts(details=[]): |
181 | - """Generate a fake test name xml for marking the build as unstable.""" |
182 | - failure = ''.join(FAILURE_TEMPLATE.format(escape(d)) for d in details) |
183 | - path = os_path_join_safe(SILO_DIR(), PUBLISHER_ARTEFACTS_FILENAME) |
184 | - with utf8_open(path, 'w') as data: |
185 | - data.write(UNSTABLE_XML_STRING.format(1 if details else 0, failure)) |
186 | - |
187 | - |
188 | def main(): |
189 | """Conduct a beautiful orchestra of publication.""" |
190 | silo_state = SiloState.safe_load(env.SILONAME) |
191 | mergemanager = MergeManager(silo_state) |
192 | - mergemanager.do('diff') |
193 | dest = silo_state.dest |
194 | ppa = silo_state.ppa |
195 | try: |
196 | + mergemanager.do('diff', 'checkupload', 'ackaging') |
197 | prevent_duplicate_publishing(silo_state.is_publishing) |
198 | get_distro_and_series(silo_state.series) |
199 | silo_state.set_publishing() |
200 | @@ -283,11 +228,8 @@ |
201 | check_versions_at_destination(dest, silo_state.all_projects) |
202 | check_for_unapproved(silo_state.mps, lp.load) |
203 | check_for_unbuilt_revids(silo_state.mps, lp.load) |
204 | - confirm_publisher_identity(lp.people) |
205 | - ack_packaging_diffs() |
206 | push_branches(silo_state.mps, lp.load) |
207 | initiate_publication(dest, ppa, silo_state.set_package_version_list) |
208 | - generate_xml_artifacts() |
209 | silo_state.set_published() |
210 | silo_state.set_migrating() |
211 | silo_state.mark_others_dirty() |
212 | |
213 | === modified file 'citrain/recipes/base.py' |
214 | --- citrain/recipes/base.py 2015-08-28 20:32:47 +0000 |
215 | +++ citrain/recipes/base.py 2015-09-02 03:52:46 +0000 |
216 | @@ -26,9 +26,13 @@ |
217 | |
218 | sys.path.append(os.path.dirname(os.path.dirname(__file__))) |
219 | |
220 | +from os.path import exists |
221 | from glob import glob |
222 | |
223 | +from lazr.restfulclient.errors import ClientError |
224 | + |
225 | from citrain.prepare_silo import clean_source |
226 | +from cupstream2distro.launchpadmanager import lp |
227 | from cupstream2distro.packagemanager import Package |
228 | from cupstream2distro.archive import Archive, ArchWatcher, newest |
229 | from cupstream2distro.branchhandling import Branch |
230 | @@ -36,11 +40,13 @@ |
231 | from cupstream2distro.version import V |
232 | from cupstream2distro.errors import ( |
233 | BuildError, |
234 | + PublishError, |
235 | MergeError, |
236 | MigrationError, |
237 | ) |
238 | from cupstream2distro.settings import ( |
239 | DEPWAIT_TIMEOUT, |
240 | + PACKAGING_DIFF, |
241 | PPA_TIMEOUT, |
242 | TIME_BETWEEN_PPA_CHECKS, |
243 | ) |
244 | @@ -83,6 +89,8 @@ |
245 | |
246 | class BuildBase(Package, Branch, Archive): |
247 | """Outlines build steps common to all types of package builds.""" |
248 | + blame = lp.people[env.BUILD_USER_ID] if env.BUILD_USER_ID else None |
249 | + authorized = None |
250 | failures = set() |
251 | states = dict() |
252 | |
253 | @@ -253,7 +261,7 @@ |
254 | |
255 | def diff_phase(self): |
256 | """Generate a diff of the uploaded source compared to distro.""" |
257 | - if os.path.exists(self.path): |
258 | + if exists(self.path): |
259 | logging.info('Generating diff for {}...'.format(self.name)) |
260 | path = SILO_DIR('ubuntu', self.name) |
261 | dest_version = newest(self.dest, source_name=self.name) |
262 | @@ -264,6 +272,41 @@ |
263 | for new in glob(SILO_DIR(dsc)): |
264 | self.generate_package_diffs(old, new) |
265 | |
266 | + def checkupload_phase(self): |
267 | + """Confirm that the silo publisher has upload rights.""" |
268 | + sourcepub = self.dest.getPublishedSources( |
269 | + distro_series=self.series, |
270 | + source_name=self.name, |
271 | + status='Published', |
272 | + pocket='Release', |
273 | + exact_match=True)[0] |
274 | + try: |
275 | + self.dest.checkUpload( |
276 | + component=sourcepub.component_name, |
277 | + sourcepackagename=self.name, |
278 | + distroseries=self.series, |
279 | + pocket='Proposed', |
280 | + person=self.blame) |
281 | + self.authorized = True |
282 | + except ClientError: |
283 | + self.authorized = False |
284 | + logging.debug('{} authorized to upload {}? {}'.format( |
285 | + self.blame, self.name, self.authorized)) |
286 | + |
287 | + def enforce_authorization(self): |
288 | + """Enforce checkupload requirements.""" |
289 | + if not self.authorized: |
290 | + raise PublishError('{} not authorized to upload {}'.format( |
291 | + self.blame.name, self.name)) |
292 | + |
293 | + def ackaging_phase(self): |
294 | + """Ensure that packaging changes are correctly ACKed.""" |
295 | + if self.authorized and env.ACK_PACKAGING == 'true': |
296 | + logging.info('Honoring your request to ACK packaging changes.') |
297 | + elif exists(SILO_DIR(PACKAGING_DIFF.format(self.name))): |
298 | + self.enforce_authorization() |
299 | + raise PublishError('Packaging changes need manual ACKing.') |
300 | + |
301 | def migration_phase(self): |
302 | """Identify the location of this package in its migration.""" |
303 | version = DotProject(self.name).published_version |
304 | |
305 | === modified file 'citrain/recipes/manual.py' |
306 | --- citrain/recipes/manual.py 2015-08-21 05:46:52 +0000 |
307 | +++ citrain/recipes/manual.py 2015-09-02 03:52:46 +0000 |
308 | @@ -60,3 +60,8 @@ |
309 | |
310 | # Proceed with standard diffing. |
311 | super().diff_phase() |
312 | + |
313 | + def ackaging_phase(self): |
314 | + """All manual sources must be published by correct uploaders.""" |
315 | + self.enforce_authorization() |
316 | + super().ackaging_phase() |
317 | |
318 | === modified file 'cupstream2distro/settings.py' |
319 | --- cupstream2distro/settings.py 2015-08-28 20:32:47 +0000 |
320 | +++ cupstream2distro/settings.py 2015-09-02 03:52:46 +0000 |
321 | @@ -57,7 +57,6 @@ |
322 | |
323 | FULL_DIFF = '{}_content.diff' |
324 | PACKAGING_DIFF = '{}_packaging_changes.diff' |
325 | -PUBLISHER_ARTEFACTS_FILENAME = 'publisher.xml' |
326 | |
327 | OLD_STACK_DIR = 'old' |
328 | |
329 | |
330 | === modified file 'tests/strings.py' |
331 | --- tests/strings.py 2015-08-22 03:06:08 +0000 |
332 | +++ tests/strings.py 2015-09-02 03:52:46 +0000 |
333 | @@ -141,23 +141,6 @@ |
334 | |
335 | NO_SYMBOLS = MULTIPLE_SYMBOLS.replace('0replaceme', '42.0.0') |
336 | |
337 | -XML_TEMPLATE = """\ |
338 | -<testsuite errors="0" failures="{}" name="" tests="1" time="0.1"> |
339 | - <testcase classname="MarkUnstable" name="Publisher" time="0.0">{} |
340 | - </testcase> |
341 | -</testsuite> |
342 | -""" |
343 | - |
344 | -XML_NO_ERROR = XML_TEMPLATE.format(0, '') |
345 | - |
346 | -XML_1_ERROR = XML_TEMPLATE.format(1, """ |
347 | - <failure type="exception">one issue</failure>""") |
348 | - |
349 | -XML_2_ERRORS = XML_TEMPLATE.format(1, """ |
350 | - <failure type="exception">one issue</failure> |
351 | - <failure type="exception">a second issue</failure>""") |
352 | - |
353 | - |
354 | TAGLIST = """\ |
355 | 0.2.0+14.04.20140217.1-0ubuntu1 254 |
356 | 0.2.0+14.10.20140714.2-0ubuntu1 257 |
357 | |
358 | === modified file 'tests/unit/test_recipe_base.py' |
359 | --- tests/unit/test_recipe_base.py 2015-08-28 20:32:47 +0000 |
360 | +++ tests/unit/test_recipe_base.py 2015-09-02 03:52:46 +0000 |
361 | @@ -23,6 +23,7 @@ |
362 | |
363 | from citrain.recipes.base import ( |
364 | BuildBase, |
365 | + ClientError, |
366 | DEPWAIT_TIMEOUT as DW, |
367 | PPA_TIMEOUT as PT, |
368 | ) |
369 | @@ -30,11 +31,15 @@ |
370 | from cupstream2distro.errors import ( |
371 | BuildError, |
372 | CITrainError, |
373 | + PublishError, |
374 | MergeError, |
375 | MigrationError, |
376 | ) |
377 | |
378 | |
379 | +N = '\n' |
380 | + |
381 | + |
382 | class BuildFake(object): |
383 | """Mimic a launchpadlib build object.""" |
384 | def __init__(self, arch, status=''): |
385 | @@ -412,6 +417,72 @@ |
386 | status='Published') |
387 | build.generate_package_diffs.assert_called_once_with(None, 'new_dsc') |
388 | |
389 | + @patch('citrain.recipes.base.lp') |
390 | + def test_buildbase_checkupload_phase(self, lp_mock): |
391 | + """Ensure that we call checkupload correctly.""" |
392 | + src = Mock() |
393 | + robru = Mock() |
394 | + env.BUILD_USER_ID = 'robru' |
395 | + lp_mock.people = dict(robru=robru) |
396 | + build = BuildBase('qt', self.series, self.dest, self.ppa) |
397 | + build.blame = robru |
398 | + build.dest.getPublishedSources.return_value = [src] |
399 | + build.checkupload_phase() |
400 | + build.dest.getPublishedSources.assert_called_once_with( |
401 | + distro_series=self.series, |
402 | + status='Published', |
403 | + pocket='Release', |
404 | + exact_match=True, |
405 | + source_name='qt') |
406 | + build.dest.checkUpload.assert_called_once_with( |
407 | + component=src.component_name, |
408 | + distroseries=self.series, |
409 | + sourcepackagename='qt', |
410 | + pocket='Proposed', |
411 | + person=robru) |
412 | + self.assertTrue(build.authorized) |
413 | + |
414 | + @patch('citrain.recipes.base.lp') |
415 | + def test_buildbase_checkupload_phase_failed(self, lp_mock): |
416 | + """Ensure that we report invalid upload rights.""" |
417 | + src = Mock() |
418 | + robru = Mock() |
419 | + env.BUILD_USER_ID = 'robru' |
420 | + lp_mock.people = dict(robru=robru) |
421 | + build = BuildBase('qt', self.series, self.dest, self.ppa) |
422 | + build.blame = Mock() |
423 | + build.dest.getPublishedSources.return_value = [src] |
424 | + build.dest.checkUpload.side_effect = ClientError(None, None) |
425 | + build.checkupload_phase() |
426 | + self.assertFalse(build.authorized) |
427 | + |
428 | + def test_buildbase_ackaging_phase_authorized_success(self): |
429 | + """Ensure that authorized people can ACK.""" |
430 | + env.ACK_PACKAGING = 'true' |
431 | + build = BuildBase('qt', self.series, self.dest, self.ppa) |
432 | + build.authorized = True |
433 | + build.ackaging_phase() |
434 | + |
435 | + @patch('citrain.recipes.base.exists', Mock(return_value=True)) |
436 | + def test_buildbase_ackaging_phase_authorized_fail(self): |
437 | + """Ensure that authorized people can ACK.""" |
438 | + env.ACK_PACKAGING = 'false' |
439 | + build = BuildBase('qt', self.series, self.dest, self.ppa) |
440 | + build.authorized = True |
441 | + with self.assertRaisesRegexp(PublishError, 'need manual ACKing'): |
442 | + build.ackaging_phase() |
443 | + |
444 | + @patch('citrain.recipes.base.exists', Mock(return_value=True)) |
445 | + def test_buildbase_ackaging_phase_authorized_unauthorized(self): |
446 | + """Ensure that authorized people can ACK.""" |
447 | + env.ACK_PACKAGING = 'true' |
448 | + build = BuildBase('qt', self.series, self.dest, self.ppa) |
449 | + build.authorized = False |
450 | + build.blame = Mock() |
451 | + build.blame.name = 'you are' |
452 | + with self.assertRaisesRegexp(PublishError, 'you are not authorized'): |
453 | + build.ackaging_phase() |
454 | + |
455 | @patch('citrain.recipes.base.DotProject') |
456 | def test_buildbase_migration_phase(self, dp_mock): |
457 | """Report the location status of this package.""" |
458 | |
459 | === modified file 'tests/unit/test_recipe_manual.py' |
460 | --- tests/unit/test_recipe_manual.py 2015-08-21 05:46:52 +0000 |
461 | +++ tests/unit/test_recipe_manual.py 2015-09-02 03:52:46 +0000 |
462 | @@ -72,3 +72,14 @@ |
463 | manual.get_from_archive.assert_called_once_with( |
464 | self.tempdir + '/', manual.silo_ppa) |
465 | BuildBase.diff_phase.assert_called_once_with() |
466 | + |
467 | + def test_manual_ackaging(self): |
468 | + """Ensure that authorization always enforced in manual packages.""" |
469 | + env.ACK_PACKAGING = 'true' |
470 | + manual = Manual('flappy', self.series, self.dest, self.ppa) |
471 | + manual.blame = Mock() |
472 | + manual.blame.name = 'stop' |
473 | + manual.authorized = True |
474 | + manual.enforce_authorization = Mock() |
475 | + manual.ackaging_phase() |
476 | + manual.enforce_authorization.assert_called_once_with() |
477 | |
478 | === modified file 'tests/unit/test_script_publisher.py' |
479 | --- tests/unit/test_script_publisher.py 2015-08-22 03:16:02 +0000 |
480 | +++ tests/unit/test_script_publisher.py 2015-09-02 03:52:46 +0000 |
481 | @@ -21,14 +21,11 @@ |
482 | |
483 | from tests.unit.test_recipe_base import SourceFake |
484 | from tests.unit import CITrainScriptTestCase |
485 | -from tests import strings as s |
486 | |
487 | -from cupstream2distro.utils import env, os_path_join_safe, utf8_open |
488 | +from cupstream2distro.utils import env |
489 | from cupstream2distro.errors import PublishError, BranchError |
490 | -from cupstream2distro.settings import PACKAGING_DIFF |
491 | - |
492 | - |
493 | -PUB = 'publisher.xml' |
494 | + |
495 | + |
496 | N = '\n' |
497 | |
498 | |
499 | @@ -54,24 +51,6 @@ |
500 | env.DISTRO = 'ubuntu' |
501 | env.SERIES = 'vivid' |
502 | |
503 | - def test_generate_xml_artefacts_no_issue(self): |
504 | - """Generate the xml jenkins artefacts when no issue occured.""" |
505 | - self.script.generate_xml_artifacts([]) |
506 | - with utf8_open(os_path_join_safe(self.tempdir, PUB)) as data: |
507 | - self.assertEqual(data.read().split(N), s.XML_NO_ERROR.split(N)) |
508 | - |
509 | - def test_generate_xml_artefacts_one_failure(self): |
510 | - """Generate the xml jenkins artefacts when there is one failure.""" |
511 | - self.script.generate_xml_artifacts(['one issue']) |
512 | - with utf8_open(os_path_join_safe(self.tempdir, PUB)) as data: |
513 | - self.assertEqual(data.read().split(N), s.XML_1_ERROR.split(N)) |
514 | - |
515 | - def test_generate_xml_artefacts_two_failures(self): |
516 | - """Generate the xml artefacts when there is more than one failure.""" |
517 | - self.script.generate_xml_artifacts(['one issue', 'a second issue']) |
518 | - with utf8_open(os_path_join_safe(self.tempdir, PUB)) as data: |
519 | - self.assertEqual(data.read().split(N), s.XML_2_ERRORS.split(N)) |
520 | - |
521 | def test_get_distro_and_series(self): |
522 | """Given a series URL, identify the distro and series.""" |
523 | env.DISTRO, env.SERIES = ('', '') |
524 | @@ -287,8 +266,6 @@ |
525 | def test_prevent_duplicate_publishing_ok(self): |
526 | """Ensure we can publish ok the first time.""" |
527 | self.script.prevent_duplicate_publishing(False) |
528 | - self.script.os.remove.assert_called_once_with( |
529 | - os_path_join_safe(self.tempdir, PUB)) |
530 | |
531 | def test_prevent_duplicate_publishing(self): |
532 | """Ensure main function cowardly refuses to run twice.""" |
533 | @@ -425,63 +402,6 @@ |
534 | call('example.com/1234'), |
535 | ]) |
536 | |
537 | - def test_confirm_publisher_identity_success(self): |
538 | - """Ensure that we can correctly identify the publisher.""" |
539 | - lp_people = defaultdict(str) |
540 | - env.PUBLISHER = '' |
541 | - env.BUILD_USER_ID = 'vorlon' |
542 | - self.script.confirm_publisher_identity(lp_people) |
543 | - self.assertEqual(lp_people, {'vorlon': ''}) |
544 | - self.assertEqual(env.PUBLISHER, 'vorlon') |
545 | - |
546 | - def test_confirm_publisher_identity_failure(self): |
547 | - """Ensure that we fail to publish without identifying the publisher.""" |
548 | - lp_people = dict() |
549 | - env.PUBLISHER = '' |
550 | - env.BUILD_USER_ID = 'vorlon' |
551 | - with self.assertRaisesRegexp(PublishError, 'not a valid launchpad'): |
552 | - self.script.confirm_publisher_identity(lp_people) |
553 | - self.assertEqual(lp_people, {}) |
554 | - self.assertEqual(env.PUBLISHER, '') |
555 | - |
556 | - def test_ack_packaging_diffs_acked(self): |
557 | - """ack_packaging_diffs acknowledges ACK.""" |
558 | - self.script.generate_xml_artifacts = Mock() |
559 | - env.ACK_PACKAGING = 'true' |
560 | - self.script.ack_packaging_diffs() |
561 | - self.assertEqual(self.script.glob.glob.call_count, 0) |
562 | - self.assertEqual(self.script.logging.error.call_count, 0) |
563 | - self.assertEqual(self.script.generate_xml_artifacts.call_count, 0) |
564 | - self.script.logging.warning.assert_called_once_with( |
565 | - 'Honoring your request to ACK packaging changes.') |
566 | - |
567 | - def test_ack_packaging_diffs_none_to_ack(self): |
568 | - """ack_packaging_diffs approved of no diffs present.""" |
569 | - env.ACK_PACKAGING = 'false' |
570 | - self.script.generate_xml_artifacts = Mock() |
571 | - self.script.glob.glob.return_value = [] |
572 | - self.script.ack_packaging_diffs() |
573 | - self.script.glob.glob.assert_called_once_with( |
574 | - os_path_join_safe(self.tempdir, PACKAGING_DIFF.format('*'))) |
575 | - self.assertEqual(self.script.logging.error.call_count, 0) |
576 | - self.assertEqual(self.script.generate_xml_artifacts.call_count, 0) |
577 | - |
578 | - def test_ack_packaging_diffs_halts_when_diff_found(self): |
579 | - """ack_packaging_diffs hates those diffs you have!""" |
580 | - env.ACK_PACKAGING = 'false' |
581 | - self.script.generate_xml_artifacts = Mock() |
582 | - self.script.glob.glob.return_value = ['/my/diff1', '/my/diff2'] |
583 | - with self.assertRaisesRegexp(PublishError, 'need manual ACKing'): |
584 | - self.script.ack_packaging_diffs() |
585 | - self.script.glob.glob.assert_called_once_with( |
586 | - os_path_join_safe(self.tempdir, PACKAGING_DIFF.format('*'))) |
587 | - self.assertEquals( |
588 | - self.script.logging.error.mock_calls, |
589 | - [call('Packaging changes found: diff1'), |
590 | - call('Packaging changes found: diff2')]) |
591 | - self.script.generate_xml_artifacts.assert_called_once_with( |
592 | - self.script.glob.glob.return_value) |
593 | - |
594 | def test_copy_to_dest(self): |
595 | """Ensure that we poke the LP API correctly for copyPackage.""" |
596 | sources = [ |
597 | @@ -523,11 +443,8 @@ |
598 | self.script.check_versions_at_destination = Mock() |
599 | self.script.check_for_unapproved = Mock() |
600 | self.script.check_for_unbuilt_revids = Mock() |
601 | - self.script.confirm_publisher_identity = Mock() |
602 | - self.script.ack_packaging_diffs = Mock() |
603 | self.script.push_branches = Mock() |
604 | self.script.initiate_publication = Mock() |
605 | - self.script.generate_xml_artifacts = Mock() |
606 | self.script.SiloState.safe_load.return_value.series = \ |
607 | 'https://api.launchpad.net/devel/ubuntu/vivid' |
608 | |
609 | @@ -540,7 +457,7 @@ |
610 | self.assertEqual(self.script.main(), 0) |
611 | self.script.MergeManager.assert_called_once_with(state) |
612 | self.script.MergeManager.return_value.do.assert_called_once_with( |
613 | - 'diff') |
614 | + 'diff', 'checkupload', 'ackaging') |
615 | self.script.prevent_duplicate_publishing.assert_called_once_with( |
616 | state.is_publishing) |
617 | state.set_publishing.assert_called_once_with() |
618 | @@ -550,14 +467,10 @@ |
619 | state.mps, self.script.lp.load) |
620 | self.script.check_for_unbuilt_revids.assert_called_once_with( |
621 | state.mps, self.script.lp.load) |
622 | - self.script.confirm_publisher_identity.assert_called_once_with( |
623 | - self.script.lp.people) |
624 | - self.script.ack_packaging_diffs.assert_called_once_with() |
625 | self.script.push_branches.assert_called_once_with( |
626 | state.mps, self.script.lp.load) |
627 | self.script.initiate_publication.assert_called_once_with( |
628 | dest, ppa, state.set_package_version_list) |
629 | - self.script.generate_xml_artifacts.assert_called_once_with() |
630 | state.set_published.assert_called_once_with() |
631 | state.set_migrating.assert_called_once_with() |
632 | self.assertEqual(state.save_config.mock_calls, [call(), call()]) |
633 | @@ -579,8 +492,6 @@ |
634 | state.mps, self.script.lp.load) |
635 | self.script.check_for_unbuilt_revids.assert_called_once_with( |
636 | state.mps, self.script.lp.load) |
637 | - self.script.confirm_publisher_identity.assert_called_once_with( |
638 | - self.script.lp.people) |
639 | self.script.push_branches.assert_called_once_with( |
640 | state.mps, self.script.lp.load) |
641 | self.assertEqual(self.script.initiate_publication.call_count, 0) |
PASSED: Continuous integration, rev:1066 jenkins. qa.ubuntu. com/job/ cu2d-choo- choo-ci/ 733/
http://
Executed test runs:
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/cu2d- choo-choo- ci/733/ rebuild
http://