← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stevenk/launchpad/destroy-branch-privacy into lp:launchpad

 

Steve Kowalik has proposed merging lp:~stevenk/launchpad/destroy-branch-privacy into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #933768 in Launchpad itself: "Update branch to use information_visibility_policy"
  https://bugs.launchpad.net/launchpad/+bug/933768

For more details, see:
https://code.launchpad.net/~stevenk/launchpad/destroy-branch-privacy/+merge/110274

Sorry for the alarmist branch name. :-P

This branch removes explicitly_private and transitively_private from the branch model code in preparation for the columns being dropped. A previous branch has switched to property backed onto information_type for reading, and the columns themselves for writing. We also drop the tests that were testing the behaviour of the transitively_private triggers.
-- 
https://code.launchpad.net/~stevenk/launchpad/destroy-branch-privacy/+merge/110274
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/destroy-branch-privacy into lp:launchpad.
=== modified file 'lib/lp/code/model/branch.py'
--- lib/lp/code/model/branch.py	2012-06-13 23:57:43 +0000
+++ lib/lp/code/model/branch.py	2012-06-14 09:23:20 +0000
@@ -184,15 +184,6 @@
     control_format = EnumCol(enum=ControlFormat, dbName='metadir_format')
     whiteboard = StringCol(default=None)
     mirror_status_message = StringCol(default=None)
-
-    # This attribute signifies whether *this* branch is private, irrespective
-    # of the state of any stacked on branches.
-    _explicitly_private = BoolCol(
-        default=False, notNull=True, dbName='private')
-    # A branch is transitively private if it is private or it is stacked on a
-    # transitively private branch. The value of this attribute is maintained
-    # by a database trigger.
-    _transitively_private = BoolCol(dbName='transitively_private')
     information_type = EnumCol(
         enum=InformationType, default=InformationType.PUBLIC)
 
@@ -250,14 +241,6 @@
                 raise BranchCannotBePublic()
         self.information_type = information_type
         self._reconcileAccess()
