1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# Copyright 2010 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
from datetime import timedelta
from storm.locals import Store
from zope.security.proxy import removeSecurityProxy
from lp.buildmaster.enums import BuildStatus
from lp.code.mail.sourcepackagerecipebuild import (
SourcePackageRecipeBuildMailer,
)
from lp.services.config import config
from lp.services.webapp import canonical_url
from lp.testing import TestCaseWithFactory
from lp.testing.layers import LaunchpadFunctionalLayer
expected_body = u"""\
* State: Successfully built
* Recipe: person/recipe
* Archive: archiveowner/ppa
* Distroseries: distroseries
* Duration: 5 minutes
* Build Log: %s
* Upload Log:
* Builder: http://launchpad.dev/builders/bob
"""
superseded_body = u"""\
* State: Build for superseded Source
* Recipe: person/recipe
* Archive: archiveowner/ppa
* Distroseries: distroseries
* Duration:
* Build Log:
* Upload Log:
* Builder:
"""
class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
layer = LaunchpadFunctionalLayer
def makeStatusEmail(self, build):
mailer = SourcePackageRecipeBuildMailer.forStatus(build)
email = removeSecurityProxy(build.requester).preferredemail.email
return mailer.generateEmail(email, build.requester)
def test_generateEmail(self):
"""GenerateEmail produces the right headers and body."""
person = self.factory.makePerson(name='person')
cake = self.factory.makeSourcePackageRecipe(
name=u'recipe', owner=person)
pantry_owner = self.factory.makePerson(name='archiveowner')
pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)
secret = self.factory.makeDistroSeries(name=u'distroseries')
build = self.factory.makeSourcePackageRecipeBuild(
recipe=cake, distroseries=secret, archive=pantry,
status=BuildStatus.FULLYBUILT, duration=timedelta(minutes=5))
naked_build = removeSecurityProxy(build)
naked_build.builder = self.factory.makeBuilder(name='bob')
naked_build.log = self.factory.makeLibraryFileAlias()
Store.of(build).flush()
ctrl = self.makeStatusEmail(build)
self.assertEqual(
u'[recipe build #%d] of ~person recipe in distroseries: '
'Successfully built' % (build.id), ctrl.subject)
body, footer = ctrl.body.split('\n-- \n')
self.assertEqual(
expected_body % build.log.getURL(), body)
build_url = canonical_url(build)
self.assertEqual(
'%s\nYou are the requester of the build.\n' % build_url, footer)
self.assertEqual(
config.canonical.noreply_from_address, ctrl.from_addr)
self.assertEqual(
'Requester', ctrl.headers['X-Launchpad-Message-Rationale'])
self.assertEqual(
'recipe-build-status',
ctrl.headers['X-Launchpad-Notification-Type'])
self.assertEqual(
'FULLYBUILT', ctrl.headers['X-Launchpad-Build-State'])
def test_generateEmail_with_null_fields(self):
"""GenerateEmail works when many fields are NULL."""
person = self.factory.makePerson(name='person')
cake = self.factory.makeSourcePackageRecipe(
name=u'recipe', owner=person)
pantry_owner = self.factory.makePerson(name='archiveowner')
pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)
secret = self.factory.makeDistroSeries(name=u'distroseries')
build = self.factory.makeSourcePackageRecipeBuild(
recipe=cake, distroseries=secret, archive=pantry,
status=BuildStatus.SUPERSEDED)
Store.of(build).flush()
ctrl = self.makeStatusEmail(build)
self.assertEqual(
u'[recipe build #%d] of ~person recipe in distroseries: '
'Build for superseded Source' % (build.id), ctrl.subject)
body, footer = ctrl.body.split('\n-- \n')
self.assertEqual(superseded_body, body)
build_url = canonical_url(build)
self.assertEqual(
'%s\nYou are the requester of the build.\n' % build_url, footer)
self.assertEqual(
config.canonical.noreply_from_address, ctrl.from_addr)
self.assertEqual(
'Requester', ctrl.headers['X-Launchpad-Message-Rationale'])
self.assertEqual(
'recipe-build-status',
ctrl.headers['X-Launchpad-Notification-Type'])
self.assertEqual(
'SUPERSEDED', ctrl.headers['X-Launchpad-Build-State'])
def test_generateEmail_upload_failure(self):
"""GenerateEmail works when many fields are NULL."""
build = self.factory.makeSourcePackageRecipeBuild()
removeSecurityProxy(build).upload_log = (
self.factory.makeLibraryFileAlias())
upload_log_fragment = 'Upload Log: %s' % build.upload_log_url
ctrl = self.makeStatusEmail(build)
self.assertTrue(upload_log_fragment in ctrl.body)
|