Merge lp:~jelmer/bzr/foreign-tests into lp:~bzr/bzr/trunk-old

Proposed by Jelmer Vernooij
Status: Rejected
Rejected by: Ian Clatworthy
Proposed branch: lp:~jelmer/bzr/foreign-tests
Merge into: lp:~bzr/bzr/trunk-old
Diff against target: 151 lines
To merge this branch: bzr merge lp:~jelmer/bzr/foreign-tests
Reviewer Review Type Date Requested Status
John A Meinel Needs Fixing
Review via email: mp+9642@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

This branch adds two testcase classes in bzrlib.tests.foreign.test_branch that can be used as basis for the testcases in foreign branch plugins. I've posted matching branches of bzr-svn (lp:~jelmer/bzr-svn/foreign-tests and bzr-git (lp:~jelmer/bzr-git/foreign-tests) that use this. I'm hoping to add a lot more (and more complex) generic tests for the foreign code, to avoid duplicate work in each foreign vcs plugin.

I've considered using adapters rather than "manual" subclassing, but since some subclassing will be needed anyway (the generic tests don't test everything that should be tested) I think that would be overkill.

Does this seem like a reasonable approach?

Revision history for this message
John A Meinel (jameinel) wrote :

If we are going to go this route, I would probably call it a ForeignBranchTestMixin

since it is meant as a second parent class. (eg, users will do:

class TestMyBranchImpl(TestCase, ForeignBranchTestMixin)

However, I think I would tweak a few things differently anyway.

1) It should probably be called "per_foreign" rather than "foreign"

2) I think I would use adaptation rather than inheritance. Yes, there are going to be *more* tests that will be needed for specific foreign branch implementations, but those can just be created in another test class.

I think having a flag, etc on register_format to indicate this is a foreign format, would be a great move towards making registering the format automatically queue it for the appropriate tests.

It makes it less susceptible to accidentally missing some tests, because you forgot to inherit from the new base test class.

It also means that when we add a new base test class, it automatically starts getting run across all of the current implementations, we don't need to change anything in bzr-svn or bzr-git.

3) I would also like to see things like:
class ForeignBranchFormatTests(object):
  format = None # set by XXXXX

  def test_foo(self):
    self.format.x

It makes it easier to figure out where things are happening.

4) For something like ForiegnBranch, I think the tests you have are ok, though
126 + def test_last_revision(self):
127 + (revno, revid) = self.branch.last_revision_info()
128 + self.assertIsInstance(revno, int)
129 + self.assertIsInstance(revid, str)
130 + self.assertEquals(revno, self.branch.revision_id_to_revno(revid))
131 + self.assertEquals(revid, self.branch.last_revision())

^- this is testing more "last_revision_info" not last_revision. And I certainly thought you wanted to get away from 'revno' since it cannot be easily computed at all times.

I think what we should be doing is designing a reasonable factory interface, so that you can have the test case say:

 def test_something(self):
   self.factory.give_me_a_branch_like_X()

(a branch with 1 commit, a branch with a few commits, a branch with merges, etc.)

There was some discussion raised by Martin on the mailing list, which didn't quite as planned, but I think foreign branch testing is a *great* place to implement some of this, since a lot of them are going to be read-only sources, and thus doing:
  self.tree.commit('foo')
to generate the shape isn't going to work.

review: Approve
Revision history for this message
John A Meinel (jameinel) wrote :

sorry I marked the wrong status.

review: Needs Fixing
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Thanks for the review.

> However, I think I would tweak a few things differently anyway.
>
> 1) It should probably be called "per_foreign" rather than "foreign"
Wouldn't this mean we'd need per_foreign_branch, per_foreign_repository, per_foreign_branch_format, etc?

Cheers,

Jelmer

Revision history for this message
John A Meinel (jameinel) wrote :

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

Jelmer Vernooij wrote:
> Thanks for the review.
>
>> However, I think I would tweak a few things differently anyway.
>>
>> 1) It should probably be called "per_foreign" rather than "foreign"
> Wouldn't this mean we'd need per_foreign_branch, per_foreign_repository, per_foreign_branch_format, etc?
>
> Cheers,
>
> Jelmer

It depends if you think you are going to have more than one branch type
per foreign type, and more than one repo type, etc.

At the moment, neither git nor hg have allowed anything of that sort.
I'm not sure that svn has either.

In which case adding the extra permutations doesn't seem to gain much of
anything.

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkqFcJ4ACgkQJdeBCYSNAAMNzwCeIdhUQ5KvUi/8GNUgDyV1TayB
930An1GpW6cnBnBKvC2dwTWPuw4UY73s
=wjYm
-----END PGP SIGNATURE-----

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

On Thu, Aug 13, 2009 at 05:09:06PM -0000, John A Meinel wrote:
> 3) I would also like to see things like:
> class ForeignBranchFormatTests(object):
> format = None # set by XXXXX

> def test_foo(self):
> self.format.x

> It makes it easier to figure out where things are happening.

This should work well for foreign branch formats. It's trickier though
in the case of foreign branches, where there is custom code necessary that
creates a branch. How would the adapter find the code that creates the
branch attribute that is used by the member methods of a testcase
class? This seems a lot easier with a MixIn, but I'm probably missing
something.

Cheers,

Jelmer

Revision history for this message
Martin Pool (mbp) wrote :

2009/9/3 Jelmer Vernooij <email address hidden>:
> On Thu, Aug 13, 2009 at 05:09:06PM -0000, John A Meinel wrote:
>> 3) I would also like to see things like:
>> class ForeignBranchFormatTests(object):
>>   format = None # set by XXXXX
>
>>   def test_foo(self):
>>     self.format.x
>
>> It makes it easier to figure out where things are happening.
>
> This should work well for foreign branch formats. It's trickier though
> in the case of foreign branches, where there is custom code necessary that
> creates a branch. How would the adapter find the code that creates the
> branch attribute that is used by the member methods of a testcase
> class? This seems a lot easier with a MixIn, but I'm probably missing
> something.