-        # Set the legacy values for now.
-        self._explicitly_private = private
-        # If this branch is private, then it is also transitively_private
-        # otherwise we need to reload the value.
-        if private:
-            self._transitively_private = True
-        else:
-            self._transitively_private = AutoReload
 
     registrant = ForeignKey(
         dbName='registrant', foreignKey='Person',
@@ -1520,7 +1503,6 @@
     naked_branch.unique_name = AutoReload
     naked_branch.owner_name = AutoReload
     naked_branch.target_suffix = AutoReload
-    naked_branch._transitively_private = AutoReload
 
 
 def branch_modified_subscriber(branch, event):

=== modified file 'lib/lp/code/model/branchnamespace.py'
--- lib/lp/code/model/branchnamespace.py	2012-06-13 23:57:43 +0000
+++ lib/lp/code/model/branchnamespace.py	2012-06-14 09:23:20 +0000
@@ -115,13 +115,13 @@
             information_type = InformationType.PUBLIC
 
         branch = Branch(
-            registrant=registrant,
-            name=name, owner=self.owner, product=product, url=url,
-            title=title, lifecycle_status=lifecycle_status, summary=summary,
-            whiteboard=whiteboard, _explicitly_private=private,
-            information_type=information_type, date_created=date_created,
-            branch_type=branch_type, date_last_modified=date_created,
-            branch_format=branch_format, repository_format=repository_format,
+            registrant=registrant, name=name, owner=self.owner,
+            product=product, url=url, title=title,
+            lifecycle_status=lifecycle_status, summary=summary,
+            whiteboard=whiteboard, information_type=information_type,
+            date_created=date_created, branch_type=branch_type,
+            date_last_modified=date_created, branch_format=branch_format,
+            repository_format=repository_format,
             control_format=control_format, distroseries=distroseries,
             sourcepackagename=sourcepackagename)
 

=== removed file 'lib/lp/code/model/tests/test_branch_privacy_triggers.py'
--- lib/lp/code/model/tests/test_branch_privacy_triggers.py	2012-05-10 02:33:07 +0000
+++ lib/lp/code/model/tests/test_branch_privacy_triggers.py	1970-01-01 00:00:00 +0000
@@ -1,223 +0,0 @@
-# Copyright 2011-2012 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Tests that the triggers to maintain the branch table transitively_private
-   column work correctly."""
-
-__metaclass__ = type
-
-import unittest
-
-from lp.registry.enums import InformationType
-from lp.services.database.sqlbase import cursor
-from lp.testing.dbuser import switch_dbuser
-from lp.testing.layers import LaunchpadZopelessLayer
-
-
-class BranchPrivacyTriggersTestCase(unittest.TestCase):
-
-    layer = LaunchpadZopelessLayer
-
-    def setUp(self):
-        switch_dbuser('testadmin')
-        self.branch_ids = dict()
-
-    def createBranches(self):
-        # Create branches 1, 2, 3, 4, 5
-        # 3 is private
-        # 4 stacked on 3 at insert time
-        # 2 stacked on 5
-        # 6 stacked on 1 at insert time
-        cur = cursor()
-        for x in range(7):
-            is_private = 'False'
-            information_type = InformationType.PUBLIC.value
-            if x == 3:
-                is_private = 'True'
-                information_type = InformationType.USERDATA.value
-            if x == 4:
-                stacked_on = self.branch_ids[3]
-            elif x == 6:
-                stacked_on = self.branch_ids[1]
-            else:
-                stacked_on = 'NULL'
-            cur.execute("""
-                INSERT INTO Branch (
-                    name, private, information_type, stacked_on, owner,
-                    registrant, branch_type
-                    )
-                    VALUES ('branch%d', %s, %s, %s, 1, 1, 1)
-                    RETURNING id
-                """ % (x, is_private, information_type, stacked_on))
-            branch_id = cur.fetchone()[0]
-            self.branch_ids[x] = branch_id
-        self.updateStackedOnForBranch(2, 5)
-
-    def check_branch_privacy(self, branch_num, expected_private,
-                             expected_transitively_private):
-        # Check branch_num has the expected privacy attributes.
-        is_private = 'True' if expected_private else 'False'
-        is_transitively_private = ('True'
-            if expected_transitively_private else 'False')
-        cur = cursor()
-        cur.execute("""
-            SELECT COUNT(*)
-            FROM Branch
-            WHERE id = %s
-                AND private is %s
-                AND transitively_private is %s
-            """ % (self.branch_ids[branch_num],
-                   is_private, is_transitively_private))
-        self.failUnlessEqual(cur.fetchone()[0], 1)
-
-    def updateStackedOnForBranch(self, branch_num, stacked_on):
-        # Update the stacked_on attribute for a branch.
-        cur = cursor()
-        if stacked_on:
-            stacked_on = self.branch_ids[stacked_on]
-        else:
-            stacked_on = 'NULL'
-        cur.execute("""
-            UPDATE Branch
-            SET stacked_on = %s
-            WHERE id = %s
-            """ % (stacked_on, self.branch_ids[branch_num]))
-
-    def updatePrivacyForBranch(self, branch_num, private):
-        # Update the private attribute for a branch.
-        is_private = 'True' if private else 'False'
-        cur = cursor()
-        cur.execute("""
-            UPDATE Branch
-            SET private = %s
-            WHERE id = %s
-            """ % (is_private, self.branch_ids[branch_num]))
-
-    def testInitialBranches(self):
-        # Branch inserts invokes the trigger correctly.
-        self.createBranches()
-        self.check_branch_privacy(1, False, False)
-        self.check_branch_privacy(3, True, True)
-        self.check_branch_privacy(4, False, True)
-        self.check_branch_privacy(6, False, False)
-
-    def testSetStackedOn(self):
-        # Stack 1 on 3 which is private.
-        # 1 should be transitively private.
-        self.createBranches()
-        self.updateStackedOnForBranch(1, 3)
-        self.check_branch_privacy(1, False, True)
-
-    def testMultiLevelStackedOn(self):
-        # 2 is stacked on 5 already.
-        # Make 5 private, stack 1 on 2.
-        # 1 and 2 should be transitively private.
-        self.createBranches()
-        self.updatePrivacyForBranch(5, True)
-        self.check_branch_privacy(5, True, True)
-        self.check_branch_privacy(2, False, True)
-        self.updateStackedOnForBranch(1, 2)
-        self.check_branch_privacy(1, False, True)
-        self.check_branch_privacy(2, False, True)
-
-    def testMultiLevelMultiStackedOn(self):
-        # 2 is stacked on 5 already.
-        # Stack 4 on 1.
-        # Make 5 private, stack 1 on 2.
-        # 1, 2 and 4 should be transitively private.
-        self.createBranches()
-        self.updateStackedOnForBranch(4, 1)
-        self.check_branch_privacy(4, False, False)
-        self.updatePrivacyForBranch(5, True)
-        self.check_branch_privacy(5, True, True)
-        self.check_branch_privacy(2, False, True)
-        self.updateStackedOnForBranch(1, 2)
-        self.check_branch_privacy(1, False, True)
-        self.check_branch_privacy(2, False, True)
-        self.check_branch_privacy(4, False, True)
-
-    def testRemoveStackedOn(self):
-        # 5 is private, 1 stacked on 5, so 1 is transitively private.
-        # Unstack 1.
-        # 1 should no longer be transitively private.
-        self.createBranches()
-        self.updateStackedOnForBranch(1, 5)
-        self.updatePrivacyForBranch(5, True)
-        self.check_branch_privacy(1, False, True)
-        self.updateStackedOnForBranch(1, None)
-        self.check_branch_privacy(1, False, False)
-
-    def testSetPrivateTrue(self):
-        # Stack 1 on 5, make 5 private.
-        # 1 should be transitively private.
-        self.createBranches()
-        self.updateStackedOnForBranch(1, 5)
-        self.check_branch_privacy(1, False, False)
-        self.updatePrivacyForBranch(5, True)
-        self.check_branch_privacy(5, True, True)
-        self.check_branch_privacy(1, False, True)
-
-    def testMultiLevelSetPrivateTrue(self):
-        # 2 is stacked on 5 already.
-        # Stack 4 on 1, stack 1 on 2
-        # Make 5 private.
-        # 1, 2 and 4 should be transitively private.
-        self.createBranches()
-        self.updateStackedOnForBranch(4, 1)
-        self.check_branch_privacy(4, False, False)
-        self.updateStackedOnForBranch(1, 2)
-        self.check_branch_privacy(2, False, False)
-        self.updatePrivacyForBranch(5, True)
-        self.check_branch_privacy(5, True, True)
-        self.check_branch_privacy(1, False, True)
-        self.check_branch_privacy(2, False, True)
-        self.check_branch_privacy(4, False, True)
-
-    def testSetPrivateFalse(self):
-        # Make 5 private, stack 1 on 5.
-        # Make 5 public.
-        # 1 should not be transitively private.
-        self.createBranches()
-        self.updatePrivacyForBranch(5, True)
-        self.updateStackedOnForBranch(1, 5)
-        self.check_branch_privacy(1, False, True)
-        self.updatePrivacyForBranch(5, False)
-        self.check_branch_privacy(5, False, False)
-        self.check_branch_privacy(1, False, False)
-
-    def testMultlLevelSetPrivateFalse(self):
-        # 2 is stacked on 5 already.
-        # Make 5 private.
-        # Stack 4 on 1, stack 1 on 2
-        # Make 5 public.
-        # 1, 2 and 4 should not be transitively private.
-        self.createBranches()
-        self.updatePrivacyForBranch(5, True)
-        self.updateStackedOnForBranch(4, 1)
-        self.updateStackedOnForBranch(1, 2)
-        self.check_branch_privacy(1, False, True)
-        self.check_branch_privacy(2, False, True)
-        self.check_branch_privacy(4, False, True)
-        self.check_branch_privacy(5, True, True)
-        self.updatePrivacyForBranch(5, False)
-        self.check_branch_privacy(1, False, False)
-        self.check_branch_privacy(2, False, False)
-        self.check_branch_privacy(4, False, False)
-        self.check_branch_privacy(5, False, False)
-
-    def testLoopedStackedOn(self):
-        # It's possible, although nonsensical, for branch stackings to form a
-        # loop. e.g., branch A is stacked on branch B is stacked on branch A.
-        # 2 is stacked on 5 already.
-        # Stack 1 on 2, stack 5 on 1, completing a 1->2->5 loop.
-        # Stack 3 on 3, the trivial case.
-        self.createBranches()
-        self.updateStackedOnForBranch(1, 2)
-        self.updateStackedOnForBranch(5, 1)
-        self.updateStackedOnForBranch(3, 3)
-        self.updatePrivacyForBranch(5, True)
-        self.updatePrivacyForBranch(3, False)
-        self.check_branch_privacy(5, True, True)
-        self.check_branch_privacy(1, False, True)
-        self.check_branch_privacy(2, False, True)
-        self.check_branch_privacy(3, False, False)


Follow ups