Merge lp://staging/~julian-edwards/launchpad/schema-distro-parents into lp://staging/launchpad/db-devel

Proposed by Julian Edwards
Status: Merged
Approved by: Julian Edwards
Approved revision: no longer in the source branch.
Merged at revision: 10447
Proposed branch: lp://staging/~julian-edwards/launchpad/schema-distro-parents
Merge into: lp://staging/launchpad/db-devel
Diff against target: 424 lines (+336/-0)
9 files modified
database/schema/comments.sql (+6/-0)
database/schema/patch-2208-61-0.sql (+20/-0)
database/schema/security.cfg (+1/-0)
lib/canonical/launchpad/security.py (+13/-0)
lib/lp/registry/configure.zcml (+16/-0)
lib/lp/registry/interfaces/distroseriesparent.py (+62/-0)
lib/lp/registry/model/distroseriesparent.py (+74/-0)
lib/lp/registry/tests/test_distroseriesparent.py (+132/-0)
lib/lp/testing/factory.py (+12/-0)
To merge this branch: bzr merge lp://staging/~julian-edwards/launchpad/schema-distro-parents
Reviewer Review Type Date Requested Status
Henning Eggers (community) code Approve
Stuart Bishop (community) db Approve
Review via email: mp+57898@code.staging.launchpad.net

Commit message

[r=henninge,stub][bug=754750] [incr] Add DistroSeriesParent table to track multiple parents for a derived distroseries.

Description of the change

Add a new database table, DistroSeriesParent, that will track all of a distroseries' derived distroseries and whether they've been initialized or not (initialized is when the packages get copied from the parent, this needs to be tracked so it can't happen twice).

This will eventually replace DistroSeries.parent_series as we need to track more than one parent for a derived series.

Most of the changes are boilerplate. The security declarations are set up so the person changing the data must have edit permission on the derived series.

Other than that, a routine and dull branch.

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

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

Hi Julian,
thanks for adding this linking table. You indeed almost had me bored but I did
find a few of my pet issues in your branch ... ;-)

I'd really like to see the tests cleaned up before I approve this.

 review needs-fixing

Cheers,
Henning

Am 15.04.2011 18:17, schrieb Julian Edwards:
> === modified file 'database/schema/comments.sql'
> === added file 'database/schema/patch-2208-99-0.sql'
> === modified file 'database/schema/security.cfg'

Stub will comment on these, if needed. Look ok to me. ;)

> === modified file 'lib/canonical/launchpad/security.py'
> --- lib/canonical/launchpad/security.py 2011-04-14 15:26:55 +0000
> +++ lib/canonical/launchpad/security.py 2011-04-15 16:31:45 +0000
> @@ -113,6 +113,7 @@
> IDistributionSourcePackage,
> )
> from lp.registry.interfaces.distroseries import IDistroSeries
> +from lp.registry.interfaces.distroseriesparent import IDistroSeriesParent
> from lp.registry.interfaces.distroseriesdifference import (
> IDistroSeriesDifferenceEdit,
> )
> @@ -1014,6 +1015,16 @@
> usedfor = IDistroSeries
>
>
> +class EditDistroSeriesParent(AuthorizationBase):
> + """DistroSeriesParent can be edited by the same people who can edit
> + the derived_distroseries."""
> + permission = "launchpad.Edit"
> + usedfor = IDistroSeriesParent
> +
> + def checkAuthenticated(self, user):
> + return check_permission(self.permission, self.obj.derived_series)

Using check_permission in security adapters is flawed and needs to be stopped.
Please see bug 764406 as to why. You can fix this by referencing
EditDistroSeriesByReleaseManagerOrDistroOwnersOrAdmins directly or leave it in
to be fixed when that bug is fixed. ;)

> +
> +
> class ViewCountry(AnonymousAuthorization):
> """Anyone can view a Country."""
> usedfor = ICountry
>
> === modified file 'lib/lp/registry/configure.zcml'
> === added file 'lib/lp/registry/interfaces/distroseriesparent.py'
> === added file 'lib/lp/registry/model/distroseriesparent.py'

Yeah, this is the boring bit ... ;) Thanks for a solid implementation.