I might be missing the point, but I think you'd have

ForeignBranchTests(TestCase):

  branch_factory = None # set by scenario

  def test_log(self):
    branch = self.branch_factory.make_branch_with_crisscross_merges()

--
Martin <http://launchpad.net/~mbp/>

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

On Thu, 2009-09-03 at 00:24 +0000, Martin Pool wrote:
> 2009/9/3 Jelmer Vernooij <email address hidden>:
> > On Thu, Aug 13, 2009 at 05:09:06PM -0000, John A Meinel wrote:
> >> 3) I would also like to see things like:
> >> class ForeignBranchFormatTests(object):
> >> format = None # set by XXXXX
> >
> >> def test_foo(self):
> >> self.format.x
> >
> >> It makes it easier to figure out where things are happening.
> >
> > This should work well for foreign branch formats. It's trickier though
> > in the case of foreign branches, where there is custom code necessary that
> > creates a branch. How would the adapter find the code that creates the
> > branch attribute that is used by the member methods of a testcase
> > class? This seems a lot easier with a MixIn, but I'm probably missing
> > something.
>
> I might be missing the point, but I think you'd have
>
> ForeignBranchTests(TestCase):
>
> branch_factory = None # set by scenario
>
> def test_log(self):
> branch = self.branch_factory.make_branch_with_crisscross_merges()
Yeah, that makes sense. What about something like the attached patch?

Cheers,

Jelmer

--
Jelmer Vernooij <email address hidden> - http://samba.org/~jelmer/
Jabber: <email address hidden>

