Merge lp:~mwhudson/launchpad/no-hosted-area-formats-from-codehosting into lp:launchpad

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-formats-from-codehosting
Merge into: lp:launchpad
Prerequisite: lp:~mwhudson/launchpad/no-hosted-area
Diff against target: 488 lines (+168/-40)
8 files modified
lib/lp/code/xmlrpc/codehosting.py (+19/-1)
lib/lp/code/xmlrpc/tests/test_codehosting.py (+65/-9)
lib/lp/codehosting/inmemory.py (+19/-1)
lib/lp/codehosting/scanner/tests/test_bzrsync.py (+1/-2)
lib/lp/codehosting/tests/test_acceptance.py (+11/-9)
lib/lp/codehosting/vfs/branchfs.py (+9/-1)
lib/lp/codehosting/vfs/branchfsclient.py (+4/-2)
lib/lp/codehosting/vfs/tests/test_branchfs.py (+40/-15)
To merge this branch: bzr merge lp:~mwhudson/launchpad/no-hosted-area-formats-from-codehosting
Reviewer Review Type Date Requested Status
Tim Penhey (community) Approve
Review via email: mp+23644@code.launchpad.net

Description of the change

Hi Tim,

This branch changes the branchChanged endpoint to record the branch formats and the codehosting server to record them, so not creating scan jobs when the tip revision doesn't change doesn't mean a stale format showing in the UI.

Cheers,
mwh

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote :

I think it would be better for the branchChanged method to take
the format strings as three separate parameters rather than a tuple that
is unpacked.

We don't really need to test the branchChanged for packs and knits.

We should remove the code from the scanner that records the
formats as part of this (or the next pipe if you wish).

review: Needs Fixing
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

On 19/04/10 16:41, Tim Penhey wrote:
> Review: Needs Fixing
> I think it would be better for the branchChanged method to take
> the format strings as three separate parameters rather than a tuple that
> is unpacked.

Yeah, I think you're right.

> We don't really need to test the branchChanged for packs and knits.

OK.

> We should remove the code from the scanner that records the
> formats as part of this (or the next pipe if you wish).

I think we should do that after the pipe that records the formats from
the branch puller, which is a couple of pipes down the line yet...

Interdiff attached.

Cheers,
mwh

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

