Merge lp:~thumper/launchpad/fix-deletion-syncUpdate into lp:launchpad

Proposed by Tim Penhey
Status: Merged
Approved by: Tim Penhey
Approved revision: no longer in the source branch.
Merged at revision: 11335
Proposed branch: lp:~thumper/launchpad/fix-deletion-syncUpdate
Merge into: lp:launchpad
Diff against target: 105 lines (+16/-17)
2 files modified
lib/lp/code/model/branch.py (+3/-5)
lib/lp/code/model/tests/test_branch.py (+13/-12)
To merge this branch: bzr merge lp:~thumper/launchpad/fix-deletion-syncUpdate
Reviewer Review Type Date Requested Status
Jonathan Lange (community) Approve
Review via email: mp+32410@code.launchpad.net

Commit message

Fix deletion of branches linked as translations_branch.

Description of the change

This branch fixes a bug stopping branches that have been linked to product series as translations branches from being deleted.

The guts of the issue was the code that cleared the translations_branch attribute of the product series didn't work - because it was clearing the "branch" attribute, not the "translations_branch". A case here of missing tests.

I added the test, and also fixed up the model class to only flush to the DB once at the end
of the _breakReference() call.

As part of the cleanup, I also moved the Store.flush() call into a test cleanup method that gets run for every test, and removed the use of sample data.

tests:
  TestBranchDeletion

To post a comment you must log in.
Revision history for this message
Jonathan Lange (jml) wrote :

On Thu, Aug 12, 2010 at 3:06 AM, Tim Penhey <email address hidden> wrote:
> Tim Penhey has proposed merging lp:~thumper/launchpad/fix-deletion-syncUpdate into lp:launchpad/devel.
>
> Requested reviews:
>  Launchpad code reviewers (launchpad-reviewers)
> Related bugs:
>  #599259 ForbiddenAttribute: syncUpdate
>  https://bugs.launchpad.net/bugs/599259
>
>
> This branch fixes a bug stopping branches that have been linked to product series as translations branches from being deleted.
>
> The guts of the issue was the code that cleared the translations_branch attribute of the product series didn't work - because it was clearing the "branch" attribute, not the "translations_branch".  A case here of missing tests.
>
> I added the test, and also fixed up the model class to only flush to the DB once at the end
> of the _breakReference() call.
>
> As part of the cleanup, I also moved the Store.flush() call into a test cleanup method that gets run for every test, and removed the use of sample data.
>

Thanks Tim.

Can you please define a constant in lp.testing.sampledata for
'<email address hidden>' and use that in the tests? Alternatively, use
self.factory.loginAsAnyone() or one of the login helpers.

Other than that, look good.

cheers,
jml

Revision history for this message
Jonathan Lange (jml) wrote :

See comment.

review: Approve
Revision history for this message
Tim Penhey (thumper) wrote :

On Fri, 13 Aug 2010 01:41:16 you wrote:
> On Thu, Aug 12, 2010 at 3:06 AM, Tim Penhey <email address hidden>
wrote:
> > Tim Penhey has proposed merging
> > lp:~thumper/launchpad/fix-deletion-syncUpdate into lp:launchpad/devel.
> >
> > Requested reviews:
> > Launchpad code reviewers (launchpad-reviewers)
> > Related bugs:
> > #599259 ForbiddenAttribute: syncUpdate
> > https://bugs.launchpad.net/bugs/599259
> >
> >
> > This branch fixes a bug stopping branches that have been linked to
> > product series as translations branches from being deleted.
> >
> > The guts of the issue was the code that cleared the translations_branch
> > attribute of the product series didn't work - because it was clearing
> > the "branch" attribute, not the "translations_branch". A case here of
> > missing tests.
> >
> > I added the test, and also fixed up the model class to only flush to the
> > DB once at the end of the _breakReference() call.
> >
> > As part of the cleanup, I also moved the Store.flush() call into a test
> > cleanup method that gets run for every test, and removed the use of
> > sample data.
>
> Thanks Tim.
>
> Can you please define a constant in lp.testing.sampledata for
> '<email address hidden>' and use that in the tests? Alternatively, use
> self.factory.loginAsAnyone() or one of the login helpers.

I removed the use of '<email address hidden>'