1# Bazaar merge directive format 2 (Bazaar 0.90)
2# revision_id: jelmer@samba.org-20091011013123-zbcruv13w8q2h6r5
3# target_branch: http://people.samba.org/bzr/jelmer/bzr/squash-xml-\
4# invalid-chars
5# testament_sha1: 32984381e00180079b59a5192388743b5ddf002e
6# timestamp: 2009-10-11 03:33:30 +0200
7# base_revision_id: pqm@pqm.ubuntu.com-20091006204548-bjnc3z4k256ppimz
8#
9# Begin patch
10=== modified file 'bzrlib/foreign.py'
11--- bzrlib/foreign.py 2009-10-06 14:40:37 +0000
12+++ bzrlib/foreign.py 2009-10-11 01:31:23 +0000
13@@ -36,7 +36,7 @@
14 """)
15
16 class VcsMapping(object):
17- """Describes the mapping between the semantics of Bazaar and a foreign vcs.
18+ """Describes the mapping between the semantics of Bazaar and a foreign VCS.
19
20 """
21 # Whether this is an experimental mapping that is still open to changes.
22@@ -122,6 +122,8 @@
23 class ForeignVcs(object):
24 """A foreign version control system."""
25
26+ branch_format = None
27+
28 def __init__(self, mapping_registry):
29 self.mapping_registry = mapping_registry
30
31
32=== modified file 'bzrlib/tests/__init__.py'
33--- bzrlib/tests/__init__.py 2009-10-01 14:44:43 +0000
34+++ bzrlib/tests/__init__.py 2009-10-10 22:28:00 +0000
35@@ -3650,6 +3650,7 @@
36 'bzrlib.tests.commands',
37 'bzrlib.tests.per_branch',
38 'bzrlib.tests.per_bzrdir',
39+ 'bzrlib.tests.per_foreign_vcs',
40 'bzrlib.tests.per_interrepository',
41 'bzrlib.tests.per_intertree',
42 'bzrlib.tests.per_inventory',
43
44=== added directory 'bzrlib/tests/per_foreign_vcs'
45=== added file 'bzrlib/tests/per_foreign_vcs/__init__.py'
46--- bzrlib/tests/per_foreign_vcs/__init__.py 1970-01-01 00:00:00 +0000
47+++ bzrlib/tests/per_foreign_vcs/__init__.py 2009-10-11 01:02:28 +0000
48@@ -0,0 +1,47 @@
49+# Copyright (C) 2009 Canonical Ltd
50+#
51+# This program is free software; you can redistribute it and/or modify
52+# it under the terms of the GNU General Public License as published by
53+# the Free Software Foundation; either version 2 of the License, or
54+# (at your option) any later version.
55+#
56+# This program is distributed in the hope that it will be useful,
57+# but WITHOUT ANY WARRANTY; without even the implied warranty of
58+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59+# GNU General Public License for more details.
60+#
61+# You should have received a copy of the GNU General Public License
62+# along with this program; if not, write to the Free Software
63+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
64+
65+
66+"""Tests specific to foreign branch implementations.
67+
68+"""
69+
70+from bzrlib import (
71+ foreign,
72+ tests,
73+ )
74+
75+
76+def vcs_scenarios():
77+ scenarios = []
78+ for name, vcs in foreign.foreign_vcs_registry.iteritems():
79+ scenarios.append((vcs.__class__.__name__, {
80+ "branch_factory": vcs.branch_format.get_foreign_tests_branch_factory(),
81+ "branch_format": vcs.branch_format,
82+ }))
83+ return scenarios
84+
85+
86+def load_tests(standard_tests, module, loader):
87+ result = loader.suiteClass()
88+ per_vcs_mod_names = [
89+ 'branch',
90+ ]
91+ sub_tests = loader.loadTestsFromModuleNames(
92+ ['bzrlib.tests.per_foreign_vcs.test_' + name
93+ for name in per_vcs_mod_names])
94+ tests.multiply_tests(sub_tests, vcs_scenarios(), result)
95+ return result
96
97=== added file 'bzrlib/tests/per_foreign_vcs/test_branch.py'
98--- bzrlib/tests/per_foreign_vcs/test_branch.py 1970-01-01 00:00:00 +0000
99+++ bzrlib/tests/per_foreign_vcs/test_branch.py 2009-10-11 01:20:37 +0000
100@@ -0,0 +1,151 @@
101+# Copyright (C) 2009 Canonical Ltd
102+#
103+# This program is free software; you can redistribute it and/or modify
104+# it under the terms of the GNU General Public License as published by
105+# the Free Software Foundation; either version 2 of the License, or
106+# (at your option) any later version.
107+#
108+# This program is distributed in the hope that it will be useful,
109+# but WITHOUT ANY WARRANTY; without even the implied warranty of
110+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
111+# GNU General Public License for more details.
112+#
113+# You should have received a copy of the GNU General Public License
114+# along with this program; if not, write to the Free Software
115+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
116+
117+
118+"""Tests specific to Branch implementations that use foreign VCS'es."""
119+
120+
121+from bzrlib.errors import (
122+ UnstackableBranchFormat,
123+ )
124+from bzrlib.revision import (
125+ NULL_REVISION,
126+ )
127+from bzrlib.tests import (
128+ TestCase,
129+ TestCaseWithTransport,
130+ )
131+
132+
133+class ForeignBranchFactory(object):
134+ """Factory of branches for ForeignBranchTests."""
135+
136+ def make_empty_branch(self, transport):
137+ """Create an empty branch with no commits in it."""
138+ raise NotImplementedError(self.make_empty_branch)
139+
140+ def make_branch(self, transport):
141+ """Create *some* branch, may be empty or not."""
142+ return self.make_empty_branch(transport)
143+
144+
145+class ForeignBranchTests(TestCaseWithTransport):
146+ """Basic tests for foreign branch implementations.
147+
148+ These tests mainly make sure that the implementation covers the required
149+ bits of the API and returns reasonable values.
150+ """
151+ branch_factory = None # Set to an instance of ForeignBranchFactory by scenario
152+
153+ def make_empty_branch(self):
154+ return self.branch_factory.make_empty_branch(self.get_transport())
155+
156+ def make_branch(self):
157+ return self.branch_factory.make_branch(self.get_transport())
158+
159+ def test_set_parent(self):
160+ """Test that setting the parent works."""
161+ branch = self.make_branch()
162+ branch.set_parent("foobar")
163+
164+ def test_break_lock(self):
165+ """Test that break_lock() works, even if it is a no-op."""
166+ branch = self.make_branch()
167+ branch.break_lock()
168+
169+ def test_set_push_location(self):
170+ """Test that setting the push location works."""
171+ branch = self.make_branch()
172+ branch.set_push_location("http://bar/bloe")
173+
174+ def test_repr_type(self):
175+ branch = self.make_branch()
176+ self.assertIsInstance(repr(branch), str)
177+
178+ def test_get_parent(self):
179+ """Test that getting the parent location works, and returns None."""
180+ # TODO: Allow this to be non-None when foreign branches add support
181+ # for storing this URL.
182+ branch = self.make_branch()
183+ self.assertIs(None, branch.get_parent())
184+
185+ def test_get_push_location(self):
186+ """Test that getting the push location works, and returns None."""
187+ # TODO: Allow this to be non-None when foreign branches add support
188+ # for storing this URL.
189+ branch = self.make_branch()
190+ self.assertIs(None, branch.get_push_location())
191+
192+ def test_attributes(self):
193+ """Check that various required attributes are present."""
194+ branch = self.make_branch()
195+ self.assertIsNot(None, getattr(branch, "repository", None))
196+ self.assertIsNot(None, getattr(branch, "mapping", None))
197+ self.assertIsNot(None, getattr(branch, "_format", None))
198+ self.assertIsNot(None, getattr(branch, "base", None))
199+
200+ def test__get_nick(self):
201+ """Make sure _get_nick is implemented and returns a string."""
202+ branch = self.make_branch()
203+ self.assertIsInstance(branch._get_nick(local=False), str)
204+ self.assertIsInstance(branch._get_nick(local=True), str)
205+
206+ def test_null_revid_revno(self):
207+ """null: should return revno 0."""
208+ branch = self.make_branch()
209+ self.assertEquals(0, branch.revision_id_to_revno(NULL_REVISION))
210+
211+ def test_get_stacked_on_url(self):
212+ """Test that get_stacked_on_url() behaves as expected.
213+
214+ Inter-Format stacking doesn't work yet, so all foreign implementations
215+ should raise UnstackableBranchFormat at the moment.
216+ """
217+ branch = self.make_branch()
218+ self.assertRaises(UnstackableBranchFormat,
219+ branch.get_stacked_on_url)
220+
221+ def test_get_physical_lock_status(self):
222+ branch = self.make_branch()
223+ self.assertFalse(branch.get_physical_lock_status())
224+
225+ def test_last_revision_empty_branch(self):
226+ branch = self.make_empty_branch()
227+ self.assertEquals(NULL_REVISION, branch.last_revision())
228+ self.assertEquals(0, branch.revno())
229+ self.assertEquals((0, NULL_REVISION), branch.last_revision_info())
230+
231+
232+class ForeignBranchFormatTests(TestCase):
233+ """Basic tests for foreign branch format objects."""
234+
235+ branch_format = None # Set to a BranchFormat instance by adapter
236+
237+ def test_initialize(self):
238+ """Test this format is not initializable.
239+
240+ Remote branches may be initializable on their own, but none currently
241+ support living in .bzr/branch.
242+ """
243+ self.assertRaises(NotImplementedError, self.branch_format.initialize, None)
244+
245+ def test_get_format_description_type(self):
246+ self.assertIsInstance(self.branch_format.get_format_description(), str)
247+
248+ def test_network_name(self):
249+ self.assertIsInstance(self.branch_format.network_name(), str)
250+
251+
252
253# Begin bundle
254IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWVqfm5cAGnX/gE5QAQBY////
255f/ff6r////pgInXdzFr7nA8PDpml9zJfc73vS9PSa7m9toG2Cq06A6DqtNCg3uea7R1udnvNxpPI
256ZpneYaD28rr3e6zEt5OcUddenlO93Tt06vLvDe9uR2wBhJIjIGgCAmENER4Umyj0mRmo009T1B6m
2571DR5QSQgBAgmiTIo8o9RtIA0ZBoAAAABpkEFFDQBvVGgANAAAAAAAAEmlImmUam0BU800EhvVPUe
258ptQbKD0IAaD1PUA2UEUgqehppqan6jTEFPNU2nqanpHlNHpNqegTTRk0ANNARSBCZNNCnimnoCno
2590xU8KeptQANNGhoAAKiPVXQm9hxAIcW+fu/igFST0YTsDN5LW9C+LQhHiTR3ceT+U726IlUfn2M4
260C7+UEseV9Hxpmf/mqhV8mM8guGKBqwKi9KeDOZQ37dHW+3Et9415hvvkIQ+iJv0ESR8Rd6MnWNva
261eBsbLuRpqMw6sRw4l7+vcu3wH3kfZWKElxLXMPJxOy0wsWm7fJN89Y2VEjdtj5n9V5S1b7ds1kuG
262tDkNmEkbrTNQaUIdDCcBlTDmYLJjGKHb/7Hn+B7OC7+fnnKf2E+Q8fPyB7j0kpyHMHyw6xNDwQqM
263aCocBdnyN3Xscp34mMd18zjdr4tLmARZsyoZshKwkr4gKMJI7EprAYZ2vD2YVTH12Gs08XnGqRTW
264RVBVVPNIKg9EG2pgRGWFjTwIVWAwKIqLMTxQxi73lKs6MUZmC4icE2Zg8pCSNbER7eMHhvsAqmpB
265eBAABwneVAtE6BcTQ/fw2z+bXyyQ9wTsgaMsgIwUEUYKsFgiQBQPwZ957whOrxdfHfrDaUWK+LCO
266yMPBiCzvDjBYkYLRSFFpK0NGmsZbRCxqBLMBaap0kRJIhhuBT6aB9y+qb3KSZALKBszTJyrC41zd
267wWEQhRkxgBBWQMhJysG5aMDXTzNk7rKESqLXZ8WjJGWMODLi1LhAtkzNnpWwnic3dhEKCsuE98Xm
268Fqy0CTLuhRzEG0C11ktc2IsRikTX1DDYbb4vLZyRu4AYD3HgbjvO3UbvgWnM7hjrIFhCi4UYlZqG
269Ace8VJ58hTnxJiA37sGBwh1ZDsMygXeUhOHaOFEtJplcI+BtIlqhrWXoHtXvZ7k95PEndVN35Efy
270sOBApHz7bFWZFG745VDBF325XCnMpyBbkQLidTsbw/5Pn/327mz1DwR1/KPLTbcFb7omDDAoTD+7
271yeeXtc9m/Nj2MiGdX0AysaVtikRUIghz/ivFpFHGJKtbx3DT0PPkgrfcid/YjJzsVKozaR0PDn8j
272H1JIv5mZLXKkYJTd8uOfjJKho+hSFI0QLrx457QEtpgbdZlBy0gBlvccc4piwTOOkh4sfI+3nVqH
273xsWl5oOkV3LIzbsgPqJHifQAakyYYaunLGx7DisVYq/uDxwMQSybyTwiZv4yMSCcmdkMSkGJlEiS
274tOofecc3vsHzkw80EHhu+mu4d4T+Xiefhbc6rdAqH+KJBYegF1Em2tOPNnKq2tfVgWPKQ4nPs8Kd
275/Py5Dg59TflXxq3w0o3toZCDtR9a+71/teAzJ45MMgeNOkGlLMufHe5zqkIHOZr9NuttlR1bpIK0
276MgYR5DE+oLD9IhBGAGDK0SKSdBOgQwIwEiQv9XZaHd2XGINzAmS2341nKSJBC+KOqdSdaNEM8N7S
277PeBnOzLJQdVAYCDwjFVBgGmYkWhzhzVVbGmazTVLA5lFYSgiSfUW/EHa792Pi5djtvsTGuzDNyVy
278VqZooKVrNU2x9WCVVzoLk3ErPRtyn8jq5jSTgnvZbxgnITyZVaGHdftMbIlt+EMkES9HU/45Y8S3
279n2io2wFvuNiRYPwmewGRzWZlCcwPTZhykEoO2mOQ5NIGac5pqZl8nw9LPsVWljZGQ5Rk/ROwLwgf
280ANqskTxFSlAkgxLSTNBfN+4GRB6Q8QWZCQUANjVWSPTNGBKiWiYhTq1CdQJPGOvdExCUQrkVgden
281H0S1Tu/cwTFP+cdOTduvL/+SPg44qzcM3Z/FfnyD/QSDQyQDhk86eLj7QNbLeUaUu+Q7s5z2LXFV
282gPHFdMwbZyGTIKwibT7Wh6yEAwbTfxEFVMwmMlmLlAGq03uU/EblSpf92/790vtLBqnTjbfz9IW0
283tpbbbLaW2W2W22/Icmuw6a67e6Tt+697ng0xxCAvduoZoSC5oCzck70sHXAhdfBcJp8AkTUsLci3
284dsSK91EYHfOcWDkUkGkkoqSNNNlpUSzIWNCBEiBW0Ca6SGhK/NZl7dsulDA6BsIEvoIlfdg45aq2
285yewlOiEeSsGOFcybgKJFzpu9SFcCxXpI4kS3DcgwfZegbXwG4OsBcSLwSqVC9ZBZulAolhgAz0cC
286DfBl7BLi4W7WwExRJqwiptWWIgbILFNWygpSUgRxuIZIZIg88tMwlktZOMHCvXHKVzejub0ZvjpO
287GeZDm5Vi0CJaEXxQKFOcqP0ELpJejrkhfvoN3vBz1ympSsAJvVlEQRPLK+EoiUqd6Kaer8yVWgeT
288EEmKyneliQxhJHnNxPmIJdlIxkLJEkgwO1JgNCEHuhzSC8I+AJtz+wS+phhIwKCsrDBUceVClYbM
289F0GAmoTltpiXoSJDGsdwekm6MML83me486lukH1Z9RttaM5Ld7FGx2l1KUCKFS+/sPLiIs0BaYZg
290i3Wa08rcy6xExnlj3ihbZUwC3CJF9VkjQhGRdam+vWJLoEg2nerW5R8aOhHT0En7u27sbgXXwkqc
2913MzLECdqnnBxPKDhaXzzkSvd1VBYl2yxLyw3G/O4wxyl1FirnBGgD5YLFCeiir4vyOSV9zZcGplM
292GDX0nQoJFTKe+hzngnxk9fRZK03mkOwDSZwKzyOcUz1UT5cGvEnu8yeQoOGUlUV5RRWqgHGSBIkI
293kuMoKKW9wj0ZoakEzlW3gRkqKLzJsYwU4lhEjBVIuiiE6SkCg3sKQBCQ4d6FepItRpQt4JXypq0D
294nRwAOjTpx6nUjIytBfJ1QSNCUjQgrBnKmPMPepYMRCjlHIoDE1ZZFt6sZgf6AlMX5k79loJFhzQu
295q8jG1jxouaVtXi0jg6KkGNosZPJ+wL8ADfHdLPGzQkSeUn53h3iUgR+SwoN5iXkc+TEG5PKkd9dk
296QJybpJyXS27JLPdYNwB0sFsHQ9yCKCJNwSkVYOvIht4BhHFglmXH1zwCLHNgsQTJvafS2CZzzs6R
297ZEmSYZY5HkkpOY+aQ6UxtIQs556SJ1UKaV0HsWXl8yklEwqEY9s8c+RzkmcEi86TJlVlvBkoIvvP
298lT2YrjQxUlVfdVHK2KFtQOD3elCkK8AoW8M9Vemf0jTU4eIAYt4nSljvJpY5eaGMp2CmT1Rs6gqX
299JcWFJsCBiQInAguOBwyosXBq9PKlAFxgRSiiFjaF4YXGFepJkKY+/RKDgEWmMpnNDZ34riP0qLjn
300p9bwU8Ba+TiSscu8264oU5EjadNTjNurfy7pnzdFNB6eTo88nawWCgsFikWDMmPOL6VjhbhPOItP
301cRAhqMkVEBuN9q8JPZBPk3ioU9iR6g7uFi2w1i0za8e2RsHzX3h3SPohbpLg+s589fJQHLQtpIwN
302eu71d3s9nJ/L2uSq5nTNOYi8pUyUQlOnuRoFAePgMA69rG4Zyhz0fDy9J9MdG6GOxgR2t1Y5v3hD
3031+UGOCZ3wbrxffK7c/fnbABYSZDNtrfYeKXok2S5ulF51KkoVrYazPxbkzZCo7GNL5txL7gRQtMR
304uqodhppNc7QkZVBTyBD3ATHAvSV6KdJ4U2G90r+mIPlxo1c1BQkTJW9tnQvGzBFHfqaTytmpcpVp
305dUCdLAXok69ZRyXOqmcZznfCCxuplGuVopMFwjooeWOElUblTLpixuYEiUEj1KsivPVuld7Ged7G
3065is7JhzPCu1DhcjeXKTpWu3uI3QB4ODniIScjsceuYpxoZijrDnJwKBM1dW9oTLzyV7A0V4Nwp1j
307zFv1I6j2ywt+vYY9Wb3jqzRJnu9QkJEJDUF2klzSVMwYkpEeVaz5cs6G/uFM8Qv5HP2ib56HM23N
3088BQvM1Q19Ou4fDyse1rIzEYGmomXXySNiyu/rWMdqs+oyWV97zlAiWNbDZsmINg6+MZjOebUOIAG
309XERyIRSoTiffC3LnVSOzxYksPPGL7pLaxl17fiQvQlZJaPXbBIczEpvMxJezJsRXsaCjq6FZWVr+
310BRS2e3EUTDlNd+anQhslneMyFcChNPytKfnbycnFX8tw1Cly88mTWTOwWVL5JEqb8q2xmREDmybv
311HBImbLPxbGQoU6MhsceOxI1PgMpYKQk0z37LcvmgiEIVfcQ/RC5Y4PBHgJHOdyFo9BuRrv3ta55t
3129ghuY0zm9HrybEG42BcCTR+Y+Q3iXbNuRtI45pmUdGJITtS0TJ7RAzPEsFn8S60rasIMacNMCALJ
313aO4vViaMjIEvLJV2lvORIsVnBctxltVN5iXBll8vfR47BfpTxgERhUsaoWOQ3Gt2NUwOk/btY5Tn
314RaRB7E9Nx3YzncL0go3TK2J3NFDhj3BF+dJ7m2kuvHjkzQtfR4z8hI80K7E5duu2iM5Pg198a8zf
315ckr+sRWCOQhweaSX6FhsY9Bis26JJQv35UoJSN6l8E4GYkGkSBLBNQnASLCSRGkrhKABMSQiQiXC
316SlQAMFEteJAkvA7T6zgflQDrUWScRIZwVUWIIzxQpELGJbCMZvgooqxRYsVWpGRk6g6ofjgDBJ6i
317G5ouU5fmEQJ9h8C89J/Z7SYdp/p8TwNDeE4FRFYIEWey2As/qdZn9LOqZ0Sk9pwPhP5kDgimh449
318I1uZoQqEPPaORaIqQcVWLwraY/AojN7ICQndAP3nEaiDsM6b6cJ/hxkGZyFoL8XgLWImzPgbhkUo
319mBfMYho3d1IxOQfIXIo7HTHOYW8ZImBMZAM4+RSYIxEaG4tEdCkkQHATDx5zKRHuRrGEMThsW048
320BicqLk1HRrE6CD2WS4hO8vNCCx5pgkypJeJ6ohxf2DMdJikHnQoFgMiY2DFo0a8HrFDCXAuMZpCj
321og95Lj72tXYloltao+qNA8DATnX2xEMVRFURZIoqlhDcmrMiE++w8MgY9MpqMmIvNsG/AaQGIyDN
3225ChYEkmjOaiQWH6g+LiSbdJYCAhWkVhfraUshoKFj563kEi2TUvmBBGYHybgiBHph+yZin2XCJ5T
323y4EwDk9RkPP3Fs5Wk1gDGjWmDBH5zQ9xz84ZI+o2xASDOOcMPIgcwbTGGtLZoESkgJ5T+RZ8rz+E
324xo21UGWBiSvUj79oF/62ZkzJLI/BcTeFow5S5ay9sx0TZWtpeS25pchHIomB2kj6XOHoKKpvlRj3
325EL7F4OuCi6g9lw6xEDtAD4xsEvMSQBYFRmhIyGZ8yFlBQ85vpDpOrxCZ9gXQdwqGsDS8oUq3GSR9
326ZyxA1ihC6080hgggiL4PmTRbM44RhigwByNUw4CnycFQTK/32m5B5cvH0GfceSz8NxdwL6HrLBXh
327oAeNtUX2hcPAqntseYTCZs7CxnoSycTy1GmBthIimGulQTm7REC48z4mhwpr1HtDSmYvWBh5i02Q
328IMxQUgFiVJoTwLMoN34m6YjTqig8IhYrktYGo18ACPrBBJB/XtJId87xEVyb4SGxcC6Z0XDX7Grp
329CFqua6+UzykmDBYXOSjl5SQ8EhgOwloE40UykfeCClkICKR10CRtN2zt3+pC4lHX2nEh1FA3I50D
330njYGrpeoPTXkjoa+NmWHWksiswWSSniYlZ2vK5wzeFxnChjyBicK6wnTfRUtq7gZcByDLQlCo1F7
33177bSYpz1pBnsN76dJFP1AZATzcTbYlSC9ERtv7DtotxpbhMggiSSlISGYHNHsG7yQ6NQOJ0iQG0O
332A/DXAObRGNYyMIOW7Ux+FOIg8+DEpTAUwXcFp0nk56iYYbshM+g5WeeRXp7MXJbqlSWwTq6y1o02
333oBlVpoImG4x0hdWrpDETQsVM1Bm7OkkE38Byt5bkqDOIViYrybAdhUr5j2qJYY24y0M+wSG1b8Ss
334OSeO4kjZfjbJP+oANx8kolZIW0AcYCYhLGvi4jqPkKJyzKECUtCJ8WzcobNuShg+01LBPqwBdbGz
335KsyhA5ipaQzGhq3e5pOQU7jTMmTGjzyXNG47Bkj9mCTBUR+qQE2iYwil44mH2PGcJHeO6KRtOxXT
3366TPxuzzl06o44bbDuw5GRSUrIi9qyLunVkWTFk0KyHfKQTA0aYD9TjS/Nh32Q02bXZn9oz6bNsNt
337D2jU6iMX4GmOJuS02DysuSjqLtsidm1vh3NQNTuN81zH06G5GsAYQUCMhh5YgIhIElELDpZzlrK8
338SKTVNCibxpcbi823AbTGjYMqcCBsORSj606ZJzdho6cqedo2o3DloFlAvxYYYwxil6DiyPoGnNBF
339Tdd2erGW/hKkRwEeJA5gLeGLo6JYZ38KHVlVMMRDxJK89JE5CUxPRpnnoVbhFs+Xa0OemRQI1w0G
3407atJ4foIYEcsQEB8xHYIQGx/RI+43h5AB0q2Hcnagd/1koHd5iA8KQKQ6bvJJiwCbSkN/MWlCUQ9
341+QlRECqcwy7ravAHvE23UhKihmahMNZa0mtLNaHw+df36PMSxu+RYT611CQkKhISBksARCRClF+A
342ek+XE9wmhDEMEMQNxAG0UicRiU2q4FjY8jVVDPLWInb57RNwWiNBghAkBBUAAwPeeXjP0+A/to8c
343WLZ9Q49nreqavNy83PTy0p2SHU3k5cmYtIyvNmupTwN4puka/FWKlM3EmbDUjasLbLeX7NTjsxmo
344xI/D4YQcapYguOdpuNwUklTcPBwXZgAkY70LSVpwABVWD6wDximdU43UWHx/N7cfEZDPL6SwnlIZ
345WYjPEHqyu5sSYViJCQ2EiU4P1bZaw7gNDtGpgJ7Roc0dyT5QAB0QoTyQhEk4TwSIoo8GhSGItski
346hjUsxjXtR3OsA6jYiHhOiQEEpQRMiAhRWA7BcaHOj0DkE5gsRxEIuAxAiyB0dckXFPXHH9N4XlLE
347fkJFF+JJgIDz0yLwoeKu0X4HccA9odqClym8TmhIF9XahCwOTkcyQfrArMAsfMOYnaoMoYkJjNlR
348KYB84AaT1ki03QB1qwL5kNQnFgitTnOJXMCXC6mHOQmRRNO8VnuuDYUI5Tsjex7DIxonn7hPoEzE
349xxMYYRRQUEkEZIDJQEZ/jrOyTrPYcsUGAtQ+0xAA9kQ7KAOKFYUNlsXwLRxAWB7PWwh3sAIF/tSG
350FMAN3CM5VgFQeo9ImDcAliUiWJSJRsEoMpEsSglBlkSgykSjQSjfGQ17YTTSefmJPOLHEd9LpMgY
351IE8jUeQKtB1IzDcIRSYSO+hsUSfALyDrOvIiVRxgd5iJyiINORgAkw6EBsJMBIssdVrx98dlDMgk
352X2DtyAOLOJCmTJnNU9inRcAgbELDQ4GyZjotMCR6xMTh9RITIEQmsQ6YB4BDuGIXKZDwmY+PSKUW
3538gLRuXcEgnhqcDAsSoSCQPsUk9QalewSxVS20N6kECMMPWPCfrOgEZPYAYCIHfGBEQxBmEAMF84E
3548PQCIWswJsBKKWB6DUN5cJcAEQPemFMCDXId6gRgaQVo07EhjmIcWUKRSlKEGAziZVmlrR2k0ZwH
355sJKyBgRPRSGeCFklpCWAgCwQeJzx87JCTgBTaexzAMwhQFrBmokHWMDcIGgYQ0xdBioKYyqDDkC7
356iISCxJz8ezARiKQ1JCSHcJabEQFsQLL/JmGwGiEoASVJABOFEyUmerXUV4o5gmNjrVr9HNsDdhlC
357TJIcCnUCZKuhMDKaXfoicYUj0zOUqjlFPOF5iXpQ9eUT0IToJeMJIGLF0a6A7xxIENDIkql8IHIL
3585/uGsKPWJnJmPEOgmJQszbCQlhcdZIMT4yAlAVwIN1RPIHeJVAHqQhOcRAmbRJhlGKCrAEZJp6JJ
359mSSdElPrPN1HYAxVhb5gjmfmaguB5ulMa79pLUWWCJCNwZEfVFdI+8SQhAiRcAGBoaHx5W8eZ+id
3604mQBLJsG1HfL5kwjKsdJ0dDD0h6FMFKuVZCRUMTMjEEKBrGhoqkGofcPiGsUw+lTYKfahsLh+QJJ
361qfpMUmJpEhMjUUnEFBtYchu3UChuZDdQ773CaabzIxjIJ4IUGwUDHBiUT3YTHwDqQTbBECqwjAId
362xcH4M3QqDLATOTnF6vZ5SEvE73GiBiQaF8Y7zhzCrO64EL4ETmPGWZTRGjZEmURJiSVay5JByifa
363JRUnAlGRKUgq5hEDWcKscdw29hYnohV9xd32DgrA9IdiMgRqTWA2ikCSDmw57uHSPQJJOTOYVE4g
364iZbzt18LAsAJSBJd5wGSIa4EfMztSkeI0O9ipNiC70ITTd9rupkoj0QJ6ldoGetqGbsml51Y0tSD
3658gUNJmIHpCPyplsTGmEEli7EbMWgnk/UAQE8QTDXOzEMhOIiB2n0Rxe+8LkJhEjIYMfsmNDMGU5g
3664vERH9gkViQMA8Cv9EMDJMKLECPeHziY5fN1EgcZ3nSjuMcAN3rEUFFigoMQmYBkZnK8Z3hfHM5I
367jAJ3GNADpJ+dBYoLFiwUFFiw5j8RDOc78OXuweGTAGhBJA90lFksE3EKzEmAS5RRzzNyiURmERYq
368HHYaJrU3rJOLWLwjqi7QNC8KOovJkiA/suOSZVtQhFxMNsFCBi1IExUYsAw95SOxgq3tjAJFlMKS
369vKllgL0dXQJQSibSG+MhMGNYRgSzYLDYgIUiyRIfOAFJQEQkwSgUNx+49ehqPIbGxCNUzKTPxbE+
370oSm4rceYTIDjI6l7lhZK84KQSDnDKUTJ9wkwA5CXmKTUSCFgzE28RSY6cFPUCbg5XgbyCCAiByPk
371jeZA3tiKdsGgSokXEBISFYEtPNAFVNDzampkGY6PKyuyOKAbMnMkMyEMyGgdZcJRSlFJhCu4E3jJ
372NzYhANhUMlLwD86EsX+Y3HJTT8Ip27Tl7wTTI9OXyR3nHcGJ6Cgll1FQ5H4w2KVCw1ZPEOCmNJBe
373+gC8oQecDvGyu46e4e9HXi6zqkSCHpekwfQK7KmcFqpSLQghrBPpvRnVyGo3vahIkZqwtAClSdWA
374O0Wiv4EcATQWPzKSHFRPR1+k3HGcne5tFDUVJk+RK1pgFBhVgTCBHzQ2C8FIvADApt7B84BJBU1H
375rDHLNXBB4vXtRqbHiMNCACI3q8wBAvhtExhvhcEIaM58D/xdyRThQkFqfm5c
Revision history for this message
Ian Clatworthy (ian-clatworthy) wrote :

