Merge lp:~jelmer/launchpad/archive-arch-fix into lp:launchpad

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Māris Fogels
Approved revision: no longer in the source branch.
Merged at revision: 11093
Proposed branch: lp:~jelmer/launchpad/archive-arch-fix
Merge into: lp:launchpad
Diff against target: 91 lines (+31/-4)
2 files modified
lib/lp/soyuz/model/archivearch.py (+3/-2)
lib/lp/soyuz/tests/test_archivearch.py (+28/-2)
To merge this branch: bzr merge lp:~jelmer/launchpad/archive-arch-fix
Reviewer Review Type Date Requested Status
Māris Fogels (community) release-critical Approve
Henning Eggers (community) code Approve
Review via email: mp+29160@code.launchpad.net

Description of the change

ArchiveArchSet.getRestricted() does not actually use the archive that is specified and will return all ArchiveArchs that exist for *any* archive. This basically means that if a restricted architecture is enabled for one PPA it will be enabled for *all* PPA's.

This also includes a test for ArchiveArchSet.getByArchive() to prove it doesn't suffer from the same issue as ArchiveArchSet.getRestricted.

To post a comment you must log in.
Revision history for this message
Henning Eggers (henninge) wrote :
Download full text (5.8 KiB)

Hi Jelmer,
thank you for this quick fix. I have a few comments about the tests and will
wait for your reply before I approve the branch.

Cheers,
Henning

Am 04.07.2010 01:40, schrieb Jelmer Vernooij:
> === modified file 'lib/lp/soyuz/model/archivearch.py'
> --- lib/lp/soyuz/model/archivearch.py 2010-02-25 15:25:30 +0000
> +++ lib/lp/soyuz/model/archivearch.py 2010-07-03 23:40:54 +0000
> @@ -13,7 +13,7 @@
> from canonical.launchpad.webapp.interfaces import (
> IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
>
> -from storm.expr import Join, LeftJoin
> +from storm.expr import And, Join, LeftJoin
> from storm.locals import Int, Reference, Storm
>
>
> @@ -65,7 +65,8 @@
> ProcessorFamily,
> LeftJoin(
> ArchiveArch,
> - ArchiveArch.processorfamily == ProcessorFamily.id))
> + And(ArchiveArch.archive == archive.id,
> + ArchiveArch.processorfamily == ProcessorFamily.id)))
> result_set = store.using(*origin).find(
> (ProcessorFamily, ArchiveArch),
> (ProcessorFamily.restricted == True))
>
> === modified file 'lib/lp/soyuz/tests/test_archivearch.py'
> --- lib/lp/soyuz/tests/test_archivearch.py 2010-02-25 15:25:30 +0000
> +++ lib/lp/soyuz/tests/test_archivearch.py 2010-07-03 23:40:54 +0000
> @@ -11,6 +11,7 @@
>
> from lp.testing import TestCaseWithFactory
>
> +from lp.registry.interfaces.distribution import IDistributionSet

from canonical.launchpad.interfaces import ILaunchpadCelebrities

See below.

> from lp.registry.interfaces.person import IPersonSet
> from lp.soyuz.interfaces.archivearch import IArchiveArchSet
> from lp.soyuz.interfaces.processor import IProcessorFamilySet
> @@ -24,6 +25,8 @@
> super(TestArchiveArch, self).setUp()
>
> self.ppa = getUtility(IPersonSet).getByName('cprov').archive
> + ubuntu = getUtility(IDistributionSet)['ubuntu']
> + self.ubuntu_archive = ubuntu.main_archive

We have a celebrity that you should use for this.

getUtility(ILaunchpadCelebrities).ubuntu

> pss = getUtility(IProcessorFamilySet)
> self.cell_proc = pss.new(
> 'cell-proc', 'PS cell processor', 'Screamingly faaaaaaaaaaaast',
> @@ -32,7 +35,7 @@
> 'omap', 'Multimedia applications processor',
> 'Does all your sound & video', True)
>
> - def test_no_associations(self):
> + def test_no_restricted_uassociations(self):
> """Our archive is not associated with any restricted processor
> families yet."""
> result_set = list(
> @@ -40,7 +43,7 @@
> archivearches = [row[1] for row in result_set]
> self.assertTrue(all(aa is None for aa in archivearches))
>
> - def test_single_association(self):
> + def test_single_restricted_association(self):
> """Our archive is now associated with one of the restricted processor
> families."""
> getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc)
> @@ -52,6 +55,29 @@
> { 'arm' : False, 'cell-proc' : True, 'omap' : False},

Leading space. ^ Copied&pasted further down ... ;)

