Merge lp:~jameinel/bzr/2.5-remote-wt-tests-1046697 into lp:bzr/2.5
- 2.5-remote-wt-tests-1046697
- Merge into 2.5
Status: | Merged |
---|---|
Approved by: | John A Meinel |
Approved revision: | no longer in the source branch. |
Merged at revision: | 6509 |
Proposed branch: | lp:~jameinel/bzr/2.5-remote-wt-tests-1046697 |
Merge into: | lp:bzr/2.5 |
Diff against target: |
596 lines (+189/-76) 14 files modified
bzrlib/remote.py (+15/-6) bzrlib/smart/repository.py (+12/-9) bzrlib/tests/per_tree/__init__.py (+18/-4) bzrlib/tests/per_workingtree/__init__.py (+39/-6) bzrlib/tests/per_workingtree/test_commit.py (+3/-2) bzrlib/tests/per_workingtree/test_executable.py (+1/-2) bzrlib/tests/per_workingtree/test_parents.py (+5/-3) bzrlib/tests/per_workingtree/test_remove.py (+1/-1) bzrlib/tests/per_workingtree/test_smart_add.py (+3/-0) bzrlib/tests/per_workingtree/test_views.py (+2/-2) bzrlib/tests/per_workingtree/test_workingtree.py (+24/-29) bzrlib/tests/test_selftest.py (+39/-9) bzrlib/workingtree_4.py (+19/-3) doc/en/release-notes/bzr-2.5.txt (+8/-0) |
To merge this branch: | bzr merge lp:~jameinel/bzr/2.5-remote-wt-tests-1046697 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Richard Wilbur | Approve | ||
Review via email: mp+123061@code.launchpad.net |
Commit message
Add per_workingtree test scenario for a lightweight checkout of a RemoteRepository (bug #1046697) and cleanup all associated fallout.
Description of the change
This branch aggregates most of the branches I proposed today.
It adds a test permutation of a lightweight WT6 checkout of a remote repository.
That resulted in a fair number of tests failing for various reasons.
1) RemoteBranch.
2) RemoteBranch.
3) Repository.
4) Lots of test suite fixups. Quite a few tests
a) assumed that WT.branch was in the same location as WT
b) assumed that make_branch(
c) WorkingTreeForm
I only ran the per_workingtree tests, but that should be enough since that is the only new permutations that were added.
John A Meinel (jameinel) wrote : | # |
sent to pqm by email
John A Meinel (jameinel) wrote : | # |
sent to pqm by email
John A Meinel (jameinel) wrote : | # |
sent to pqm by email
Preview Diff
1 | === modified file 'bzrlib/remote.py' | |||
2 | --- bzrlib/remote.py 2012-01-28 00:56:56 +0000 | |||
3 | +++ bzrlib/remote.py 2012-09-07 10:36:18 +0000 | |||
4 | @@ -3129,7 +3129,8 @@ | |||
5 | 3129 | return a_bzrdir.open_branch(name=name, | 3129 | return a_bzrdir.open_branch(name=name, |
6 | 3130 | ignore_fallbacks=ignore_fallbacks) | 3130 | ignore_fallbacks=ignore_fallbacks) |
7 | 3131 | 3131 | ||
9 | 3132 | def _vfs_initialize(self, a_bzrdir, name, append_revisions_only): | 3132 | def _vfs_initialize(self, a_bzrdir, name, append_revisions_only, |
10 | 3133 | repository=None): | ||
11 | 3133 | # Initialisation when using a local bzrdir object, or a non-vfs init | 3134 | # Initialisation when using a local bzrdir object, or a non-vfs init |
12 | 3134 | # method is not available on the server. | 3135 | # method is not available on the server. |
13 | 3135 | # self._custom_format is always set - the start of initialize ensures | 3136 | # self._custom_format is always set - the start of initialize ensures |
14 | @@ -3137,11 +3138,13 @@ | |||
15 | 3137 | if isinstance(a_bzrdir, RemoteBzrDir): | 3138 | if isinstance(a_bzrdir, RemoteBzrDir): |
16 | 3138 | a_bzrdir._ensure_real() | 3139 | a_bzrdir._ensure_real() |
17 | 3139 | result = self._custom_format.initialize(a_bzrdir._real_bzrdir, | 3140 | result = self._custom_format.initialize(a_bzrdir._real_bzrdir, |
19 | 3140 | name=name, append_revisions_only=append_revisions_only) | 3141 | name=name, append_revisions_only=append_revisions_only, |
20 | 3142 | repository=repository) | ||
21 | 3141 | else: | 3143 | else: |
22 | 3142 | # We assume the bzrdir is parameterised; it may not be. | 3144 | # We assume the bzrdir is parameterised; it may not be. |
23 | 3143 | result = self._custom_format.initialize(a_bzrdir, name=name, | 3145 | result = self._custom_format.initialize(a_bzrdir, name=name, |
25 | 3144 | append_revisions_only=append_revisions_only) | 3146 | append_revisions_only=append_revisions_only, |
26 | 3147 | repository=repository) | ||
27 | 3145 | if (isinstance(a_bzrdir, RemoteBzrDir) and | 3148 | if (isinstance(a_bzrdir, RemoteBzrDir) and |
28 | 3146 | not isinstance(result, RemoteBranch)): | 3149 | not isinstance(result, RemoteBranch)): |
29 | 3147 | result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result, | 3150 | result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result, |
30 | @@ -3164,11 +3167,13 @@ | |||
31 | 3164 | # Being asked to create on a non RemoteBzrDir: | 3167 | # Being asked to create on a non RemoteBzrDir: |
32 | 3165 | if not isinstance(a_bzrdir, RemoteBzrDir): | 3168 | if not isinstance(a_bzrdir, RemoteBzrDir): |
33 | 3166 | return self._vfs_initialize(a_bzrdir, name=name, | 3169 | return self._vfs_initialize(a_bzrdir, name=name, |
35 | 3167 | append_revisions_only=append_revisions_only) | 3170 | append_revisions_only=append_revisions_only, |
36 | 3171 | repository=repository) | ||
37 | 3168 | medium = a_bzrdir._client._medium | 3172 | medium = a_bzrdir._client._medium |
38 | 3169 | if medium._is_remote_before((1, 13)): | 3173 | if medium._is_remote_before((1, 13)): |
39 | 3170 | return self._vfs_initialize(a_bzrdir, name=name, | 3174 | return self._vfs_initialize(a_bzrdir, name=name, |
41 | 3171 | append_revisions_only=append_revisions_only) | 3175 | append_revisions_only=append_revisions_only, |
42 | 3176 | repository=repository) | ||
43 | 3172 | # Creating on a remote bzr dir. | 3177 | # Creating on a remote bzr dir. |
44 | 3173 | # 2) try direct creation via RPC | 3178 | # 2) try direct creation via RPC |
45 | 3174 | path = a_bzrdir._path_for_remote_call(a_bzrdir._client) | 3179 | path = a_bzrdir._path_for_remote_call(a_bzrdir._client) |
46 | @@ -3182,7 +3187,8 @@ | |||
47 | 3182 | # Fallback - use vfs methods | 3187 | # Fallback - use vfs methods |
48 | 3183 | medium._remember_remote_is_before((1, 13)) | 3188 | medium._remember_remote_is_before((1, 13)) |
49 | 3184 | return self._vfs_initialize(a_bzrdir, name=name, | 3189 | return self._vfs_initialize(a_bzrdir, name=name, |
51 | 3185 | append_revisions_only=append_revisions_only) | 3190 | append_revisions_only=append_revisions_only, |
52 | 3191 | repository=repository) | ||
53 | 3186 | if response[0] != 'ok': | 3192 | if response[0] != 'ok': |
54 | 3187 | raise errors.UnexpectedSmartServerResponse(response) | 3193 | raise errors.UnexpectedSmartServerResponse(response) |
55 | 3188 | # Turn the response into a RemoteRepository object. | 3194 | # Turn the response into a RemoteRepository object. |
56 | @@ -3867,6 +3873,9 @@ | |||
57 | 3867 | target, overwrite=overwrite, stop_revision=stop_revision, lossy=lossy, | 3873 | target, overwrite=overwrite, stop_revision=stop_revision, lossy=lossy, |
58 | 3868 | _override_hook_source_branch=self) | 3874 | _override_hook_source_branch=self) |
59 | 3869 | 3875 | ||
60 | 3876 | def peek_lock_mode(self): | ||
61 | 3877 | return self._lock_mode | ||
62 | 3878 | |||
63 | 3870 | def is_locked(self): | 3879 | def is_locked(self): |
64 | 3871 | return self._lock_count >= 1 | 3880 | return self._lock_count >= 1 |
65 | 3872 | 3881 | ||
66 | 3873 | 3882 | ||
67 | === modified file 'bzrlib/smart/repository.py' | |||
68 | --- bzrlib/smart/repository.py 2011-12-19 13:23:58 +0000 | |||
69 | +++ bzrlib/smart/repository.py 2012-09-07 10:36:18 +0000 | |||
70 | @@ -736,15 +736,18 @@ | |||
71 | 736 | self.seed_state() | 736 | self.seed_state() |
72 | 737 | pb = ui.ui_factory.nested_progress_bar() | 737 | pb = ui.ui_factory.nested_progress_bar() |
73 | 738 | rc = self._record_counter | 738 | rc = self._record_counter |
83 | 739 | # Make and consume sub generators, one per substream type: | 739 | try: |
84 | 740 | while self.first_bytes is not None: | 740 | # Make and consume sub generators, one per substream type: |
85 | 741 | substream = NetworkRecordStream(self.iter_substream_bytes()) | 741 | while self.first_bytes is not None: |
86 | 742 | # after substream is fully consumed, self.current_type is set to | 742 | substream = NetworkRecordStream(self.iter_substream_bytes()) |
87 | 743 | # the next type, and self.first_bytes is set to the matching bytes. | 743 | # after substream is fully consumed, self.current_type is set |
88 | 744 | yield self.current_type, wrap_and_count(pb, rc, substream) | 744 | # to the next type, and self.first_bytes is set to the matching |
89 | 745 | if rc: | 745 | # bytes. |
90 | 746 | pb.update('Done', rc.max, rc.max) | 746 | yield self.current_type, wrap_and_count(pb, rc, substream) |
91 | 747 | pb.finished() | 747 | finally: |
92 | 748 | if rc: | ||
93 | 749 | pb.update('Done', rc.max, rc.max) | ||
94 | 750 | pb.finished() | ||
95 | 748 | 751 | ||
96 | 749 | def seed_state(self): | 752 | def seed_state(self): |
97 | 750 | """Prepare the _ByteStreamDecoder to decode from the pack stream.""" | 753 | """Prepare the _ByteStreamDecoder to decode from the pack stream.""" |
98 | 751 | 754 | ||
99 | === modified file 'bzrlib/tests/per_tree/__init__.py' | |||
100 | --- bzrlib/tests/per_tree/__init__.py 2011-06-14 01:26:41 +0000 | |||
101 | +++ bzrlib/tests/per_tree/__init__.py 2012-09-07 10:36:18 +0000 | |||
102 | @@ -29,6 +29,7 @@ | |||
103 | 29 | errors, | 29 | errors, |
104 | 30 | tests, | 30 | tests, |
105 | 31 | transform, | 31 | transform, |
106 | 32 | transport, | ||
107 | 32 | ) | 33 | ) |
108 | 33 | from bzrlib.tests.per_controldir.test_controldir import TestCaseWithControlDir | 34 | from bzrlib.tests.per_controldir.test_controldir import TestCaseWithControlDir |
109 | 34 | from bzrlib.tests.per_workingtree import ( | 35 | from bzrlib.tests.per_workingtree import ( |
110 | @@ -99,11 +100,24 @@ | |||
111 | 99 | class TestCaseWithTree(TestCaseWithControlDir): | 100 | class TestCaseWithTree(TestCaseWithControlDir): |
112 | 100 | 101 | ||
113 | 101 | def make_branch_and_tree(self, relpath): | 102 | def make_branch_and_tree(self, relpath): |
116 | 102 | made_control = self.make_bzrdir(relpath, format= | 103 | bzrdir_format = self.workingtree_format.get_controldir_for_branch() |
117 | 103 | self.workingtree_format._matchingbzrdir) | 104 | made_control = self.make_bzrdir(relpath, format=bzrdir_format) |
118 | 104 | made_control.create_repository() | 105 | made_control.create_repository() |
121 | 105 | made_control.create_branch() | 106 | b = made_control.create_branch() |
122 | 106 | return self.workingtree_format.initialize(made_control) | 107 | if getattr(self, 'repo_is_remote', False): |
123 | 108 | # If the repo is remote, then we just create a local lightweight | ||
124 | 109 | # checkout | ||
125 | 110 | # XXX: This duplicates a lot of Branch.create_checkout, but we know | ||
126 | 111 | # we want a) lightweight, and b) a specific WT format. We also | ||
127 | 112 | # know that nothing should already exist, etc. | ||
128 | 113 | t = transport.get_transport(relpath) | ||
129 | 114 | t.ensure_base() | ||
130 | 115 | wt_dir = bzrdir_format.initialize_on_transport(t) | ||
131 | 116 | branch_ref = wt_dir.set_branch_reference(b) | ||
132 | 117 | wt = wt_dir.create_workingtree(None, from_branch=branch_ref) | ||
133 | 118 | else: | ||
134 | 119 | wt = self.workingtree_format.initialize(made_control) | ||
135 | 120 | return wt | ||
136 | 107 | 121 | ||
137 | 108 | def workingtree_to_test_tree(self, tree): | 122 | def workingtree_to_test_tree(self, tree): |
138 | 109 | return self._workingtree_to_test_tree(self, tree) | 123 | return self._workingtree_to_test_tree(self, tree) |
139 | 110 | 124 | ||
140 | === modified file 'bzrlib/tests/per_workingtree/__init__.py' | |||
141 | --- bzrlib/tests/per_workingtree/__init__.py 2011-09-23 12:32:30 +0000 | |||
142 | +++ bzrlib/tests/per_workingtree/__init__.py 2012-09-07 10:36:18 +0000 | |||
143 | @@ -25,18 +25,37 @@ | |||
144 | 25 | from bzrlib import ( | 25 | from bzrlib import ( |
145 | 26 | branchbuilder, | 26 | branchbuilder, |
146 | 27 | tests, | 27 | tests, |
147 | 28 | transport, | ||
148 | 28 | workingtree, | 29 | workingtree, |
149 | 29 | ) | 30 | ) |
154 | 30 | from bzrlib.tests import per_controldir | 31 | from bzrlib.transport import memory |
155 | 31 | 32 | from bzrlib.tests import ( | |
156 | 32 | 33 | per_controldir, | |
157 | 33 | def make_scenarios(transport_server, transport_readonly_server, formats): | 34 | test_server, |
158 | 35 | ) | ||
159 | 36 | |||
160 | 37 | |||
161 | 38 | def make_scenarios(transport_server, transport_readonly_server, formats, | ||
162 | 39 | remote_server=None, remote_readonly_server=None, | ||
163 | 40 | remote_backing_server=None): | ||
164 | 34 | result = [] | 41 | result = [] |
165 | 35 | for workingtree_format in formats: | 42 | for workingtree_format in formats: |
166 | 36 | result.append((workingtree_format.__class__.__name__, | 43 | result.append((workingtree_format.__class__.__name__, |
167 | 37 | make_scenario(transport_server, | 44 | make_scenario(transport_server, |
168 | 38 | transport_readonly_server, | 45 | transport_readonly_server, |
169 | 39 | workingtree_format))) | 46 | workingtree_format))) |
170 | 47 | default_wt_format = workingtree.format_registry.get_default() | ||
171 | 48 | if remote_server is None: | ||
172 | 49 | remote_server = test_server.SmartTCPServer_for_testing | ||
173 | 50 | if remote_readonly_server is None: | ||
174 | 51 | remote_readonly_server = test_server.ReadonlySmartTCPServer_for_testing | ||
175 | 52 | if remote_backing_server is None: | ||
176 | 53 | remote_backing_server = memory.MemoryServer | ||
177 | 54 | scenario = make_scenario(remote_server, remote_readonly_server, | ||
178 | 55 | default_wt_format) | ||
179 | 56 | scenario['repo_is_remote'] = True; | ||
180 | 57 | scenario['vfs_transport_factory'] = remote_backing_server | ||
181 | 58 | result.append((default_wt_format.__class__.__name__ + ',remote', scenario)) | ||
182 | 40 | return result | 59 | return result |
183 | 41 | 60 | ||
184 | 42 | 61 | ||
185 | @@ -71,8 +90,22 @@ | |||
186 | 71 | def make_branch_and_tree(self, relpath, format=None): | 90 | def make_branch_and_tree(self, relpath, format=None): |
187 | 72 | made_control = self.make_bzrdir(relpath, format=format) | 91 | made_control = self.make_bzrdir(relpath, format=format) |
188 | 73 | made_control.create_repository() | 92 | made_control.create_repository() |
191 | 74 | made_control.create_branch() | 93 | b = made_control.create_branch() |
192 | 75 | return self.workingtree_format.initialize(made_control) | 94 | if getattr(self, 'repo_is_remote', False): |
193 | 95 | # If the repo is remote, then we just create a local lightweight | ||
194 | 96 | # checkout | ||
195 | 97 | # XXX: This duplicates a lot of Branch.create_checkout, but we know | ||
196 | 98 | # we want a) lightweight, and b) a specific WT format. We also | ||
197 | 99 | # know that nothing should already exist, etc. | ||
198 | 100 | t = transport.get_transport(relpath) | ||
199 | 101 | t.ensure_base() | ||
200 | 102 | bzrdir_format = self.workingtree_format.get_controldir_for_branch() | ||
201 | 103 | wt_dir = bzrdir_format.initialize_on_transport(t) | ||
202 | 104 | branch_ref = wt_dir.set_branch_reference(b) | ||
203 | 105 | wt = wt_dir.create_workingtree(None, from_branch=branch_ref) | ||
204 | 106 | else: | ||
205 | 107 | wt = self.workingtree_format.initialize(made_control) | ||
206 | 108 | return wt | ||
207 | 76 | 109 | ||
208 | 77 | def make_branch_builder(self, relpath, format=None): | 110 | def make_branch_builder(self, relpath, format=None): |
209 | 78 | if format is None: | 111 | if format is None: |
210 | 79 | 112 | ||
211 | === modified file 'bzrlib/tests/per_workingtree/test_commit.py' | |||
212 | --- bzrlib/tests/per_workingtree/test_commit.py 2012-01-25 21:13:15 +0000 | |||
213 | +++ bzrlib/tests/per_workingtree/test_commit.py 2012-09-07 10:36:18 +0000 | |||
214 | @@ -26,6 +26,7 @@ | |||
215 | 26 | osutils, | 26 | osutils, |
216 | 27 | revision as _mod_revision, | 27 | revision as _mod_revision, |
217 | 28 | tests, | 28 | tests, |
218 | 29 | transport as _mod_transport, | ||
219 | 29 | ui, | 30 | ui, |
220 | 30 | ) | 31 | ) |
221 | 31 | from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree | 32 | from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree |
222 | @@ -316,7 +317,7 @@ | |||
223 | 316 | wt.lock_write() | 317 | wt.lock_write() |
224 | 317 | self.build_tree(['a', 'b/', 'b/c', 'd']) | 318 | self.build_tree(['a', 'b/', 'b/c', 'd']) |
225 | 318 | wt.add(['a', 'b', 'b/c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id']) | 319 | wt.add(['a', 'b', 'b/c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id']) |
227 | 319 | this_dir = self.get_transport() | 320 | this_dir = wt.bzrdir.root_transport |
228 | 320 | this_dir.delete_tree('b') | 321 | this_dir.delete_tree('b') |
229 | 321 | this_dir.delete('d') | 322 | this_dir.delete('d') |
230 | 322 | # now we have a tree with a through d in the inventory, but only | 323 | # now we have a tree with a through d in the inventory, but only |
231 | @@ -352,7 +353,7 @@ | |||
232 | 352 | wt.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id']) | 353 | wt.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id']) |
233 | 353 | wt.commit('first') | 354 | wt.commit('first') |
234 | 354 | wt.remove('b/c') | 355 | wt.remove('b/c') |
236 | 355 | this_dir = self.get_transport() | 356 | this_dir = wt.bzrdir.root_transport |
237 | 356 | this_dir.delete_tree('b') | 357 | this_dir.delete_tree('b') |
238 | 357 | wt.lock_write() | 358 | wt.lock_write() |
239 | 358 | wt.commit('commit deleted rename') | 359 | wt.commit('commit deleted rename') |
240 | 359 | 360 | ||
241 | === modified file 'bzrlib/tests/per_workingtree/test_executable.py' | |||
242 | --- bzrlib/tests/per_workingtree/test_executable.py 2011-12-19 16:59:14 +0000 | |||
243 | +++ bzrlib/tests/per_workingtree/test_executable.py 2012-09-07 10:36:18 +0000 | |||
244 | @@ -71,8 +71,7 @@ | |||
245 | 71 | self.wt.commit('adding a,b', rev_id='r1') | 71 | self.wt.commit('adding a,b', rev_id='r1') |
246 | 72 | # Now make sure that 'bzr branch' also preserves the | 72 | # Now make sure that 'bzr branch' also preserves the |
247 | 73 | # executable bit | 73 | # executable bit |
250 | 74 | # TODO: Maybe this should be a blackbox test | 74 | dir2 = self.wt.branch.bzrdir.sprout('b2', revision_id='r1') |
249 | 75 | dir2 = self.wt.branch.bzrdir.clone('b2', revision_id='r1') | ||
251 | 76 | wt2 = dir2.open_workingtree() | 75 | wt2 = dir2.open_workingtree() |
252 | 77 | self.assertEqual(['r1'], wt2.get_parent_ids()) | 76 | self.assertEqual(['r1'], wt2.get_parent_ids()) |
253 | 78 | self.assertEqual('r1', wt2.branch.last_revision()) | 77 | self.assertEqual('r1', wt2.branch.last_revision()) |
254 | 79 | 78 | ||
255 | === modified file 'bzrlib/tests/per_workingtree/test_parents.py' | |||
256 | --- bzrlib/tests/per_workingtree/test_parents.py 2011-06-14 01:26:41 +0000 | |||
257 | +++ bzrlib/tests/per_workingtree/test_parents.py 2012-09-07 10:36:18 +0000 | |||
258 | @@ -21,9 +21,7 @@ | |||
259 | 21 | 21 | ||
260 | 22 | from bzrlib import ( | 22 | from bzrlib import ( |
261 | 23 | errors, | 23 | errors, |
262 | 24 | osutils, | ||
263 | 25 | revision as _mod_revision, | 24 | revision as _mod_revision, |
264 | 26 | tests, | ||
265 | 27 | ) | 25 | ) |
266 | 28 | from bzrlib.inventory import ( | 26 | from bzrlib.inventory import ( |
267 | 29 | Inventory, | 27 | Inventory, |
268 | @@ -475,7 +473,11 @@ | |||
269 | 475 | # large hammer, this is a particularly sensitive area of code, so the | 473 | # large hammer, this is a particularly sensitive area of code, so the |
270 | 476 | # extra assurance is well worth it. | 474 | # extra assurance is well worth it. |
271 | 477 | tree._validate() | 475 | tree._validate() |
273 | 478 | osutils.rmtree('tree') | 476 | # If tree.branch is remote |
274 | 477 | if tree.user_url != tree.branch.user_url: | ||
275 | 478 | # We have a lightweight checkout, delete both locations | ||
276 | 479 | tree.branch.bzrdir.root_transport.delete_tree('.') | ||
277 | 480 | tree.bzrdir.root_transport.delete_tree('.') | ||
278 | 479 | 481 | ||
279 | 480 | def test_no_parents_just_root(self): | 482 | def test_no_parents_just_root(self): |
280 | 481 | """Test doing an empty commit - no parent, set a root only.""" | 483 | """Test doing an empty commit - no parent, set a root only.""" |
281 | 482 | 484 | ||
282 | === modified file 'bzrlib/tests/per_workingtree/test_remove.py' | |||
283 | --- bzrlib/tests/per_workingtree/test_remove.py 2011-05-13 12:51:05 +0000 | |||
284 | +++ bzrlib/tests/per_workingtree/test_remove.py 2012-09-07 10:36:18 +0000 | |||
285 | @@ -173,7 +173,7 @@ | |||
286 | 173 | """Removing a absent directory succeeds without corruption (#150438).""" | 173 | """Removing a absent directory succeeds without corruption (#150438).""" |
287 | 174 | paths = ['a/', 'a/b'] | 174 | paths = ['a/', 'a/b'] |
288 | 175 | tree = self.get_committed_tree(paths) | 175 | tree = self.get_committed_tree(paths) |
290 | 176 | self.get_transport('.').delete_tree('a') | 176 | tree.bzrdir.root_transport.delete_tree('a') |
291 | 177 | tree.remove(['a']) | 177 | tree.remove(['a']) |
292 | 178 | self.assertRemovedAndDeleted('b') | 178 | self.assertRemovedAndDeleted('b') |
293 | 179 | tree._validate() | 179 | tree._validate() |
294 | 180 | 180 | ||
295 | === modified file 'bzrlib/tests/per_workingtree/test_smart_add.py' | |||
296 | --- bzrlib/tests/per_workingtree/test_smart_add.py 2011-09-06 09:51:45 +0000 | |||
297 | +++ bzrlib/tests/per_workingtree/test_smart_add.py 2012-09-07 10:36:18 +0000 | |||
298 | @@ -135,6 +135,9 @@ | |||
299 | 135 | 135 | ||
300 | 136 | self.build_tree(build_paths) | 136 | self.build_tree(build_paths) |
301 | 137 | wt = self.make_branch_and_tree('.') | 137 | wt = self.make_branch_and_tree('.') |
302 | 138 | if wt.user_url != wt.branch.user_url: | ||
303 | 139 | # Lightweight checkout, make sure we have a repo location. | ||
304 | 140 | wt.branch.bzrdir.root_transport.mkdir('original') | ||
305 | 138 | child_tree = self.make_branch_and_tree('original/child') | 141 | child_tree = self.make_branch_and_tree('original/child') |
306 | 139 | wt.smart_add((".",)) | 142 | wt.smart_add((".",)) |
307 | 140 | for path in paths: | 143 | for path in paths: |
308 | 141 | 144 | ||
309 | === modified file 'bzrlib/tests/per_workingtree/test_views.py' | |||
310 | --- bzrlib/tests/per_workingtree/test_views.py 2009-07-10 07:14:02 +0000 | |||
311 | +++ bzrlib/tests/per_workingtree/test_views.py 2012-09-07 10:36:18 +0000 | |||
312 | @@ -22,7 +22,7 @@ | |||
313 | 22 | 22 | ||
314 | 23 | 23 | ||
315 | 24 | from bzrlib import views, errors | 24 | from bzrlib import views, errors |
317 | 25 | from bzrlib.tests import TestSkipped | 25 | from bzrlib.tests import TestNotApplicable, TestSkipped |
318 | 26 | from bzrlib.workingtree import WorkingTree | 26 | from bzrlib.workingtree import WorkingTree |
319 | 27 | 27 | ||
320 | 28 | from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree | 28 | from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree |
321 | @@ -39,7 +39,7 @@ | |||
322 | 39 | raise TestSkipped("format %s doesn't declare whether it " | 39 | raise TestSkipped("format %s doesn't declare whether it " |
323 | 40 | "supports views, assuming not" % fmt) | 40 | "supports views, assuming not" % fmt) |
324 | 41 | if not f(): | 41 | if not f(): |
326 | 42 | raise TestSkipped("format %s doesn't support views" % fmt) | 42 | raise TestNotApplicable("format %s doesn't support views" % fmt) |
327 | 43 | TestCaseWithWorkingTree.setUp(self) | 43 | TestCaseWithWorkingTree.setUp(self) |
328 | 44 | 44 | ||
329 | 45 | def test_views_initially_empty(self): | 45 | def test_views_initially_empty(self): |
330 | 46 | 46 | ||
331 | === modified file 'bzrlib/tests/per_workingtree/test_workingtree.py' | |||
332 | --- bzrlib/tests/per_workingtree/test_workingtree.py 2012-01-25 21:13:15 +0000 | |||
333 | +++ bzrlib/tests/per_workingtree/test_workingtree.py 2012-09-07 10:36:18 +0000 | |||
334 | @@ -57,10 +57,20 @@ | |||
335 | 57 | 57 | ||
336 | 58 | class TestWorkingTree(TestCaseWithWorkingTree): | 58 | class TestWorkingTree(TestCaseWithWorkingTree): |
337 | 59 | 59 | ||
338 | 60 | def requireBranchReference(self): | ||
339 | 61 | test_branch = self.make_branch('test-branch') | ||
340 | 62 | try: | ||
341 | 63 | # if there is a working tree now, this is not supported. | ||
342 | 64 | test_branch.bzrdir.open_workingtree() | ||
343 | 65 | raise TestNotApplicable("only on trees that can be separate" | ||
344 | 66 | " from their branch.") | ||
345 | 67 | except (errors.NoWorkingTree, errors.NotLocalUrl): | ||
346 | 68 | pass | ||
347 | 69 | |||
348 | 60 | def test_branch_builder(self): | 70 | def test_branch_builder(self): |
349 | 61 | # Just a smoke test that we get a branch at the specified relpath | 71 | # Just a smoke test that we get a branch at the specified relpath |
350 | 62 | builder = self.make_branch_builder('foobar') | 72 | builder = self.make_branch_builder('foobar') |
352 | 63 | br = branch.Branch.open('foobar') | 73 | br = branch.Branch.open(self.get_url('foobar')) |
353 | 64 | 74 | ||
354 | 65 | def test_list_files(self): | 75 | def test_list_files(self): |
355 | 66 | tree = self.make_branch_and_tree('.') | 76 | tree = self.make_branch_and_tree('.') |
356 | @@ -122,8 +132,10 @@ | |||
357 | 122 | result[0][:4]) | 132 | result[0][:4]) |
358 | 123 | 133 | ||
359 | 124 | def test_open_containing(self): | 134 | def test_open_containing(self): |
362 | 125 | branch = self.make_branch_and_tree('.').branch | 135 | local_wt = self.make_branch_and_tree('.') |
363 | 126 | local_base = urlutils.local_path_from_url(branch.base) | 136 | local_url = local_wt.bzrdir.root_transport.base |
364 | 137 | local_base = urlutils.local_path_from_url(local_url) | ||
365 | 138 | del local_wt | ||
366 | 127 | 139 | ||
367 | 128 | # Empty opens '.' | 140 | # Empty opens '.' |
368 | 129 | wt, relpath = WorkingTree.open_containing() | 141 | wt, relpath = WorkingTree.open_containing() |
369 | @@ -161,6 +173,7 @@ | |||
370 | 161 | 173 | ||
371 | 162 | def test_lock_locks_branch(self): | 174 | def test_lock_locks_branch(self): |
372 | 163 | tree = self.make_branch_and_tree('.') | 175 | tree = self.make_branch_and_tree('.') |
373 | 176 | self.assertEqual(None, tree.branch.peek_lock_mode()) | ||
374 | 164 | tree.lock_read() | 177 | tree.lock_read() |
375 | 165 | self.assertEqual('r', tree.branch.peek_lock_mode()) | 178 | self.assertEqual('r', tree.branch.peek_lock_mode()) |
376 | 166 | tree.unlock() | 179 | tree.unlock() |
377 | @@ -362,14 +375,8 @@ | |||
378 | 362 | # that formats where initialising a branch does not initialise a | 375 | # that formats where initialising a branch does not initialise a |
379 | 363 | # tree - and thus have separable entities - support skewing the | 376 | # tree - and thus have separable entities - support skewing the |
380 | 364 | # two things. | 377 | # two things. |
389 | 365 | branch = self.make_branch('tree') | 378 | self.requireBranchReference() |
390 | 366 | try: | 379 | wt = self.make_branch_and_tree('tree') |
383 | 367 | # if there is a working tree now, this is not supported. | ||
384 | 368 | branch.bzrdir.open_workingtree() | ||
385 | 369 | return | ||
386 | 370 | except errors.NoWorkingTree: | ||
387 | 371 | pass | ||
388 | 372 | wt = branch.bzrdir.create_workingtree() | ||
391 | 373 | wt.commit('A', allow_pointless=True, rev_id='A') | 380 | wt.commit('A', allow_pointless=True, rev_id='A') |
392 | 374 | wt.set_last_revision(None) | 381 | wt.set_last_revision(None) |
393 | 375 | self.assertEqual([], wt.get_parent_ids()) | 382 | self.assertEqual([], wt.get_parent_ids()) |
394 | @@ -478,19 +485,13 @@ | |||
395 | 478 | # that formats where initialising a branch does not initialise a | 485 | # that formats where initialising a branch does not initialise a |
396 | 479 | # tree - and thus have separable entities - support skewing the | 486 | # tree - and thus have separable entities - support skewing the |
397 | 480 | # two things. | 487 | # two things. |
406 | 481 | main_branch = self.make_branch('tree') | 488 | self.requireBranchReference() |
407 | 482 | try: | 489 | wt = self.make_branch_and_tree('tree') |
400 | 483 | # if there is a working tree now, this is not supported. | ||
401 | 484 | main_branch.bzrdir.open_workingtree() | ||
402 | 485 | return | ||
403 | 486 | except errors.NoWorkingTree: | ||
404 | 487 | pass | ||
405 | 488 | wt = main_branch.bzrdir.create_workingtree() | ||
408 | 489 | # create an out of date working tree by making a checkout in this | 490 | # create an out of date working tree by making a checkout in this |
409 | 490 | # current format | 491 | # current format |
410 | 491 | self.build_tree(['checkout/', 'tree/file']) | 492 | self.build_tree(['checkout/', 'tree/file']) |
411 | 492 | checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout') | 493 | checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout') |
413 | 493 | checkout.set_branch_reference(main_branch) | 494 | checkout.set_branch_reference(wt.branch) |
414 | 494 | old_tree = self.workingtree_format.initialize(checkout) | 495 | old_tree = self.workingtree_format.initialize(checkout) |
415 | 495 | # now commit to 'tree' | 496 | # now commit to 'tree' |
416 | 496 | wt.add('file') | 497 | wt.add('file') |
417 | @@ -545,19 +546,13 @@ | |||
418 | 545 | # that formats where initialising a branch does not initialise a | 546 | # that formats where initialising a branch does not initialise a |
419 | 546 | # tree - and thus have separable entities - support skewing the | 547 | # tree - and thus have separable entities - support skewing the |
420 | 547 | # two things. | 548 | # two things. |
429 | 548 | main_branch = self.make_branch('tree') | 549 | self.requireBranchReference() |
430 | 549 | try: | 550 | wt = self.make_branch_and_tree('tree') |
423 | 550 | # if there is a working tree now, this is not supported. | ||
424 | 551 | main_branch.bzrdir.open_workingtree() | ||
425 | 552 | return | ||
426 | 553 | except errors.NoWorkingTree: | ||
427 | 554 | pass | ||
428 | 555 | wt = main_branch.bzrdir.create_workingtree() | ||
431 | 556 | # create an out of date working tree by making a checkout in this | 551 | # create an out of date working tree by making a checkout in this |
432 | 557 | # current format | 552 | # current format |
433 | 558 | self.build_tree(['checkout/', 'tree/file']) | 553 | self.build_tree(['checkout/', 'tree/file']) |
434 | 559 | checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout') | 554 | checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout') |
436 | 560 | checkout.set_branch_reference(main_branch) | 555 | checkout.set_branch_reference(wt.branch) |
437 | 561 | old_tree = self.workingtree_format.initialize(checkout) | 556 | old_tree = self.workingtree_format.initialize(checkout) |
438 | 562 | # now commit to 'tree' | 557 | # now commit to 'tree' |
439 | 563 | wt.add('file') | 558 | wt.add('file') |
440 | 564 | 559 | ||
441 | === modified file 'bzrlib/tests/test_selftest.py' | |||
442 | --- bzrlib/tests/test_selftest.py 2011-11-08 17:07:23 +0000 | |||
443 | +++ bzrlib/tests/test_selftest.py 2012-09-07 10:36:18 +0000 | |||
444 | @@ -334,8 +334,11 @@ | |||
445 | 334 | server1 = "a" | 334 | server1 = "a" |
446 | 335 | server2 = "b" | 335 | server2 = "b" |
447 | 336 | formats = [workingtree_4.WorkingTreeFormat4(), | 336 | formats = [workingtree_4.WorkingTreeFormat4(), |
450 | 337 | workingtree_3.WorkingTreeFormat3(),] | 337 | workingtree_3.WorkingTreeFormat3(), |
451 | 338 | scenarios = make_scenarios(server1, server2, formats) | 338 | workingtree_4.WorkingTreeFormat6()] |
452 | 339 | scenarios = make_scenarios(server1, server2, formats, | ||
453 | 340 | remote_server='c', remote_readonly_server='d', | ||
454 | 341 | remote_backing_server='e') | ||
455 | 339 | self.assertEqual([ | 342 | self.assertEqual([ |
456 | 340 | ('WorkingTreeFormat4', | 343 | ('WorkingTreeFormat4', |
457 | 341 | {'bzrdir_format': formats[0]._matchingbzrdir, | 344 | {'bzrdir_format': formats[0]._matchingbzrdir, |
458 | @@ -346,19 +349,33 @@ | |||
459 | 346 | {'bzrdir_format': formats[1]._matchingbzrdir, | 349 | {'bzrdir_format': formats[1]._matchingbzrdir, |
460 | 347 | 'transport_readonly_server': 'b', | 350 | 'transport_readonly_server': 'b', |
461 | 348 | 'transport_server': 'a', | 351 | 'transport_server': 'a', |
464 | 349 | 'workingtree_format': formats[1]})], | 352 | 'workingtree_format': formats[1]}), |
465 | 350 | scenarios) | 353 | ('WorkingTreeFormat6', |
466 | 354 | {'bzrdir_format': formats[2]._matchingbzrdir, | ||
467 | 355 | 'transport_readonly_server': 'b', | ||
468 | 356 | 'transport_server': 'a', | ||
469 | 357 | 'workingtree_format': formats[2]}), | ||
470 | 358 | ('WorkingTreeFormat6,remote', | ||
471 | 359 | {'bzrdir_format': formats[2]._matchingbzrdir, | ||
472 | 360 | 'repo_is_remote': True, | ||
473 | 361 | 'transport_readonly_server': 'd', | ||
474 | 362 | 'transport_server': 'c', | ||
475 | 363 | 'vfs_transport_factory': 'e', | ||
476 | 364 | 'workingtree_format': formats[2]}), | ||
477 | 365 | ], scenarios) | ||
478 | 351 | 366 | ||
479 | 352 | 367 | ||
480 | 353 | class TestTreeScenarios(tests.TestCase): | 368 | class TestTreeScenarios(tests.TestCase): |
481 | 354 | 369 | ||
482 | 355 | def test_scenarios(self): | 370 | def test_scenarios(self): |
483 | 356 | # the tree implementation scenario generator is meant to setup one | 371 | # the tree implementation scenario generator is meant to setup one |
485 | 357 | # instance for each working tree format, and one additional instance | 372 | # instance for each working tree format, one additional instance |
486 | 358 | # that will use the default wt format, but create a revision tree for | 373 | # that will use the default wt format, but create a revision tree for |
490 | 359 | # the tests. this means that the wt ones should have the | 374 | # the tests, and one more that uses the default wt format as a |
491 | 360 | # workingtree_to_test_tree attribute set to 'return_parameter' and the | 375 | # lightweight checkout of a remote repository. This means that the wt |
492 | 361 | # revision one set to revision_tree_from_workingtree. | 376 | # ones should have the workingtree_to_test_tree attribute set to |
493 | 377 | # 'return_parameter' and the revision one set to | ||
494 | 378 | # revision_tree_from_workingtree. | ||
495 | 362 | 379 | ||
496 | 363 | from bzrlib.tests.per_tree import ( | 380 | from bzrlib.tests.per_tree import ( |
497 | 364 | _dirstate_tree_from_workingtree, | 381 | _dirstate_tree_from_workingtree, |
498 | @@ -370,13 +387,17 @@ | |||
499 | 370 | ) | 387 | ) |
500 | 371 | server1 = "a" | 388 | server1 = "a" |
501 | 372 | server2 = "b" | 389 | server2 = "b" |
502 | 390 | smart_server = test_server.SmartTCPServer_for_testing | ||
503 | 391 | smart_readonly_server = test_server.ReadonlySmartTCPServer_for_testing | ||
504 | 392 | mem_server = memory.MemoryServer | ||
505 | 373 | formats = [workingtree_4.WorkingTreeFormat4(), | 393 | formats = [workingtree_4.WorkingTreeFormat4(), |
506 | 374 | workingtree_3.WorkingTreeFormat3(),] | 394 | workingtree_3.WorkingTreeFormat3(),] |
507 | 375 | scenarios = make_scenarios(server1, server2, formats) | 395 | scenarios = make_scenarios(server1, server2, formats) |
509 | 376 | self.assertEqual(7, len(scenarios)) | 396 | self.assertEqual(8, len(scenarios)) |
510 | 377 | default_wt_format = workingtree.format_registry.get_default() | 397 | default_wt_format = workingtree.format_registry.get_default() |
511 | 378 | wt4_format = workingtree_4.WorkingTreeFormat4() | 398 | wt4_format = workingtree_4.WorkingTreeFormat4() |
512 | 379 | wt5_format = workingtree_4.WorkingTreeFormat5() | 399 | wt5_format = workingtree_4.WorkingTreeFormat5() |
513 | 400 | wt6_format = workingtree_4.WorkingTreeFormat6() | ||
514 | 380 | expected_scenarios = [ | 401 | expected_scenarios = [ |
515 | 381 | ('WorkingTreeFormat4', | 402 | ('WorkingTreeFormat4', |
516 | 382 | {'bzrdir_format': formats[0]._matchingbzrdir, | 403 | {'bzrdir_format': formats[0]._matchingbzrdir, |
517 | @@ -392,6 +413,15 @@ | |||
518 | 392 | 'workingtree_format': formats[1], | 413 | 'workingtree_format': formats[1], |
519 | 393 | '_workingtree_to_test_tree': return_parameter, | 414 | '_workingtree_to_test_tree': return_parameter, |
520 | 394 | }), | 415 | }), |
521 | 416 | ('WorkingTreeFormat6,remote', | ||
522 | 417 | {'bzrdir_format': wt6_format._matchingbzrdir, | ||
523 | 418 | 'repo_is_remote': True, | ||
524 | 419 | 'transport_readonly_server': smart_readonly_server, | ||
525 | 420 | 'transport_server': smart_server, | ||
526 | 421 | 'vfs_transport_factory': mem_server, | ||
527 | 422 | 'workingtree_format': wt6_format, | ||
528 | 423 | '_workingtree_to_test_tree': return_parameter, | ||
529 | 424 | }), | ||
530 | 395 | ('RevisionTree', | 425 | ('RevisionTree', |
531 | 396 | {'_workingtree_to_test_tree': revision_tree_from_workingtree, | 426 | {'_workingtree_to_test_tree': revision_tree_from_workingtree, |
532 | 397 | 'bzrdir_format': default_wt_format._matchingbzrdir, | 427 | 'bzrdir_format': default_wt_format._matchingbzrdir, |
533 | 398 | 428 | ||
534 | === modified file 'bzrlib/workingtree_4.py' | |||
535 | --- bzrlib/workingtree_4.py 2012-01-06 14:09:04 +0000 | |||
536 | +++ bzrlib/workingtree_4.py 2012-09-07 10:36:18 +0000 | |||
537 | @@ -1,4 +1,4 @@ | |||
539 | 1 | # Copyright (C) 2007-2011 Canonical Ltd | 1 | # Copyright (C) 2007-2012 Canonical Ltd |
540 | 2 | # | 2 | # |
541 | 3 | # This program is free software; you can redistribute it and/or modify | 3 | # This program is free software; you can redistribute it and/or modify |
542 | 4 | # it under the terms of the GNU General Public License as published by | 4 | # it under the terms of the GNU General Public License as published by |
543 | @@ -1677,6 +1677,12 @@ | |||
544 | 1677 | def supports_views(self): | 1677 | def supports_views(self): |
545 | 1678 | return True | 1678 | return True |
546 | 1679 | 1679 | ||
547 | 1680 | def _get_matchingbzrdir(self): | ||
548 | 1681 | """Overrideable method to get a bzrdir for testing.""" | ||
549 | 1682 | # We use 'development-subtree' instead of '2a', because we have a | ||
550 | 1683 | # few tests that want to test tree references | ||
551 | 1684 | return bzrdir.format_registry.make_bzrdir('development-subtree') | ||
552 | 1685 | |||
553 | 1680 | 1686 | ||
554 | 1681 | class DirStateRevisionTree(InventoryTree): | 1687 | class DirStateRevisionTree(InventoryTree): |
555 | 1682 | """A revision tree pulling the inventory from a dirstate. | 1688 | """A revision tree pulling the inventory from a dirstate. |
556 | @@ -1882,8 +1888,18 @@ | |||
557 | 1882 | return self.inventory[file_id].text_size | 1888 | return self.inventory[file_id].text_size |
558 | 1883 | 1889 | ||
559 | 1884 | def get_file_text(self, file_id, path=None): | 1890 | def get_file_text(self, file_id, path=None): |
562 | 1885 | _, content = list(self.iter_files_bytes([(file_id, None)]))[0] | 1891 | content = None |
563 | 1886 | return ''.join(content) | 1892 | for _, content_iter in self.iter_files_bytes([(file_id, None)]): |
564 | 1893 | if content is not None: | ||
565 | 1894 | raise AssertionError('iter_files_bytes returned' | ||
566 | 1895 | ' too many entries') | ||
567 | 1896 | # For each entry returned by iter_files_bytes, we must consume the | ||
568 | 1897 | # content_iter before we step the files iterator. | ||
569 | 1898 | content = ''.join(content_iter) | ||
570 | 1899 | if content is None: | ||
571 | 1900 | raise AssertionError('iter_files_bytes did not return' | ||
572 | 1901 | ' the requested data') | ||
573 | 1902 | return content | ||
574 | 1887 | 1903 | ||
575 | 1888 | def get_reference_revision(self, file_id, path=None): | 1904 | def get_reference_revision(self, file_id, path=None): |
576 | 1889 | return self.inventory[file_id].reference_revision | 1905 | return self.inventory[file_id].reference_revision |
577 | 1890 | 1906 | ||
578 | === modified file 'doc/en/release-notes/bzr-2.5.txt' | |||
579 | --- doc/en/release-notes/bzr-2.5.txt 2012-08-01 08:51:57 +0000 | |||
580 | +++ doc/en/release-notes/bzr-2.5.txt 2012-09-07 10:36:18 +0000 | |||
581 | @@ -35,8 +35,16 @@ | |||
582 | 35 | * ``bzr config`` properly handles aliases and references in the | 35 | * ``bzr config`` properly handles aliases and references in the |
583 | 36 | ``--directory`` parameter (Vincent Ladeuil, Wouter van Heyst, #947049) | 36 | ``--directory`` parameter (Vincent Ladeuil, Wouter van Heyst, #947049) |
584 | 37 | 37 | ||
585 | 38 | * Lightweight checkouts of remote repositories had a bug with how they | ||
586 | 39 | extracted texts from the repository. (Just an ordering constraint on how | ||
587 | 40 | they consumed the stream.) (John Arbash Meinel, #1046284) | ||
588 | 41 | |||
589 | 38 | * Revert use of --no-tty when gpg signing commits. (Jelmer Vernooij, #1014570) | 42 | * Revert use of --no-tty when gpg signing commits. (Jelmer Vernooij, #1014570) |
590 | 39 | 43 | ||
591 | 44 | * Some small bug fixes wrt lightweight checkouts and remote repositories. | ||
592 | 45 | A test permutation was added that runs all working tree tests against a | ||
593 | 46 | lightweight checkout. (John Arbash Meinel, #1046697) | ||
594 | 47 | |||
595 | 40 | Documentation | 48 | Documentation |
596 | 41 | ************* | 49 | ************* |
597 | 42 | 50 |
Lots of good fixes for working trees and tests. This looks like good stuff for the baseline. +1
Interesting behaviour from .iter_files_bytes() in get_file_text(): yielding empty results until the last result which contains the full contents of the file.
Nice cleanup on the progress bars.