Good now.

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/xmlrpc/codehosting.py'
2--- lib/lp/code/xmlrpc/codehosting.py 2010-04-27 02:16:59 +0000
3+++ lib/lp/code/xmlrpc/codehosting.py 2010-04-27 02:17:19 +0000
4@@ -34,6 +34,7 @@
5 from canonical.launchpad.xmlrpc.helpers import return_fault
6
7 from lp.code.errors import UnknownBranchTypeError
8+from lp.code.bzr import BranchFormat, ControlFormat, RepositoryFormat
9 from lp.code.enums import BranchType
10 from lp.code.interfaces.branch import BranchCreationException
11 from lp.code.interfaces.branchjob import IBranchScanJobSource
12@@ -248,7 +249,8 @@
13 return True
14 return run_with_login(login_id, request_mirror)
15
16- def branchChanged(self, branch_id, stacked_on_location, last_revision_id):
17+ def branchChanged(self, branch_id, stacked_on_location, last_revision_id,
18+ control_string, branch_string, repository_string):
19 """See `IBranchFileSystem`."""
20 branch_set = removeSecurityProxy(getUtility(IBranchLookup))
21 branch = branch_set.get(branch_id)
22@@ -268,6 +270,22 @@
23 if branch.last_mirrored_id != last_revision_id:
24 branch.last_mirrored_id = last_revision_id
25 getUtility(IBranchScanJobSource).create(branch)
26+
27+ def match_title(enum, title, default):
28+ for value in enum.items:
29+ if value.title == title:
30+ return value
31+ else:
32+ return default
33+
34+ branch.control_format = match_title(
35+ ControlFormat, control_string, ControlFormat.UNRECOGNIZED)
36+ branch.branch_format = match_title(
37+ BranchFormat, branch_string, BranchFormat.UNRECOGNIZED)
38+ branch.repository_format = match_title(
39+ RepositoryFormat, repository_string,
40+ RepositoryFormat.UNRECOGNIZED)
41+
42 return True
43
44 def _serializeBranch(self, requester, branch, trailing_path):
45
46=== modified file 'lib/lp/code/xmlrpc/tests/test_codehosting.py'
47--- lib/lp/code/xmlrpc/tests/test_codehosting.py 2010-04-27 02:16:59 +0000
48+++ lib/lp/code/xmlrpc/tests/test_codehosting.py 2010-04-27 02:17:19 +0000
49@@ -9,6 +9,7 @@
50 import pytz
51 import unittest
52
53+from bzrlib import bzrdir
54 from bzrlib.tests import multiply_tests
55 from bzrlib.urlutils import escape
56
57@@ -28,6 +29,7 @@
58 from canonical.launchpad.xmlrpc import faults
59 from canonical.testing import DatabaseFunctionalLayer, FunctionalLayer
60
61+from lp.code.bzr import BranchFormat, ControlFormat, RepositoryFormat
62 from lp.code.enums import BranchType
63 from lp.code.errors import UnknownBranchTypeError
64 from lp.code.interfaces.branch import BRANCH_NAME_VALIDATION_ERROR_MESSAGE
65@@ -712,11 +714,24 @@
66 self.assertSqlAttributeEqualsDate(
67 branch, 'next_mirror_time', UTC_NOW)
68
69+ def getFormatStringsForFormatName(self, format_name):
70+ default_format = bzrdir.format_registry.get(format_name)()
71+ control_string = default_format.get_format_string()
72+ branch_string = default_format.get_branch_format().get_format_string()
73+ repository_string = \
74+ default_format.repository_format.get_format_string()
75+ return (control_string, branch_string, repository_string)
76+
77+ @property
78+ def arbitrary_format_strings(self):
79+ return self.getFormatStringsForFormatName('default')
80+
81 def test_branchChanged_sets_last_mirrored_id(self):
82 # branchChanged sets the last_mirrored_id attribute on the branch.
83 revid = self.factory.getUniqueString()
84 branch = self.factory.makeAnyBranch()
85- self.branchfs.branchChanged(branch.id, '', revid)
86+ self.branchfs.branchChanged(
87+ branch.id, '', revid, *self.arbitrary_format_strings)
88 self.assertEqual(revid, branch.last_mirrored_id)
89
90 def test_branchChanged_sets_stacked_on(self):
91@@ -724,7 +739,9 @@
92 # passed in.
93 branch = self.factory.makeAnyBranch()
94 stacked_on = self.factory.makeAnyBranch()
95- self.branchfs.branchChanged(branch.id, stacked_on.unique_name, '')
96+ self.branchfs.branchChanged(
97+ branch.id, stacked_on.unique_name, '',
98+ *self.arbitrary_format_strings)
99 self.assertEqual(stacked_on, branch.stacked_on)
100
101 def test_branchChanged_unsets_stacked_on(self):
102@@ -732,14 +749,16 @@
103 # passed in as the stacked_on location.
104 branch = self.factory.makeAnyBranch()
105 removeSecurityProxy(branch).stacked_on = self.factory.makeAnyBranch()
106- self.branchfs.branchChanged(branch.id, '', '')
107+ self.branchfs.branchChanged(
108+ branch.id, '', '', *self.arbitrary_format_strings)
109 self.assertIs(None, branch.stacked_on)
110
111 def test_branchChanged_sets_last_mirrored(self):
112 # branchChanged sets the last_mirrored attribute on the branch to the
113 # current time.
114 branch = self.factory.makeAnyBranch()
115- self.branchfs.branchChanged(branch.id, '', '')
116+ self.branchfs.branchChanged(
117+ branch.id, '', '', *self.arbitrary_format_strings)
118 if self.frontend == LaunchpadDatabaseFrontend:
119 self.assertSqlAttributeEqualsDate(
120 branch, 'last_mirrored', UTC_NOW)
121@@ -751,7 +770,8 @@
122 # mirror_status_message is set to indicate the problem and stacked_on
123 # set to None.
124 branch = self.factory.makeAnyBranch()
125- self.branchfs.branchChanged(branch.id, '~does/not/exist', '')
126+ self.branchfs.branchChanged(
127+ branch.id, '~does/not/exist', '', *self.arbitrary_format_strings)
128 self.assertIs(None, branch.stacked_on)
129 self.assertTrue('~does/not/exist' in branch.mirror_status_message)
130
131@@ -760,7 +780,8 @@
132 # mirror_status_message.
133 branch = self.factory.makeAnyBranch()
134 removeSecurityProxy(branch).mirror_status_message = 'foo'
135- self.branchfs.branchChanged(branch.id, '', '')
136+ self.branchfs.branchChanged(
137+ branch.id, '', '', *self.arbitrary_format_strings)
138 self.assertIs(None, branch.mirror_status_message)
139
140 def test_branchChanged_fault_on_unknown_id(self):
141@@ -768,7 +789,8 @@
142 # "NoBranchWithID" is returned.
143 unused_id = -1
144 expected_fault = faults.NoBranchWithID(unused_id)
145- received_fault = self.branchfs.branchChanged(unused_id, '', '')
146+ received_fault = self.branchfs.branchChanged(
147+ unused_id, '', '', *self.arbitrary_format_strings)
148 self.assertEqual(
149 (expected_fault.faultCode, expected_fault.faultString),
150 (received_fault.faultCode, received_fault.faultString))
151@@ -780,7 +802,8 @@
152 branch = self.factory.makeAnyBranch()
153 jobs = list(getUtility(IBranchScanJobSource).iterReady())
154 self.assertEqual(0, len(jobs))
155- self.branchfs.branchChanged(branch.id, '', 'rev1')
156+ self.branchfs.branchChanged(
157+ branch.id, '', 'rev1', *self.arbitrary_format_strings)
158 jobs = list(getUtility(IBranchScanJobSource).iterReady())
159 self.assertEqual(1, len(jobs))
160
161@@ -791,10 +814,43 @@
162 removeSecurityProxy(branch).last_mirrored_id = 'rev1'
163 jobs = list(getUtility(IBranchScanJobSource).iterReady())
164 self.assertEqual(0, len(jobs))
165- self.branchfs.branchChanged(branch.id, '', 'rev1')
166+ self.branchfs.branchChanged(
167+ branch.id, '', 'rev1', *self.arbitrary_format_strings)
168 jobs = list(getUtility(IBranchScanJobSource).iterReady())
169 self.assertEqual(0, len(jobs))
170
171+ def test_branchChanged_2a_format(self):
172+ branch = self.factory.makeAnyBranch()
173+ self.branchfs.branchChanged(
174+ branch.id, '', 'rev1', *self.getFormatStringsForFormatName('2a'))
175+ self.assertEqual(
176+ (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_7,
177+ RepositoryFormat.BZR_CHK_2A),
178+ (branch.control_format, branch.branch_format,
179+ branch.repository_format))
180+
181+ def test_branchChanged_packs_format(self):
182+ branch = self.factory.makeAnyBranch()
183+ self.branchfs.branchChanged(
184+ branch.id, '', 'rev1',
185+ *self.getFormatStringsForFormatName('pack-0.92'))
186+ self.assertEqual(
187+ (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_6,
188+ RepositoryFormat.BZR_KNITPACK_1),
189+ (branch.control_format, branch.branch_format,
190+ branch.repository_format))
191+
192+ def test_branchChanged_knits_format(self):
193+ branch = self.factory.makeAnyBranch()
194+ self.branchfs.branchChanged(
195+ branch.id, '', 'rev1',
196+ *self.getFormatStringsForFormatName('knit'))
197+ self.assertEqual(
198+ (ControlFormat.BZR_METADIR_1, BranchFormat.BZR_BRANCH_5,
199+ RepositoryFormat.BZR_KNIT_1),
200+ (branch.control_format, branch.branch_format,
201+ branch.repository_format))
202+
203 def assertCannotTranslate(self, requester, path):
204 """Assert that we cannot translate 'path'."""
205 fault = self.branchfs.translatePath(requester.id, path)
206
207=== modified file 'lib/lp/codehosting/inmemory.py'
208--- lib/lp/codehosting/inmemory.py 2010-04-27 02:16:59 +0000
209+++ lib/lp/codehosting/inmemory.py 2010-04-27 02:17:19 +0000
210@@ -21,6 +21,7 @@
211 from canonical.launchpad.validators import LaunchpadValidationError
212 from canonical.launchpad.xmlrpc import faults
213
214+from lp.code.bzr import BranchFormat, ControlFormat, RepositoryFormat
215 from lp.code.errors import UnknownBranchTypeError
216 from lp.code.model.branchnamespace import BranchNamespaceSet
217 from lp.code.model.branchtarget import (
218@@ -618,7 +619,8 @@
219 def requestMirror(self, requester_id, branch_id):
220 self._branch_set.get(branch_id).requestMirror()
221
222- def branchChanged(self, branch_id, stacked_on_location, last_revision_id):
223+ def branchChanged(self, branch_id, stacked_on_location, last_revision_id,
224+ control_string, branch_string, repository_string):
225 branch = self._branch_set._find(id=branch_id)
226 if branch is None:
227 return faults.NoBranchWithID(branch_id)
228@@ -638,6 +640,22 @@
229 branch.last_mirrored = UTC_NOW
230 if branch.last_mirrored_id != last_revision_id:
231 branch.last_mirrored_id = last_revision_id
232+
233+ def match_title(enum, title, default):
234+ for value in enum.items:
235+ if value.title == title:
236+ return value
237+ else:
238+ return default
239+
240+ branch.control_format = match_title(
241+ ControlFormat, control_string, ControlFormat.UNRECOGNIZED)
242+ branch.branch_format = match_title(
243+ BranchFormat, branch_string, BranchFormat.UNRECOGNIZED)
244+ branch.repository_format = match_title(
245+ RepositoryFormat, repository_string,
246+ RepositoryFormat.UNRECOGNIZED)
247+
248 return True
249
250 def _canRead(self, person_id, branch):
251
252=== modified file 'lib/lp/codehosting/scanner/tests/test_bzrsync.py'
253--- lib/lp/codehosting/scanner/tests/test_bzrsync.py 2010-04-27 02:16:59 +0000
254+++ lib/lp/codehosting/scanner/tests/test_bzrsync.py 2010-04-27 02:17:19 +0000
255@@ -547,8 +547,7 @@
256 # We can scan a stacked branch that's stacked on a branch that has an
257 # lp-mirrored:// URL.
258 db_stacked_on_branch = self.factory.makeAnyBranch()
259- stacked_on_tree = self.makeBzrBranchAndTree(
260- db_stacked_on_branch, format='1.6')
261+ self.makeBzrBranchAndTree(db_stacked_on_branch, format='1.6')
262 db_stacked_branch = self.factory.makeAnyBranch()
263 stacked_tree = self.makeBzrBranchAndTree(
264 db_stacked_branch, format='1.6')
265
266=== modified file 'lib/lp/codehosting/tests/test_acceptance.py'
267--- lib/lp/codehosting/tests/test_acceptance.py 2010-04-27 02:16:59 +0000
268+++ lib/lp/codehosting/tests/test_acceptance.py 2010-04-27 02:17:19 +0000
269@@ -23,6 +23,7 @@
270 from canonical.testing import ZopelessAppServerLayer
271 from canonical.testing.profiled import profiled
272
273+from lp.code.bzr import BranchFormat, ControlFormat, RepositoryFormat
274 from lp.code.enums import BranchType
275 from lp.code.interfaces.branch import IBranchSet
276 from lp.code.interfaces.branchnamespace import get_branch_namespace
277@@ -321,18 +322,19 @@
278 url=url)
279
280 def test_push_to_new_branch(self):
281- """
282- The bzr client should be able to read and write to the codehosting
283- server just like another other server. This means that actions
284- like:
285- * `bzr push bzr+ssh://testinstance/somepath`
286- * `bzr log sftp://testinstance/somepath`
287- (and/or their bzrlib equivalents) and so on should work, so long as
288- the user has permission to read or write to those URLs.
289- """
290 remote_url = self.getTransportURL('~testuser/+junk/test-branch')
291 self.push(self.local_branch_path, remote_url)
292 self.assertBranchesMatch(self.local_branch_path, remote_url)
293+ LaunchpadZopelessTestSetup().txn.begin()
294+ db_branch = getUtility(IBranchSet).getByUniqueName(
295+ '~testuser/+junk/test-branch')
296+ self.assertEqual(
297+ RepositoryFormat.BZR_CHK_2A, db_branch.repository_format)
298+ self.assertEqual(
299+ BranchFormat.BZR_BRANCH_7, db_branch.branch_format)
300+ self.assertEqual(
301+ ControlFormat.BZR_METADIR_1, db_branch.control_format)
302+ LaunchpadZopelessTestSetup().txn.commit()
303
304 def test_push_to_existing_branch(self):
305 """Pushing to an existing branch must work."""
306
307=== modified file 'lib/lp/codehosting/vfs/branchfs.py'
308--- lib/lp/codehosting/vfs/branchfs.py 2010-04-27 02:16:59 +0000
309+++ lib/lp/codehosting/vfs/branchfs.py 2010-04-27 02:17:19 +0000
310@@ -675,13 +675,21 @@
311 ignore_fallbacks=True)
312 last_revision = branch.last_revision()
313 stacked_on_url = self._normalize_stacked_on_url(branch)
314+ # XXX: Aaron Bentley 2008-06-13
315+ # Bazaar does not provide a public API for learning about
316+ # format markers. Fix this in Bazaar, then here.
317+ control_string = branch.bzrdir._format.get_format_string()
318+ branch_string = branch._format.get_format_string()
319+ repository_string = \
320+ branch.repository._format.get_format_string()
321 finally:
322 if jail_info.transports:
323 jail_info.transports.remove(transport)
324 if stacked_on_url is None:
325 stacked_on_url = ''
326 return self._authserver.branchChanged(
327- data['id'], stacked_on_url, last_revision)
328+ data['id'], stacked_on_url, last_revision,
329+ control_string, branch_string, repository_string)
330
331 # It gets really confusing if we raise an exception from this method
332 # (the branch remains locked, but this isn't obvious to the client) so
333
334=== modified file 'lib/lp/codehosting/vfs/branchfsclient.py'
335--- lib/lp/codehosting/vfs/branchfsclient.py 2010-04-27 02:16:59 +0000
336+++ lib/lp/codehosting/vfs/branchfsclient.py 2010-04-27 02:17:19 +0000
337@@ -115,14 +115,16 @@
338 self._branchfs_endpoint.callRemote, 'createBranch', self._user_id,
339 branch_path)
340
341- def branchChanged(self, branch_id, stacked_on_url, last_revision_id):
342+ def branchChanged(self, branch_id, stacked_on_url, last_revision_id,
343+ control_string, branch_string, repository_string):
344 """Mark a branch as needing to be mirrored.
345
346 :param branch_id: The database ID of the branch.
347 """
348 return defer.maybeDeferred(
349 self._branchfs_endpoint.callRemote,
350- 'branchChanged', branch_id, stacked_on_url, last_revision_id)
351+ 'branchChanged', branch_id, stacked_on_url, last_revision_id,
352+ control_string, branch_string, repository_string)
353
354 def translatePath(self, path):
355 """Translate 'path'."""
356
357=== modified file 'lib/lp/codehosting/vfs/tests/test_branchfs.py'
358--- lib/lp/codehosting/vfs/tests/test_branchfs.py 2010-04-27 02:16:59 +0000
359+++ lib/lp/codehosting/vfs/tests/test_branchfs.py 2010-04-27 02:17:19 +0000
360@@ -11,7 +11,7 @@
361 import unittest
362
363 from bzrlib import errors
364-from bzrlib.bzrdir import BzrDir
365+from bzrlib.bzrdir import BzrDir, format_registry
366 from bzrlib.tests import (
367 TestCase as BzrTestCase, TestCaseInTempDir, TestCaseWithTransport)
368 from bzrlib.transport import (
369@@ -821,12 +821,17 @@
370 frontend = InMemoryFrontend()
371 self.factory = frontend.getLaunchpadObjectFactory()
372 self.authserver = frontend.getFilesystemEndpoint()
373- self.authserver.branchChanged = (
374- lambda *args: self._branch_changed_log.append(args))
375+ self.authserver.branchChanged = self._replacement_branchChanged
376 self.requester = self.factory.makePerson()
377 self.backing_transport = MemoryTransport()
378 self.disable_directory_isolation()
379
380+ def _replacement_branchChanged(self, branch_id, stacked_on_url,
381+ last_revision, *format_strings):
382+ self._branch_changed_log.append(dict(
383+ branch_id=branch_id, stacked_on_url=stacked_on_url,
384+ last_revision=last_revision, format_strings=format_strings))
385+
386 def get_server(self):
387 if self._server is None:
388 self._server = LaunchpadServer(
389@@ -844,8 +849,7 @@
390 db_branch = self.factory.makeAnyBranch(
391 branch_type=BranchType.HOSTED, owner=self.requester)
392 self.make_branch(db_branch.unique_name)
393- self.assertEqual(
394- [(db_branch.id, '', 'null:')], self._branch_changed_log)
395+ self.assertEqual(1, len(self._branch_changed_log))
396
397 def test_branch_unlock_calls_branchChanged(self):
398 # Unlocking a branch calls branchChanged on the branch filesystem
399@@ -856,8 +860,7 @@
400 del self._branch_changed_log[:]
401 branch.lock_write()
402 branch.unlock()
403- self.assertEqual(
404- [(db_branch.id, '', 'null:')], self._branch_changed_log)
405+ self.assertEqual(1, len(self._branch_changed_log))
406
407 def test_branch_unlock_reports_stacked_on_url(self):
408 # Unlocking a branch reports the stacked on URL to the branch
409@@ -872,9 +875,10 @@
410 branch.lock_write()
411 branch.set_stacked_on_url('/' + db_branch1.unique_name)
412 branch.unlock()
413+ self.assertEqual(1, len(self._branch_changed_log))
414 self.assertEqual(
415- [(db_branch2.id, '/' + db_branch1.unique_name, 'null:')],
416- self._branch_changed_log)
417+ '/' + db_branch1.unique_name,
418+ self._branch_changed_log[0]['stacked_on_url'])
419
420 def test_branch_unlock_reports_last_revision(self):
421 # Unlocking a branch reports the tip revision of the branch to the
422@@ -886,8 +890,10 @@
423 del self._branch_changed_log[:]
424 branch.lock_write()
425 branch.unlock()
426+ self.assertEqual(1, len(self._branch_changed_log))
427 self.assertEqual(
428- [(db_branch.id, '', revid)], self._branch_changed_log)
429+ revid,
430+ self._branch_changed_log[0]['last_revision'])
431
432 def test_branch_unlock_relativizes_absolute_stacked_on_url(self):
433 # When a branch that has been stacked on the absolute URL of another
434@@ -904,9 +910,10 @@
435 'http://bazaar.launchpad.dev/~user/product/branch')
436 branch.unlock()
437 self.assertEqual('/~user/product/branch', branch.get_stacked_on_url())
438+ self.assertEqual(1, len(self._branch_changed_log))
439 self.assertEqual(
440- [(db_branch.id, '/~user/product/branch', 'null:')],
441- self._branch_changed_log)
442+ '/~user/product/branch',
443+ self._branch_changed_log[0]['stacked_on_url'])
444
445 def test_branch_unlock_ignores_non_launchpad_stacked_url(self):
446 # When a branch that has been stacked on the absolute URL of a branch
447@@ -920,8 +927,9 @@
448 branch.get_config().set_user_option(
449 'stacked_on_location', stacked_on_url)
450 branch.unlock()
451+ self.assertEqual(1, len(self._branch_changed_log))
452 self.assertEqual(
453- [(db_branch.id, stacked_on_url, 'null:')], self._branch_changed_log)
454+ stacked_on_url, self._branch_changed_log[0]['stacked_on_url'])
455 self.assertEqual(stacked_on_url, branch.get_stacked_on_url())
456
457 def test_branch_unlock_ignores_odd_scheme_stacked_url(self):
458@@ -937,11 +945,28 @@
459 branch.get_config().set_user_option(
460 'stacked_on_location', stacked_on_url)
461 branch.unlock()
462+ self.assertEqual(1, len(self._branch_changed_log))
463 self.assertEqual(
464- [(db_branch.id, stacked_on_url, 'null:')],
465- self._branch_changed_log)
466+ stacked_on_url, self._branch_changed_log[0]['stacked_on_url'])
467 self.assertEqual(stacked_on_url, branch.get_stacked_on_url())
468
469+ def assertFormatStringsPassed(self, branch):
470+ self.assertEqual(1, len(self._branch_changed_log))
471+ control_string = branch.bzrdir._format.get_format_string()
472+ branch_string = branch._format.get_format_string()
473+ repository_string = branch.repository._format.get_format_string()
474+ self.assertEqual(
475+ (control_string, branch_string, repository_string),
476+ self._branch_changed_log[0]['format_strings'])
477+
478+ def test_format_2a(self):
479+ # Creating a 2a branch reports the format to branchChanged.
480+ db_branch = self.factory.makeAnyBranch(
481+ branch_type=BranchType.HOSTED, owner=self.requester)
482+ branch = self.make_branch(
483+ db_branch.unique_name, format=format_registry.get('2a')())
484+ self.assertFormatStringsPassed(branch)
485+
486
487 class TestLaunchpadTransportReadOnly(TrialTestCase, BzrTestCase):
488 """Tests for read-only operations on the LaunchpadTransport."""