> results...

Read more...

Revision history for this message
Julian Edwards (julian-edwards) wrote :
Download full text (4.0 KiB)

On Monday 05 July 2010 11:07:27 Henning Eggers wrote:
> Hi Jelmer,
> thank you for this quick fix. I have a few comments about the tests and
> will wait for your reply before I approve the branch.
>
> Cheers,
> Henning

Thanks Henning.

I'm taking this over since Jelmer's away for 2 weeks.

> > + ubuntu = getUtility(IDistributionSet)['ubuntu']
> > + self.ubuntu_archive = ubuntu.main_archive
>
> We have a celebrity that you should use for this.
>
> getUtility(ILaunchpadCelebrities).ubuntu

We hardly ever use it in Soyuz code, I don't see point of changing it here,
celebs should be optional.

> > { 'arm' : False, 'cell-proc' : True, 'omap' : False},
>
> Leading space. ^ Copied&pasted further down ... ;)

I'll fix those.

>
> > results)
> >
> > + def test_restricted_association_archive_only(self):
> Looks like this naming is used throughout this file but the correct name
> would probably be "test_getRestrictedFamilies_archive_only" or similar.
>
> https://dev.launchpad.net/TestsStyleGuide#Python Test Cases

Yeah those are wrong, I'll fix the names.

> > + """Test that only the associated archs for the archive itself
> > are + returned."""
>
> This doc string violates our docstring conventions but you don't need a doc
> string for test methods anyway, just a comment.

I'll fix that too!

> # Test that only the associated archs for the archive itself are
> # returned.
>
> I see more instances of that, maybe you correct fix them as a drive-by fix?
> Thank you very much!

I need to get an R-C for this so I'll leave that for another time if you don't
mind :)

>
> > + getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc)
> > + getUtility(IArchiveArchSet).new(self.ubuntu_archive, self.omap)
>
> Hm, maybe you could add a factory method to the LaunchpadObjectFactory for
> ArchiveArch? Or are there reasons against that?

We could do. But this is an R-C so we'll do it later!

>
> > + result_set = list(
> > + getUtility(IArchiveArchSet).getRestrictedfamilies(self.ppa))
>
> Else, the repeated calls to getUtility(IArchiveArchSet) clutter the code.
> Maybe you should use a local or instance variable to store that?

I can do that.

> Also, I think getRestrictedfamilies should be getRestrictedFamilies to be
> proper camelCase. I know this is not your doing but could you please fix
> that if it does not have too many call sites?

Yeah I can fix that.

> > + results = dict(
> > + (row[0].name, row[1] is not None) for row in result_set)
> > + self.assertEquals(
> > + { 'arm' : False, 'cell-proc' : True, 'omap' : False},
>
> Leading space. ^

Yep.

>
> > + results)
> > +
> > + def test_get_by_archive(self):
> > + """Test ArchiveArchSet.getByArchive."""
> > + getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc)
> > + getUtility(IArchiveArchSet).new(self.ubuntu_archive, self.omap)
> > + result_set = list(
> > + getUtility(IArchiveArchSet).getByArchive(self.ppa))
>
> Same comment about storing archive_arch_set

Yep.

>
> > + self.assertEqual...

Read more...

Revision history for this message
Julian Edwards (julian-edwards) wrote :
Revision history for this message
Henning Eggers (henninge) wrote :
Download full text (6.8 KiB)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am 05.07.2010 12:43, schrieb Julian Edwards:
> I'm taking this over since Jelmer's away for 2 weeks.

Hi Julian! ;)

>
>>> + ubuntu = getUtility(IDistributionSet)['ubuntu']
>>> + self.ubuntu_archive = ubuntu.main_archive
>>
>> We have a celebrity that you should use for this.
>>
>> getUtility(ILaunchpadCelebrities).ubuntu
>
> We hardly ever use it in Soyuz code, I don't see point of changing it here,
> celebs should be optional.

Wow, all code is equal but some code is more equal than other? I am not sure I
am buying this. ;-) Is it not all Launchpad code, Julian? I don't think that
"we don't do that in Soyuz/Rosetta/Malone/etc. code" should ever be a valid
excuse to diverge from the coding styles. That just makes reviewing other
teams' code so much harder when you have to consider their conventions. And
think about the nightmare for community contributors ...

OK, both ideas, Soyuz code receiving special treatment in reviews and the
required use of celebs (or not) should be discussed among reviewers. Will you
add them to the agenda or shall I do it?

>
>>> { 'arm' : False, 'cell-proc' : True, 'omap' : False},
>>
>> Leading space. ^ Copied&pasted further down ... ;)
>
> I'll fix those.