Tim

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/model/branch.py'
2--- lib/lp/code/model/branch.py 2010-08-02 02:36:32 +0000
3+++ lib/lp/code/model/branch.py 2010-08-12 02:06:49 +0000
4@@ -646,6 +646,7 @@
5 # actually a very interesting thing to tell the user about.
6 if self.code_import is not None:
7 DeleteCodeImport(self.code_import)()
8+ Store.of(self).flush()
9
10 def associatedProductSeries(self):
11 """See `IBranch`."""
12@@ -1129,7 +1130,6 @@
13
14 def __call__(self):
15 self.affected_object.prerequisite_branch = None
16- Store.of(self.affected_object).flush()
17
18
19 class ClearSeriesBranch(DeletionOperation):
20@@ -1143,7 +1143,6 @@
21 def __call__(self):
22 if self.affected_object.branch == self.branch:
23 self.affected_object.branch = None
24- Store.of(self.affected_object).flush()
25
26
27 class ClearSeriesTranslationsBranch(DeletionOperation):
28@@ -1156,9 +1155,8 @@
29 self.branch = branch
30
31 def __call__(self):
32- if self.affected_object.branch == self.branch:
33- self.affected_object.branch = None
34- self.affected_object.syncUpdate()
35+ if self.affected_object.translations_branch == self.branch:
36+ self.affected_object.translations_branch = None
37
38
39 class ClearOfficialPackageBranch(DeletionOperation):
40
41=== modified file 'lib/lp/code/model/tests/test_branch.py'
42--- lib/lp/code/model/tests/test_branch.py 2010-08-02 02:36:32 +0000
43+++ lib/lp/code/model/tests/test_branch.py 2010-08-12 02:06:49 +0000
44@@ -931,15 +931,18 @@
45 layer = LaunchpadZopelessLayer
46
47 def setUp(self):
48- TestCaseWithFactory.setUp(self, 'test@canonical.com')
49- self.product = ProductSet().getByName('firefox')
50- self.user = getUtility(IPersonSet).getByEmail('test@canonical.com')
51+ TestCaseWithFactory.setUp(self)
52+ self.user = self.factory.makePerson()
53+ self.product = self.factory.makeProduct(owner=self.user)
54 self.branch = self.factory.makeProductBranch(
55 name='to-delete', owner=self.user, product=self.product)
56 # The owner of the branch is subscribed to the branch when it is
57 # created. The tests here assume no initial connections, so
58 # unsubscribe the branch owner here.
59 self.branch.unsubscribe(self.branch.owner, self.branch.owner)
60+ # Make sure that the tests all flush the database changes.
61+ self.addCleanup(Store.of(self.branch).flush)
62+ login_person(self.user)
63
64 def test_deletable(self):
65 """A newly created branch can be deleted without any problems."""
66@@ -1077,10 +1080,14 @@
67 # remove the Job and BranchJob.
68 branch = self.factory.makeAnyBranch()
69 getUtility(ITranslationTemplatesBuildJobSource).create(branch)
70-
71 branch.destroySelf(break_references=True)
72
73- Store.of(branch).flush()
74+ def test_linked_translations_branch_cleared(self):
75+ # The translations_branch of a series that is linked to the branch
76+ # should be cleared.
77+ dev_focus = self.branch.product.development_focus
78+ dev_focus.translations_branch = self.branch
79+ self.branch.destroySelf(break_references=True)
80
81 def test_unrelated_TranslationTemplatesBuildJob_intact(self):
82 # No innocent BuildQueue entries are harmed in deleting a
83@@ -1120,21 +1127,15 @@
84 def test_destroySelf_with_SourcePackageRecipe(self):
85 """If branch is a base_branch in a recipe, it is deleted."""
86 recipe = self.factory.makeSourcePackageRecipe()
87- store = Store.of(recipe)
88 recipe.base_branch.destroySelf(break_references=True)
89- # show no DB constraints have been violated
90- store.flush()
91
92 def test_destroySelf_with_SourcePackageRecipe_as_non_base(self):
93 """If branch is referred to by a recipe, it is deleted."""
94 branch1 = self.factory.makeAnyBranch()
95 branch2 = self.factory.makeAnyBranch()
96- recipe = self.factory.makeSourcePackageRecipe(
97+ self.factory.makeSourcePackageRecipe(
98 branches=[branch1, branch2])
99- store = Store.of(recipe)
100 branch2.destroySelf(break_references=True)
101- # show no DB constraints have been violated
102- store.flush()
103
104
105 class TestBranchDeletionConsequences(TestCase):