Merge lp:~robru/cupstream2distro/check-approved-uploaders-for-publish into lp:cupstream2distro

Proposed by Robert Bruce Park
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
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.

To post a comment you must log in.
1066. By Robert Bruce Park

Catch ClientError.

1067. By Robert Bruce Park

Log PublishError properly.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1066
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/733/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/733/rebuild

review: Approve (continuous-integration)
1068. By Robert Bruce Park

Absorb redundant confirm_publisher_identity.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1068
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/734/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/734/rebuild

review: Approve (continuous-integration)
1069. By Robert Bruce Park

More logging.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1069
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/735/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/735/rebuild

review: Approve (continuous-integration)
1070. By Robert Bruce Park

No more honor system for who is acking packages.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1070
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/736/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/736/rebuild

review: Approve (continuous-integration)
1071. By Robert Bruce Park

Enforce checkupload for all manual sources but merges only with diffs.

1072. By Robert Bruce Park

Debug logging.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1072
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/737/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/737/rebuild

review: Approve (continuous-integration)
1073. By Robert Bruce Park

Stop generating XML artifacts.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1073
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/738/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/738/rebuild

review: Approve (continuous-integration)
1074. By Robert Bruce Park

Fail properly.

1075. By Robert Bruce Park

-rf

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1075
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/739/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/739/rebuild

review: Approve (continuous-integration)
1076. By Robert Bruce Park

Set self.authorized after, just to be sure.

Revision history for this message
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.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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" ] &amp;&amp; set -x
32
33-# Cleanup workspace
34-pwd|grep -q workspace &amp;&amp; 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&gt;/dev/null || true
43-
44-# create rsync out dir
45+RETVAL=$?
46+
47+cp *diff packagelist* $WORKSPACE/ 2&gt;/dev/null || true
48+
49 mkdir -p {RSYNC_OUTDIR}
50 mv packagelist_rsync_* {RSYNC_OUTDIR} 2&gt;/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)

Subscribers

People subscribed via source and target branches