I'm going to change the status to 'reject' because it looks like this has been superseded by the merge proposal for foreign-tests1. If I'm wrong, please resubmit this.

Updating diff...

An updated diff will be available in a few minutes. Reload to see the changes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'bzrlib/tests/foreign'
2=== added file 'bzrlib/tests/foreign/__init__.py'
3--- bzrlib/tests/foreign/__init__.py 1970-01-01 00:00:00 +0000
4+++ bzrlib/tests/foreign/__init__.py 2009-08-31 04:36:07 +0000
5@@ -0,0 +1,20 @@
6+# Copyright (C) 2009 Canonical Ltd
7+#
8+# This program is free software; you can redistribute it and/or modify
9+# it under the terms of the GNU General Public License as published by
10+# the Free Software Foundation; either version 2 of the License, or
11+# (at your option) any later version.
12+#
13+# This program is distributed in the hope that it will be useful,
14+# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+# GNU General Public License for more details.
17+#
18+# You should have received a copy of the GNU General Public License
19+# along with this program; if not, write to the Free Software
20+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
22+
23+"""Tests specific to foreign branch implementations.
24+
25+"""
26
27=== added file 'bzrlib/tests/foreign/test_branch.py'
28--- bzrlib/tests/foreign/test_branch.py 1970-01-01 00:00:00 +0000
29+++ bzrlib/tests/foreign/test_branch.py 2009-08-31 04:36:07 +0000
30@@ -0,0 +1,121 @@
31+# Copyright (C) 2009 Canonical Ltd
32+#
33+# This program is free software; you can redistribute it and/or modify
34+# it under the terms of the GNU General Public License as published by
35+# the Free Software Foundation; either version 2 of the License, or
36+# (at your option) any later version.
37+#
38+# This program is distributed in the hope that it will be useful,
39+# but WITHOUT ANY WARRANTY; without even the implied warranty of
40+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41+# GNU General Public License for more details.
42+#
43+# You should have received a copy of the GNU General Public License
44+# along with this program; if not, write to the Free Software
45+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
46+
47+
48+"""Tests specific to Branch implementations that use foreign VCS'es."""
49+
50+
51+from bzrlib.errors import (
52+ UnstackableBranchFormat,
53+ )
54+from bzrlib.revision import (
55+ NULL_REVISION,
56+ )
57+
58+
59+class ForeignBranchTests(object):
60+ """Basic tests for foreign branch implementations.
61+
62+ These tests mainly make sure that the implementation covers the required
63+ bits of the API and returns reasonable values.
64+ """
65+
66+ def test_set_parent(self):
67+ """Test that setting the parent works."""
68+ self.branch.set_parent("foobar")
69+
70+ def test_break_lock(self):
71+ """Test that break_lock() works, even if it is a no-op."""
72+ self.branch.break_lock()
73+
74+ def test_set_push_location(self):
75+ """Test that setting the push location works."""
76+ self.branch.set_push_location("http://bar/bloe")
77+
78+ def test_repr_type(self):
79+ self.assertIsInstance(repr(self.branch), str)
80+
81+ def test_get_parent(self):
82+ """Test that getting the parent location works, and returns None."""
83+ # TODO: Allow this to be non-None when foreign branches add support
84+ # for storing this URL.
85+ self.assertIs(None, self.branch.get_parent())
86+
87+ def test_get_push_location(self):
88+ """Test that getting the push location works, and returns None."""
89+ # TODO: Allow this to be non-None when foreign branches add support
90+ # for storing this URL.
91+ self.assertIs(None, self.branch.get_push_location())
92+
93+ def test_check(self):
94+ """See if a basic check works."""
95+ result = self.branch.check()
96+ self.assertEqual(self.branch, result.branch)
97+
98+ def test_attributes(self):
99+ """Check that various required attributes are present."""
100+ self.assertIsNot(None, getattr(self.branch, "repository", None))
101+ self.assertIsNot(None, getattr(self.branch, "mapping", None))
102+ self.assertIsNot(None, getattr(self.branch, "_format", None))
103+ self.assertIsNot(None, getattr(self.branch, "base", None))
104+
105+ def test__get_nick(self):
106+ """Make sure _get_nick is implemented and returns a string."""
107+ self.assertIsInstance(self.branch._get_nick(local=False), str)
108+ self.assertIsInstance(self.branch._get_nick(local=True), str)
109+
110+ def test_null_revid_revno(self):
111+ """null: should return revno 0."""
112+ self.assertEquals(0, self.branch.revision_id_to_revno(NULL_REVISION))
113+
114+ def test_get_stacked_on_url(self):
115+ """Test that get_stacked_on_url() behaves as expected.
116+
117+ Inter-Format stacking doesn't work yet, so all foreign implementations
118+ should raise UnstackableBranchFormat at the moment.
119+ """
120+ self.assertRaises(UnstackableBranchFormat,
121+ self.branch.get_stacked_on_url)
122+
123+ def test_get_physical_lock_status(self):
124+ self.assertFalse(self.branch.get_physical_lock_status())
125+
126+ def test_last_revision(self):
127+ (revno, revid) = self.branch.last_revision_info()
128+ self.assertIsInstance(revno, int)
129+ self.assertIsInstance(revid, str)
130+ self.assertEquals(revno, self.branch.revision_id_to_revno(revid))
131+ self.assertEquals(revid, self.branch.last_revision())
132+
133+
134+class ForeignBranchFormatTests(object):
135+ """Basic tests for foreign branch format objects."""
136+
137+ def test_initialize(self):
138+ """Test this format is not initializable.
139+
140+ Remote branches may be initializable on their own, but none currently
141+ support living in .bzr/branch.
142+ """
143+ self.assertRaises(NotImplementedError, self.format.initialize, None)
144+
145+ def test_get_format_description_type(self):
146+ self.assertIsInstance(self.format.get_format_description(), str)
147+
148+ def test_network_name(self):
149+ self.assertIsInstance(self.format.network_name(), str)
150+
151+