> === added file 'lib/lp/registry/tests/test_distroseriesparent.py'
> --- lib/lp/registry/tests/test_distroseriesparent.py 1970-01-01 00:00:00 +0000
> +++ lib/lp/registry/tests/test_distroseriesparent.py 2011-04-15 16:31:45 +0000
> @@ -0,0 +1,145 @@
> +# Copyright 2011 Canonical Ltd. This software is licensed under the
> +# GNU Affero General Public License version 3 (see the file LICENSE).
> +
> +"""Tests for DistroSeriesParent model class."""
> +
> +__metaclass__ = type
> +
> +from testtools.matchers import (
> + Equals,
> + MatchesStructure,
> + )
> +
> +from zope.component import getUtility
> +from zope.interface.verify import verifyObject
> +from zope.security.interfaces import Unauthorized
> +
> +from canonical.launchpad.ftests import login
> +from canonical.testing.layers import (
> + DatabaseFunctionalLayer,
> + ZopelessDatabaseLayer,
> + )
> +from lp.registry.interfaces.distroseriesparent import (
> + IDistroSeriesParent,
> + IDistroSeriesParentSet,
> + )
> +from lp.testing import (
> + person_logged_in,
> +...

Read more...

review: Needs Fixing
Revision history for this message
Stuart Bishop (stub) wrote :

Discussed on IRC.

The proposed DB patch is fine from DBA pov.

Consider if an enum would be more use than a boolean field.

No need to add checks that the child != parent - the Python code already needs to maintain more than this to avoid loops.

patch-2208-61-0.sql

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

Thanks for the review Henning!

On Monday 18 April 2011 11:22:26 you wrote:
> Review: Needs Fixing
> Hi Julian,
> thanks for adding this linking table. You indeed almost had me bored but I
> did find a few of my pet issues in your branch ... ;-)
>
> I'd really like to see the tests cleaned up before I approve this.

Not sure I agree with all of your comments there :-) But read on ...

> >
> > +class EditDistroSeriesParent(AuthorizationBase):
> > + """DistroSeriesParent can be edited by the same people who can edit
> > + the derived_distroseries."""
> > + permission = "launchpad.Edit"
> > + usedfor = IDistroSeriesParent
> > +
> > + def checkAuthenticated(self, user):
> > + return check_permission(self.permission,
> > self.obj.derived_series)
>
> Using check_permission in security adapters is flawed and needs to be
> stopped. Please see bug 764406 as to why. You can fix this by referencing
> EditDistroSeriesByReleaseManagerOrDistroOwnersOrAdmins directly or leave it
> in to be fixed when that bug is fixed. ;)

Woops, fixed :-)

> > === modified file 'lib/lp/registry/configure.zcml'
> > === added file 'lib/lp/registry/interfaces/distroseriesparent.py'
> > === added file 'lib/lp/registry/model/distroseriesparent.py'
>
> Yeah, this is the boring bit ... ;) Thanks for a solid implementation.

I've done it too many times now!

> > + def setUp(self):
> > + TestCaseWithFactory.setUp(self)
> > + #self.distribution =
> > self.factory.makeDistribution(name='conftest')
>
> Oh, an unused setUp!

Bugger, forgot to remove it :-)

> > +
> > + def test_verify_interface(self):
> > + # Test the interface for the model.
> > + dsp = self.factory.makeDistroSeriesParent()
> > + verified = verifyObject(IDistroSeriesParent, dsp)
> > + self.assertTrue(verified)
> > +
> > + def test_properties(self):
> > + # Test the model properties.
> > + parent_series = self.factory.makeDistroSeries()
> > + derived_series = self.factory.makeDistroSeries()
> > + dsp = self.factory.makeDistroSeriesParent(
> > + derived_series=derived_series,
> > + parent_series=parent_series,
> > + initialized=True
> > + )
> > +
> > + self.assertThat(
> > + dsp,
> > + MatchesStructure(
> > + derived_series=Equals(derived_series),
> > + parent_series=Equals(parent_series),
> > + initialized=Equals(True)
> > + ))
> > +
> > + def test_getByDerivedSeries(self):
> > + parent_series = self.factory.makeDistroSeries()
> > + derived_series = self.factory.makeDistroSeries()
> > + self.factory.makeDistroSeriesParent(
> > + derived_series, parent_series)
>
> Hm, why not let makeDistroSeriesParent create the series? Just pick them
> from the dsp object you get from the factory.

I've re-worked these tests entirely so it's actually testing *editing*
(previously it was doing nothing :/) and they are much simpler now.

>
> > + results = getUtility(IDistroSeriesParentSet).getByDerivedSeries(
> > + derived_series)
> > + s...

Read more...