Thanks.

>
>>
>>> results)
>>>
>>> + def test_restricted_association_archive_only(self):
>> Looks like this naming is used throughout this file but the correct name
>> would probably be "test_getRestrictedFamilies_archive_only" or similar.
>>
>> https://dev.launchpad.net/TestsStyleGuide#Python Test Cases
>
> Yeah those are wrong, I'll fix the names.

Great!

>
>>> + """Test that only the associated archs for the archive itself
>>> are + returned."""
>>
>> This doc string violates our docstring conventions but you don't need a doc
>> string for test methods anyway, just a comment.
>
> I'll fix that too!

Good.

>
>> # Test that only the associated archs for the archive itself are
>> # returned.
>>
>> I see more instances of that, maybe you correct fix them as a drive-by fix?
>> Thank you very much!
>
> I need to get an R-C for this so I'll leave that for another time if you don't
> mind :)

Understood. Fair enough. Maybe record a tech-debt bug for this?

>
>>
>>> + getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc)
>>> + getUtility(IArchiveArchSet).new(self.ubuntu_archive, self.omap)
>>
>> Hm, maybe you could add a factory method to the LaunchpadObjectFactory for
>> ArchiveArch? Or are there reasons against that?
>
> We could do. But this is an R-C so we'll do it later!

Ok. Again, a bug will help to remember it. ;)

>
>>
>>> + result_set = list(
>>> + getUtility(IArchiveArchSet).getRestrictedfamilies(self.ppa))
>>
>> Else, the repeated calls to getUtility(IArchiveArchSet) clutter the code.
>> Maybe you should use a local or instance variable to store that?
>
> I can do that.

Thanks.

>
>> Also, I think getRestrictedfamilies should be getRestrictedFamilies to be
>> proper camelCase. I know this is not your doing but could you please fix
>> that if it does not have too many call sites?
...

Read more...

review: Approve (code)
Revision history for this message
Julian Edwards (julian-edwards) wrote :
Download full text (4.4 KiB)

On Monday 05 July 2010 12:43:24 Henning Eggers wrote:
> Review: Approve code

Cheers.

>
> Am 05.07.2010 12:43, schrieb Julian Edwards:
> > I'm taking this over since Jelmer's away for 2 weeks.
>
> Hi Julian! ;)

Hai!

> Wow, all code is equal but some code is more equal than other? I am not
> sure I am buying this. ;-) Is it not all Launchpad code, Julian? I don't
> think that "we don't do that in Soyuz/Rosetta/Malone/etc. code" should
> ever be a valid excuse to diverge from the coding styles. That just makes
> reviewing other teams' code so much harder when you have to consider their
> conventions. And think about the nightmare for community contributors ...

Well, consider that celebrities are essentially hard-coded special cases for a
moment. This in itself is pretty gross, but sometimes unfortunately
unavoidable.

For me, the use of a celebrity means that the code in question *requires* that
particular celebrity for some special case and that using a different value of
the same type won't work.

In the case of this branch, that's not true. It could be argued in fact that
the test should be using makeDistro instead, but I expect there's some bizarre
sample data weirdness (which unfortunately Soyuz depends on heavily) requiring
the use of Ubuntu.

It therefore makes perfect sense that the code is pulling "ubuntu" like that
instead of using the celebrity.

Did I explain that nuance well enough?

> OK, both ideas, Soyuz code receiving special treatment in reviews and the
> required use of celebs (or not) should be discussed among reviewers. Will
> you add them to the agenda or shall I do it?

Feel free if you want to discuss it.

> > I need to get an R-C for this so I'll leave that for another time if you
> > don't mind :)
>
> Understood. Fair enough. Maybe record a tech-debt bug for this?

Actually I ended up doing it, it wasn't many.

> The style guide says:
> "When asserting for equality use the form assertEqual(expected_results,
> actual_results, "...")".
> I remember that we agreed not to go around and change existing tests unless
> we touch them but it is definitely the recommended style for new tests.

Euargh. I could have sworn it was the other way around. This is going to
really confuse me now. I'd love to see the IRC logs for that conversation
that we had in the reviewers' meeting again though.

> I am not going into who you might be referring to by "we" here ... :-P

The royal We? :)

> Yes, I have always been a fan of those. The asserts in LaunchpadTestCase
> already provide strings and I guess that's why we don't see them a lot in
> our assert calls. I have actually had reviewers ask me to remove them.
>
> > A non-matching dictionary would look messy in comparison, no?
>
> You can test all three conditions at the same time. You can see how many
> rows were returned instead and what their values are. Much more useful.
>
> The problem with multiple assert statements in one test method is that not
> all will be executed if one fails and you are missing valuable information
> that you can only gain by changing the test code and running the test
> again.

