Merge lp:~james-w/launchpad/no-more-sampledata-0 into lp:launchpad
- no-more-sampledata-0
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Jonathan Lange |
Approved revision: | no longer in the source branch. |
Merged at revision: | 11293 |
Proposed branch: | lp:~james-w/launchpad/no-more-sampledata-0 |
Merge into: | lp:launchpad |
Diff against target: |
1358 lines (+769/-248) 10 files modified
lib/lp/soyuz/tests/ppa.py (+13/-7) lib/lp/soyuz/tests/soyuz.py (+15/-10) lib/lp/soyuz/tests/soyuzbuilddhelpers.py (+4/-3) lib/lp/soyuz/tests/test_archive.py (+135/-155) lib/lp/testing/__init__.py (+3/-8) lib/lp/testing/factory.py (+84/-57) lib/lp/testing/matchers.py (+135/-0) lib/lp/testing/sampledata.py (+38/-0) lib/lp/testing/tests/test_factory.py (+171/-8) lib/lp/testing/tests/test_matchers.py (+171/-0) |
To merge this branch: | bzr merge lp:~james-w/launchpad/no-more-sampledata-0 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jonathan Lange (community) | Approve | ||
Review via email: mp+31470@code.launchpad.net |
Commit message
Description of the change
Hi,
This changes a bunch of soyuz tests to not use the sampledata.
It goes a bit further than that in that it restructures them to
have less setup and to create the things they need using the
factory rather than SoyuzTestPublisher.
In addition I moved some other code that is too deeply buried
right now in to lp.testing.
with some new methods to satisfy the needs of the changed code.
Thanks,
James
Jonathan Lange (jml) wrote : | # |
Jonathan Lange (jml) wrote : | # |
As per my comments via email.
James Westby (james-w) wrote : | # |
> The review below mostly picks up on some naming standard glitches and
> points out some things that could be improved in the soyuz tests
> (rather than in your changes). However, I've also got a couple of
> questions about your changes and would very much appreciate hearing
> back from you.
>
> I also feel a little guilty about making so many petty comments when
> you've done such a helpful thing. Please do not feel obliged to act on
> all of my suggestions.
Thanks for the review. The intent is to improve the understandability
of the tests, so your suggestions are helpful.
> > === modified file 'lib/lp/
> > --- lib/lp/
> > +++ lib/lp/
> > @@ -25,6 +25,10 @@
> > from lp.soyuz.
> > from lp.soyuz.
> > PackagePublishi
> > +from lp.testing.
> > + HOARY_DISTROSER
> > + MOZILLA_
> MOZILLA_
> > + NAME16_PERSON_NAME, UBUNTU_TEAM_NAME)
> >
>
> I'm very glad you've started putting things in the sampledata module.
>
> Would it be possible to change these names to clarify the intent
> behind their use?
>
> For example, NAME16_PERSON_NAME tells me nothing about the person
> object, and when I see it in a test, I don't know why name16 was
> chosen instead of name15. UBUNTU_
> Likewise, it would be good to have intent-revealing names for the
> FIREFOX constants and the HOARY constants.
I can do that, but it will require some research. It's one of the
problems with sampledata that I don't know what the intent is.
> My comment about the other error message applies here. I think it can
> be dropped. (If archives have unhelpful __repr__ implementations, we
> should fix that rather than working around it all the time in tests).
They have the default repr, should we change that?
> Hmm. These assertions look very much like the ones previous. Is there
> a domain-specific assertion method or Matcher to be had here?
Probably, I'll take a look. I think there's only two uses, so it hadn't
hit my refactoring threshold yet.
> I think this one needs a comment. What's an LFA?
LibraryFileAlias, I thought it was standard parlance, should I expand the
variable name instead?
Thanks,
James
Jonathan Lange (jml) wrote : | # |
On Mon, Aug 2, 2010 at 2:25 PM, James Westby <email address hidden> wrote:
...
>> > === modified file 'lib/lp/
>> > --- lib/lp/
>> > +++ lib/lp/
>> > @@ -25,6 +25,10 @@
>> > from lp.soyuz.
>> > from lp.soyuz.
>> > PackagePublishi
>> > +from lp.testing.
>> > + HOARY_DISTROSER
>> > + MOZILLA_
>> MOZILLA_
>> > + NAME16_PERSON_NAME, UBUNTU_TEAM_NAME)
>> >
>>
>> I'm very glad you've started putting things in the sampledata module.
>>
>> Would it be possible to change these names to clarify the intent
>> behind their use?
>>
>> For example, NAME16_PERSON_NAME tells me nothing about the person
>> object, and when I see it in a test, I don't know why name16 was
>> chosen instead of name15. UBUNTU_
>> Likewise, it would be good to have intent-revealing names for the
>> FIREFOX constants and the HOARY constants.
>
> I can do that, but it will require some research. It's one of the
> problems with sampledata that I don't know what the intent is.
>
At the very least make the UBUNTU_
I don't want to make you spend a whole heap of time figuring out why
all of this stuff gets used. However, I'm also a little worried that
the trend will continue. Perhaps we could work a little to avoid the
risk by adding some comments or something. I don't know.
>> My comment about the other error message applies here. I think it can
>> be dropped. (If archives have unhelpful __repr__ implementations, we
>> should fix that rather than working around it all the time in tests).
>
> They have the default repr, should we change that?
>
Don't bother. Someone else can when it comes time to actually debug.
>> Hmm. These assertions look very much like the ones previous. Is there
>> a domain-specific assertion method or Matcher to be had here?
>
> Probably, I'll take a look. I think there's only two uses, so it hadn't
> hit my refactoring threshold yet.
>
Yeah, maybe it's not needed.
>> I think this one needs a comment. What's an LFA?
>
> LibraryFileAlias, I thought it was standard parlance, should I expand the
> variable name instead?
>
Hmm, maybe it is. I don't do much with the librarian.
I have no strong opinion about the rename. Follow your heart.
cheers,
jml
James Westby (james-w) wrote : | # |
Hi,
I have made all the requested changes.
I went a little further than necessary and created some matchers
rather than new assertion methods.
Thanks,
James
James Westby (james-w) wrote : | # |
I tried to rename the sampledata variables as best I could, but for things
like "hoary", it just means "one bag of stuff as opposed to 'warty' which
is a different bag of stuff."
Thanks,
James
Robert Collins (lifeless) wrote : | # |
Something that stood out to me, and perhaps jml's review mentions this
is that your new factory methods don't seem to have tests?
-Rob
James Westby (james-w) wrote : | # |
On Mon, 02 Aug 2010 20:01:40 -0000, Robert Collins <email address hidden> wrote:
> Something that stood out to me, and perhaps jml's review mentions this
> is that your new factory methods don't seem to have tests?
It did, and they do now.
Thanks,
James
Jonathan Lange (jml) wrote : | # |
Awesome. Thanks so much.
Preview Diff
1 | === modified file 'lib/lp/soyuz/tests/ppa.py' |
2 | --- lib/lp/soyuz/tests/ppa.py 2010-03-11 16:48:37 +0000 |
3 | +++ lib/lp/soyuz/tests/ppa.py 2010-08-04 00:47:45 +0000 |
4 | @@ -25,6 +25,10 @@ |
5 | from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet |
6 | from lp.soyuz.interfaces.publishing import ( |
7 | PackagePublishingPriority, PackagePublishingStatus) |
8 | +from lp.testing.sampledata import ( |
9 | + HOARY_DISTROSERIES_NAME, I386_ARCHITECTURE_NAME, MAIN_COMPONENT_NAME, |
10 | + UBUNTU_DEVELOPER_ADMIN_NAME, UBUNTU_UPLOAD_TEAM_NAME, |
11 | + WARTY_ONLY_SOURCEPACKAGENAME, WARTY_ONLY_SOURCEPACKAGEVERSION) |
12 | |
13 | |
14 | def publishToTeamPPA(team_name=None, distroseries_name=None, |
15 | @@ -40,15 +44,16 @@ |
16 | The team PPA must already be created. |
17 | """ |
18 | if team_name is None: |
19 | - team_name = "ubuntu-team" |
20 | + team_name = UBUNTU_UPLOAD_TEAM_NAME |
21 | if team_member_name is None: |
22 | - team_member_name = "name16" |
23 | + team_member_name = UBUNTU_DEVELOPER_ADMIN_NAME |
24 | team = getUtility(IPersonSet).getByName(team_name) |
25 | _publishToPPA( |
26 | team.archive, team_member_name, distroseries_name, |
27 | sourcepackage_name, sourcepackage_version, distribution_name, |
28 | binarypackage_version, publishing_status, arch) |
29 | |
30 | + |
31 | def publishToPPA(person_name, distroseries_name=None, sourcepackage_name=None, |
32 | sourcepackage_version=None, distribution_name=None, |
33 | binarypackage_version=None, publishing_status=None, |
34 | @@ -59,6 +64,7 @@ |
35 | distribution_name, binarypackage_version, publishing_status, |
36 | arch) |
37 | |
38 | + |
39 | def _publishToPPA(archive, person_name, distroseries_name, sourcepackage_name, |
40 | sourcepackage_version, distribution_name, |
41 | binarypackage_version, publishing_status, arch): |
42 | @@ -67,15 +73,15 @@ |
43 | else: |
44 | distribution = getUtility(IDistributionSet)[distribution_name] |
45 | if distroseries_name is None: |
46 | - distroseries_name = "hoary" |
47 | + distroseries_name = HOARY_DISTROSERIES_NAME |
48 | if sourcepackage_name is None: |
49 | - sourcepackage_name = "mozilla-firefox" |
50 | + sourcepackage_name = WARTY_ONLY_SOURCEPACKAGENAME |
51 | if sourcepackage_version is None: |
52 | - sourcepackage_version = "0.9" |
53 | + sourcepackage_version = WARTY_ONLY_SOURCEPACKAGEVERSION |
54 | if publishing_status is None: |
55 | publishing_status = PackagePublishingStatus.PENDING |
56 | if arch is None: |
57 | - arch = "i386" |
58 | + arch = I386_ARCHITECTURE_NAME |
59 | |
60 | sourcepackagename = getUtility(ISourcePackageNameSet)[sourcepackage_name] |
61 | distroseries = distribution[distroseries_name] |
62 | @@ -88,7 +94,7 @@ |
63 | # XXX: kiko 2007-10-25: oy, what a hack. I need to test with cprov |
64 | # and he doesn't have a signing key in the database |
65 | sourcepackagerelease.dscsigningkey = person.gpg_keys[0] |
66 | - main_component = getUtility(IComponentSet)['main'] |
67 | + main_component = getUtility(IComponentSet)[MAIN_COMPONENT_NAME] |
68 | SourcePackagePublishingHistory( |
69 | distroseries=distroseries, |
70 | sourcepackagerelease=sourcepackagerelease, |
71 | |
72 | === modified file 'lib/lp/soyuz/tests/soyuz.py' |
73 | --- lib/lp/soyuz/tests/soyuz.py 2010-02-08 11:40:06 +0000 |
74 | +++ lib/lp/soyuz/tests/soyuz.py 2010-08-04 00:47:45 +0000 |
75 | @@ -27,14 +27,19 @@ |
76 | from lp.soyuz.model.publishing import ( |
77 | SourcePackagePublishingHistory, |
78 | BinaryPackagePublishingHistory) |
79 | +from lp.testing.sampledata import ( |
80 | + BUILDD_ADMIN_USERNAME, CHROOT_LIBRARYFILEALIAS, I386_ARCHITECTURE_NAME, |
81 | + LAUNCHPAD_DBUSER_NAME, UBUNTU_DISTRIBUTION_NAME, WARTY_DISTROSERIES_NAME, |
82 | + WARTY_UPDATES_SUITE_NAME) |
83 | |
84 | |
85 | class SoyuzTestHelper: |
86 | """Helper class to support easier tests in Soyuz component.""" |
87 | |
88 | def __init__(self): |
89 | - self.ubuntu = getUtility(IDistributionSet)['ubuntu'] |
90 | - self.cprov_archive = getUtility(IPersonSet).getByName('cprov').archive |
91 | + self.ubuntu = getUtility(IDistributionSet)[UBUNTU_DISTRIBUTION_NAME] |
92 | + self.cprov_archive = getUtility( |
93 | + IPersonSet).getByName(BUILDD_ADMIN_USERNAME).archive |
94 | |
95 | @property |
96 | def sample_publishing_data(self): |
97 | @@ -142,12 +147,13 @@ |
98 | Store the `FakePackager` object used in the test uploads as `packager` |
99 | so the tests can reuse it if necessary. |
100 | """ |
101 | - self.layer.alterConnection(dbuser='launchpad') |
102 | + self.layer.alterConnection(dbuser=LAUNCHPAD_DBUSER_NAME) |
103 | |
104 | - fake_chroot = LibraryFileAlias.get(1) |
105 | - ubuntu = getUtility(IDistributionSet).getByName('ubuntu') |
106 | - warty = ubuntu.getSeries('warty') |
107 | - warty['i386'].addOrUpdateChroot(fake_chroot) |
108 | + fake_chroot = LibraryFileAlias.get(CHROOT_LIBRARYFILEALIAS) |
109 | + ubuntu = getUtility(IDistributionSet).getByName( |
110 | + UBUNTU_DISTRIBUTION_NAME) |
111 | + warty = ubuntu.getSeries(WARTY_DISTROSERIES_NAME) |
112 | + warty[I386_ARCHITECTURE_NAME].addOrUpdateChroot(fake_chroot) |
113 | |
114 | self.layer.txn.commit() |
115 | |
116 | @@ -176,13 +182,13 @@ |
117 | 'zeca', '1.0', 'foo.bar@canonical.com-passwordless.sec') |
118 | packager.buildUpstream() |
119 | packager.buildSource() |
120 | - packager.uploadSourceVersion('1.0-1', suite="warty-updates") |
121 | + packager.uploadSourceVersion('1.0-1', suite=WARTY_UPDATES_SUITE_NAME) |
122 | |
123 | # Upload a new version of the source, so a PackageDiff can |
124 | # be created. |
125 | packager.buildVersion('1.0-2', changelog_text="cookies") |
126 | packager.buildSource(include_orig=False) |
127 | - packager.uploadSourceVersion('1.0-2', suite="warty-updates") |
128 | + packager.uploadSourceVersion('1.0-2', suite=WARTY_UPDATES_SUITE_NAME) |
129 | |
130 | # Check if there is exactly one pending PackageDiff record and |
131 | # It's the one we have just created. |
132 | @@ -193,4 +199,3 @@ |
133 | def getPendingDiffs(self): |
134 | """Pending `PackageDiff` available.""" |
135 | return getUtility(IPackageDiffSet).getPendingDiffs() |
136 | - |
137 | |
138 | === modified file 'lib/lp/soyuz/tests/soyuzbuilddhelpers.py' |
139 | --- lib/lp/soyuz/tests/soyuzbuilddhelpers.py 2010-04-14 13:54:06 +0000 |
140 | +++ lib/lp/soyuz/tests/soyuzbuilddhelpers.py 2010-08-04 00:47:45 +0000 |
141 | @@ -26,6 +26,7 @@ |
142 | updateBuilderStatus) |
143 | from lp.soyuz.model.binarypackagebuildbehavior import ( |
144 | BinaryPackageBuildBehavior) |
145 | +from lp.testing.sampledata import I386_ARCHITECTURE_NAME |
146 | |
147 | |
148 | class MockBuilder: |
149 | @@ -85,7 +86,7 @@ |
150 | |
151 | The architecture tag can be customised during initialisation.""" |
152 | |
153 | - def __init__(self, arch_tag='i386'): |
154 | + def __init__(self, arch_tag=I386_ARCHITECTURE_NAME): |
155 | self.arch_tag = arch_tag |
156 | |
157 | def status(self): |
158 | @@ -159,7 +160,7 @@ |
159 | def getFile(self, sum): |
160 | if sum == "buildlog": |
161 | s = StringIO("This is a build log") |
162 | - s.headers = {'content-length':19} |
163 | + s.headers = {'content-length': 19} |
164 | return s |
165 | |
166 | |
167 | @@ -185,7 +186,7 @@ |
168 | if hash in self.valid_file_hashes: |
169 | content = "This is a %s" % hash |
170 | s = StringIO(content) |
171 | - s.headers = {'content-length':len(content)} |
172 | + s.headers = {'content-length': len(content)} |
173 | return s |
174 | |
175 | |
176 | |
177 | === modified file 'lib/lp/soyuz/tests/test_archive.py' |
178 | --- lib/lp/soyuz/tests/test_archive.py 2010-07-21 07:45:50 +0000 |
179 | +++ lib/lp/soyuz/tests/test_archive.py 2010-08-04 00:47:45 +0000 |
180 | @@ -3,10 +3,8 @@ |
181 | |
182 | """Test Archive features.""" |
183 | |
184 | -from datetime import date, datetime, timedelta |
185 | -import unittest |
186 | +from datetime import date, timedelta |
187 | |
188 | -import pytz |
189 | import transaction |
190 | |
191 | from zope.component import getUtility |
192 | @@ -29,7 +27,8 @@ |
193 | from lp.services.worlddata.interfaces.country import ICountrySet |
194 | from lp.soyuz.interfaces.archivearch import IArchiveArchSet |
195 | from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet |
196 | -from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat |
197 | +from lp.soyuz.interfaces.binarypackagerelease import ( |
198 | + BinaryPackageFileType, BinaryPackageFormat) |
199 | from lp.soyuz.interfaces.component import IComponentSet |
200 | from lp.soyuz.interfaces.processor import IProcessorFamilySet |
201 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus |
202 | @@ -42,185 +41,167 @@ |
203 | |
204 | class TestGetPublicationsInArchive(TestCaseWithFactory): |
205 | |
206 | - layer = LaunchpadZopelessLayer |
207 | - |
208 | - def setUp(self): |
209 | - """Use `SoyuzTestPublisher` to publish some sources in archives.""" |
210 | - super(TestGetPublicationsInArchive, self).setUp() |
211 | - |
212 | - self.distribution = getUtility(IDistributionSet)['ubuntutest'] |
213 | - |
214 | - # Create two PPAs for gedit. |
215 | - self.archives = {} |
216 | - self.archives['ubuntu-main'] = self.distribution.main_archive |
217 | - self.archives['gedit-nightly'] = self.factory.makeArchive( |
218 | - name="gedit-nightly", distribution=self.distribution) |
219 | - self.archives['gedit-beta'] = self.factory.makeArchive( |
220 | - name="gedit-beta", distribution=self.distribution) |
221 | - |
222 | - self.publisher = SoyuzTestPublisher() |
223 | - self.publisher.prepareBreezyAutotest() |
224 | - |
225 | - # Publish gedit in all three archives, but with different |
226 | - # upload dates. |
227 | - self.gedit_nightly_src_hist = self.publisher.getPubSource( |
228 | - sourcename="gedit", archive=self.archives['gedit-nightly'], |
229 | - date_uploaded=datetime(2010, 12, 1, tzinfo=pytz.UTC), |
230 | - status=PackagePublishingStatus.PUBLISHED) |
231 | - self.gedit_beta_src_hist = self.publisher.getPubSource( |
232 | - sourcename="gedit", archive=self.archives['gedit-beta'], |
233 | - date_uploaded=datetime(2010, 11, 30, tzinfo=pytz.UTC), |
234 | - status=PackagePublishingStatus.PUBLISHED) |
235 | - self.gedit_main_src_hist = self.publisher.getPubSource( |
236 | - sourcename="gedit", archive=self.archives['ubuntu-main'], |
237 | - date_uploaded=datetime(2010, 12, 30, tzinfo=pytz.UTC), |
238 | - status=PackagePublishingStatus.PUBLISHED) |
239 | - |
240 | - # Save the archive utility for easy access, as well as the gedit |
241 | - # source package name. |
242 | - self.archive_set = getUtility(IArchiveSet) |
243 | - spr = self.gedit_main_src_hist.sourcepackagerelease |
244 | - self.gedit_name = spr.sourcepackagename |
245 | - |
246 | - def testReturnsAllPublishedPublications(self): |
247 | + layer = DatabaseFunctionalLayer |
248 | + |
249 | + def makeArchivesForOneDistribution(self, count=3): |
250 | + distribution = self.factory.makeDistribution() |
251 | + archives = [] |
252 | + for i in range(count): |
253 | + archives.append( |
254 | + self.factory.makeArchive(distribution=distribution)) |
255 | + return archives |
256 | + |
257 | + def makeArchivesWithPublications(self, count=3): |
258 | + archives = self.makeArchivesForOneDistribution(count=count) |
259 | + sourcepackagename = self.factory.makeSourcePackageName() |
260 | + for archive in archives: |
261 | + self.factory.makeSourcePackagePublishingHistory( |
262 | + sourcepackagename=sourcepackagename, archive=archive, |
263 | + status=PackagePublishingStatus.PUBLISHED, |
264 | + ) |
265 | + return archives, sourcepackagename |
266 | + |
267 | + def getPublications(self, sourcepackagename, archives, distribution): |
268 | + return getUtility(IArchiveSet).getPublicationsInArchives( |
269 | + sourcepackagename, archives, distribution=distribution) |
270 | + |
271 | + def test_getPublications_returns_all_published_publications(self): |
272 | # Returns all currently published publications for archives |
273 | - results = self.archive_set.getPublicationsInArchives( |
274 | - self.gedit_name, self.archives.values(), |
275 | - distribution=self.distribution) |
276 | + archives, sourcepackagename = self.makeArchivesWithPublications() |
277 | + results = self.getPublications( |
278 | + sourcepackagename, archives, archives[0].distribution) |
279 | num_results = results.count() |
280 | - self.assertEquals(3, num_results, "Expected 3 publications but " |
281 | - "got %s" % num_results) |
282 | + self.assertEquals(3, num_results) |
283 | |
284 | - def testEmptyListOfArchives(self): |
285 | + def test_getPublications_empty_list_of_archives(self): |
286 | # Passing an empty list of archives will result in an empty |
287 | # resultset. |
288 | - results = self.archive_set.getPublicationsInArchives( |
289 | - self.gedit_name, [], distribution=self.distribution) |
290 | - self.assertEquals(0, results.count()) |
291 | - |
292 | - def testReturnsOnlyPublicationsForGivenArchives(self): |
293 | + archives, sourcepackagename = self.makeArchivesWithPublications() |
294 | + results = self.getPublications( |
295 | + sourcepackagename, [], archives[0].distribution) |
296 | + self.assertEquals([], list(results)) |
297 | + |
298 | + def assertPublicationsFromArchives(self, publications, archives): |
299 | + self.assertEquals(len(archives), publications.count()) |
300 | + for publication, archive in zip(publications, archives): |
301 | + self.assertEquals(archive, publication.archive) |
302 | + |
303 | + def test_getPublications_returns_only_for_given_archives(self): |
304 | # Returns only publications for the specified archives |
305 | - results = self.archive_set.getPublicationsInArchives( |
306 | - self.gedit_name, [self.archives['gedit-beta']], |
307 | - distribution=self.distribution) |
308 | - num_results = results.count() |
309 | - self.assertEquals(1, num_results, "Expected 1 publication but " |
310 | - "got %s" % num_results) |
311 | - self.assertEquals(self.archives['gedit-beta'], |
312 | - results[0].archive, |
313 | - "Expected publication from %s but was instead " |
314 | - "from %s." % ( |
315 | - self.archives['gedit-beta'].displayname, |
316 | - results[0].archive.displayname)) |
317 | + archives, sourcepackagename = self.makeArchivesWithPublications() |
318 | + results = self.getPublications( |
319 | + sourcepackagename, [archives[0]], archives[0].distribution) |
320 | + self.assertPublicationsFromArchives(results, [archives[0]]) |
321 | |
322 | - def testReturnsOnlyPublishedPublications(self): |
323 | + def test_getPublications_returns_only_published_publications(self): |
324 | # Publications that are not published will not be returned. |
325 | - secure_src_hist = self.gedit_beta_src_hist |
326 | - secure_src_hist.status = PackagePublishingStatus.PENDING |
327 | - |
328 | - results = self.archive_set.getPublicationsInArchives( |
329 | - self.gedit_name, [self.archives['gedit-beta']], |
330 | - distribution=self.distribution) |
331 | - num_results = results.count() |
332 | - self.assertEquals(0, num_results, "Expected 0 publication but " |
333 | - "got %s" % num_results) |
334 | - |
335 | - def testPubsForSpecificDistro(self): |
336 | + archive = self.factory.makeArchive() |
337 | + sourcepackagename = self.factory.makeSourcePackageName() |
338 | + self.factory.makeSourcePackagePublishingHistory( |
339 | + archive=archive, sourcepackagename=sourcepackagename, |
340 | + status=PackagePublishingStatus.PENDING) |
341 | + results = self.getPublications( |
342 | + sourcepackagename, [archive], archive.distribution) |
343 | + self.assertEquals([], list(results)) |
344 | + |
345 | + def publishSourceInNewArchive(self, sourcepackagename): |
346 | + distribution = self.factory.makeDistribution() |
347 | + distroseries = self.factory.makeDistroSeries( |
348 | + distribution=distribution) |
349 | + archive = self.factory.makeArchive(distribution=distribution) |
350 | + self.factory.makeSourcePackagePublishingHistory( |
351 | + archive=archive, sourcepackagename=sourcepackagename, |
352 | + distroseries=distroseries, |
353 | + status=PackagePublishingStatus.PUBLISHED) |
354 | + return archive |
355 | + |
356 | + def test_getPublications_for_specific_distro(self): |
357 | # Results can be filtered for specific distributions. |
358 | - |
359 | - # Add a publication in the ubuntu distribution |
360 | - ubuntu = getUtility(IDistributionSet)['ubuntu'] |
361 | - warty = ubuntu['warty'] |
362 | - gedit_main_src_hist = self.publisher.getPubSource( |
363 | - sourcename="gedit", |
364 | - archive=self.archives['ubuntu-main'], |
365 | - distroseries=warty, |
366 | - date_uploaded=datetime(2010, 12, 30, tzinfo=pytz.UTC), |
367 | - status=PackagePublishingStatus.PUBLISHED) |
368 | - |
369 | - # Only the 3 results for ubuntutest are returned when requested: |
370 | - results = self.archive_set.getPublicationsInArchives( |
371 | - self.gedit_name, self.archives.values(), |
372 | - distribution=self.distribution) |
373 | - num_results = results.count() |
374 | - self.assertEquals(3, num_results, "Expected 3 publications but " |
375 | - "got %s" % num_results) |
376 | - |
377 | - # Similarly, requesting the ubuntu publications only returns the |
378 | - # one we created: |
379 | - results = self.archive_set.getPublicationsInArchives( |
380 | - self.gedit_name, self.archives.values(), |
381 | - distribution=ubuntu) |
382 | - num_results = results.count() |
383 | - self.assertEquals(1, num_results, "Expected 1 publication but " |
384 | - "got %s" % num_results) |
385 | + sourcepackagename = self.factory.makeSourcePackageName() |
386 | + archive = self.publishSourceInNewArchive(sourcepackagename) |
387 | + other_archive = self.publishSourceInNewArchive(sourcepackagename) |
388 | + # We don't get the results for other_distribution |
389 | + results = self.getPublications( |
390 | + sourcepackagename, [archive, other_archive], |
391 | + distribution=archive.distribution) |
392 | + self.assertPublicationsFromArchives(results, [archive]) |
393 | |
394 | |
395 | class TestArchiveRepositorySize(TestCaseWithFactory): |
396 | |
397 | layer = LaunchpadZopelessLayer |
398 | |
399 | - def setUp(self): |
400 | - super(TestArchiveRepositorySize, self).setUp() |
401 | - self.publisher = SoyuzTestPublisher() |
402 | - self.publisher.prepareBreezyAutotest() |
403 | - self.ppa = self.factory.makeArchive( |
404 | - name="testing", distribution=self.publisher.ubuntutest) |
405 | + def publishDDEBInArchive(self, archive): |
406 | + """Publish an arbitrary DDEB with content in to the archive. |
407 | + |
408 | + Publishes a DDEB that will take up some space in to `archive`. |
409 | + |
410 | + :param archive: the IArchive to publish to. |
411 | + """ |
412 | + binarypackagerelease = self.factory.makeBinaryPackageRelease( |
413 | + binpackageformat=BinaryPackageFormat.DDEB) |
414 | + self.factory.makeBinaryPackagePublishingHistory( |
415 | + archive=archive, binarypackagerelease=binarypackagerelease, |
416 | + status=PackagePublishingStatus.PUBLISHED) |
417 | + self.factory.makeBinaryPackageFile( |
418 | + binarypackagerelease=binarypackagerelease, |
419 | + filetype=BinaryPackageFileType.DDEB) |
420 | + |
421 | + def test_empty_ppa_has_zero_binaries_size(self): |
422 | + # An empty PPA has no binaries so has zero binaries_size. |
423 | + ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA) |
424 | + self.assertEquals(0, ppa.binaries_size) |
425 | |
426 | def test_binaries_size_does_not_include_ddebs_for_ppas(self): |
427 | # DDEBs are not computed in the PPA binaries size because |
428 | # they are not being published. See bug #399444. |
429 | - self.assertEquals(0, self.ppa.binaries_size) |
430 | - self.publisher.getPubBinaries( |
431 | - filecontent='X', format=BinaryPackageFormat.DDEB, |
432 | - archive=self.ppa) |
433 | - self.assertEquals(0, self.ppa.binaries_size) |
434 | + ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA) |
435 | + self.publishDDEBInArchive(ppa) |
436 | + self.assertEquals(0, ppa.binaries_size) |
437 | + |
438 | + def test_empty_primary_archive_has_zero_binaries_size(self): |
439 | + # PRIMARY archives have zero binaries_size when created. |
440 | + archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) |
441 | + self.assertEquals(0, archive.binaries_size) |
442 | |
443 | def test_binaries_size_includes_ddebs_for_other_archives(self): |
444 | # DDEBs size are computed for all archive purposes, except PPAs. |
445 | - previous_size = self.publisher.ubuntutest.main_archive.binaries_size |
446 | - self.publisher.getPubBinaries( |
447 | - filecontent='X', format=BinaryPackageFormat.DDEB) |
448 | - self.assertEquals( |
449 | - previous_size + 1, |
450 | - self.publisher.ubuntutest.main_archive.binaries_size) |
451 | + archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) |
452 | + self.publishDDEBInArchive(archive) |
453 | + self.assertNotEquals(0, archive.binaries_size) |
454 | |
455 | def test_sources_size_on_empty_archive(self): |
456 | # Zero is returned for an archive without sources. |
457 | - self.assertEquals( |
458 | - 0, self.ppa.sources_size, |
459 | - 'Zero should be returned for an archive without sources.') |
460 | + archive = self.factory.makeArchive() |
461 | + self.assertEquals(0, archive.sources_size) |
462 | + |
463 | + def publishSourceFile(self, archive, library_file): |
464 | + """Publish a source package with the given content to the archive. |
465 | + |
466 | + :param archive: the IArchive to publish to. |
467 | + :param library_file: a LibraryFileAlias for the content of the |
468 | + source file. |
469 | + """ |
470 | + sourcepackagerelease = self.factory.makeSourcePackageRelease() |
471 | + self.factory.makeSourcePackagePublishingHistory( |
472 | + archive=archive, sourcepackagerelease=sourcepackagerelease, |
473 | + status=PackagePublishingStatus.PUBLISHED) |
474 | + self.factory.makeSourcePackageReleaseFile( |
475 | + sourcepackagerelease=sourcepackagerelease, |
476 | + library_file=library_file) |
477 | |
478 | def test_sources_size_does_not_count_duplicated_files(self): |
479 | # If there are multiple copies of the same file name/size |
480 | # only one will be counted. |
481 | - pub_1 = self.publisher.getPubSource( |
482 | - filecontent='22', version='0.5.11~ppa1', archive=self.ppa) |
483 | - |
484 | - pub_2 = self.publisher.getPubSource( |
485 | - filecontent='333', version='0.5.11~ppa2', archive=self.ppa) |
486 | - |
487 | - self.assertEquals(5, self.ppa.sources_size) |
488 | - |
489 | - shared_tarball = self.publisher.addMockFile( |
490 | - filename='foo_0.5.11.tar.gz', filecontent='1') |
491 | - |
492 | - # After adding a the shared tarball to the ppa1 version, |
493 | - # the sources_size updates to reflect the change. |
494 | - pub_1.sourcepackagerelease.addFile(shared_tarball) |
495 | - self.assertEquals( |
496 | - 6, self.ppa.sources_size, |
497 | - 'The sources_size should update after a file is added.') |
498 | - |
499 | - # But after adding a copy of the shared tarball to the ppa2 version, |
500 | - # the sources_size is unchanged. |
501 | - shared_tarball_copy = self.publisher.addMockFile( |
502 | - filename='foo_0.5.11.tar.gz', filecontent='1') |
503 | - |
504 | - pub_2.sourcepackagerelease.addFile(shared_tarball_copy) |
505 | - self.assertEquals( |
506 | - 6, self.ppa.sources_size, |
507 | - 'The sources_size should change after adding a duplicate file.') |
508 | + archive = self.factory.makeArchive() |
509 | + library_file = self.factory.makeLibraryFileAlias() |
510 | + self.publishSourceFile(archive, library_file) |
511 | + self.assertEquals( |
512 | + library_file.content.filesize, archive.sources_size) |
513 | + |
514 | + self.publishSourceFile(archive, library_file) |
515 | + self.assertEquals( |
516 | + library_file.content.filesize, archive.sources_size) |
517 | |
518 | |
519 | class TestSeriesWithSources(TestCaseWithFactory): |
520 | @@ -634,7 +615,6 @@ |
521 | self.factory.makeComponent(), |
522 | PackagePublishingPocket.PROPOSED), |
523 | InvalidPocketForPPA) |
524 | - |
525 | # XXX: JRV 20100511: IArchive.canUploadSuiteSourcePackage needs tests |
526 | |
527 | |
528 | |
529 | === modified file 'lib/lp/testing/__init__.py' |
530 | --- lib/lp/testing/__init__.py 2010-07-25 14:54:01 +0000 |
531 | +++ lib/lp/testing/__init__.py 2010-08-04 00:47:45 +0000 |
532 | @@ -79,7 +79,7 @@ |
533 | |
534 | from zope.component import adapter, getUtility |
535 | import zope.event |
536 | -from zope.interface.verify import verifyClass, verifyObject |
537 | +from zope.interface.verify import verifyClass |
538 | from zope.security.proxy import ( |
539 | isinstance as zope_isinstance, removeSecurityProxy) |
540 | from zope.testing.testrunner.runner import TestResult as ZopeTestResult |
541 | @@ -115,6 +115,7 @@ |
542 | from lp.testing._tales import test_tales |
543 | from lp.testing._webservice import ( |
544 | launchpadlib_credentials_for, launchpadlib_for, oauth_access_token_for) |
545 | +from lp.testing.matchers import Provides |
546 | from lp.testing.fixture import ZopeEventHandlerFixture |
547 | |
548 | # zope.exception demands more of frame objects than twisted.python.failure |
549 | @@ -286,13 +287,7 @@ |
550 | |
551 | def assertProvides(self, obj, interface): |
552 | """Assert 'obj' correctly provides 'interface'.""" |
553 | - self.assertTrue( |
554 | - interface.providedBy(obj), |
555 | - "%r does not provide %r." % (obj, interface)) |
556 | - self.assertTrue( |
557 | - verifyObject(interface, obj), |
558 | - "%r claims to provide %r but does not do so correctly." |
559 | - % (obj, interface)) |
560 | + self.assertThat(obj, Provides(interface)) |
561 | |
562 | def assertClassImplements(self, cls, interface): |
563 | """Assert 'cls' may correctly implement 'interface'.""" |
564 | |
565 | === modified file 'lib/lp/testing/factory.py' |
566 | --- lib/lp/testing/factory.py 2010-08-03 22:49:42 +0000 |
567 | +++ lib/lp/testing/factory.py 2010-08-04 00:47:45 +0000 |
568 | @@ -125,7 +125,7 @@ |
569 | from lp.registry.interfaces.projectgroup import IProjectGroupSet |
570 | from lp.registry.interfaces.series import SeriesStatus |
571 | from lp.registry.interfaces.sourcepackage import ( |
572 | - ISourcePackage, SourcePackageUrgency) |
573 | + ISourcePackage, SourcePackageFileType, SourcePackageUrgency) |
574 | from lp.registry.interfaces.sourcepackagename import ( |
575 | ISourcePackageNameSet) |
576 | from lp.registry.interfaces.ssh import ISSHKeySet |
577 | @@ -143,18 +143,18 @@ |
578 | from lp.soyuz.interfaces.archive import ( |
579 | default_name_by_purpose, IArchiveSet, ArchivePurpose) |
580 | from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet |
581 | -from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat |
582 | +from lp.soyuz.interfaces.binarypackagerelease import ( |
583 | + BinaryPackageFileType, BinaryPackageFormat) |
584 | from lp.soyuz.interfaces.component import IComponentSet |
585 | from lp.soyuz.interfaces.packageset import IPackagesetSet |
586 | from lp.soyuz.interfaces.processor import IProcessorFamilySet |
587 | from lp.soyuz.interfaces.publishing import ( |
588 | - PackagePublishingPriority, PackagePublishingStatus) |
589 | + IPublishingSet, PackagePublishingPriority, PackagePublishingStatus) |
590 | from lp.soyuz.interfaces.section import ISectionSet |
591 | from lp.soyuz.model.binarypackagename import BinaryPackageName |
592 | from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease |
593 | +from lp.soyuz.model.files import BinaryPackageFile, SourcePackageReleaseFile |
594 | from lp.soyuz.model.processor import ProcessorFamilySet |
595 | -from lp.soyuz.model.publishing import ( |
596 | - BinaryPackagePublishingHistory, SourcePackagePublishingHistory) |
597 | from lp.testing import ( |
598 | ANONYMOUS, |
599 | login, |
600 | @@ -2349,6 +2349,19 @@ |
601 | dateuploaded=date_uploaded, |
602 | source_package_recipe_build=source_package_recipe_build) |
603 | |
604 | + def makeSourcePackageReleaseFile(self, sourcepackagerelease=None, |
605 | + library_file=None, filetype=None): |
606 | + if sourcepackagerelease is None: |
607 | + sourcepackagerelease = self.makeSourcePackageRelease() |
608 | + if library_file is None: |
609 | + library_file = self.makeLibraryFileAlias() |
610 | + if filetype is None: |
611 | + filetype = SourcePackageFileType.DSC |
612 | + return ProxyFactory( |
613 | + SourcePackageReleaseFile( |
614 | + sourcepackagerelease=sourcepackagerelease, |
615 | + libraryfile=library_file, filetype=filetype)) |
616 | + |
617 | def makeBinaryPackageBuild(self, source_package_release=None, |
618 | distroarchseries=None, archive=None, builder=None): |
619 | """Create a BinaryPackageBuild. |
620 | @@ -2410,6 +2423,7 @@ |
621 | dsc_standards_version='3.6.2', |
622 | dsc_format='1.0', |
623 | dsc_binaries='foo-bin', |
624 | + sourcepackagerelease=None, |
625 | ): |
626 | """Make a `SourcePackagePublishingHistory`.""" |
627 | if distroseries is None: |
628 | @@ -2430,36 +2444,37 @@ |
629 | if status is None: |
630 | status = PackagePublishingStatus.PENDING |
631 | |
632 | - spr = self.makeSourcePackageRelease( |
633 | - archive=archive, |
634 | - sourcepackagename=sourcepackagename, |
635 | - distroseries=distroseries, |
636 | - maintainer=maintainer, |
637 | - creator=creator, component=component, |
638 | - section_name=section_name, |
639 | - urgency=urgency, |
640 | - version=version, |
641 | - builddepends=builddepends, |
642 | - builddependsindep=builddependsindep, |
643 | - build_conflicts=build_conflicts, |
644 | - build_conflicts_indep=build_conflicts_indep, |
645 | - architecturehintlist=architecturehintlist, |
646 | - dsc_standards_version=dsc_standards_version, |
647 | - dsc_format=dsc_format, |
648 | - dsc_binaries=dsc_binaries, |
649 | - date_uploaded=date_uploaded) |
650 | - |
651 | - return ProxyFactory(SourcePackagePublishingHistory( |
652 | - distroseries=distroseries, |
653 | - sourcepackagerelease=spr, |
654 | - component=spr.component, |
655 | - section=spr.section, |
656 | - status=status, |
657 | - datecreated=date_uploaded, |
658 | - dateremoved=dateremoved, |
659 | - scheduleddeletiondate=scheduleddeletiondate, |
660 | - pocket=pocket, |
661 | - archive=archive)) |
662 | + if sourcepackagerelease is None: |
663 | + sourcepackagerelease = self.makeSourcePackageRelease( |
664 | + archive=archive, |
665 | + sourcepackagename=sourcepackagename, |
666 | + distroseries=distroseries, |
667 | + maintainer=maintainer, |
668 | + creator=creator, component=component, |
669 | + section_name=section_name, |
670 | + urgency=urgency, |
671 | + version=version, |
672 | + builddepends=builddepends, |
673 | + builddependsindep=builddependsindep, |
674 | + build_conflicts=build_conflicts, |
675 | + build_conflicts_indep=build_conflicts_indep, |
676 | + architecturehintlist=architecturehintlist, |
677 | + dsc_standards_version=dsc_standards_version, |
678 | + dsc_format=dsc_format, |
679 | + dsc_binaries=dsc_binaries, |
680 | + date_uploaded=date_uploaded) |
681 | + |
682 | + spph = getUtility(IPublishingSet).newSourcePublication( |
683 | + archive, sourcepackagerelease, distroseries, |
684 | + sourcepackagerelease.component, sourcepackagerelease.section, |
685 | + pocket) |
686 | + |
687 | + naked_spph = removeSecurityProxy(spph) |
688 | + naked_spph.status = status |
689 | + naked_spph.datecreated = date_uploaded |
690 | + naked_spph.dateremoved = dateremoved |
691 | + naked_spph.scheduleddeletiondate = scheduleddeletiondate |
692 | + return spph |
693 | |
694 | def makeBinaryPackagePublishingHistory(self, binarypackagerelease=None, |
695 | distroarchseries=None, |
696 | @@ -2492,28 +2507,40 @@ |
697 | if priority is None: |
698 | priority = PackagePublishingPriority.OPTIONAL |
699 | |
700 | - bpr = self.makeBinaryPackageRelease( |
701 | - component=component, |
702 | - section_name=section_name, |
703 | - priority=priority) |
704 | + if binarypackagerelease is None: |
705 | + binarypackagerelease = self.makeBinaryPackageRelease( |
706 | + component=component, |
707 | + section_name=section_name, |
708 | + priority=priority) |
709 | |
710 | - return BinaryPackagePublishingHistory( |
711 | - distroarchseries=distroarchseries, |
712 | - binarypackagerelease=bpr, |
713 | - component=bpr.component, |
714 | - section=bpr.section, |
715 | - status=status, |
716 | - dateremoved=dateremoved, |
717 | - scheduleddeletiondate=scheduleddeletiondate, |
718 | - pocket=pocket, |
719 | - priority=priority, |
720 | - archive=archive) |
721 | + bpph = getUtility(IPublishingSet).newBinaryPublication( |
722 | + archive, binarypackagerelease, distroarchseries, |
723 | + binarypackagerelease.component, binarypackagerelease.section, |
724 | + priority, pocket) |
725 | + naked_bpph = removeSecurityProxy(bpph) |
726 | + naked_bpph.status = status |
727 | + naked_bpph.dateremoved = dateremoved |
728 | + naked_bpph.scheduleddeletiondate = scheduleddeletiondate |
729 | + naked_bpph.priority = priority |
730 | + return bpph |
731 | |
732 | def makeBinaryPackageName(self, name=None): |
733 | if name is None: |
734 | name = self.getUniqueString("binarypackage") |
735 | return BinaryPackageName(name=name) |
736 | |
737 | + def makeBinaryPackageFile(self, binarypackagerelease=None, |
738 | + library_file=None, filetype=None): |
739 | + if binarypackagerelease is None: |
740 | + binarypackagerelease = self.makeBinaryPackageRelease() |
741 | + if library_file is None: |
742 | + library_file = self.makeLibraryFileAlias() |
743 | + if filetype is None: |
744 | + filetype = BinaryPackageFileType.DEB |
745 | + return ProxyFactory(BinaryPackageFile( |
746 | + binarypackagerelease=binarypackagerelease, |
747 | + libraryfile=library_file, filetype=filetype)) |
748 | + |
749 | def makeBinaryPackageRelease(self, binarypackagename=None, |
750 | version=None, build=None, |
751 | binpackageformat=None, component=None, |
752 | @@ -2538,13 +2565,13 @@ |
753 | summary = self.getUniqueString("summary") |
754 | if description is None: |
755 | description = self.getUniqueString("description") |
756 | - return BinaryPackageRelease(binarypackagename=binarypackagename, |
757 | - version=version, build=build, |
758 | - binpackageformat=binpackageformat, |
759 | - component=component, section=section, |
760 | - priority=priority, summary=summary, |
761 | - description=description, |
762 | - architecturespecific=architecturespecific) |
763 | + return ProxyFactory( |
764 | + BinaryPackageRelease( |
765 | + binarypackagename=binarypackagename, version=version, |
766 | + build=build, binpackageformat=binpackageformat, |
767 | + component=component, section=section, priority=priority, |
768 | + summary=summary, description=description, |
769 | + architecturespecific=architecturespecific)) |
770 | |
771 | def makeSection(self, name=None): |
772 | """Make a `Section`.""" |
773 | |
774 | === added file 'lib/lp/testing/matchers.py' |
775 | --- lib/lp/testing/matchers.py 1970-01-01 00:00:00 +0000 |
776 | +++ lib/lp/testing/matchers.py 2010-08-04 00:47:45 +0000 |
777 | @@ -0,0 +1,135 @@ |
778 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
779 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
780 | + |
781 | +__metaclass__ = type |
782 | +__all__ = [ |
783 | + 'DoesNotProvide', |
784 | + 'DoesNotCorrectlyProvide', |
785 | + 'IsNotProxied', |
786 | + 'IsProxied', |
787 | + 'Provides', |
788 | + 'ProvidesAndIsProxied', |
789 | + ] |
790 | + |
791 | +from zope.interface.verify import verifyObject |
792 | +from zope.interface.exceptions import ( |
793 | + BrokenImplementation, BrokenMethodImplementation, DoesNotImplement) |
794 | +from zope.security.proxy import builtin_isinstance, Proxy |
795 | + |
796 | +from testtools.matchers import Matcher, Mismatch |
797 | + |
798 | + |
799 | +class DoesNotProvide(Mismatch): |
800 | + """An object does not provide an interface.""" |
801 | + |
802 | + def __init__(self, obj, interface): |
803 | + """Create a DoesNotProvide Mismatch. |
804 | + |
805 | + :param obj: the object that does not match. |
806 | + :param interface: the Interface that the object was supposed to match. |
807 | + """ |
808 | + self.obj = obj |
809 | + self.interface = interface |
810 | + |
811 | + def describe(self): |
812 | + return "%r does not provide %r." % (self.obj, self.interface) |
813 | + |
814 | + |
815 | +class DoesNotCorrectlyProvide(DoesNotProvide): |
816 | + """An object does not correctly provide an interface.""" |
817 | + |
818 | + def __init__(self, obj, interface, extra=None): |
819 | + """Create a DoesNotCorrectlyProvide Mismatch. |
820 | + |
821 | + :param obj: the object that does not match. |
822 | + :param interface: the Interface that the object was supposed to match. |
823 | + :param extra: any extra information about the mismatch as a string, |
824 | + or None |
825 | + """ |
826 | + super(DoesNotCorrectlyProvide, self).__init__(obj, interface) |
827 | + self.extra = extra |
828 | + |
829 | + def describe(self): |
830 | + if self.extra is not None: |
831 | + extra = ": %s" % self.extra |
832 | + else: |
833 | + extra = "." |
834 | + return ("%r claims to provide %r, but does not do so correctly%s" |
835 | + % (self.obj, self.interface, extra)) |
836 | + |
837 | + |
838 | +class Provides(Matcher): |
839 | + """Test that an object provides a certain interface.""" |
840 | + |
841 | + def __init__(self, interface): |
842 | + """Create a Provides Matcher. |
843 | + |
844 | + :param interface: the Interface that the object should provide. |
845 | + """ |
846 | + self.interface = interface |
847 | + |
848 | + def __str__(self): |
849 | + return "provides %r." % self.interface |
850 | + |
851 | + def match(self, matchee): |
852 | + if not self.interface.providedBy(matchee): |
853 | + return DoesNotProvide(matchee, self.interface) |
854 | + passed = True |
855 | + extra = None |
856 | + try: |
857 | + if not verifyObject(self.interface, matchee): |
858 | + passed = False |
859 | + except (BrokenImplementation, BrokenMethodImplementation, |
860 | + DoesNotImplement), e: |
861 | + passed = False |
862 | + extra = str(e) |
863 | + if not passed: |
864 | + return DoesNotCorrectlyProvide( |
865 | + matchee, self.interface, extra=extra) |
866 | + return None |
867 | + |
868 | + |
869 | +class IsNotProxied(Mismatch): |
870 | + """An object is not proxied.""" |
871 | + |
872 | + def __init__(self, obj): |
873 | + """Create an IsNotProxied Mismatch. |
874 | + |
875 | + :param obj: the object that is not proxied. |
876 | + """ |
877 | + self.obj = obj |
878 | + |
879 | + def describe(self): |
880 | + return "%r is not proxied." % self.obj |
881 | + |
882 | + |
883 | +class IsProxied(Matcher): |
884 | + """Check that an object is proxied.""" |
885 | + |
886 | + def __str__(self): |
887 | + return "Is proxied." |
888 | + |
889 | + def match(self, matchee): |
890 | + if not builtin_isinstance(matchee, Proxy): |
891 | + return IsNotProxied(matchee) |
892 | + return None |
893 | + |
894 | + |
895 | +class ProvidesAndIsProxied(Matcher): |
896 | + """Test that an object implements an interface, and is proxied.""" |
897 | + |
898 | + def __init__(self, interface): |
899 | + """Create a ProvidesAndIsProxied matcher. |
900 | + |
901 | + :param interface: the Interface the object must provide. |
902 | + """ |
903 | + self.interface = interface |
904 | + |
905 | + def __str__(self): |
906 | + return "Provides %r and is proxied." % self.interface |
907 | + |
908 | + def match(self, matchee): |
909 | + mismatch = Provides(self.interface).match(matchee) |
910 | + if mismatch is not None: |
911 | + return mismatch |
912 | + return IsProxied().match(matchee) |
913 | |
914 | === modified file 'lib/lp/testing/sampledata.py' |
915 | --- lib/lp/testing/sampledata.py 2010-07-17 15:52:19 +0000 |
916 | +++ lib/lp/testing/sampledata.py 2010-08-04 00:47:45 +0000 |
917 | @@ -9,8 +9,46 @@ |
918 | |
919 | __metaclass__ = type |
920 | __all__ = [ |
921 | + 'BUILDD_ADMIN_USERNAME', |
922 | + 'CHROOT_LIBRARYFILEALIAS', |
923 | + 'HOARY_DISTROSERIES_NAME', |
924 | + 'I386_ARCHITECTURE_NAME', |
925 | + 'LAUNCHPAD_DBUSER_NAME', |
926 | + 'MAIN_COMPONENT_NAME', |
927 | 'NO_PRIVILEGE_EMAIL', |
928 | + 'UBUNTU_DEVELOPER_ADMIN_NAME', |
929 | + 'UBUNTU_DISTRIBUTION_NAME', |
930 | + 'UBUNTU_UPLOAD_TEAM_NAME', |
931 | + 'UBUNTUTEST_DISTRIBUTION_NAME', |
932 | + 'WARTY_DISTROSERIES_NAME', |
933 | + 'WARTY_ONLY_SOURCEPACKAGENAME', |
934 | + 'WARTY_ONLY_SOURCEPACKAGEVERSION', |
935 | + 'WARTY_UPDATES_SUITE_NAME', |
936 | ] |
937 | |
938 | +# Please use names that reveal intent, rather than being purely |
939 | +# descriptive, i.e. USER16_NAME isn't as good as |
940 | +# UBUNTU_DEVELOPER_NAME. Where intent is tricky to convey in the |
941 | +# name, please leave a comment as well. |
942 | |
943 | +# A user with buildd admin rights and upload rights to Ubuntu. |
944 | +BUILDD_ADMIN_USERNAME = 'cprov' |
945 | +# The LibraryFileAlias of a chroot for attaching to a DistroArchSeries |
946 | +CHROOT_LIBRARYFILEALIAS = 1 |
947 | +HOARY_DISTROSERIES_NAME = 'hoary' |
948 | +I386_ARCHITECTURE_NAME = 'i386' |
949 | +LAUNCHPAD_DBUSER_NAME = 'launchpad' |
950 | +MAIN_COMPONENT_NAME = 'main' |
951 | NO_PRIVILEGE_EMAIL = 'no-priv@canonical.com' |
952 | +# A user that is an admin of ubuntu-team, which has upload rights |
953 | +# to Ubuntu. |
954 | +UBUNTU_DEVELOPER_ADMIN_NAME = 'name16' |
955 | +UBUNTU_DISTRIBUTION_NAME = 'ubuntu' |
956 | +# A team that has upload rights to Ubuntu |
957 | +UBUNTU_UPLOAD_TEAM_NAME = 'ubuntu-team' |
958 | +WARTY_DISTROSERIES_NAME = 'warty' |
959 | +# A source package name and version for a package only published in |
960 | +# warty |
961 | +WARTY_ONLY_SOURCEPACKAGENAME = 'mozilla-firefox' |
962 | +WARTY_ONLY_SOURCEPACKAGEVERSION = '0.9' |
963 | +WARTY_UPDATES_SUITE_NAME = WARTY_DISTROSERIES_NAME + '-updates' |
964 | |
965 | === modified file 'lib/lp/testing/tests/test_factory.py' |
966 | --- lib/lp/testing/tests/test_factory.py 2010-07-26 12:58:13 +0000 |
967 | +++ lib/lp/testing/tests/test_factory.py 2010-08-04 00:47:45 +0000 |
968 | @@ -5,23 +5,88 @@ |
969 | |
970 | __metaclass__ = type |
971 | |
972 | +from datetime import datetime |
973 | +import pytz |
974 | import unittest |
975 | |
976 | from zope.component import getUtility |
977 | from zope.security.proxy import removeSecurityProxy |
978 | |
979 | from canonical.launchpad.webapp.interfaces import ILaunchBag |
980 | -from canonical.testing.layers import DatabaseFunctionalLayer |
981 | +from canonical.testing.layers import ( |
982 | + DatabaseFunctionalLayer, LaunchpadZopelessLayer) |
983 | from lp.code.enums import CodeImportReviewStatus |
984 | +from lp.registry.interfaces.sourcepackage import SourcePackageFileType |
985 | +from lp.services.worlddata.interfaces.language import ILanguage |
986 | +from lp.soyuz.interfaces.binarypackagerelease import ( |
987 | + BinaryPackageFileType, IBinaryPackageRelease) |
988 | +from lp.soyuz.interfaces.files import ( |
989 | + IBinaryPackageFile, ISourcePackageReleaseFile) |
990 | +from lp.soyuz.interfaces.publishing import ( |
991 | + IBinaryPackagePublishingHistory, ISourcePackagePublishingHistory, |
992 | + PackagePublishingPriority, PackagePublishingStatus) |
993 | from lp.testing import TestCaseWithFactory |
994 | -from lp.services.worlddata.interfaces.language import ILanguage |
995 | from lp.testing.factory import is_security_proxied_or_harmless |
996 | +from lp.testing.matchers import IsProxied, Provides, ProvidesAndIsProxied |
997 | |
998 | |
999 | class TestFactory(TestCaseWithFactory): |
1000 | |
1001 | layer = DatabaseFunctionalLayer |
1002 | |
1003 | + # loginAsAnyone |
1004 | + def test_loginAsAnyone(self): |
1005 | + # Login as anyone logs you in as any user. |
1006 | + person = self.factory.loginAsAnyone() |
1007 | + current_person = getUtility(ILaunchBag).user |
1008 | + self.assertIsNot(None, person) |
1009 | + self.assertEqual(person, current_person) |
1010 | + |
1011 | + # makeBinaryPackagePublishingHistory |
1012 | + def test_makeBinaryPackagePublishingHistory_returns_IBPPH(self): |
1013 | + bpph = self.factory.makeBinaryPackagePublishingHistory() |
1014 | + self.assertThat( |
1015 | + removeSecurityProxy(bpph), |
1016 | + Provides(IBinaryPackagePublishingHistory)) |
1017 | + |
1018 | + def test_makeBinaryPackagePublishingHistory_returns_proxied(self): |
1019 | + bpph = self.factory.makeBinaryPackagePublishingHistory() |
1020 | + self.assertThat(bpph, IsProxied()) |
1021 | + |
1022 | + def test_makeBinaryPackagePublishingHistory_uses_status(self): |
1023 | + bpph = self.factory.makeBinaryPackagePublishingHistory( |
1024 | + status=PackagePublishingStatus.PENDING) |
1025 | + self.assertEquals(PackagePublishingStatus.PENDING, bpph.status) |
1026 | + bpph = self.factory.makeBinaryPackagePublishingHistory( |
1027 | + status=PackagePublishingStatus.PUBLISHED) |
1028 | + self.assertEquals(PackagePublishingStatus.PUBLISHED, bpph.status) |
1029 | + |
1030 | + def test_makeBinaryPackagePublishingHistory_uses_dateremoved(self): |
1031 | + dateremoved = datetime.now(pytz.UTC) |
1032 | + bpph = self.factory.makeBinaryPackagePublishingHistory( |
1033 | + dateremoved=dateremoved) |
1034 | + self.assertEquals(dateremoved, bpph.dateremoved) |
1035 | + |
1036 | + def test_makeBinaryPackagePublishingHistory_scheduleddeletiondate(self): |
1037 | + scheduleddeletiondate = datetime.now(pytz.UTC) |
1038 | + bpph = self.factory.makeBinaryPackagePublishingHistory( |
1039 | + scheduleddeletiondate=scheduleddeletiondate) |
1040 | + self.assertEquals(scheduleddeletiondate, bpph.scheduleddeletiondate) |
1041 | + |
1042 | + def test_makeBinaryPackagePublishingHistory_uses_priority(self): |
1043 | + bpph = self.factory.makeBinaryPackagePublishingHistory( |
1044 | + priority=PackagePublishingPriority.OPTIONAL) |
1045 | + self.assertEquals(PackagePublishingPriority.OPTIONAL, bpph.priority) |
1046 | + bpph = self.factory.makeBinaryPackagePublishingHistory( |
1047 | + priority=PackagePublishingPriority.EXTRA) |
1048 | + self.assertEquals(PackagePublishingPriority.EXTRA, bpph.priority) |
1049 | + |
1050 | + # makeBinaryPackageRelease |
1051 | + def test_makeBinaryPackageRelease_returns_IBinaryPackageRelease(self): |
1052 | + bpr = self.factory.makeBinaryPackageRelease() |
1053 | + self.assertThat(bpr, ProvidesAndIsProxied(IBinaryPackageRelease)) |
1054 | + |
1055 | + # makeCodeImport |
1056 | def test_makeCodeImportNoStatus(self): |
1057 | # If makeCodeImport is not given a review status, it defaults to NEW. |
1058 | code_import = self.factory.makeCodeImport() |
1059 | @@ -35,6 +100,7 @@ |
1060 | code_import = self.factory.makeCodeImport(review_status=status) |
1061 | self.assertEqual(status, code_import.review_status) |
1062 | |
1063 | + # makeLanguage |
1064 | def test_makeLanguage(self): |
1065 | # Without parameters, makeLanguage creates a language with code |
1066 | # starting with 'lang'. |
1067 | @@ -61,12 +127,109 @@ |
1068 | # And name is constructed from code as 'Language %(code)s'. |
1069 | self.assertEquals('Test language', language.englishname) |
1070 | |
1071 | - def test_loginAsAnyone(self): |
1072 | - # Login as anyone logs you in as any user. |
1073 | - person = self.factory.loginAsAnyone() |
1074 | - current_person = getUtility(ILaunchBag).user |
1075 | - self.assertIsNot(None, person) |
1076 | - self.assertEqual(person, current_person) |
1077 | + # makeSourcePackagePublishingHistory |
1078 | + def test_makeSourcePackagePublishingHistory_returns_ISPPH(self): |
1079 | + spph = self.factory.makeSourcePackagePublishingHistory() |
1080 | + self.assertThat( |
1081 | + removeSecurityProxy(spph), |
1082 | + Provides(ISourcePackagePublishingHistory)) |
1083 | + |
1084 | + def test_makeSourcePackagePublishingHistory_returns_proxied(self): |
1085 | + spph = self.factory.makeSourcePackagePublishingHistory() |
1086 | + self.assertThat(spph, IsProxied()) |
1087 | + |
1088 | + def test_makeSourcePackagePublishingHistory_uses_spr(self): |
1089 | + spr = self.factory.makeSourcePackageRelease() |
1090 | + spph = self.factory.makeSourcePackagePublishingHistory( |
1091 | + sourcepackagerelease=spr) |
1092 | + self.assertEquals(spr, spph.sourcepackagerelease) |
1093 | + |
1094 | + def test_makeSourcePackagePublishingHistory_uses_status(self): |
1095 | + spph = self.factory.makeSourcePackagePublishingHistory( |
1096 | + status=PackagePublishingStatus.PENDING) |
1097 | + self.assertEquals(PackagePublishingStatus.PENDING, spph.status) |
1098 | + spph = self.factory.makeSourcePackagePublishingHistory( |
1099 | + status=PackagePublishingStatus.PUBLISHED) |
1100 | + self.assertEquals(PackagePublishingStatus.PUBLISHED, spph.status) |
1101 | + |
1102 | + def test_makeSourcePackagePublishingHistory_uses_date_uploaded(self): |
1103 | + date_uploaded = datetime.now(pytz.UTC) |
1104 | + spph = self.factory.makeSourcePackagePublishingHistory( |
1105 | + date_uploaded=date_uploaded) |
1106 | + self.assertEquals(date_uploaded, spph.datecreated) |
1107 | + |
1108 | + def test_makeSourcePackagePublishingHistory_uses_dateremoved(self): |
1109 | + dateremoved = datetime.now(pytz.UTC) |
1110 | + spph = self.factory.makeSourcePackagePublishingHistory( |
1111 | + dateremoved=dateremoved) |
1112 | + self.assertEquals(dateremoved, spph.dateremoved) |
1113 | + |
1114 | + def test_makeSourcePackagePublishingHistory_scheduleddeletiondate(self): |
1115 | + scheduleddeletiondate = datetime.now(pytz.UTC) |
1116 | + spph = self.factory.makeSourcePackagePublishingHistory( |
1117 | + scheduleddeletiondate=scheduleddeletiondate) |
1118 | + self.assertEquals(scheduleddeletiondate, spph.scheduleddeletiondate) |
1119 | + |
1120 | + |
1121 | +class TestFactoryWithLibrarian(TestCaseWithFactory): |
1122 | + |
1123 | + layer = LaunchpadZopelessLayer |
1124 | + |
1125 | + # makeBinaryPackageFile |
1126 | + def test_makeBinaryPackageFile_returns_IBinaryPackageFile(self): |
1127 | + bpf = self.factory.makeBinaryPackageFile() |
1128 | + self.assertThat(bpf, ProvidesAndIsProxied(IBinaryPackageFile)) |
1129 | + |
1130 | + def test_makeBinaryPackageFile_uses_binarypackagerelease(self): |
1131 | + binarypackagerelease = self.factory.makeBinaryPackageRelease() |
1132 | + bpf = self.factory.makeBinaryPackageFile( |
1133 | + binarypackagerelease=binarypackagerelease) |
1134 | + self.assertEqual(binarypackagerelease, bpf.binarypackagerelease) |
1135 | + |
1136 | + def test_makeBinaryPackageFile_uses_library_file(self): |
1137 | + library_file = self.factory.makeLibraryFileAlias() |
1138 | + bpf = self.factory.makeBinaryPackageFile( |
1139 | + library_file=library_file) |
1140 | + self.assertEqual(library_file, bpf.libraryfile) |
1141 | + |
1142 | + def test_makeBinaryPackageFile_uses_filetype(self): |
1143 | + bpf = self.factory.makeBinaryPackageFile( |
1144 | + filetype=BinaryPackageFileType.DEB) |
1145 | + self.assertEqual(BinaryPackageFileType.DEB, bpf.filetype) |
1146 | + bpf = self.factory.makeBinaryPackageFile( |
1147 | + filetype=BinaryPackageFileType.DDEB) |
1148 | + self.assertEqual(BinaryPackageFileType.DDEB, bpf.filetype) |
1149 | + |
1150 | + # makeSourcePackageReleaseFile |
1151 | + def test_makeSourcePackageReleaseFile_returns_ISPRF(self): |
1152 | + spr_file = self.factory.makeSourcePackageReleaseFile() |
1153 | + self.assertThat( |
1154 | + spr_file, ProvidesAndIsProxied(ISourcePackageReleaseFile)) |
1155 | + |
1156 | + def test_makeSourcePackageReleaseFile_uses_sourcepackagerelease(self): |
1157 | + spr = self.factory.makeSourcePackageRelease() |
1158 | + spr_file = self.factory.makeSourcePackageReleaseFile( |
1159 | + sourcepackagerelease=spr) |
1160 | + self.assertEqual(spr, spr_file.sourcepackagerelease) |
1161 | + |
1162 | + def test_makeSourcePackageReleaseFile_uses_library_file(self): |
1163 | + library_file = self.factory.makeLibraryFileAlias() |
1164 | + spr_file = self.factory.makeSourcePackageReleaseFile( |
1165 | + library_file=library_file) |
1166 | + self.assertEqual(library_file, spr_file.libraryfile) |
1167 | + |
1168 | + def test_makeSourcePackageReleaseFile_uses_filetype(self): |
1169 | + spr_file = self.factory.makeSourcePackageReleaseFile( |
1170 | + filetype=SourcePackageFileType.DIFF) |
1171 | + self.assertEqual(SourcePackageFileType.DIFF, spr_file.filetype) |
1172 | + spr_file = self.factory.makeSourcePackageReleaseFile( |
1173 | + filetype=SourcePackageFileType.DSC) |
1174 | + self.assertEqual(SourcePackageFileType.DSC, spr_file.filetype) |
1175 | + |
1176 | + |
1177 | +class IsSecurityProxiedOrHarmlessTests(TestCaseWithFactory): |
1178 | + |
1179 | + layer = DatabaseFunctionalLayer |
1180 | |
1181 | def test_is_security_proxied_or_harmless__none(self): |
1182 | # is_security_proxied_or_harmless() considers the None object |
1183 | |
1184 | === added file 'lib/lp/testing/tests/test_matchers.py' |
1185 | --- lib/lp/testing/tests/test_matchers.py 1970-01-01 00:00:00 +0000 |
1186 | +++ lib/lp/testing/tests/test_matchers.py 2010-08-04 00:47:45 +0000 |
1187 | @@ -0,0 +1,171 @@ |
1188 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
1189 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
1190 | + |
1191 | +__metaclass__ = type |
1192 | + |
1193 | +from zope.interface import implements, Interface |
1194 | +from zope.interface.verify import verifyObject |
1195 | +from zope.interface.exceptions import BrokenImplementation |
1196 | +from zope.security.checker import NamesChecker |
1197 | +from zope.security.proxy import ProxyFactory |
1198 | + |
1199 | +from lp.testing import TestCase |
1200 | +from lp.testing.matchers import ( |
1201 | + DoesNotCorrectlyProvide, DoesNotProvide, IsNotProxied, IsProxied, |
1202 | + Provides, ProvidesAndIsProxied) |
1203 | + |
1204 | + |
1205 | +class ITestInterface(Interface): |
1206 | + """A dummy interface for testing.""" |
1207 | + |
1208 | + def doFoo(): |
1209 | + """Dummy method for interface compliance testing.""" |
1210 | + |
1211 | + |
1212 | +class Implementor: |
1213 | + """Dummy class that implements ITestInterface for testing.""" |
1214 | + |
1215 | + implements(ITestInterface) |
1216 | + |
1217 | + def doFoo(self): |
1218 | + pass |
1219 | + |
1220 | + |
1221 | +class DoesNotProvideTests(TestCase): |
1222 | + |
1223 | + def test_describe(self): |
1224 | + obj = object() |
1225 | + mismatch = DoesNotProvide(obj, ITestInterface) |
1226 | + self.assertEqual( |
1227 | + "%r does not provide %r." % (obj, ITestInterface), |
1228 | + mismatch.describe()) |
1229 | + |
1230 | + |
1231 | +class DoesNotCorrectlyProvideMismatchTests(TestCase): |
1232 | + |
1233 | + def test_describe(self): |
1234 | + obj = object() |
1235 | + mismatch = DoesNotCorrectlyProvide(obj, ITestInterface) |
1236 | + self.assertEqual( |
1237 | + "%r claims to provide %r, but does not do so correctly." |
1238 | + % (obj, ITestInterface), |
1239 | + mismatch.describe()) |
1240 | + |
1241 | + def test_describe_with_extra(self): |
1242 | + obj = object() |
1243 | + mismatch = DoesNotCorrectlyProvide( |
1244 | + obj, ITestInterface, extra="foo") |
1245 | + self.assertEqual( |
1246 | + "%r claims to provide %r, but does not do so correctly: foo" |
1247 | + % (obj, ITestInterface), |
1248 | + mismatch.describe()) |
1249 | + |
1250 | + |
1251 | +class ProvidesTests(TestCase): |
1252 | + |
1253 | + def test_str(self): |
1254 | + matcher = Provides(ITestInterface) |
1255 | + self.assertEqual("provides %r." % ITestInterface, str(matcher)) |
1256 | + |
1257 | + def test_matches(self): |
1258 | + matcher = Provides(ITestInterface) |
1259 | + self.assertEqual(None, matcher.match(Implementor())) |
1260 | + |
1261 | + def match_does_not_provide(self): |
1262 | + obj = object() |
1263 | + matcher = Provides(ITestInterface) |
1264 | + return obj, matcher.match(obj) |
1265 | + |
1266 | + def test_mismatches_not_implements(self): |
1267 | + obj, mismatch = self.match_does_not_provide() |
1268 | + self.assertIsInstance(mismatch, DoesNotProvide) |
1269 | + |
1270 | + def test_does_not_provide_sets_object(self): |
1271 | + obj, mismatch = self.match_does_not_provide() |
1272 | + self.assertEqual(obj, mismatch.obj) |
1273 | + |
1274 | + def test_does_not_provide_sets_interface(self): |
1275 | + obj, mismatch = self.match_does_not_provide() |
1276 | + self.assertEqual(ITestInterface, mismatch.interface) |
1277 | + |
1278 | + def match_does_not_verify(self): |
1279 | + class BadlyImplementedClass: |
1280 | + implements(ITestInterface) |
1281 | + obj = BadlyImplementedClass() |
1282 | + matcher = Provides(ITestInterface) |
1283 | + return obj, matcher.match(obj) |
1284 | + |
1285 | + def test_mismatch_does_not_verify(self): |
1286 | + obj, mismatch = self.match_does_not_verify() |
1287 | + self.assertIsInstance(mismatch, DoesNotCorrectlyProvide) |
1288 | + |
1289 | + def test_does_not_verify_sets_object(self): |
1290 | + obj, mismatch = self.match_does_not_verify() |
1291 | + self.assertEqual(obj, mismatch.obj) |
1292 | + |
1293 | + def test_does_not_verify_sets_interface(self): |
1294 | + obj, mismatch = self.match_does_not_verify() |
1295 | + self.assertEqual(ITestInterface, mismatch.interface) |
1296 | + |
1297 | + def test_does_not_verify_sets_extra(self): |
1298 | + obj, mismatch = self.match_does_not_verify() |
1299 | + try: |
1300 | + verifyObject(ITestInterface, obj) |
1301 | + self.assert_("verifyObject did not raise an exception.") |
1302 | + except BrokenImplementation, e: |
1303 | + extra = str(e) |
1304 | + self.assertEqual(extra, mismatch.extra) |
1305 | + |
1306 | + |
1307 | +class IsNotProxiedTests(TestCase): |
1308 | + |
1309 | + def test_describe(self): |
1310 | + obj = object() |
1311 | + mismatch = IsNotProxied(obj) |
1312 | + self.assertEqual("%r is not proxied." % obj, mismatch.describe()) |
1313 | + |
1314 | + |
1315 | +class IsProxiedTests(TestCase): |
1316 | + |
1317 | + def test_str(self): |
1318 | + matcher = IsProxied() |
1319 | + self.assertEqual("Is proxied.", str(matcher)) |
1320 | + |
1321 | + def test_match(self): |
1322 | + obj = ProxyFactory(object(), checker=NamesChecker()) |
1323 | + self.assertEqual(None, IsProxied().match(obj)) |
1324 | + |
1325 | + def test_mismatch(self): |
1326 | + obj = object() |
1327 | + self.assertIsInstance(IsProxied().match(obj), IsNotProxied) |
1328 | + |
1329 | + def test_mismatch_sets_object(self): |
1330 | + obj = object() |
1331 | + mismatch = IsProxied().match(obj) |
1332 | + self.assertEqual(obj, mismatch.obj) |
1333 | + |
1334 | + |
1335 | +class ProvidesAndIsProxiedTests(TestCase): |
1336 | + |
1337 | + def test_str(self): |
1338 | + matcher = ProvidesAndIsProxied(ITestInterface) |
1339 | + self.assertEqual( |
1340 | + "Provides %r and is proxied." % ITestInterface, |
1341 | + str(matcher)) |
1342 | + |
1343 | + def test_match(self): |
1344 | + obj = ProxyFactory( |
1345 | + Implementor(), checker=NamesChecker(names=("doFoo",))) |
1346 | + matcher = ProvidesAndIsProxied(ITestInterface) |
1347 | + self.assertThat(obj, matcher) |
1348 | + self.assertEqual(None, matcher.match(obj)) |
1349 | + |
1350 | + def test_mismatch_unproxied(self): |
1351 | + obj = Implementor() |
1352 | + matcher = ProvidesAndIsProxied(ITestInterface) |
1353 | + self.assertIsInstance(matcher.match(obj), IsNotProxied) |
1354 | + |
1355 | + def test_mismatch_does_not_implement(self): |
1356 | + obj = ProxyFactory(object(), checker=NamesChecker()) |
1357 | + matcher = ProvidesAndIsProxied(ITestInterface) |
1358 | + self.assertIsInstance(matcher.match(obj), DoesNotProvide) |
On Sun, Aug 1, 2010 at 12:06 AM, James Westby <email address hidden> wrote: reviewers)
> James Westby has proposed merging lp:~james-w/launchpad/no-more-sampledata-0 into lp:launchpad/devel.
>
> Requested reviews:
> Launchpad code reviewers (launchpad-
>
>
> Hi,
>
> This changes a bunch of soyuz tests to not use the sampledata.
>
Woot.
> It goes a bit further than that in that it restructures them to sampledata, and extended the factory
> have less setup and to create the things they need using the
> factory rather than SoyuzTestPublisher.
>
> In addition I moved some other code that is too deeply buried
> right now in to lp.testing.
> with some new methods to satisfy the needs of the changed code.
>
> Thanks,
>
Thank you.
The review below mostly picks up on some naming standard glitches and
points out some things that could be improved in the soyuz tests
(rather than in your changes). However, I've also got a couple of
questions about your changes and would very much appreciate hearing
back from you.
I also feel a little guilty about making so many petty comments when
you've done such a helpful thing. Please do not feel obliged to act on
all of my suggestions.
jml
> === modified file 'lib/lp/ soyuz/tests/ ppa.py' soyuz/tests/ ppa.py 2010-03-11 16:48:37 +0000 soyuz/tests/ ppa.py 2010-07-31 23:06:48 +0000 interfaces. binarypackagena me import IBinaryPackageN ameSet interfaces. publishing import ( ngPriority, PackagePublishi ngStatus) sampledata import ( IES_NAME, I386_ARCHITECTU RE_NAME, MAIN_COMPONENT_ NAME, FIREFOX_ SOURCEPACKAGENA ME, MOZILLA_ FIREFOX_ SOURCEPACKAGEVE RSION,
> --- lib/lp/
> +++ lib/lp/
> @@ -25,6 +25,10 @@
> from lp.soyuz.
> from lp.soyuz.
> PackagePublishi
> +from lp.testing.
> + HOARY_DISTROSER
> + MOZILLA_
> + NAME16_PERSON_NAME, UBUNTU_TEAM_NAME)
>
I'm very glad you've started putting things in the sampledata module.
Would it be possible to change these names to clarify the intent
behind their use?
For example, NAME16_PERSON_NAME tells me nothing about the person TEAM_MEMBER_ NAME might be better.
object, and when I see it in a test, I don't know why name16 was
chosen instead of name15. UBUNTU_
Likewise, it would be good to have intent-revealing names for the
FIREFOX constants and the HOARY constants.
> === modified file 'lib/lp/ soyuz/tests/ soyuz.py' soyuz/tests/ soyuz.py 2010-02-08 11:40:06 +0000 soyuz/tests/ soyuz.py 2010-07-31 23:06:48 +0000 model.publishin g import ( blishingHistory , blishingHistory ) sampledata import ( RE_NAME, LAUNCHPAD_ DBUSER_ NAME, DISTRIBUTION_ NAME, WARTY_DISTROSER IES_NAME, SUITE_NAME)
> --- lib/lp/
> +++ lib/lp/
> @@ -27,14 +27,19 @@
> from lp.soyuz.
> SourcePackagePu
> BinaryPackagePu
> +from lp.testing.
> + CHROOT_LFA, CPROV_NAME, I386_ARCHITECTU
> + UBUNTU_
> + WARTY_UPDATES_
>
Ditto CPROV, LAUNCHPAD_ DBUSER_ NAME and WARTY_*
> === modified file 'lib/lp/ soyuz/tests/ test_archive. py' soyuz/tests/ test_archive. py 2010-07-21 07:45:50 +0000 soyuz/tests/ test_archive. py 2010-07-31 23:06:48 +0000 ionsInArchive( TestCaseWithFac tory): ssLayer
> --- lib/lp/
> +++ lib/lp/
...
> @@ -42,118 +41,110 @@
>
> class TestGetPublicat
>
> - layer = LaunchpadZopele
> -
> - def setUp(self):
> - ...