1=== modified file 'lib/canonical/launchpad/security.py'
2--- lib/canonical/launchpad/security.py 2011-04-15 16:23:07 +0000
3+++ lib/canonical/launchpad/security.py 2011-04-18 11:40:43 +0000
4@@ -1022,7 +1022,9 @@
5 usedfor = IDistroSeriesParent
6
7 def checkAuthenticated(self, user):
8- return check_permission(self.permission, self.obj.derived_series)
9+ auth = EditDistroSeriesByReleaseManagerOrDistroOwnersOrAdmins(
10+ self.obj.derived_series)
11+ return auth.checkAuthenticated(user)
12
13
14 class ViewCountry(AnonymousAuthorization):
15
16=== modified file 'lib/lp/registry/tests/test_distroseriesparent.py'
17--- lib/lp/registry/tests/test_distroseriesparent.py 2011-04-15 15:51:18 +0000
18+++ lib/lp/registry/tests/test_distroseriesparent.py 2011-04-18 11:40:55 +0000
19@@ -34,10 +34,6 @@
20 """Test the `DistroSeriesParent` model."""
21 layer = ZopelessDatabaseLayer
22
23- def setUp(self):
24- TestCaseWithFactory.setUp(self)
25- #self.distribution = self.factory.makeDistribution(name='conftest')
26-
27 def test_verify_interface(self):
28 # Test the interface for the model.
29 dsp = self.factory.makeDistroSeriesParent()
30@@ -101,45 +97,36 @@
31
32 layer = DatabaseFunctionalLayer
33
34- def setUp(self):
35- super(TestDistroSeriesParentSecurity, self).setUp()
36- self.parent_series = self.factory.makeDistroSeries()
37- self.derived_series = self.factory.makeDistroSeries()
38- self.person = self.factory.makePerson()
39-
40 def test_random_person_is_unauthorized(self):
41- dsp_set = getUtility(IDistroSeriesParentSet)
42- dsp = dsp_set.new(self.derived_series, self.parent_series, False)
43- with person_logged_in(self.person):
44+ dsp = self.factory.makeDistroSeriesParent()
45+ person = self.factory.makePerson()
46+ with person_logged_in(person):
47 self.assertRaises(
48 Unauthorized,
49- setattr, dsp, "derived_series", self.parent_series)
50-
51- def assertCanEdit(self):
52- dsp_set = getUtility(IDistroSeriesParentSet)
53- dsp = dsp_set.new(
54- self.derived_series, self.parent_series, False)
55- self.assertThat(
56- dsp,
57- MatchesStructure(
58- derived_series=Equals(self.derived_series),
59- parent_series=Equals(self.parent_series),
60- initialized=Equals(False)
61- ))
62-
63- def test_distro_drivers_can_edit(self):
64- # Test that distro drivers can edit the data.
65+ setattr, dsp, "derived_series", dsp.parent_series)
66+
67+ def assertCanEdit(self, dsp):
68+ dsp.initialized = False
69+ self.assertEquals(False, dsp.initialized)
70+
71+ def test_distroseries_drivers_can_edit(self):
72+ # Test that distroseries drivers can edit the data.
73+ dsp = self.factory.makeDistroSeriesParent()
74+ person = self.factory.makePerson()
75 login(LAUNCHPAD_ADMIN)
76- self.derived_series.distribution.driver = self.person
77- with person_logged_in(self.person):
78- self.assertCanEdit()
79+ dsp.derived_series.driver = person
80+ with person_logged_in(person):
81+ self.assertCanEdit(dsp)
82
83 def test_admins_can_edit(self):
84+ dsp = self.factory.makeDistroSeriesParent()
85 login(LAUNCHPAD_ADMIN)
86- self.assertCanEdit()
87+ self.assertCanEdit(dsp)
88
89 def test_distro_owners_can_edit(self):
90+ dsp = self.factory.makeDistroSeriesParent()
91+ person = self.factory.makePerson()
92 login(LAUNCHPAD_ADMIN)
93- self.derived_series.distribution.owner = self.person
94- with person_logged_in(self.person):
95- self.assertCanEdit()
96+ dsp.derived_series.distribution.owner = person
97+ with person_logged_in(person):
98+ self.assertCanEdit(dsp)
Revision history for this message
Henning Eggers (henninge) wrote :

Yes, much better, thank you. I had actually wondered about how you were testing "can edit" but forgot to ask. Thanks for fixing that.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.

Subscribers

People subscribed via source and target branches

to status/vote changes: