Merge lp:~mwhudson/launchpad/no-hosted-area-branchChanged-on-branch into lp:launchpad
- no-hosted-area-branchChanged-on-branch
- Merge into devel
Proposed by
Michael Hudson-Doyle
Status: | Merged |
---|---|
Approved by: | Tim Penhey |
Approved revision: | no longer in the source branch. |
Merged at revision: | 10828 |
Proposed branch: | lp:~mwhudson/launchpad/no-hosted-area-branchChanged-on-branch |
Merge into: | lp:launchpad |
Prerequisite: | lp:~mwhudson/launchpad/no-hosted-area-one-codehosting-endpoint |
Diff against target: |
512 lines (+215/-130) 9 files modified
lib/lp/code/configure.zcml (+1/-1) lib/lp/code/interfaces/branch.py (+17/-0) lib/lp/code/interfaces/codehosting.py (+10/-4) lib/lp/code/model/branch.py (+29/-0) lib/lp/code/model/tests/test_branch.py (+107/-2) lib/lp/code/xmlrpc/codehosting.py (+31/-39) lib/lp/code/xmlrpc/tests/test_codehosting.py (+14/-80) lib/lp/codehosting/inmemory.py (+3/-2) lib/lp/codehosting/vfs/branchfsclient.py (+3/-2) |
To merge this branch: | bzr merge lp:~mwhudson/launchpad/no-hosted-area-branchChanged-on-branch |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tim Penhey (community) | Approve | ||
Review via email:
|
Commit message
Description of the change
Hi,
This branch moves the guts of the branchChanged method from the endpoint implementation to a method on the branch itself.
Cheers,
mwh
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Tim Penhey (thumper) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/code/configure.zcml' | |||
2 | --- lib/lp/code/configure.zcml 2010-04-27 02:17:46 +0000 | |||
3 | +++ lib/lp/code/configure.zcml 2010-04-27 02:18:06 +0000 | |||
4 | @@ -548,7 +548,7 @@ | |||
5 | 548 | <require | 548 | <require |
6 | 549 | permission="launchpad.Edit" | 549 | permission="launchpad.Edit" |
7 | 550 | attributes="destroySelf destroySelfBreakReferences setPrivate | 550 | attributes="destroySelf destroySelfBreakReferences setPrivate |
9 | 551 | setOwner setTarget requestUpgrade" | 551 | setOwner setTarget requestUpgrade branchChanged" |
10 | 552 | set_attributes="name url mirror_status_message | 552 | set_attributes="name url mirror_status_message |
11 | 553 | description lifecycle_status | 553 | description lifecycle_status |
12 | 554 | last_mirrored last_mirrored_id last_mirror_attempt | 554 | last_mirrored last_mirrored_id last_mirror_attempt |
13 | 555 | 555 | ||
14 | === modified file 'lib/lp/code/interfaces/branch.py' | |||
15 | --- lib/lp/code/interfaces/branch.py 2010-04-27 02:17:46 +0000 | |||
16 | +++ lib/lp/code/interfaces/branch.py 2010-04-27 02:18:06 +0000 | |||
17 | @@ -1088,6 +1088,23 @@ | |||
18 | 1088 | def startMirroring(): | 1088 | def startMirroring(): |
19 | 1089 | """Signal that this branch is being mirrored.""" | 1089 | """Signal that this branch is being mirrored.""" |
20 | 1090 | 1090 | ||
21 | 1091 | def branchChanged(stacked_on_url, last_revision_id, control_format, | ||
22 | 1092 | branch_format, repository_format): | ||
23 | 1093 | """Record that a branch has been changed. | ||
24 | 1094 | |||
25 | 1095 | This method records the stacked on branch tip revision id and format | ||
26 | 1096 | or the branch and creates a scan job if the tip revision id has | ||
27 | 1097 | changed. | ||
28 | 1098 | |||
29 | 1099 | :param stacked_on_url: The unique name of the branch this branch is | ||
30 | 1100 | stacked on, or '' if this branch is not stacked. | ||
31 | 1101 | :param last_revision_id: The tip revision ID of the branch. | ||
32 | 1102 | :param control_format: The entry from ControlFormat for the branch. | ||
33 | 1103 | :param branch_format: The entry from BranchFormat for the branch. | ||
34 | 1104 | :param repository_format: The entry from RepositoryFormat for the | ||
35 | 1105 | branch. | ||
36 | 1106 | """ | ||
37 | 1107 | |||
38 | 1091 | def mirrorComplete(last_revision_id): | 1108 | def mirrorComplete(last_revision_id): |
39 | 1092 | """Signal that a mirror attempt has completed successfully. | 1109 | """Signal that a mirror attempt has completed successfully. |
40 | 1093 | 1110 | ||
41 | 1094 | 1111 | ||
42 | === modified file 'lib/lp/code/interfaces/codehosting.py' | |||
43 | --- lib/lp/code/interfaces/codehosting.py 2010-04-27 02:17:46 +0000 | |||
44 | +++ lib/lp/code/interfaces/codehosting.py 2010-04-27 02:18:06 +0000 | |||
45 | @@ -166,16 +166,22 @@ | |||
46 | 166 | :param branchID: a branch ID. | 166 | :param branchID: a branch ID. |
47 | 167 | """ | 167 | """ |
48 | 168 | 168 | ||
50 | 169 | def branchChanged(branch_id, stacked_on_url, last_revision_id): | 169 | def branchChanged(login_id, branch_id, stacked_on_url, last_revision_id, |
51 | 170 | control_string, branch_string, repository_string): | ||
52 | 170 | """Record that a branch has been changed. | 171 | """Record that a branch has been changed. |
53 | 171 | 172 | ||
56 | 172 | This method records the stacked on branch and tip revision id of the | 173 | See `IBranch.branchChanged`. |
55 | 173 | branch and creates a scan job if the tip revision id has changed. | ||
57 | 174 | 174 | ||
59 | 175 | :param branchID: The database id of the branch to operate on. | 175 | :param login_id: the person ID of the user changing the branch. |
60 | 176 | :param branch_id: The database id of the branch to operate on. | ||
61 | 176 | :param stacked_on_url: The unique name of the branch this branch is | 177 | :param stacked_on_url: The unique name of the branch this branch is |
62 | 177 | stacked on, or '' if this branch is not stacked. | 178 | stacked on, or '' if this branch is not stacked. |
63 | 178 | :param last_revision_id: The tip revision ID of the branch. | 179 | :param last_revision_id: The tip revision ID of the branch. |
64 | 180 | :param control_string: The format string of the control directory of | ||
65 | 181 | the branch. | ||
66 | 182 | :param branch_string: The format string of the branch. | ||
67 | 183 | :param repository_string: The format string of the branch's | ||
68 | 184 | repository. | ||
69 | 179 | """ | 185 | """ |
70 | 180 | 186 | ||
71 | 181 | def translatePath(requester_id, path): | 187 | def translatePath(requester_id, path): |
72 | 182 | 188 | ||
73 | === modified file 'lib/lp/code/model/branch.py' | |||
74 | --- lib/lp/code/model/branch.py 2010-04-27 02:17:46 +0000 | |||
75 | +++ lib/lp/code/model/branch.py 2010-04-27 02:18:06 +0000 | |||
76 | @@ -899,6 +899,35 @@ | |||
77 | 899 | self.last_mirror_attempt = UTC_NOW | 899 | self.last_mirror_attempt = UTC_NOW |
78 | 900 | self.next_mirror_time = None | 900 | self.next_mirror_time = None |
79 | 901 | 901 | ||
80 | 902 | def branchChanged(self, stacked_on_location, last_revision_id, | ||
81 | 903 | control_format, branch_format, repository_format): | ||
82 | 904 | """See `IBranch`.""" | ||
83 | 905 | self.mirror_status_message = None | ||
84 | 906 | if stacked_on_location == '': | ||
85 | 907 | stacked_on_branch = None | ||
86 | 908 | else: | ||
87 | 909 | stacked_on_branch = getUtility(IBranchLookup).getByUniqueName( | ||
88 | 910 | stacked_on_location.strip('/')) | ||
89 | 911 | if stacked_on_branch is None: | ||
90 | 912 | self.mirror_status_message = ( | ||
91 | 913 | 'Invalid stacked on location: ' + stacked_on_location) | ||
92 | 914 | self.stacked_on = stacked_on_branch | ||
93 | 915 | self.last_mirrored = UTC_NOW | ||
94 | 916 | self.mirror_failures = 0 | ||
95 | 917 | if (self.next_mirror_time is None | ||
96 | 918 | and self.branch_type == BranchType.MIRRORED): | ||
97 | 919 | # No mirror was requested since we started mirroring. | ||
98 | 920 | increment = getUtility(IBranchPuller).MIRROR_TIME_INCREMENT | ||
99 | 921 | self.next_mirror_time = ( | ||
100 | 922 | datetime.datetime.now(pytz.timezone('UTC')) + increment) | ||
101 | 923 | if self.last_mirrored_id != last_revision_id: | ||
102 | 924 | self.last_mirrored_id = last_revision_id | ||
103 | 925 | from lp.code.model.branchjob import BranchScanJob | ||
104 | 926 | BranchScanJob.create(self) | ||
105 | 927 | self.control_format = control_format | ||
106 | 928 | self.branch_format = branch_format | ||
107 | 929 | self.repository_format = repository_format | ||
108 | 930 | |||
109 | 902 | def mirrorComplete(self, last_revision_id): | 931 | def mirrorComplete(self, last_revision_id): |
110 | 903 | """See `IBranch`.""" | 932 | """See `IBranch`.""" |
111 | 904 | if self.branch_type == BranchType.REMOTE: | 933 | if self.branch_type == BranchType.REMOTE: |
112 | 905 | 934 | ||
113 | === modified file 'lib/lp/code/model/tests/test_branch.py' | |||
114 | --- lib/lp/code/model/tests/test_branch.py 2010-04-27 02:17:46 +0000 | |||
115 | +++ lib/lp/code/model/tests/test_branch.py 2010-04-27 02:18:06 +0000 | |||
116 | @@ -38,7 +38,7 @@ | |||
117 | 38 | SpecificationBranch) | 38 | SpecificationBranch) |
118 | 39 | from lp.bugs.interfaces.bug import CreateBugParams, IBugSet | 39 | from lp.bugs.interfaces.bug import CreateBugParams, IBugSet |
119 | 40 | from lp.bugs.model.bugbranch import BugBranch | 40 | from lp.bugs.model.bugbranch import BugBranch |
121 | 41 | from lp.code.bzr import BranchFormat, RepositoryFormat | 41 | from lp.code.bzr import BranchFormat, ControlFormat, RepositoryFormat |
122 | 42 | from lp.code.enums import ( | 42 | from lp.code.enums import ( |
123 | 43 | BranchLifecycleStatus, BranchSubscriptionNotificationLevel, BranchType, | 43 | BranchLifecycleStatus, BranchSubscriptionNotificationLevel, BranchType, |
124 | 44 | BranchVisibilityRule, CodeReviewNotificationLevel) | 44 | BranchVisibilityRule, CodeReviewNotificationLevel) |
125 | @@ -47,7 +47,8 @@ | |||
126 | 47 | BranchCannotBePrivate, BranchCannotBePublic, | 47 | BranchCannotBePrivate, BranchCannotBePublic, |
127 | 48 | BranchCreatorNotMemberOfOwnerTeam, BranchCreatorNotOwner, | 48 | BranchCreatorNotMemberOfOwnerTeam, BranchCreatorNotOwner, |
128 | 49 | BranchTargetError, CannotDeleteBranch, DEFAULT_BRANCH_STATUS_IN_LISTING) | 49 | BranchTargetError, CannotDeleteBranch, DEFAULT_BRANCH_STATUS_IN_LISTING) |
130 | 50 | from lp.code.interfaces.branchjob import IBranchUpgradeJobSource | 50 | from lp.code.interfaces.branchjob import ( |
131 | 51 | IBranchUpgradeJobSource, IBranchScanJobSource) | ||
132 | 51 | from lp.code.interfaces.branchlookup import IBranchLookup | 52 | from lp.code.interfaces.branchlookup import IBranchLookup |
133 | 52 | from lp.code.interfaces.branchnamespace import IBranchNamespaceSet | 53 | from lp.code.interfaces.branchnamespace import IBranchNamespaceSet |
134 | 53 | from lp.code.interfaces.branchmergeproposal import ( | 54 | from lp.code.interfaces.branchmergeproposal import ( |
135 | @@ -94,6 +95,110 @@ | |||
136 | 94 | self.assertEqual(None, branch.code_import) | 95 | self.assertEqual(None, branch.code_import) |
137 | 95 | 96 | ||
138 | 96 | 97 | ||
139 | 98 | class TestBranchChanged(TestCaseWithFactory): | ||
140 | 99 | """Tests for `IBranch.branchChanged`.""" | ||
141 | 100 | |||
142 | 101 | layer = DatabaseFunctionalLayer | ||
143 | 102 | |||
144 | 103 | def setUp(self): | ||
145 | 104 | TestCaseWithFactory.setUp(self) | ||
146 | 105 | self.arbitrary_formats = ( | ||
147 | 106 | ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_6, | ||
148 | 107 | RepositoryFormat.BZR_CHK_2A) | ||
149 | 108 | |||
150 | 109 | def test_branchChanged_sets_last_mirrored_id(self): | ||
151 | 110 | # branchChanged sets the last_mirrored_id attribute on the branch. | ||
152 | 111 | revid = self.factory.getUniqueString() | ||
153 | 112 | branch = self.factory.makeAnyBranch() | ||
154 | 113 | login_person(branch.owner) | ||
155 | 114 | branch.branchChanged('', revid, *self.arbitrary_formats) | ||
156 | 115 | self.assertEqual(revid, branch.last_mirrored_id) | ||
157 | 116 | |||
158 | 117 | def test_branchChanged_sets_stacked_on(self): | ||
159 | 118 | # branchChanged sets the stacked_on attribute based on the unique_name | ||
160 | 119 | # passed in. | ||
161 | 120 | branch = self.factory.makeAnyBranch() | ||
162 | 121 | stacked_on = self.factory.makeAnyBranch() | ||
163 | 122 | login_person(branch.owner) | ||
164 | 123 | branch.branchChanged( | ||
165 | 124 | stacked_on.unique_name, '', *self.arbitrary_formats) | ||
166 | 125 | self.assertEqual(stacked_on, branch.stacked_on) | ||
167 | 126 | |||
168 | 127 | def test_branchChanged_unsets_stacked_on(self): | ||
169 | 128 | # branchChanged clears the stacked_on attribute on the branch if '' is | ||
170 | 129 | # passed in as the stacked_on location. | ||
171 | 130 | branch = self.factory.makeAnyBranch() | ||
172 | 131 | removeSecurityProxy(branch).stacked_on = self.factory.makeAnyBranch() | ||
173 | 132 | login_person(branch.owner) | ||
174 | 133 | branch.branchChanged('', '', *self.arbitrary_formats) | ||
175 | 134 | self.assertIs(None, branch.stacked_on) | ||
176 | 135 | |||
177 | 136 | def test_branchChanged_sets_last_mirrored(self): | ||
178 | 137 | # branchChanged sets the last_mirrored attribute on the branch to the | ||
179 | 138 | # current time. | ||
180 | 139 | branch = self.factory.makeAnyBranch() | ||
181 | 140 | login_person(branch.owner) | ||
182 | 141 | branch.branchChanged('', '', *self.arbitrary_formats) | ||
183 | 142 | self.assertSqlAttributeEqualsDate( | ||
184 | 143 | branch, 'last_mirrored', UTC_NOW) | ||
185 | 144 | |||
186 | 145 | def test_branchChanged_records_bogus_stacked_on_url(self): | ||
187 | 146 | # If a bogus location is passed in as the stacked_on parameter, | ||
188 | 147 | # mirror_status_message is set to indicate the problem and stacked_on | ||
189 | 148 | # set to None. | ||
190 | 149 | branch = self.factory.makeAnyBranch() | ||
191 | 150 | login_person(branch.owner) | ||
192 | 151 | branch.branchChanged('~does/not/exist', '', *self.arbitrary_formats) | ||
193 | 152 | self.assertIs(None, branch.stacked_on) | ||
194 | 153 | self.assertTrue('~does/not/exist' in branch.mirror_status_message) | ||
195 | 154 | |||
196 | 155 | def test_branchChanged_clears_mirror_status_message_if_no_error(self): | ||
197 | 156 | # branchChanged() clears any error that's currently mentioned in | ||
198 | 157 | # mirror_status_message. | ||
199 | 158 | branch = self.factory.makeAnyBranch() | ||
200 | 159 | removeSecurityProxy(branch).mirror_status_message = 'foo' | ||
201 | 160 | login_person(branch.owner) | ||
202 | 161 | branch.branchChanged('', '', *self.arbitrary_formats) | ||
203 | 162 | self.assertIs(None, branch.mirror_status_message) | ||
204 | 163 | |||
205 | 164 | def test_branchChanged_creates_scan_job(self): | ||
206 | 165 | # branchChanged() creates a scan job for the branch. | ||
207 | 166 | branch = self.factory.makeAnyBranch() | ||
208 | 167 | login_person(branch.owner) | ||
209 | 168 | jobs = list(getUtility(IBranchScanJobSource).iterReady()) | ||
210 | 169 | self.assertEqual(0, len(jobs)) | ||
211 | 170 | branch.branchChanged('', 'rev1', *self.arbitrary_formats) | ||
212 | 171 | jobs = list(getUtility(IBranchScanJobSource).iterReady()) | ||
213 | 172 | self.assertEqual(1, len(jobs)) | ||
214 | 173 | |||
215 | 174 | def test_branchChanged_doesnt_create_scan_job_for_noop_change(self): | ||
216 | 175 | # branchChanged() doesn't create a scan job if the tip revision id | ||
217 | 176 | # hasn't changed. | ||
218 | 177 | branch = self.factory.makeAnyBranch() | ||
219 | 178 | login_person(branch.owner) | ||
220 | 179 | removeSecurityProxy(branch).last_mirrored_id = 'rev1' | ||
221 | 180 | jobs = list(getUtility(IBranchScanJobSource).iterReady()) | ||
222 | 181 | self.assertEqual(0, len(jobs)) | ||
223 | 182 | branch.branchChanged('', 'rev1', *self.arbitrary_formats) | ||
224 | 183 | jobs = list(getUtility(IBranchScanJobSource).iterReady()) | ||
225 | 184 | self.assertEqual(0, len(jobs)) | ||
226 | 185 | |||
227 | 186 | def test_branchChanged_packs_format(self): | ||
228 | 187 | # branchChanged sets the branch_format etc attributes to the passed in | ||
229 | 188 | # values. | ||
230 | 189 | branch = self.factory.makeAnyBranch() | ||
231 | 190 | login_person(branch.owner) | ||
232 | 191 | branch.branchChanged( | ||
233 | 192 | '', 'rev1', ControlFormat.BZR_METADIR_1, | ||
234 | 193 | BranchFormat.BZR_BRANCH_6, RepositoryFormat.BZR_KNITPACK_1) | ||
235 | 194 | login(ANONYMOUS) | ||
236 | 195 | self.assertEqual( | ||
237 | 196 | (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_6, | ||
238 | 197 | RepositoryFormat.BZR_KNITPACK_1), | ||
239 | 198 | (branch.control_format, branch.branch_format, | ||
240 | 199 | branch.repository_format)) | ||
241 | 200 | |||
242 | 201 | |||
243 | 97 | class TestBranchGetRevision(TestCaseWithFactory): | 202 | class TestBranchGetRevision(TestCaseWithFactory): |
244 | 98 | """Make sure that `Branch.getBranchRevision` works as expected.""" | 203 | """Make sure that `Branch.getBranchRevision` works as expected.""" |
245 | 99 | 204 | ||
246 | 100 | 205 | ||
247 | === modified file 'lib/lp/code/xmlrpc/codehosting.py' | |||
248 | --- lib/lp/code/xmlrpc/codehosting.py 2010-04-27 02:17:46 +0000 | |||
249 | +++ lib/lp/code/xmlrpc/codehosting.py 2010-04-27 02:18:06 +0000 | |||
250 | @@ -22,7 +22,6 @@ | |||
251 | 22 | from zope.security.proxy import removeSecurityProxy | 22 | from zope.security.proxy import removeSecurityProxy |
252 | 23 | from zope.security.management import endInteraction | 23 | from zope.security.management import endInteraction |
253 | 24 | 24 | ||
254 | 25 | from canonical.database.constants import UTC_NOW | ||
255 | 26 | from canonical.launchpad.validators import LaunchpadValidationError | 25 | from canonical.launchpad.validators import LaunchpadValidationError |
256 | 27 | from canonical.launchpad.webapp import LaunchpadXMLRPCView | 26 | from canonical.launchpad.webapp import LaunchpadXMLRPCView |
257 | 28 | from canonical.launchpad.webapp.authorization import check_permission | 27 | from canonical.launchpad.webapp.authorization import check_permission |
258 | @@ -36,7 +35,6 @@ | |||
259 | 36 | from lp.code.bzr import BranchFormat, ControlFormat, RepositoryFormat | 35 | from lp.code.bzr import BranchFormat, ControlFormat, RepositoryFormat |
260 | 37 | from lp.code.enums import BranchType | 36 | from lp.code.enums import BranchType |
261 | 38 | from lp.code.interfaces.branch import BranchCreationException | 37 | from lp.code.interfaces.branch import BranchCreationException |
262 | 39 | from lp.code.interfaces.branchjob import IBranchScanJobSource | ||
263 | 40 | from lp.code.interfaces.branchlookup import IBranchLookup | 38 | from lp.code.interfaces.branchlookup import IBranchLookup |
264 | 41 | from lp.code.interfaces.branchnamespace import ( | 39 | from lp.code.interfaces.branchnamespace import ( |
265 | 42 | InvalidNamespace, lookup_branch_namespace, split_unique_name) | 40 | InvalidNamespace, lookup_branch_namespace, split_unique_name) |
266 | @@ -240,44 +238,38 @@ | |||
267 | 240 | return True | 238 | return True |
268 | 241 | return run_with_login(login_id, request_mirror) | 239 | return run_with_login(login_id, request_mirror) |
269 | 242 | 240 | ||
272 | 243 | def branchChanged(self, branch_id, stacked_on_location, last_revision_id, | 241 | def branchChanged(self, login_id, branch_id, stacked_on_location, |
273 | 244 | control_string, branch_string, repository_string): | 242 | last_revision_id, control_string, branch_string, |
274 | 243 | repository_string): | ||
275 | 245 | """See `ICodehostingAPI`.""" | 244 | """See `ICodehostingAPI`.""" |
311 | 246 | branch_set = removeSecurityProxy(getUtility(IBranchLookup)) | 245 | def branch_changed(request_mirror): |
312 | 247 | branch = branch_set.get(branch_id) | 246 | branch_set = getUtility(IBranchLookup) |
313 | 248 | if branch is None: | 247 | branch = branch_set.get(branch_id) |
314 | 249 | return faults.NoBranchWithID(branch_id) | 248 | if branch is None: |
315 | 250 | branch.mirror_status_message = None | 249 | return faults.NoBranchWithID(branch_id) |
316 | 251 | if stacked_on_location == '': | 250 | |
317 | 252 | stacked_on_branch = None | 251 | def match_title(enum, title, default): |
318 | 253 | else: | 252 | for value in enum.items: |
319 | 254 | stacked_on_branch = branch_set.getByUniqueName( | 253 | if value.title == title: |
320 | 255 | stacked_on_location.strip('/')) | 254 | return value |
321 | 256 | if stacked_on_branch is None: | 255 | else: |
322 | 257 | branch.mirror_status_message = ( | 256 | return default |
323 | 258 | 'Invalid stacked on location: ' + stacked_on_location) | 257 | |
324 | 259 | branch.stacked_on = stacked_on_branch | 258 | control_format = match_title( |
325 | 260 | branch.last_mirrored = UTC_NOW | 259 | ControlFormat, control_string, ControlFormat.UNRECOGNIZED) |
326 | 261 | if branch.last_mirrored_id != last_revision_id: | 260 | branch_format = match_title( |
327 | 262 | branch.last_mirrored_id = last_revision_id | 261 | BranchFormat, branch_string, BranchFormat.UNRECOGNIZED) |
328 | 263 | getUtility(IBranchScanJobSource).create(branch) | 262 | repository_format = match_title( |
329 | 264 | 263 | RepositoryFormat, repository_string, | |
330 | 265 | def match_title(enum, title, default): | 264 | RepositoryFormat.UNRECOGNIZED) |
331 | 266 | for value in enum.items: | 265 | |
332 | 267 | if value.title == title: | 266 | branch.branchChanged( |
333 | 268 | return value | 267 | stacked_on_location, last_revision_id, control_format, |
334 | 269 | else: | 268 | branch_format, repository_format) |
335 | 270 | return default | 269 | |
336 | 271 | 270 | return True | |
337 | 272 | branch.control_format = match_title( | 271 | |
338 | 273 | ControlFormat, control_string, ControlFormat.UNRECOGNIZED) | 272 | return run_with_login(login_id, branch_changed) |
304 | 274 | branch.branch_format = match_title( | ||
305 | 275 | BranchFormat, branch_string, BranchFormat.UNRECOGNIZED) | ||
306 | 276 | branch.repository_format = match_title( | ||
307 | 277 | RepositoryFormat, repository_string, | ||
308 | 278 | RepositoryFormat.UNRECOGNIZED) | ||
309 | 279 | |||
310 | 280 | return True | ||
339 | 281 | 273 | ||
340 | 282 | def _serializeBranch(self, requester, branch, trailing_path): | 274 | def _serializeBranch(self, requester, branch, trailing_path): |
341 | 283 | if requester == LAUNCHPAD_SERVICES: | 275 | if requester == LAUNCHPAD_SERVICES: |
342 | 284 | 276 | ||
343 | === modified file 'lib/lp/code/xmlrpc/tests/test_codehosting.py' | |||
344 | --- lib/lp/code/xmlrpc/tests/test_codehosting.py 2010-04-27 02:17:46 +0000 | |||
345 | +++ lib/lp/code/xmlrpc/tests/test_codehosting.py 2010-04-27 02:18:06 +0000 | |||
346 | @@ -578,102 +578,34 @@ | |||
347 | 578 | return self.getFormatStringsForFormatName('default') | 578 | return self.getFormatStringsForFormatName('default') |
348 | 579 | 579 | ||
349 | 580 | def test_branchChanged_sets_last_mirrored_id(self): | 580 | def test_branchChanged_sets_last_mirrored_id(self): |
351 | 581 | # branchChanged sets the last_mirrored_id attribute on the branch. | 581 | # branchChanged does many things but lets just check the setting of |
352 | 582 | # last_mirrored_id here. The other things are tested in unit tests. | ||
353 | 582 | revid = self.factory.getUniqueString() | 583 | revid = self.factory.getUniqueString() |
354 | 583 | branch = self.factory.makeAnyBranch() | 584 | branch = self.factory.makeAnyBranch() |
355 | 584 | self.codehosting_api.branchChanged( | 585 | self.codehosting_api.branchChanged( |
357 | 585 | branch.id, '', revid, *self.arbitrary_format_strings) | 586 | branch.owner.id, branch.id, '', revid, |
358 | 587 | *self.arbitrary_format_strings) | ||
359 | 588 | login(ANONYMOUS) | ||
360 | 586 | self.assertEqual(revid, branch.last_mirrored_id) | 589 | self.assertEqual(revid, branch.last_mirrored_id) |
361 | 587 | 590 | ||
362 | 588 | def test_branchChanged_sets_stacked_on(self): | ||
363 | 589 | # branchChanged sets the stacked_on attribute based on the unique_name | ||
364 | 590 | # passed in. | ||
365 | 591 | branch = self.factory.makeAnyBranch() | ||
366 | 592 | stacked_on = self.factory.makeAnyBranch() | ||
367 | 593 | self.codehosting_api.branchChanged( | ||
368 | 594 | branch.id, stacked_on.unique_name, '', | ||
369 | 595 | *self.arbitrary_format_strings) | ||
370 | 596 | self.assertEqual(stacked_on, branch.stacked_on) | ||
371 | 597 | |||
372 | 598 | def test_branchChanged_unsets_stacked_on(self): | ||
373 | 599 | # branchChanged clears the stacked_on attribute on the branch if '' is | ||
374 | 600 | # passed in as the stacked_on location. | ||
375 | 601 | branch = self.factory.makeAnyBranch() | ||
376 | 602 | removeSecurityProxy(branch).stacked_on = self.factory.makeAnyBranch() | ||
377 | 603 | self.codehosting_api.branchChanged( | ||
378 | 604 | branch.id, '', '', *self.arbitrary_format_strings) | ||
379 | 605 | self.assertIs(None, branch.stacked_on) | ||
380 | 606 | |||
381 | 607 | def test_branchChanged_sets_last_mirrored(self): | ||
382 | 608 | # branchChanged sets the last_mirrored attribute on the branch to the | ||
383 | 609 | # current time. | ||
384 | 610 | branch = self.factory.makeAnyBranch() | ||
385 | 611 | self.codehosting_api.branchChanged( | ||
386 | 612 | branch.id, '', '', *self.arbitrary_format_strings) | ||
387 | 613 | if self.frontend == LaunchpadDatabaseFrontend: | ||
388 | 614 | self.assertSqlAttributeEqualsDate( | ||
389 | 615 | branch, 'last_mirrored', UTC_NOW) | ||
390 | 616 | else: | ||
391 | 617 | self.assertIs(UTC_NOW, branch.last_mirrored) | ||
392 | 618 | |||
393 | 619 | def test_branchChanged_records_bogus_stacked_on_url(self): | ||
394 | 620 | # If a bogus location is passed in as the stacked_on parameter, | ||
395 | 621 | # mirror_status_message is set to indicate the problem and stacked_on | ||
396 | 622 | # set to None. | ||
397 | 623 | branch = self.factory.makeAnyBranch() | ||
398 | 624 | self.codehosting_api.branchChanged( | ||
399 | 625 | branch.id, '~does/not/exist', '', *self.arbitrary_format_strings) | ||
400 | 626 | self.assertIs(None, branch.stacked_on) | ||
401 | 627 | self.assertTrue('~does/not/exist' in branch.mirror_status_message) | ||
402 | 628 | |||
403 | 629 | def test_branchChanged_clears_mirror_status_message_if_no_error(self): | ||
404 | 630 | # branchChanged() clears any error that's currently mentioned in | ||
405 | 631 | # mirror_status_message. | ||
406 | 632 | branch = self.factory.makeAnyBranch() | ||
407 | 633 | removeSecurityProxy(branch).mirror_status_message = 'foo' | ||
408 | 634 | self.codehosting_api.branchChanged( | ||
409 | 635 | branch.id, '', '', *self.arbitrary_format_strings) | ||
410 | 636 | self.assertIs(None, branch.mirror_status_message) | ||
411 | 637 | |||
412 | 638 | def test_branchChanged_fault_on_unknown_id(self): | 591 | def test_branchChanged_fault_on_unknown_id(self): |
413 | 639 | # If the id passed in doesn't match an existing branch, the fault | 592 | # If the id passed in doesn't match an existing branch, the fault |
414 | 640 | # "NoBranchWithID" is returned. | 593 | # "NoBranchWithID" is returned. |
415 | 641 | unused_id = -1 | 594 | unused_id = -1 |
416 | 642 | expected_fault = faults.NoBranchWithID(unused_id) | 595 | expected_fault = faults.NoBranchWithID(unused_id) |
417 | 643 | received_fault = self.codehosting_api.branchChanged( | 596 | received_fault = self.codehosting_api.branchChanged( |
419 | 644 | unused_id, '', '', *self.arbitrary_format_strings) | 597 | 1, unused_id, '', '', *self.arbitrary_format_strings) |
420 | 598 | login(ANONYMOUS) | ||
421 | 645 | self.assertEqual( | 599 | self.assertEqual( |
422 | 646 | (expected_fault.faultCode, expected_fault.faultString), | 600 | (expected_fault.faultCode, expected_fault.faultString), |
423 | 647 | (received_fault.faultCode, received_fault.faultString)) | 601 | (received_fault.faultCode, received_fault.faultString)) |
424 | 648 | 602 | ||
425 | 649 | def test_branchChanged_creates_scan_job(self): | ||
426 | 650 | # branchChanged() creates a scan job for the branch. | ||
427 | 651 | if self.frontend != LaunchpadDatabaseFrontend: | ||
428 | 652 | return | ||
429 | 653 | branch = self.factory.makeAnyBranch() | ||
430 | 654 | jobs = list(getUtility(IBranchScanJobSource).iterReady()) | ||
431 | 655 | self.assertEqual(0, len(jobs)) | ||
432 | 656 | self.codehosting_api.branchChanged( | ||
433 | 657 | branch.id, '', 'rev1', *self.arbitrary_format_strings) | ||
434 | 658 | jobs = list(getUtility(IBranchScanJobSource).iterReady()) | ||
435 | 659 | self.assertEqual(1, len(jobs)) | ||
436 | 660 | |||
437 | 661 | def test_branchChanged_doesnt_create_scan_job_for_noop_change(self): | ||
438 | 662 | if self.frontend != LaunchpadDatabaseFrontend: | ||
439 | 663 | return | ||
440 | 664 | branch = self.factory.makeAnyBranch() | ||
441 | 665 | removeSecurityProxy(branch).last_mirrored_id = 'rev1' | ||
442 | 666 | jobs = list(getUtility(IBranchScanJobSource).iterReady()) | ||
443 | 667 | self.assertEqual(0, len(jobs)) | ||
444 | 668 | self.codehosting_api.branchChanged( | ||
445 | 669 | branch.id, '', 'rev1', *self.arbitrary_format_strings) | ||
446 | 670 | jobs = list(getUtility(IBranchScanJobSource).iterReady()) | ||
447 | 671 | self.assertEqual(0, len(jobs)) | ||
448 | 672 | |||
449 | 673 | def test_branchChanged_2a_format(self): | 603 | def test_branchChanged_2a_format(self): |
450 | 674 | branch = self.factory.makeAnyBranch() | 604 | branch = self.factory.makeAnyBranch() |
451 | 675 | self.codehosting_api.branchChanged( | 605 | self.codehosting_api.branchChanged( |
453 | 676 | branch.id, '', 'rev1', *self.getFormatStringsForFormatName('2a')) | 606 | branch.owner.id, branch.id, '', 'rev1', |
454 | 607 | *self.getFormatStringsForFormatName('2a')) | ||
455 | 608 | login(ANONYMOUS) | ||
456 | 677 | self.assertEqual( | 609 | self.assertEqual( |
457 | 678 | (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_7, | 610 | (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_7, |
458 | 679 | RepositoryFormat.BZR_CHK_2A), | 611 | RepositoryFormat.BZR_CHK_2A), |
459 | @@ -683,8 +615,9 @@ | |||
460 | 683 | def test_branchChanged_packs_format(self): | 615 | def test_branchChanged_packs_format(self): |
461 | 684 | branch = self.factory.makeAnyBranch() | 616 | branch = self.factory.makeAnyBranch() |
462 | 685 | self.codehosting_api.branchChanged( | 617 | self.codehosting_api.branchChanged( |
464 | 686 | branch.id, '', 'rev1', | 618 | branch.owner.id, branch.id, '', 'rev1', |
465 | 687 | *self.getFormatStringsForFormatName('pack-0.92')) | 619 | *self.getFormatStringsForFormatName('pack-0.92')) |
466 | 620 | login(ANONYMOUS) | ||
467 | 688 | self.assertEqual( | 621 | self.assertEqual( |
468 | 689 | (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_6, | 622 | (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_6, |
469 | 690 | RepositoryFormat.BZR_KNITPACK_1), | 623 | RepositoryFormat.BZR_KNITPACK_1), |
470 | @@ -694,8 +627,9 @@ | |||
471 | 694 | def test_branchChanged_knits_format(self): | 627 | def test_branchChanged_knits_format(self): |
472 | 695 | branch = self.factory.makeAnyBranch() | 628 | branch = self.factory.makeAnyBranch() |
473 | 696 | self.codehosting_api.branchChanged( | 629 | self.codehosting_api.branchChanged( |
475 | 697 | branch.id, '', 'rev1', | 630 | branch.owner.id, branch.id, '', 'rev1', |
476 | 698 | *self.getFormatStringsForFormatName('knit')) | 631 | *self.getFormatStringsForFormatName('knit')) |
477 | 632 | login(ANONYMOUS) | ||
478 | 699 | self.assertEqual( | 633 | self.assertEqual( |
479 | 700 | (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_5, | 634 | (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_5, |
480 | 701 | RepositoryFormat.BZR_KNIT_1), | 635 | RepositoryFormat.BZR_KNIT_1), |
481 | 702 | 636 | ||
482 | === modified file 'lib/lp/codehosting/inmemory.py' | |||
483 | --- lib/lp/codehosting/inmemory.py 2010-04-27 02:17:46 +0000 | |||
484 | +++ lib/lp/codehosting/inmemory.py 2010-04-27 02:18:06 +0000 | |||
485 | @@ -614,8 +614,9 @@ | |||
486 | 614 | def requestMirror(self, requester_id, branch_id): | 614 | def requestMirror(self, requester_id, branch_id): |
487 | 615 | self._branch_set.get(branch_id).requestMirror() | 615 | self._branch_set.get(branch_id).requestMirror() |
488 | 616 | 616 | ||
491 | 617 | def branchChanged(self, branch_id, stacked_on_location, last_revision_id, | 617 | def branchChanged(self, login_id, branch_id, stacked_on_location, |
492 | 618 | control_string, branch_string, repository_string): | 618 | last_revision_id, control_string, branch_string, |
493 | 619 | repository_string): | ||
494 | 619 | branch = self._branch_set._find(id=branch_id) | 620 | branch = self._branch_set._find(id=branch_id) |
495 | 620 | if branch is None: | 621 | if branch is None: |
496 | 621 | return faults.NoBranchWithID(branch_id) | 622 | return faults.NoBranchWithID(branch_id) |
497 | 622 | 623 | ||
498 | === modified file 'lib/lp/codehosting/vfs/branchfsclient.py' | |||
499 | --- lib/lp/codehosting/vfs/branchfsclient.py 2010-04-27 02:17:46 +0000 | |||
500 | +++ lib/lp/codehosting/vfs/branchfsclient.py 2010-04-27 02:18:06 +0000 | |||
501 | @@ -126,8 +126,9 @@ | |||
502 | 126 | """ | 126 | """ |
503 | 127 | return defer.maybeDeferred( | 127 | return defer.maybeDeferred( |
504 | 128 | self._codehosting_endpoint.callRemote, | 128 | self._codehosting_endpoint.callRemote, |
507 | 129 | 'branchChanged', branch_id, stacked_on_url, last_revision_id, | 129 | 'branchChanged', self._user_id, branch_id, stacked_on_url, |
508 | 130 | control_string, branch_string, repository_string) | 130 | last_revision_id, control_string, branch_string, |
509 | 131 | repository_string) | ||
510 | 131 | 132 | ||
511 | 132 | def translatePath(self, path): | 133 | def translatePath(self, path): |
512 | 133 | """Translate 'path'.""" | 134 | """Translate 'path'.""" |