That's an interesting point that I hadn't considered.

> ...

Read more...

Revision history for this message
Māris Fogels (mars) :
review: Approve (release-critical)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/soyuz/model/archivearch.py'
2--- lib/lp/soyuz/model/archivearch.py 2010-02-25 15:25:30 +0000
3+++ lib/lp/soyuz/model/archivearch.py 2010-07-03 23:45:44 +0000
4@@ -13,7 +13,7 @@
5 from canonical.launchpad.webapp.interfaces import (
6 IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
7
8-from storm.expr import Join, LeftJoin
9+from storm.expr import And, Join, LeftJoin
10 from storm.locals import Int, Reference, Storm
11
12
13@@ -65,7 +65,8 @@
14 ProcessorFamily,
15 LeftJoin(
16 ArchiveArch,
17- ArchiveArch.processorfamily == ProcessorFamily.id))
18+ And(ArchiveArch.archive == archive.id,
19+ ArchiveArch.processorfamily == ProcessorFamily.id)))
20 result_set = store.using(*origin).find(
21 (ProcessorFamily, ArchiveArch),
22 (ProcessorFamily.restricted == True))
23
24=== modified file 'lib/lp/soyuz/tests/test_archivearch.py'
25--- lib/lp/soyuz/tests/test_archivearch.py 2010-02-25 15:25:30 +0000
26+++ lib/lp/soyuz/tests/test_archivearch.py 2010-07-03 23:45:44 +0000
27@@ -11,6 +11,7 @@
28
29 from lp.testing import TestCaseWithFactory
30
31+from lp.registry.interfaces.distribution import IDistributionSet
32 from lp.registry.interfaces.person import IPersonSet
33 from lp.soyuz.interfaces.archivearch import IArchiveArchSet
34 from lp.soyuz.interfaces.processor import IProcessorFamilySet
35@@ -24,6 +25,8 @@
36 super(TestArchiveArch, self).setUp()
37
38 self.ppa = getUtility(IPersonSet).getByName('cprov').archive
39+ ubuntu = getUtility(IDistributionSet)['ubuntu']
40+ self.ubuntu_archive = ubuntu.main_archive
41 pss = getUtility(IProcessorFamilySet)
42 self.cell_proc = pss.new(
43 'cell-proc', 'PS cell processor', 'Screamingly faaaaaaaaaaaast',
44@@ -32,7 +35,7 @@
45 'omap', 'Multimedia applications processor',
46 'Does all your sound & video', True)
47
48- def test_no_associations(self):
49+ def test_no_restricted_associations(self):
50 """Our archive is not associated with any restricted processor
51 families yet."""
52 result_set = list(
53@@ -40,7 +43,7 @@
54 archivearches = [row[1] for row in result_set]
55 self.assertTrue(all(aa is None for aa in archivearches))
56
57- def test_single_association(self):
58+ def test_single_restricted_association(self):
59 """Our archive is now associated with one of the restricted processor
60 families."""
61 getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc)
62@@ -52,6 +55,29 @@
63 { 'arm' : False, 'cell-proc' : True, 'omap' : False},
64 results)
65
66+ def test_restricted_association_archive_only(self):
67+ """Test that only the associated archs for the archive itself are
68+ returned."""
69+ getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc)
70+ getUtility(IArchiveArchSet).new(self.ubuntu_archive, self.omap)
71+ result_set = list(
72+ getUtility(IArchiveArchSet).getRestrictedfamilies(self.ppa))
73+ results = dict(
74+ (row[0].name, row[1] is not None) for row in result_set)
75+ self.assertEquals(
76+ { 'arm' : False, 'cell-proc' : True, 'omap' : False},
77+ results)
78+
79+ def test_get_by_archive_no_other_archives(self):
80+ """Test ArchiveArchSet.getByArchive returns no other archives."""
81+ getUtility(IArchiveArchSet).new(self.ppa, self.cell_proc)
82+ getUtility(IArchiveArchSet).new(self.ubuntu_archive, self.omap)
83+ result_set = list(
84+ getUtility(IArchiveArchSet).getByArchive(self.ppa))
85+ self.assertEquals(1, len(result_set))
86+ self.assertEquals(self.ppa, result_set[0].archive)
87+ self.assertEquals(self.cell_proc, result_set[0].processorfamily)
88+
89
90 def test_suite():
91 return unittest.TestLoader().loadTestsFromName(__name__)