/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1
# Copyright (C) 2005-2013, 2016 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
16
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
17
from cStringIO import StringIO
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
18
import os
6206.1.9 by Vincent Ladeuil
Simpler fix for test_smart_server_connection_reset re-using more of the existing test server infrastructure.
19
import SocketServer
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
20
import sys
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
21
1910.2.64 by Aaron Bentley
Changes from review
22
from bzrlib import (
1996.3.20 by John Arbash Meinel
[merge] bzr.dev 2063
23
    bzrdir,
4241.14.13 by Vincent Ladeuil
Some more cleanup.
24
    diff,
1996.3.20 by John Arbash Meinel
[merge] bzr.dev 2063
25
    errors,
26
    inventory,
4241.14.13 by Vincent Ladeuil
Some more cleanup.
27
    merge,
3638.3.2 by Vincent Ladeuil
Fix all calls to tempfile.mkdtemp to osutils.mkdtemp.
28
    osutils,
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
29
    revision as _mod_revision,
4241.14.13 by Vincent Ladeuil
Some more cleanup.
30
    tests,
1910.2.64 by Aaron Bentley
Changes from review
31
    treebuilder,
32
    )
3251.4.11 by Aaron Bentley
Fix wrong local lookups
33
from bzrlib.bundle import read_mergeable_from_url
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
34
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
1793.2.3 by Aaron Bentley
Rename read_bundle.py to bundle_data.py
35
from bzrlib.bundle.bundle_data import BundleTree
3251.4.11 by Aaron Bentley
Fix wrong local lookups
36
from bzrlib.directory_service import directories
2520.5.1 by Aaron Bentley
Test installing revisions with subtrees
37
from bzrlib.bundle.serializer import write_bundle, read_bundle, v09, v4
1910.2.49 by Aaron Bentley
Ensure that 0.8 bundles aren't used with KnitRepository2
38
from bzrlib.bundle.serializer.v08 import BundleSerializerV08
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
39
from bzrlib.bundle.serializer.v09 import BundleSerializerV09
2520.4.72 by Aaron Bentley
Rename format to 4alpha
40
from bzrlib.bundle.serializer.v4 import BundleSerializerV4
2241.1.5 by Martin Pool
Move KnitFormat2 into repofmt
41
from bzrlib.repofmt import knitrepo
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
42
from bzrlib.tests import (
6206.1.9 by Vincent Ladeuil
Simpler fix for test_smart_server_connection_reset re-using more of the existing test server infrastructure.
43
    features,
44
    test_commit,
3251.4.11 by Aaron Bentley
Fix wrong local lookups
45
    test_read_bundle,
6206.1.9 by Vincent Ladeuil
Simpler fix for test_smart_server_connection_reset re-using more of the existing test server infrastructure.
46
    test_server,
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
47
    )
1185.82.66 by Aaron Bentley
Handle new executable files
48
from bzrlib.transform import TreeTransform
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
49
1185.82.90 by Aaron Bentley
Reorganized test suite
50
4543.2.9 by John Arbash Meinel
Down to 2 failing tests.
51
def get_text(vf, key):
52
    """Get the fulltext for a given revision id that is present in the vf"""
53
    stream = vf.get_record_stream([key], 'unordered', True)
54
    record = stream.next()
55
    return record.get_bytes_as('fulltext')
56
57
58
def get_inventory_text(repo, revision_id):
59
    """Get the fulltext for the inventory at revision id"""
60
    repo.lock_read()
61
    try:
62
        return get_text(repo.inventories, (revision_id,))
63
    finally:
64
        repo.unlock()
65
66
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
67
class MockTree(object):
5837.2.5 by Jelmer Vernooij
Fix two warnings.
68
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
69
    def __init__(self):
1731.1.4 by Aaron Bentley
merge from bzr.dev
70
        from bzrlib.inventory import InventoryDirectory, ROOT_ID
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
71
        object.__init__(self)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
72
        self.paths = {ROOT_ID: ""}
73
        self.ids = {"": ROOT_ID}
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
74
        self.contents = {}
1731.1.4 by Aaron Bentley
merge from bzr.dev
75
        self.root = InventoryDirectory(ROOT_ID, '', None)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
76
77
    inventory = property(lambda x:x)
6405.2.9 by Jelmer Vernooij
More test fixes.
78
    root_inventory = property(lambda x:x)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
79
6405.2.10 by Jelmer Vernooij
Fix more tests.
80
    def get_root_id(self):
81
        return self.root.file_id
82
5837.2.5 by Jelmer Vernooij
Fix two warnings.
83
    def all_file_ids(self):
84
        return set(self.paths.keys())
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
85
6405.2.9 by Jelmer Vernooij
More test fixes.
86
    def is_executable(self, file_id):
6445.2.6 by Jelmer Vernooij
Review feedback.
87
        # Not all the files are executable.
6405.2.9 by Jelmer Vernooij
More test fixes.
88
        return False
89
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
90
    def __getitem__(self, file_id):
91
        if file_id == self.root.file_id:
92
            return self.root
93
        else:
94
            return self.make_entry(file_id, self.paths[file_id])
95
96
    def parent_id(self, file_id):
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
97
        parent_dir = os.path.dirname(self.paths[file_id])
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
98
        if parent_dir == "":
99
            return None
100
        return self.ids[parent_dir]
101
102
    def iter_entries(self):
103
        for path, file_id in self.ids.iteritems():
104
            yield path, self[file_id]
105
6405.2.10 by Jelmer Vernooij
Fix more tests.
106
    def kind(self, file_id):
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
107
        if file_id in self.contents:
108
            kind = 'file'
109
        else:
110
            kind = 'directory'
111
        return kind
112
113
    def make_entry(self, file_id, path):
6468.2.8 by Jelmer Vernooij
Fix remaining test.
114
        from bzrlib.inventory import (InventoryFile , InventoryDirectory,
115
            InventoryLink)
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
116
        name = os.path.basename(path)
6405.2.10 by Jelmer Vernooij
Fix more tests.
117
        kind = self.kind(file_id)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
118
        parent_id = self.parent_id(file_id)
119
        text_sha_1, text_size = self.contents_stats(file_id)
0.5.119 by John Arbash Meinel
Recreated the factory. We really need InventoryEntry.create()
120
        if kind == 'directory':
121
            ie = InventoryDirectory(file_id, name, parent_id)
122
        elif kind == 'file':
123
            ie = InventoryFile(file_id, name, parent_id)
5365.2.2 by Andrew Bennetts
Fix test failures for bundles and upgrades.
124
            ie.text_sha1 = text_sha_1
125
            ie.text_size = text_size
0.5.119 by John Arbash Meinel
Recreated the factory. We really need InventoryEntry.create()
126
        elif kind == 'symlink':
127
            ie = InventoryLink(file_id, name, parent_id)
128
        else:
3638.3.16 by Vincent Ladeuil
Remove XFAIL from test_unicode_bundle.
129
            raise errors.BzrError('unknown kind %r' % kind)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
130
        return ie
131
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
132
    def add_dir(self, file_id, path):
133
        self.paths[file_id] = path
134
        self.ids[path] = file_id
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
135
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
136
    def add_file(self, file_id, path, contents):
137
        self.add_dir(file_id, path)
138
        self.contents[file_id] = contents
139
140
    def path2id(self, path):
141
        return self.ids.get(path)
142
143
    def id2path(self, file_id):
144
        return self.paths.get(file_id)
145
146
    def has_id(self, file_id):
147
        return self.id2path(file_id) is not None
148
149
    def get_file(self, file_id):
150
        result = StringIO()
151
        result.write(self.contents[file_id])
152
        result.seek(0,0)
153
        return result
154
5793.2.6 by Jelmer Vernooij
Add MockTree.get_file_revision.
155
    def get_file_revision(self, file_id):
156
        return self.inventory[file_id].revision
157
6468.2.8 by Jelmer Vernooij
Fix remaining test.
158
    def get_file_size(self, file_id):
159
        return self.inventory[file_id].text_size
160
161
    def get_file_sha1(self, file_id):
162
        return self.inventory[file_id].text_sha1
163
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
164
    def contents_stats(self, file_id):
165
        if file_id not in self.contents:
166
            return None, None
4241.14.13 by Vincent Ladeuil
Some more cleanup.
167
        text_sha1 = osutils.sha_file(self.get_file(file_id))
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
168
        return text_sha1, len(self.contents[file_id])
169
170
4241.14.13 by Vincent Ladeuil
Some more cleanup.
171
class BTreeTester(tests.TestCase):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
172
    """A simple unittest tester for the BundleTree class."""
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
173
174
    def make_tree_1(self):
175
        mtree = MockTree()
176
        mtree.add_dir("a", "grandparent")
177
        mtree.add_dir("b", "grandparent/parent")
178
        mtree.add_file("c", "grandparent/parent/file", "Hello\n")
179
        mtree.add_dir("d", "grandparent/alt_parent")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
180
        return BundleTree(mtree, ''), mtree
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
181
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
182
    def test_renames(self):
183
        """Ensure that file renames have the proper effect on children"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
184
        btree = self.make_tree_1()[0]
185
        self.assertEqual(btree.old_path("grandparent"), "grandparent")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
186
        self.assertEqual(btree.old_path("grandparent/parent"),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
187
                         "grandparent/parent")
188
        self.assertEqual(btree.old_path("grandparent/parent/file"),
189
                         "grandparent/parent/file")
190
191
        self.assertEqual(btree.id2path("a"), "grandparent")
192
        self.assertEqual(btree.id2path("b"), "grandparent/parent")
193
        self.assertEqual(btree.id2path("c"), "grandparent/parent/file")
194
195
        self.assertEqual(btree.path2id("grandparent"), "a")
196
        self.assertEqual(btree.path2id("grandparent/parent"), "b")
197
        self.assertEqual(btree.path2id("grandparent/parent/file"), "c")
198
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
199
        self.assertTrue(btree.path2id("grandparent2") is None)
200
        self.assertTrue(btree.path2id("grandparent2/parent") is None)
201
        self.assertTrue(btree.path2id("grandparent2/parent/file") is None)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
202
203
        btree.note_rename("grandparent", "grandparent2")
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
204
        self.assertTrue(btree.old_path("grandparent") is None)
205
        self.assertTrue(btree.old_path("grandparent/parent") is None)
206
        self.assertTrue(btree.old_path("grandparent/parent/file") is None)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
207
208
        self.assertEqual(btree.id2path("a"), "grandparent2")
209
        self.assertEqual(btree.id2path("b"), "grandparent2/parent")
210
        self.assertEqual(btree.id2path("c"), "grandparent2/parent/file")
211
212
        self.assertEqual(btree.path2id("grandparent2"), "a")
213
        self.assertEqual(btree.path2id("grandparent2/parent"), "b")
214
        self.assertEqual(btree.path2id("grandparent2/parent/file"), "c")
215
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
216
        self.assertTrue(btree.path2id("grandparent") is None)
217
        self.assertTrue(btree.path2id("grandparent/parent") is None)
218
        self.assertTrue(btree.path2id("grandparent/parent/file") is None)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
219
220
        btree.note_rename("grandparent/parent", "grandparent2/parent2")
221
        self.assertEqual(btree.id2path("a"), "grandparent2")
222
        self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
223
        self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file")
224
225
        self.assertEqual(btree.path2id("grandparent2"), "a")
226
        self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
227
        self.assertEqual(btree.path2id("grandparent2/parent2/file"), "c")
228
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
229
        self.assertTrue(btree.path2id("grandparent2/parent") is None)
230
        self.assertTrue(btree.path2id("grandparent2/parent/file") is None)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
231
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
232
        btree.note_rename("grandparent/parent/file",
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
233
                          "grandparent2/parent2/file2")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
234
        self.assertEqual(btree.id2path("a"), "grandparent2")
235
        self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
236
        self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file2")
237
238
        self.assertEqual(btree.path2id("grandparent2"), "a")
239
        self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
240
        self.assertEqual(btree.path2id("grandparent2/parent2/file2"), "c")
241
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
242
        self.assertTrue(btree.path2id("grandparent2/parent2/file") is None)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
243
244
    def test_moves(self):
245
        """Ensure that file moves have the proper effect on children"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
246
        btree = self.make_tree_1()[0]
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
247
        btree.note_rename("grandparent/parent/file",
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
248
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
249
        self.assertEqual(btree.id2path("c"), "grandparent/alt_parent/file")
250
        self.assertEqual(btree.path2id("grandparent/alt_parent/file"), "c")
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
251
        self.assertTrue(btree.path2id("grandparent/parent/file") is None)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
252
253
    def unified_diff(self, old, new):
254
        out = StringIO()
4241.14.13 by Vincent Ladeuil
Some more cleanup.
255
        diff.internal_diff("old", old, "new", new, out)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
256
        out.seek(0,0)
257
        return out.read()
258
259
    def make_tree_2(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
260
        btree = self.make_tree_1()[0]
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
261
        btree.note_rename("grandparent/parent/file",
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
262
                          "grandparent/alt_parent/file")
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
263
        self.assertTrue(btree.id2path("e") is None)
264
        self.assertTrue(btree.path2id("grandparent/parent/file") is None)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
265
        btree.note_id("e", "grandparent/parent/file")
266
        return btree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
267
268
    def test_adds(self):
269
        """File/inventory adds"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
270
        btree = self.make_tree_2()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
271
        add_patch = self.unified_diff([], ["Extra cheese\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
272
        btree.note_patch("grandparent/parent/file", add_patch)
273
        btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
274
        btree.note_target('grandparent/parent/symlink', 'venus')
275
        self.adds_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
276
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
277
    def adds_test(self, btree):
278
        self.assertEqual(btree.id2path("e"), "grandparent/parent/file")
279
        self.assertEqual(btree.path2id("grandparent/parent/file"), "e")
280
        self.assertEqual(btree.get_file("e").read(), "Extra cheese\n")
281
        self.assertEqual(btree.get_symlink_target('f'), 'venus')
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
282
283
    def test_adds2(self):
284
        """File/inventory adds, with patch-compatibile renames"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
285
        btree = self.make_tree_2()
286
        btree.contents_by_id = False
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
287
        add_patch = self.unified_diff(["Hello\n"], ["Extra cheese\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
288
        btree.note_patch("grandparent/parent/file", add_patch)
289
        btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
290
        btree.note_target('grandparent/parent/symlink', 'venus')
291
        self.adds_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
292
293
    def make_tree_3(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
294
        btree, mtree = self.make_tree_1()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
295
        mtree.add_file("e", "grandparent/parent/topping", "Anchovies\n")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
296
        btree.note_rename("grandparent/parent/file",
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
297
                          "grandparent/alt_parent/file")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
298
        btree.note_rename("grandparent/parent/topping",
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
299
                          "grandparent/alt_parent/stopping")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
300
        return btree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
301
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
302
    def get_file_test(self, btree):
303
        self.assertEqual(btree.get_file("e").read(), "Lemon\n")
304
        self.assertEqual(btree.get_file("c").read(), "Hello\n")
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
305
306
    def test_get_file(self):
307
        """Get file contents"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
308
        btree = self.make_tree_3()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
309
        mod_patch = self.unified_diff(["Anchovies\n"], ["Lemon\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
310
        btree.note_patch("grandparent/alt_parent/stopping", mod_patch)
311
        self.get_file_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
312
313
    def test_get_file2(self):
314
        """Get file contents, with patch-compatibile renames"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
315
        btree = self.make_tree_3()
316
        btree.contents_by_id = False
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
317
        mod_patch = self.unified_diff([], ["Lemon\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
318
        btree.note_patch("grandparent/alt_parent/stopping", mod_patch)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
319
        mod_patch = self.unified_diff([], ["Hello\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
320
        btree.note_patch("grandparent/alt_parent/file", mod_patch)
321
        self.get_file_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
322
323
    def test_delete(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
324
        "Deletion by bundle"
325
        btree = self.make_tree_1()[0]
326
        self.assertEqual(btree.get_file("c").read(), "Hello\n")
327
        btree.note_deletion("grandparent/parent/file")
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
328
        self.assertTrue(btree.id2path("c") is None)
329
        self.assertTrue(btree.path2id("grandparent/parent/file") is None)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
330
331
    def sorted_ids(self, tree):
6619.3.18 by Jelmer Vernooij
Run 2to3 idioms fixer.
332
        ids = sorted(tree.all_file_ids())
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
333
        return ids
334
335
    def test_iteration(self):
336
        """Ensure that iteration through ids works properly"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
337
        btree = self.make_tree_1()[0]
1852.6.3 by Robert Collins
Make iter(Tree) consistent for all tree types.
338
        self.assertEqual(self.sorted_ids(btree),
339
            [inventory.ROOT_ID, 'a', 'b', 'c', 'd'])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
340
        btree.note_deletion("grandparent/parent/file")
341
        btree.note_id("e", "grandparent/alt_parent/fool", kind="directory")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
342
        btree.note_last_changed("grandparent/alt_parent/fool",
1185.82.95 by Aaron Bentley
Restore path-orientation of ChangesetTree
343
                                "revisionidiguess")
1852.6.3 by Robert Collins
Make iter(Tree) consistent for all tree types.
344
        self.assertEqual(self.sorted_ids(btree),
345
            [inventory.ROOT_ID, 'a', 'b', 'd', 'e'])
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
346
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
347
4241.14.13 by Vincent Ladeuil
Some more cleanup.
348
class BundleTester1(tests.TestCaseWithTransport):
1910.2.49 by Aaron Bentley
Ensure that 0.8 bundles aren't used with KnitRepository2
349
350
    def test_mismatched_bundle(self):
351
        format = bzrdir.BzrDirMetaFormat1()
2255.2.211 by Robert Collins
Remove knit2 repository format- it has never been supported.
352
        format.repository_format = knitrepo.RepositoryFormatKnit3()
1910.2.49 by Aaron Bentley
Ensure that 0.8 bundles aren't used with KnitRepository2
353
        serializer = BundleSerializerV08('0.8')
354
        b = self.make_branch('.', format=format)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
355
        self.assertRaises(errors.IncompatibleBundleFormat, serializer.write,
1910.2.49 by Aaron Bentley
Ensure that 0.8 bundles aren't used with KnitRepository2
356
                          b.repository, [], {}, StringIO())
357
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
358
    def test_matched_bundle(self):
2067.3.1 by Martin Pool
Clean up BzrNewError, other exception classes and users.
359
        """Don't raise IncompatibleBundleFormat for knit2 and bundle0.9"""
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
360
        format = bzrdir.BzrDirMetaFormat1()
2255.2.211 by Robert Collins
Remove knit2 repository format- it has never been supported.
361
        format.repository_format = knitrepo.RepositoryFormatKnit3()
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
362
        serializer = BundleSerializerV09('0.9')
363
        b = self.make_branch('.', format=format)
364
        serializer.write(b.repository, [], {}, StringIO())
365
1910.2.60 by Aaron Bentley
Ensure that new-model revisions aren't installed into old-model repos
366
    def test_mismatched_model(self):
367
        """Try copying a bundle from knit2 to knit1"""
368
        format = bzrdir.BzrDirMetaFormat1()
2255.2.211 by Robert Collins
Remove knit2 repository format- it has never been supported.
369
        format.repository_format = knitrepo.RepositoryFormatKnit3()
1910.2.60 by Aaron Bentley
Ensure that new-model revisions aren't installed into old-model repos
370
        source = self.make_branch_and_tree('source', format=format)
371
        source.commit('one', rev_id='one-id')
372
        source.commit('two', rev_id='two-id')
373
        text = StringIO()
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
374
        write_bundle(source.branch.repository, 'two-id', 'null:', text,
1910.2.60 by Aaron Bentley
Ensure that new-model revisions aren't installed into old-model repos
375
                     format='0.9')
376
        text.seek(0)
377
378
        format = bzrdir.BzrDirMetaFormat1()
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
379
        format.repository_format = knitrepo.RepositoryFormatKnit1()
1910.2.60 by Aaron Bentley
Ensure that new-model revisions aren't installed into old-model repos
380
        target = self.make_branch('target', format=format)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
381
        self.assertRaises(errors.IncompatibleRevision, install_bundle,
1910.2.60 by Aaron Bentley
Ensure that new-model revisions aren't installed into old-model repos
382
                          target.repository, read_bundle(text))
383
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
384
2520.4.43 by Aaron Bentley
Fix test suite
385
class BundleTester(object):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
386
387
    def bzrdir_format(self):
388
        format = bzrdir.BzrDirMetaFormat1()
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
389
        format.repository_format = knitrepo.RepositoryFormatKnit1()
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
390
        return format
391
392
    def make_branch_and_tree(self, path, format=None):
393
        if format is None:
394
            format = self.bzrdir_format()
4241.14.13 by Vincent Ladeuil
Some more cleanup.
395
        return tests.TestCaseWithTransport.make_branch_and_tree(
396
            self, path, format)
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
397
398
    def make_branch(self, path, format=None):
399
        if format is None:
400
            format = self.bzrdir_format()
4241.14.13 by Vincent Ladeuil
Some more cleanup.
401
        return tests.TestCaseWithTransport.make_branch(self, path, format)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
402
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
403
    def create_bundle_text(self, base_rev_id, rev_id):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
404
        bundle_txt = StringIO()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
405
        rev_ids = write_bundle(self.b1.repository, rev_id, base_rev_id,
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
406
                               bundle_txt, format=self.format)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
407
        bundle_txt.seek(0)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
408
        self.assertEqual(bundle_txt.readline(),
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
409
                         '# Bazaar revision bundle v%s\n' % self.format)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
410
        self.assertEqual(bundle_txt.readline(), '#\n')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
411
1185.82.14 by Aaron Bentley
API updates
412
        rev = self.b1.repository.get_revision(rev_id)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
413
        self.assertEqual(bundle_txt.readline().decode('utf-8'),
414
                         u'# message:\n')
415
        bundle_txt.seek(0)
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
416
        return bundle_txt, rev_ids
417
418
    def get_valid_bundle(self, base_rev_id, rev_id, checkout_dir=None):
419
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
420
        Make sure that the text generated is valid, and that it
421
        can be applied against the base, and generate the same information.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
422
423
        :return: The in-memory bundle
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
424
        """
425
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
426
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
427
        # This should also validate the generated bundle
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
428
        bundle = read_bundle(bundle_txt)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
429
        repository = self.b1.repository
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
430
        for bundle_rev in bundle.real_revisions:
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
431
            # These really should have already been checked when we read the
432
            # bundle, since it computes the sha1 hash for the revision, which
433
            # only will match if everything is okay, but lets be explicit about
434
            # it
435
            branch_rev = repository.get_revision(bundle_rev.revision_id)
1185.82.33 by Aaron Bentley
Strengthen tests
436
            for a in ('inventory_sha1', 'revision_id', 'parent_ids',
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
437
                      'timestamp', 'timezone', 'message', 'committer',
1185.82.33 by Aaron Bentley
Strengthen tests
438
                      'parent_ids', 'properties'):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
439
                self.assertEqual(getattr(branch_rev, a),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
440
                                 getattr(bundle_rev, a))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
441
            self.assertEqual(len(branch_rev.parent_ids),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
442
                             len(bundle_rev.parent_ids))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
443
        self.assertEqual(rev_ids,
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
444
                         [r.revision_id for r in bundle.real_revisions])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
445
        self.valid_apply_bundle(base_rev_id, bundle,
1185.82.89 by Aaron Bentley
Remove auto_commit stuff
446
                                   checkout_dir=checkout_dir)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
447
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
448
        return bundle
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
449
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
450
    def get_invalid_bundle(self, base_rev_id, rev_id):
451
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
452
        Munge the text so that it's invalid.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
453
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
454
        :return: The in-memory bundle
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
455
        """
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
456
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
457
        new_text = bundle_txt.getvalue().replace('executable:no',
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
458
                                               'executable:yes')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
459
        bundle_txt = StringIO(new_text)
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
460
        bundle = read_bundle(bundle_txt)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
461
        self.valid_apply_bundle(base_rev_id, bundle)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
462
        return bundle
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
463
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
464
    def test_non_bundle(self):
3638.3.16 by Vincent Ladeuil
Remove XFAIL from test_unicode_bundle.
465
        self.assertRaises(errors.NotABundle,
466
                          read_bundle, StringIO('#!/bin/sh\n'))
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
467
1793.2.7 by Aaron Bentley
Fix reporting of malformed, (especially, crlf) bundles
468
    def test_malformed(self):
3638.3.16 by Vincent Ladeuil
Remove XFAIL from test_unicode_bundle.
469
        self.assertRaises(errors.BadBundle, read_bundle,
1793.2.7 by Aaron Bentley
Fix reporting of malformed, (especially, crlf) bundles
470
                          StringIO('# Bazaar revision bundle v'))
471
472
    def test_crlf_bundle(self):
1793.2.9 by Aaron Bentley
Don't use assertNotRaises-- instead, catch BadBundle and pass
473
        try:
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
474
            read_bundle(StringIO('# Bazaar revision bundle v0.8\r\n'))
3638.3.16 by Vincent Ladeuil
Remove XFAIL from test_unicode_bundle.
475
        except errors.BadBundle:
1793.2.9 by Aaron Bentley
Don't use assertNotRaises-- instead, catch BadBundle and pass
476
            # It is currently permitted for bundles with crlf line endings to
477
            # make read_bundle raise a BadBundle, but this should be fixed.
1793.2.10 by Aaron Bentley
Whitespace/comment fix
478
            # Anything else, especially NotABundle, is an error.
1793.2.9 by Aaron Bentley
Don't use assertNotRaises-- instead, catch BadBundle and pass
479
            pass
480
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
481
    def get_checkout(self, rev_id, checkout_dir=None):
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
482
        """Get a new tree, with the specified revision in it.
483
        """
484
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
485
        if checkout_dir is None:
3638.3.2 by Vincent Ladeuil
Fix all calls to tempfile.mkdtemp to osutils.mkdtemp.
486
            checkout_dir = osutils.mkdtemp(prefix='test-branch-', dir='.')
0.5.89 by John Arbash Meinel
Updating for explicitly defined directories.
487
        else:
488
            if not os.path.exists(checkout_dir):
489
                os.mkdir(checkout_dir)
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
490
        tree = self.make_branch_and_tree(checkout_dir)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
491
        s = StringIO()
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
492
        ancestors = write_bundle(self.b1.repository, rev_id, 'null:', s,
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
493
                                 format=self.format)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
494
        s.seek(0)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
495
        self.assertIsInstance(s.getvalue(), str)
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
496
        install_bundle(tree.branch.repository, read_bundle(s))
1185.82.41 by Aaron Bentley
More work on installing changesets
497
        for ancestor in ancestors:
498
            old = self.b1.repository.revision_tree(ancestor)
499
            new = tree.branch.repository.revision_tree(ancestor)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
500
            old.lock_read()
501
            new.lock_read()
502
            try:
503
                # Check that there aren't any inventory level changes
504
                delta = new.changes_from(old)
505
                self.assertFalse(delta.has_changed(),
506
                                 'Revision %s not copied correctly.'
507
                                 % (ancestor,))
508
509
                # Now check that the file contents are all correct
5837.2.2 by Jelmer Vernooij
Fix more uses of Tree.__iter__
510
                for inventory_id in old.all_file_ids():
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
511
                    try:
512
                        old_file = old.get_file(inventory_id)
3638.3.16 by Vincent Ladeuil
Remove XFAIL from test_unicode_bundle.
513
                    except errors.NoSuchFile:
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
514
                        continue
515
                    if old_file is None:
516
                        continue
517
                    self.assertEqual(old_file.read(),
518
                                     new.get_file(inventory_id).read())
519
            finally:
520
                new.unlock()
521
                old.unlock()
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
522
        if not _mod_revision.is_null(rev_id):
6165.4.19 by Jelmer Vernooij
Avoid all iter_reverse_revision_history calls.
523
            tree.branch.generate_revision_history(rev_id)
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
524
            tree.update()
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
525
            delta = tree.changes_from(self.b1.repository.revision_tree(rev_id))
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
526
            self.assertFalse(delta.has_changed(),
2255.10.5 by John Arbash Meinel
Fix a small bug when we have a symlink that does not need to be re-read.
527
                             'Working tree has modifications: %s' % delta)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
528
        return tree
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
529
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
530
    def valid_apply_bundle(self, base_rev_id, info, checkout_dir=None):
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
531
        """Get the base revision, apply the changes, and make
532
        sure everything matches the builtin branch.
533
        """
1185.82.17 by Aaron Bentley
More API updates
534
        to_tree = self.get_checkout(base_rev_id, checkout_dir=checkout_dir)
3146.4.11 by Aaron Bentley
Fix lock errors in bundle tests
535
        to_tree.lock_write()
536
        try:
537
            self._valid_apply_bundle(base_rev_id, info, to_tree)
538
        finally:
539
            to_tree.unlock()
540
541
    def _valid_apply_bundle(self, base_rev_id, info, to_tree):
1908.6.4 by Robert Collins
Update to replaced parent checking api bzrlib/merge.py
542
        original_parents = to_tree.get_parent_ids()
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
543
        repository = to_tree.branch.repository
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
544
        original_parents = to_tree.get_parent_ids()
1185.82.41 by Aaron Bentley
More work on installing changesets
545
        self.assertIs(repository.has_revision(base_rev_id), True)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
546
        for rev in info.real_revisions:
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
547
            self.assertTrue(not repository.has_revision(rev.revision_id),
548
                            'Revision {%s} present before applying bundle'
549
                            % rev.revision_id)
4241.14.13 by Vincent Ladeuil
Some more cleanup.
550
        merge_bundle(info, to_tree, True, merge.Merge3Merger, False, False)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
551
552
        for rev in info.real_revisions:
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
553
            self.assertTrue(repository.has_revision(rev.revision_id),
554
                            'Missing revision {%s} after applying bundle'
555
                            % rev.revision_id)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
556
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
557
        self.assertTrue(to_tree.branch.repository.has_revision(info.target))
0.5.117 by John Arbash Meinel
Almost there. Just need to track down a few remaining bugs.
558
        # Do we also want to verify that all the texts have been added?
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
559
1908.6.4 by Robert Collins
Update to replaced parent checking api bzrlib/merge.py
560
        self.assertEqual(original_parents + [info.target],
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
561
                         to_tree.get_parent_ids())
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
562
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
563
        rev = info.real_revisions[-1]
1185.82.17 by Aaron Bentley
More API updates
564
        base_tree = self.b1.repository.revision_tree(rev.revision_id)
565
        to_tree = to_tree.branch.repository.revision_tree(rev.revision_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
566
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
567
        # TODO: make sure the target tree is identical to base tree
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
568
        #       we might also check the working tree.
569
570
        base_files = list(base_tree.list_files())
571
        to_files = list(to_tree.list_files())
572
        self.assertEqual(len(base_files), len(to_files))
1185.82.66 by Aaron Bentley
Handle new executable files
573
        for base_file, to_file in zip(base_files, to_files):
574
            self.assertEqual(base_file, to_file)
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
575
0.5.117 by John Arbash Meinel
Almost there. Just need to track down a few remaining bugs.
576
        for path, status, kind, fileid, entry in base_files:
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
577
            # Check that the meta information is the same
578
            self.assertEqual(base_tree.get_file_size(fileid),
579
                    to_tree.get_file_size(fileid))
580
            self.assertEqual(base_tree.get_file_sha1(fileid),
581
                    to_tree.get_file_sha1(fileid))
582
            # Check that the contents are the same
583
            # This is pretty expensive
584
            # self.assertEqual(base_tree.get_file(fileid).read(),
585
            #         to_tree.get_file(fileid).read())
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
586
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
587
    def test_bundle(self):
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
588
        self.tree1 = self.make_branch_and_tree('b1')
1185.82.14 by Aaron Bentley
API updates
589
        self.b1 = self.tree1.branch
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
590
4543.2.11 by John Arbash Meinel
Use a fixed file-id for the root to make the tests more stable.
591
        self.build_tree_contents([('b1/one', 'one\n')])
592
        self.tree1.add('one', 'one-id')
593
        self.tree1.set_root_id('root-id')
1185.82.14 by Aaron Bentley
API updates
594
        self.tree1.commit('add one', rev_id='a@cset-0-1')
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
595
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
596
        bundle = self.get_valid_bundle('null:', 'a@cset-0-1')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
597
598
        # Make sure we can handle files with spaces, tabs, other
599
        # bogus characters
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
600
        self.build_tree([
0.5.84 by John Arbash Meinel
(broken) problem with removes.
601
                'b1/with space.txt'
602
                , 'b1/dir/'
603
                , 'b1/dir/filein subdir.c'
604
                , 'b1/dir/WithCaps.txt'
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
605
                , 'b1/dir/ pre space'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
606
                , 'b1/sub/'
607
                , 'b1/sub/sub/'
608
                , 'b1/sub/sub/nonempty.txt'
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
609
                ])
4543.2.11 by John Arbash Meinel
Use a fixed file-id for the root to make the tests more stable.
610
        self.build_tree_contents([('b1/sub/sub/emptyfile.txt', ''),
611
                                  ('b1/dir/nolastnewline.txt', 'bloop')])
1185.82.66 by Aaron Bentley
Handle new executable files
612
        tt = TreeTransform(self.tree1)
613
        tt.new_file('executable', tt.root, '#!/bin/sh\n', 'exe-1', True)
614
        tt.apply()
2520.4.84 by Aaron Bentley
Fix heisenbug record-rewriting test
615
        # have to fix length of file-id so that we can predictably rewrite
616
        # a (length-prefixed) record containing it later.
617
        self.tree1.add('with space.txt', 'withspace-id')
1185.82.14 by Aaron Bentley
API updates
618
        self.tree1.add([
2520.4.84 by Aaron Bentley
Fix heisenbug record-rewriting test
619
                  'dir'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
620
                , 'dir/filein subdir.c'
621
                , 'dir/WithCaps.txt'
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
622
                , 'dir/ pre space'
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
623
                , 'dir/nolastnewline.txt'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
624
                , 'sub'
625
                , 'sub/sub'
626
                , 'sub/sub/nonempty.txt'
627
                , 'sub/sub/emptyfile.txt'
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
628
                ])
1185.82.14 by Aaron Bentley
API updates
629
        self.tree1.commit('add whitespace', rev_id='a@cset-0-2')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
630
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
631
        bundle = self.get_valid_bundle('a@cset-0-1', 'a@cset-0-2')
0.5.117 by John Arbash Meinel
Almost there. Just need to track down a few remaining bugs.
632
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
633
        # Check a rollup bundle
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
634
        bundle = self.get_valid_bundle('null:', 'a@cset-0-2')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
635
636
        # Now delete entries
1185.82.21 by Aaron Bentley
Stop using deprecated function
637
        self.tree1.remove(
0.5.118 by John Arbash Meinel
Got most of test_changeset to work. Still needs work for Aaron's test code.
638
                ['sub/sub/nonempty.txt'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
639
                , 'sub/sub/emptyfile.txt'
0.5.118 by John Arbash Meinel
Got most of test_changeset to work. Still needs work for Aaron's test code.
640
                , 'sub/sub'
641
                ])
1185.82.68 by Aaron Bentley
Handle execute bit on modified files
642
        tt = TreeTransform(self.tree1)
643
        trans_id = tt.trans_id_tree_file_id('exe-1')
644
        tt.set_executability(False, trans_id)
645
        tt.apply()
1185.82.19 by Aaron Bentley
More API updates
646
        self.tree1.commit('removed', rev_id='a@cset-0-3')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
647
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
648
        bundle = self.get_valid_bundle('a@cset-0-2', 'a@cset-0-3')
3638.3.16 by Vincent Ladeuil
Remove XFAIL from test_unicode_bundle.
649
        self.assertRaises((errors.TestamentMismatch,
4543.2.8 by John Arbash Meinel
Add a custom get_invalid_bundle and allow BadBundle to be
650
            errors.VersionedFileInvalidChecksum,
651
            errors.BadBundle), self.get_invalid_bundle,
2520.4.71 by Aaron Bentley
Update test to accept VersionedFileInvalidChecksum instead of TestamentMismatch
652
            'a@cset-0-2', 'a@cset-0-3')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
653
        # Check a rollup bundle
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
654
        bundle = self.get_valid_bundle('null:', 'a@cset-0-3')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
655
656
        # Now move the directory
1185.82.19 by Aaron Bentley
More API updates
657
        self.tree1.rename_one('dir', 'sub/dir')
658
        self.tree1.commit('rename dir', rev_id='a@cset-0-4')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
659
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
660
        bundle = self.get_valid_bundle('a@cset-0-3', 'a@cset-0-4')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
661
        # Check a rollup bundle
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
662
        bundle = self.get_valid_bundle('null:', 'a@cset-0-4')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
663
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
664
        # Modified files
6437.20.3 by Wouter van Heyst
mechanically replace file().write() pattern with a with-keyword version
665
        with open('b1/sub/dir/WithCaps.txt', 'ab') as f: f.write('\nAdding some text\n')
666
        with open('b1/sub/dir/ pre space', 'ab') as f: f.write(
2520.4.83 by Aaron Bentley
Clean up tests
667
             '\r\nAdding some\r\nDOS format lines\r\n')
6437.20.3 by Wouter van Heyst
mechanically replace file().write() pattern with a with-keyword version
668
        with open('b1/sub/dir/nolastnewline.txt', 'ab') as f: f.write('\n')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
669
        self.tree1.rename_one('sub/dir/ pre space',
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
670
                              'sub/ start space')
1185.82.19 by Aaron Bentley
More API updates
671
        self.tree1.commit('Modified files', rev_id='a@cset-0-5')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
672
        bundle = self.get_valid_bundle('a@cset-0-4', 'a@cset-0-5')
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
673
1185.82.70 by Aaron Bentley
Handle renamed files better
674
        self.tree1.rename_one('sub/dir/WithCaps.txt', 'temp')
675
        self.tree1.rename_one('with space.txt', 'WithCaps.txt')
676
        self.tree1.rename_one('temp', 'with space.txt')
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
677
        self.tree1.commit(u'swap filenames', rev_id='a@cset-0-6',
678
                          verbose=False)
679
        bundle = self.get_valid_bundle('a@cset-0-5', 'a@cset-0-6')
680
        other = self.get_checkout('a@cset-0-5')
4543.2.9 by John Arbash Meinel
Down to 2 failing tests.
681
        tree1_inv = get_inventory_text(self.tree1.branch.repository,
682
                                       'a@cset-0-5')
683
        tree2_inv = get_inventory_text(other.branch.repository,
684
                                       'a@cset-0-5')
1910.2.54 by Aaron Bentley
Implement testament format 3 strict
685
        self.assertEqualDiff(tree1_inv, tree2_inv)
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
686
        other.rename_one('sub/dir/nolastnewline.txt', 'sub/nolastnewline.txt')
687
        other.commit('rename file', rev_id='a@cset-0-6b')
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
688
        self.tree1.merge_from_branch(other.branch)
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
689
        self.tree1.commit(u'Merge', rev_id='a@cset-0-7',
1185.82.70 by Aaron Bentley
Handle renamed files better
690
                          verbose=False)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
691
        bundle = self.get_valid_bundle('a@cset-0-6', 'a@cset-0-7')
1185.82.72 by Aaron Bentley
Always use leftmost base for changesets
692
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
693
    def _test_symlink_bundle(self, link_name, link_target, new_link_target):
694
        link_id = 'link-1'
695
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
696
        self.requireFeature(features.SymlinkFeature)
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
697
        self.tree1 = self.make_branch_and_tree('b1')
1185.82.87 by Aaron Bentley
Got symlink adding working
698
        self.b1 = self.tree1.branch
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
699
1185.82.87 by Aaron Bentley
Got symlink adding working
700
        tt = TreeTransform(self.tree1)
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
701
        tt.new_symlink(link_name, tt.root, link_target, link_id)
1185.82.87 by Aaron Bentley
Got symlink adding working
702
        tt.apply()
703
        self.tree1.commit('add symlink', rev_id='l@cset-0-1')
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
704
        bundle = self.get_valid_bundle('null:', 'l@cset-0-1')
705
        if getattr(bundle ,'revision_tree', None) is not None:
706
            # Not all bundle formats supports revision_tree
707
            bund_tree = bundle.revision_tree(self.b1.repository, 'l@cset-0-1')
708
            self.assertEqual(link_target, bund_tree.get_symlink_target(link_id))
709
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
710
        tt = TreeTransform(self.tree1)
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
711
        trans_id = tt.trans_id_tree_file_id(link_id)
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
712
        tt.adjust_path('link2', tt.root, trans_id)
713
        tt.delete_contents(trans_id)
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
714
        tt.create_symlink(new_link_target, trans_id)
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
715
        tt.apply()
716
        self.tree1.commit('rename and change symlink', rev_id='l@cset-0-2')
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
717
        bundle = self.get_valid_bundle('l@cset-0-1', 'l@cset-0-2')
718
        if getattr(bundle ,'revision_tree', None) is not None:
719
            # Not all bundle formats supports revision_tree
720
            bund_tree = bundle.revision_tree(self.b1.repository, 'l@cset-0-2')
721
            self.assertEqual(new_link_target,
722
                             bund_tree.get_symlink_target(link_id))
723
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
724
        tt = TreeTransform(self.tree1)
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
725
        trans_id = tt.trans_id_tree_file_id(link_id)
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
726
        tt.delete_contents(trans_id)
727
        tt.create_symlink('jupiter', trans_id)
728
        tt.apply()
729
        self.tree1.commit('just change symlink target', rev_id='l@cset-0-3')
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
730
        bundle = self.get_valid_bundle('l@cset-0-2', 'l@cset-0-3')
731
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
732
        tt = TreeTransform(self.tree1)
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
733
        trans_id = tt.trans_id_tree_file_id(link_id)
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
734
        tt.delete_contents(trans_id)
735
        tt.apply()
736
        self.tree1.commit('Delete symlink', rev_id='l@cset-0-4')
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
737
        bundle = self.get_valid_bundle('l@cset-0-3', 'l@cset-0-4')
738
739
    def test_symlink_bundle(self):
740
        self._test_symlink_bundle('link', 'bar/foo', 'mars')
741
742
    def test_unicode_symlink_bundle(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
743
        self.requireFeature(features.UnicodeFilenameFeature)
4241.14.12 by Vincent Ladeuil
Far too many modifications for a single commit, need to restart.
744
        self._test_symlink_bundle(u'\N{Euro Sign}link',
745
                                  u'bar/\N{Euro Sign}foo',
746
                                  u'mars\N{Euro Sign}')
1185.82.96 by Aaron Bentley
Got first binary test passing
747
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
748
    def test_binary_bundle(self):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
749
        self.tree1 = self.make_branch_and_tree('b1')
1185.82.96 by Aaron Bentley
Got first binary test passing
750
        self.b1 = self.tree1.branch
751
        tt = TreeTransform(self.tree1)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
752
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
753
        # Add
754
        tt.new_file('file', tt.root, '\x00\n\x00\r\x01\n\x02\r\xff', 'binary-1')
2520.4.83 by Aaron Bentley
Clean up tests
755
        tt.new_file('file2', tt.root, '\x01\n\x02\r\x03\n\x04\r\xff',
756
            'binary-2')
1185.82.96 by Aaron Bentley
Got first binary test passing
757
        tt.apply()
758
        self.tree1.commit('add binary', rev_id='b@cset-0-1')
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
759
        self.get_valid_bundle('null:', 'b@cset-0-1')
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
760
761
        # Delete
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
762
        tt = TreeTransform(self.tree1)
763
        trans_id = tt.trans_id_tree_file_id('binary-1')
764
        tt.delete_contents(trans_id)
765
        tt.apply()
766
        self.tree1.commit('delete binary', rev_id='b@cset-0-2')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
767
        self.get_valid_bundle('b@cset-0-1', 'b@cset-0-2')
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
768
769
        # Rename & modify
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
770
        tt = TreeTransform(self.tree1)
771
        trans_id = tt.trans_id_tree_file_id('binary-2')
772
        tt.adjust_path('file3', tt.root, trans_id)
773
        tt.delete_contents(trans_id)
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
774
        tt.create_file('file\rcontents\x00\n\x00', trans_id)
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
775
        tt.apply()
776
        self.tree1.commit('rename and modify binary', rev_id='b@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
777
        self.get_valid_bundle('b@cset-0-2', 'b@cset-0-3')
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
778
779
        # Modify
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
780
        tt = TreeTransform(self.tree1)
781
        trans_id = tt.trans_id_tree_file_id('binary-2')
782
        tt.delete_contents(trans_id)
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
783
        tt.create_file('\x00file\rcontents', trans_id)
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
784
        tt.apply()
785
        self.tree1.commit('just modify binary', rev_id='b@cset-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
786
        self.get_valid_bundle('b@cset-0-3', 'b@cset-0-4')
1185.82.115 by Aaron Bentley
Add test for last-changed special cases
787
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
788
        # Rollup
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
789
        self.get_valid_bundle('null:', 'b@cset-0-4')
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
790
1185.82.115 by Aaron Bentley
Add test for last-changed special cases
791
    def test_last_modified(self):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
792
        self.tree1 = self.make_branch_and_tree('b1')
1185.82.115 by Aaron Bentley
Add test for last-changed special cases
793
        self.b1 = self.tree1.branch
794
        tt = TreeTransform(self.tree1)
795
        tt.new_file('file', tt.root, 'file', 'file')
796
        tt.apply()
797
        self.tree1.commit('create file', rev_id='a@lmod-0-1')
798
799
        tt = TreeTransform(self.tree1)
800
        trans_id = tt.trans_id_tree_file_id('file')
801
        tt.delete_contents(trans_id)
802
        tt.create_file('file2', trans_id)
803
        tt.apply()
804
        self.tree1.commit('modify text', rev_id='a@lmod-0-2a')
805
806
        other = self.get_checkout('a@lmod-0-1')
807
        tt = TreeTransform(other)
808
        trans_id = tt.trans_id_tree_file_id('file')
809
        tt.delete_contents(trans_id)
810
        tt.create_file('file2', trans_id)
811
        tt.apply()
812
        other.commit('modify text in another tree', rev_id='a@lmod-0-2b')
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
813
        self.tree1.merge_from_branch(other.branch)
1185.82.115 by Aaron Bentley
Add test for last-changed special cases
814
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-3',
815
                          verbose=False)
816
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
817
        bundle = self.get_valid_bundle('a@lmod-0-2a', 'a@lmod-0-4')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
818
819
    def test_hide_history(self):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
820
        self.tree1 = self.make_branch_and_tree('b1')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
821
        self.b1 = self.tree1.branch
822
6437.19.1 by Wouter van Heyst
fix pypy failures
823
        with open('b1/one', 'wb') as f: f.write('one\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
824
        self.tree1.add('one')
825
        self.tree1.commit('add file', rev_id='a@cset-0-1')
6437.19.1 by Wouter van Heyst
fix pypy failures
826
        with open('b1/one', 'wb') as f: f.write('two\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
827
        self.tree1.commit('modify', rev_id='a@cset-0-2')
6437.19.1 by Wouter van Heyst
fix pypy failures
828
        with open('b1/one', 'wb') as f: f.write('three\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
829
        self.tree1.commit('modify', rev_id='a@cset-0-3')
830
        bundle_file = StringIO()
831
        rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
832
                               'a@cset-0-1', bundle_file, format=self.format)
2382.1.1 by Ian Clatworthy
Fixes #98510 - bundle selftest fails if email has 'two' embedded
833
        self.assertNotContainsRe(bundle_file.getvalue(), '\btwo\b')
2520.4.32 by Aaron Bentley
Fix test case
834
        self.assertContainsRe(self.get_raw(bundle_file), 'one')
835
        self.assertContainsRe(self.get_raw(bundle_file), 'three')
836
2520.4.75 by Aaron Bentley
Fix traceback on empty bundles.
837
    def test_bundle_same_basis(self):
838
        """Ensure using the basis as the target doesn't cause an error"""
839
        self.tree1 = self.make_branch_and_tree('b1')
840
        self.tree1.commit('add file', rev_id='a@cset-0-1')
841
        bundle_file = StringIO()
842
        rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-1',
843
                               'a@cset-0-1', bundle_file)
844
2520.4.32 by Aaron Bentley
Fix test case
845
    @staticmethod
846
    def get_raw(bundle_file):
847
        return bundle_file.getvalue()
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
848
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
849
    def test_unicode_bundle(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
850
        self.requireFeature(features.UnicodeFilenameFeature)
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
851
        # Handle international characters
852
        os.mkdir('b1')
4241.14.13 by Vincent Ladeuil
Some more cleanup.
853
        f = open(u'b1/with Dod\N{Euro Sign}', 'wb')
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
854
855
        self.tree1 = self.make_branch_and_tree('b1')
856
        self.b1 = self.tree1.branch
857
858
        f.write((u'A file\n'
859
            u'With international man of mystery\n'
860
            u'William Dod\xe9\n').encode('utf-8'))
861
        f.close()
862
3638.3.18 by Vincent Ladeuil
Fixed as per jam's review.
863
        self.tree1.add([u'with Dod\N{Euro Sign}'], ['withdod-id'])
2386.1.1 by John Arbash Meinel
Update test_unicode_bundle, since we know how it fails on Mac OSX
864
        self.tree1.commit(u'i18n commit from William Dod\xe9',
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
865
                          rev_id='i18n-1', committer=u'William Dod\xe9')
866
867
        # Add
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
868
        bundle = self.get_valid_bundle('null:', 'i18n-1')
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
869
870
        # Modified
3638.3.18 by Vincent Ladeuil
Fixed as per jam's review.
871
        f = open(u'b1/with Dod\N{Euro Sign}', 'wb')
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
872
        f.write(u'Modified \xb5\n'.encode('utf8'))
873
        f.close()
874
        self.tree1.commit(u'modified', rev_id='i18n-2')
875
876
        bundle = self.get_valid_bundle('i18n-1', 'i18n-2')
3638.3.16 by Vincent Ladeuil
Remove XFAIL from test_unicode_bundle.
877
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
878
        # Renamed
3638.3.18 by Vincent Ladeuil
Fixed as per jam's review.
879
        self.tree1.rename_one(u'with Dod\N{Euro Sign}', u'B\N{Euro Sign}gfors')
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
880
        self.tree1.commit(u'renamed, the new i18n man', rev_id='i18n-3',
881
                          committer=u'Erik B\xe5gfors')
882
883
        bundle = self.get_valid_bundle('i18n-2', 'i18n-3')
884
885
        # Removed
3638.3.18 by Vincent Ladeuil
Fixed as per jam's review.
886
        self.tree1.remove([u'B\N{Euro Sign}gfors'])
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
887
        self.tree1.commit(u'removed', rev_id='i18n-4')
888
889
        bundle = self.get_valid_bundle('i18n-3', 'i18n-4')
890
891
        # Rollup
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
892
        bundle = self.get_valid_bundle('null:', 'i18n-4')
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
893
894
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
895
    def test_whitespace_bundle(self):
896
        if sys.platform in ('win32', 'cygwin'):
4241.14.13 by Vincent Ladeuil
Some more cleanup.
897
            raise tests.TestSkipped('Windows doesn\'t support filenames'
898
                                    ' with tabs or trailing spaces')
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
899
        self.tree1 = self.make_branch_and_tree('b1')
900
        self.b1 = self.tree1.branch
901
902
        self.build_tree(['b1/trailing space '])
903
        self.tree1.add(['trailing space '])
904
        # TODO: jam 20060701 Check for handling files with '\t' characters
905
        #       once we actually support them
906
907
        # Added
908
        self.tree1.commit('funky whitespace', rev_id='white-1')
909
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
910
        bundle = self.get_valid_bundle('null:', 'white-1')
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
911
912
        # Modified
6437.20.3 by Wouter van Heyst
mechanically replace file().write() pattern with a with-keyword version
913
        with open('b1/trailing space ', 'ab') as f: f.write('add some text\n')
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
914
        self.tree1.commit('add text', rev_id='white-2')
915
916
        bundle = self.get_valid_bundle('white-1', 'white-2')
917
918
        # Renamed
919
        self.tree1.rename_one('trailing space ', ' start and end space ')
920
        self.tree1.commit('rename', rev_id='white-3')
921
922
        bundle = self.get_valid_bundle('white-2', 'white-3')
923
924
        # Removed
925
        self.tree1.remove([' start and end space '])
926
        self.tree1.commit('removed', rev_id='white-4')
927
928
        bundle = self.get_valid_bundle('white-3', 'white-4')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
929
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
930
        # Now test a complet roll-up
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
931
        bundle = self.get_valid_bundle('null:', 'white-4')
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
932
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
933
    def test_alt_timezone_bundle(self):
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
934
        self.tree1 = self.make_branch_and_memory_tree('b1')
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
935
        self.b1 = self.tree1.branch
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
936
        builder = treebuilder.TreeBuilder()
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
937
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
938
        self.tree1.lock_write()
939
        builder.start_tree(self.tree1)
940
        builder.build(['newfile'])
941
        builder.finish_tree()
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
942
943
        # Asia/Colombo offset = 5 hours 30 minutes
944
        self.tree1.commit('non-hour offset timezone', rev_id='tz-1',
945
                          timezone=19800, timestamp=1152544886.0)
946
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
947
        bundle = self.get_valid_bundle('null:', 'tz-1')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
948
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
949
        rev = bundle.revisions[0]
950
        self.assertEqual('Mon 2006-07-10 20:51:26.000000000 +0530', rev.date)
951
        self.assertEqual(19800, rev.timezone)
952
        self.assertEqual(1152544886.0, rev.timestamp)
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
953
        self.tree1.unlock()
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
954
1910.2.1 by Aaron Bentley
Ensure root entry always has a revision
955
    def test_bundle_root_id(self):
956
        self.tree1 = self.make_branch_and_tree('b1')
957
        self.b1 = self.tree1.branch
958
        self.tree1.commit('message', rev_id='revid1')
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
959
        bundle = self.get_valid_bundle('null:', 'revid1')
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
960
        tree = self.get_bundle_tree(bundle, 'revid1')
6405.2.6 by Jelmer Vernooij
Lots of test fixes.
961
        root_revision = tree.get_file_revision(tree.get_root_id())
962
        self.assertEqual('revid1', root_revision)
1910.2.1 by Aaron Bentley
Ensure root entry always has a revision
963
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
964
    def test_install_revisions(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
965
        self.tree1 = self.make_branch_and_tree('b1')
966
        self.b1 = self.tree1.branch
967
        self.tree1.commit('message', rev_id='rev2a')
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
968
        bundle = self.get_valid_bundle('null:', 'rev2a')
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
969
        branch2 = self.make_branch('b2')
970
        self.assertFalse(branch2.repository.has_revision('rev2a'))
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
971
        target_revision = bundle.install_revisions(branch2.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
972
        self.assertTrue(branch2.repository.has_revision('rev2a'))
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
973
        self.assertEqual('rev2a', target_revision)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
974
2447.1.2 by John Arbash Meinel
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
975
    def test_bundle_empty_property(self):
976
        """Test serializing revision properties with an empty value."""
977
        tree = self.make_branch_and_memory_tree('tree')
978
        tree.lock_write()
979
        self.addCleanup(tree.unlock)
980
        tree.add([''], ['TREE_ROOT'])
981
        tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
982
        self.b1 = tree.branch
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
983
        bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
2520.4.33 by Aaron Bentley
remove test dependencies on serialization minutia
984
        bundle = read_bundle(bundle_sio)
985
        revision_info = bundle.revisions[0]
986
        self.assertEqual('rev1', revision_info.revision_id)
987
        rev = revision_info.as_revision()
988
        self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
989
                         rev.properties)
990
991
    def test_bundle_sorted_properties(self):
992
        """For stability the writer should write properties in sorted order."""
993
        tree = self.make_branch_and_memory_tree('tree')
994
        tree.lock_write()
995
        self.addCleanup(tree.unlock)
996
997
        tree.add([''], ['TREE_ROOT'])
998
        tree.commit('One', rev_id='rev1',
999
                    revprops={'a':'4', 'b':'3', 'c':'2', 'd':'1'})
1000
        self.b1 = tree.branch
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1001
        bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
2520.4.33 by Aaron Bentley
remove test dependencies on serialization minutia
1002
        bundle = read_bundle(bundle_sio)
1003
        revision_info = bundle.revisions[0]
1004
        self.assertEqual('rev1', revision_info.revision_id)
1005
        rev = revision_info.as_revision()
1006
        self.assertEqual({'branch-nick':'tree', 'a':'4', 'b':'3', 'c':'2',
1007
                          'd':'1'}, rev.properties)
1008
1009
    def test_bundle_unicode_properties(self):
1010
        """We should be able to round trip a non-ascii property."""
1011
        tree = self.make_branch_and_memory_tree('tree')
1012
        tree.lock_write()
1013
        self.addCleanup(tree.unlock)
1014
1015
        tree.add([''], ['TREE_ROOT'])
1016
        # Revisions themselves do not require anything about revision property
1017
        # keys, other than that they are a basestring, and do not contain
1018
        # whitespace.
1019
        # However, Testaments assert than they are str(), and thus should not
1020
        # be Unicode.
1021
        tree.commit('One', rev_id='rev1',
1022
                    revprops={'omega':u'\u03a9', 'alpha':u'\u03b1'})
1023
        self.b1 = tree.branch
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1024
        bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
2520.4.33 by Aaron Bentley
remove test dependencies on serialization minutia
1025
        bundle = read_bundle(bundle_sio)
1026
        revision_info = bundle.revisions[0]
1027
        self.assertEqual('rev1', revision_info.revision_id)
1028
        rev = revision_info.as_revision()
1029
        self.assertEqual({'branch-nick':'tree', 'omega':u'\u03a9',
1030
                          'alpha':u'\u03b1'}, rev.properties)
1031
2520.4.43 by Aaron Bentley
Fix test suite
1032
    def test_bundle_with_ghosts(self):
1033
        tree = self.make_branch_and_tree('tree')
1034
        self.b1 = tree.branch
1035
        self.build_tree_contents([('tree/file', 'content1')])
1036
        tree.add(['file'])
1037
        tree.commit('rev1')
1038
        self.build_tree_contents([('tree/file', 'content2')])
1039
        tree.add_parent_tree_id('ghost')
1040
        tree.commit('rev2', rev_id='rev2')
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1041
        bundle = self.get_valid_bundle('null:', 'rev2')
2520.4.43 by Aaron Bentley
Fix test suite
1042
2520.4.97 by Aaron Bentley
Hack in support for inventory conversion
1043
    def make_simple_tree(self, format=None):
1044
        tree = self.make_branch_and_tree('b1', format=format)
1045
        self.b1 = tree.branch
1046
        self.build_tree(['b1/file'])
1047
        tree.add('file')
1048
        return tree
1049
1050
    def test_across_serializers(self):
1051
        tree = self.make_simple_tree('knit')
1052
        tree.commit('hello', rev_id='rev1')
2520.4.98 by Aaron Bentley
Support inventory conversion with parents
1053
        tree.commit('hello', rev_id='rev2')
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1054
        bundle = read_bundle(self.create_bundle_text('null:', 'rev2')[0])
2520.4.97 by Aaron Bentley
Hack in support for inventory conversion
1055
        repo = self.make_repository('repo', format='dirstate-with-subtree')
1056
        bundle.install_revisions(repo)
4988.5.1 by Jelmer Vernooij
Rename Repository.get_inventory_xml -> Repository._get_inventory_xml.
1057
        inv_text = repo._get_inventory_xml('rev2')
2520.4.97 by Aaron Bentley
Hack in support for inventory conversion
1058
        self.assertNotContainsRe(inv_text, 'format="5"')
2520.4.99 by Aaron Bentley
Test conversion across models
1059
        self.assertContainsRe(inv_text, 'format="7"')
1060
3380.1.8 by Aaron Bentley
Test that the stored inventory hash is correct when bundles are used
1061
    def make_repo_with_installed_revisions(self):
1062
        tree = self.make_simple_tree('knit')
1063
        tree.commit('hello', rev_id='rev1')
1064
        tree.commit('hello', rev_id='rev2')
1065
        bundle = read_bundle(self.create_bundle_text('null:', 'rev2')[0])
1066
        repo = self.make_repository('repo', format='dirstate-with-subtree')
1067
        bundle.install_revisions(repo)
1068
        return repo
1069
2520.4.99 by Aaron Bentley
Test conversion across models
1070
    def test_across_models(self):
3380.1.8 by Aaron Bentley
Test that the stored inventory hash is correct when bundles are used
1071
        repo = self.make_repo_with_installed_revisions()
3380.1.12 by Aaron Bentley
fix test
1072
        inv = repo.get_inventory('rev2')
2520.4.99 by Aaron Bentley
Test conversion across models
1073
        self.assertEqual('rev2', inv.root.revision)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1074
        root_id = inv.root.file_id
1075
        repo.lock_read()
1076
        self.addCleanup(repo.unlock)
1077
        self.assertEqual({(root_id, 'rev1'):(),
1078
            (root_id, 'rev2'):((root_id, 'rev1'),)},
1079
            repo.texts.get_parent_map([(root_id, 'rev1'), (root_id, 'rev2')]))
2520.4.99 by Aaron Bentley
Test conversion across models
1080
3380.1.8 by Aaron Bentley
Test that the stored inventory hash is correct when bundles are used
1081
    def test_inv_hash_across_serializers(self):
1082
        repo = self.make_repo_with_installed_revisions()
4988.3.1 by Jelmer Vernooij
Remove Repository.get_inventory_sha1().
1083
        recorded_inv_sha1 = repo.get_revision('rev2').inventory_sha1
4988.5.1 by Jelmer Vernooij
Rename Repository.get_inventory_xml -> Repository._get_inventory_xml.
1084
        xml = repo._get_inventory_xml('rev2')
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1085
        self.assertEqual(osutils.sha_string(xml), recorded_inv_sha1)
3380.1.8 by Aaron Bentley
Test that the stored inventory hash is correct when bundles are used
1086
2520.4.99 by Aaron Bentley
Test conversion across models
1087
    def test_across_models_incompatible(self):
1088
        tree = self.make_simple_tree('dirstate-with-subtree')
1089
        tree.commit('hello', rev_id='rev1')
1090
        tree.commit('hello', rev_id='rev2')
1091
        try:
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1092
            bundle = read_bundle(self.create_bundle_text('null:', 'rev1')[0])
2520.4.99 by Aaron Bentley
Test conversion across models
1093
        except errors.IncompatibleBundleFormat:
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1094
            raise tests.TestSkipped("Format 0.8 doesn't work with knit3")
2520.4.99 by Aaron Bentley
Test conversion across models
1095
        repo = self.make_repository('repo', format='knit')
1096
        bundle.install_revisions(repo)
1097
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1098
        bundle = read_bundle(self.create_bundle_text('null:', 'rev2')[0])
2520.4.99 by Aaron Bentley
Test conversion across models
1099
        self.assertRaises(errors.IncompatibleRevision,
1100
                          bundle.install_revisions, repo)
2520.4.97 by Aaron Bentley
Hack in support for inventory conversion
1101
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
1102
    def test_get_merge_request(self):
1103
        tree = self.make_simple_tree()
1104
        tree.commit('hello', rev_id='rev1')
1105
        tree.commit('hello', rev_id='rev2')
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1106
        bundle = read_bundle(self.create_bundle_text('null:', 'rev1')[0])
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
1107
        result = bundle.get_merge_request(tree.branch.repository)
1108
        self.assertEqual((None, 'rev1', 'inapplicable'), result)
1109
2520.5.1 by Aaron Bentley
Test installing revisions with subtrees
1110
    def test_with_subtree(self):
1111
        tree = self.make_branch_and_tree('tree',
1112
                                         format='dirstate-with-subtree')
1113
        self.b1 = tree.branch
1114
        subtree = self.make_branch_and_tree('tree/subtree',
1115
                                            format='dirstate-with-subtree')
1116
        tree.add('subtree')
1117
        tree.commit('hello', rev_id='rev1')
1118
        try:
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1119
            bundle = read_bundle(self.create_bundle_text('null:', 'rev1')[0])
2520.5.1 by Aaron Bentley
Test installing revisions with subtrees
1120
        except errors.IncompatibleBundleFormat:
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1121
            raise tests.TestSkipped("Format 0.8 doesn't work with knit3")
2520.5.1 by Aaron Bentley
Test installing revisions with subtrees
1122
        if isinstance(bundle, v09.BundleInfo09):
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1123
            raise tests.TestSkipped("Format 0.9 doesn't work with subtrees")
2520.5.1 by Aaron Bentley
Test installing revisions with subtrees
1124
        repo = self.make_repository('repo', format='knit')
1125
        self.assertRaises(errors.IncompatibleRevision,
1126
                          bundle.install_revisions, repo)
1127
        repo2 = self.make_repository('repo2', format='dirstate-with-subtree')
1128
        bundle.install_revisions(repo2)
1129
2520.4.127 by Aaron Bentley
Fix up name encoding to handle revision-ids with slashes
1130
    def test_revision_id_with_slash(self):
1131
        self.tree1 = self.make_branch_and_tree('tree')
1132
        self.b1 = self.tree1.branch
1133
        try:
1134
            self.tree1.commit('Revision/id/with/slashes', rev_id='rev/id')
1135
        except ValueError:
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1136
            raise tests.TestSkipped(
1137
                "Repository doesn't support revision ids with slashes")
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1138
        bundle = self.get_valid_bundle('null:', 'rev/id')
2520.4.127 by Aaron Bentley
Fix up name encoding to handle revision-ids with slashes
1139
2520.6.2 by Aaron Bentley
Fix bundle installation wrong-versionedfile bug
1140
    def test_skip_file(self):
1141
        """Make sure we don't accidentally write to the wrong versionedfile"""
1142
        self.tree1 = self.make_branch_and_tree('tree')
1143
        self.b1 = self.tree1.branch
1144
        # rev1 is not present in bundle, done by fetch
1145
        self.build_tree_contents([('tree/file2', 'contents1')])
1146
        self.tree1.add('file2', 'file2-id')
1147
        self.tree1.commit('rev1', rev_id='reva')
1148
        self.build_tree_contents([('tree/file3', 'contents2')])
1149
        # rev2 is present in bundle, and done by fetch
1150
        # having file1 in the bunle causes file1's versionedfile to be opened.
1151
        self.tree1.add('file3', 'file3-id')
1152
        self.tree1.commit('rev2')
1153
        # Updating file2 should not cause an attempt to add to file1's vf
1154
        target = self.tree1.bzrdir.sprout('target').open_workingtree()
1155
        self.build_tree_contents([('tree/file2', 'contents3')])
1156
        self.tree1.commit('rev3', rev_id='rev3')
1157
        bundle = self.get_valid_bundle('reva', 'rev3')
2520.6.5 by Aaron Bentley
Skip for bundle formats that don't provide get_bundle_reader
1158
        if getattr(bundle, 'get_bundle_reader', None) is None:
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1159
            raise tests.TestSkipped('Bundle format cannot provide reader')
2520.6.2 by Aaron Bentley
Fix bundle installation wrong-versionedfile bug
1160
        # be sure that file1 comes before file2
1161
        for b, m, k, r, f in bundle.get_bundle_reader().iter_records():
1162
            if f == 'file3-id':
1163
                break
1164
            self.assertNotEqual(f, 'file2-id')
1165
        bundle.install_revisions(target.branch.repository)
1166
2520.4.43 by Aaron Bentley
Fix test suite
1167
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1168
class V08BundleTester(BundleTester, tests.TestCaseWithTransport):
2520.4.33 by Aaron Bentley
remove test dependencies on serialization minutia
1169
1170
    format = '0.8'
1171
1172
    def test_bundle_empty_property(self):
1173
        """Test serializing revision properties with an empty value."""
1174
        tree = self.make_branch_and_memory_tree('tree')
1175
        tree.lock_write()
1176
        self.addCleanup(tree.unlock)
1177
        tree.add([''], ['TREE_ROOT'])
1178
        tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
1179
        self.b1 = tree.branch
2520.4.132 by Aaron Bentley
Merge from bzr.dev
1180
        bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
2447.1.2 by John Arbash Meinel
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
1181
        self.assertContainsRe(bundle_sio.getvalue(),
1182
                              '# properties:\n'
1183
                              '#   branch-nick: tree\n'
2447.1.3 by John Arbash Meinel
Change the default serializer to include a trailing whitespace for empty properties.
1184
                              '#   empty: \n'
2447.1.2 by John Arbash Meinel
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
1185
                              '#   one: two\n'
1186
                             )
1187
        bundle = read_bundle(bundle_sio)
1188
        revision_info = bundle.revisions[0]
1189
        self.assertEqual('rev1', revision_info.revision_id)
1190
        rev = revision_info.as_revision()
1191
        self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
1192
                         rev.properties)
1193
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
1194
    def get_bundle_tree(self, bundle, revision_id):
1195
        repository = self.make_repository('repo')
1196
        return bundle.revision_tree(repository, 'revid1')
1197
2447.1.2 by John Arbash Meinel
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
1198
    def test_bundle_empty_property_alt(self):
2447.1.3 by John Arbash Meinel
Change the default serializer to include a trailing whitespace for empty properties.
1199
        """Test serializing revision properties with an empty value.
1200
1201
        Older readers had a bug when reading an empty property.
1202
        They assumed that all keys ended in ': \n'. However they would write an
1203
        empty value as ':\n'. This tests make sure that all newer bzr versions
1204
        can handle th second form.
1205
        """
2447.1.2 by John Arbash Meinel
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
1206
        tree = self.make_branch_and_memory_tree('tree')
1207
        tree.lock_write()
1208
        self.addCleanup(tree.unlock)
1209
        tree.add([''], ['TREE_ROOT'])
1210
        tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
1211
        self.b1 = tree.branch
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
1212
        bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
2447.1.2 by John Arbash Meinel
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
1213
        txt = bundle_sio.getvalue()
2447.1.3 by John Arbash Meinel
Change the default serializer to include a trailing whitespace for empty properties.
1214
        loc = txt.find('#   empty: ') + len('#   empty:')
1215
        # Create a new bundle, which strips the trailing space after empty
1216
        bundle_sio = StringIO(txt[:loc] + txt[loc+1:])
2447.1.2 by John Arbash Meinel
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
1217
1218
        self.assertContainsRe(bundle_sio.getvalue(),
1219
                              '# properties:\n'
1220
                              '#   branch-nick: tree\n'
2447.1.3 by John Arbash Meinel
Change the default serializer to include a trailing whitespace for empty properties.
1221
                              '#   empty:\n'
2447.1.2 by John Arbash Meinel
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
1222
                              '#   one: two\n'
1223
                             )
1224
        bundle = read_bundle(bundle_sio)
1225
        revision_info = bundle.revisions[0]
1226
        self.assertEqual('rev1', revision_info.revision_id)
1227
        rev = revision_info.as_revision()
1228
        self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
1229
                         rev.properties)
1230
2447.1.1 by John Arbash Meinel
For stability and ease of testing, write properties in sorted order.
1231
    def test_bundle_sorted_properties(self):
1232
        """For stability the writer should write properties in sorted order."""
1233
        tree = self.make_branch_and_memory_tree('tree')
1234
        tree.lock_write()
1235
        self.addCleanup(tree.unlock)
1236
1237
        tree.add([''], ['TREE_ROOT'])
1238
        tree.commit('One', rev_id='rev1',
1239
                    revprops={'a':'4', 'b':'3', 'c':'2', 'd':'1'})
1240
        self.b1 = tree.branch
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
1241
        bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
2447.1.1 by John Arbash Meinel
For stability and ease of testing, write properties in sorted order.
1242
        self.assertContainsRe(bundle_sio.getvalue(),
1243
                              '# properties:\n'
1244
                              '#   a: 4\n'
1245
                              '#   b: 3\n'
1246
                              '#   branch-nick: tree\n'
1247
                              '#   c: 2\n'
1248
                              '#   d: 1\n'
1249
                             )
2447.1.4 by John Arbash Meinel
Add a test that we properly round-trip unicode properties.
1250
        bundle = read_bundle(bundle_sio)
1251
        revision_info = bundle.revisions[0]
1252
        self.assertEqual('rev1', revision_info.revision_id)
1253
        rev = revision_info.as_revision()
1254
        self.assertEqual({'branch-nick':'tree', 'a':'4', 'b':'3', 'c':'2',
1255
                          'd':'1'}, rev.properties)
1256
1257
    def test_bundle_unicode_properties(self):
1258
        """We should be able to round trip a non-ascii property."""
1259
        tree = self.make_branch_and_memory_tree('tree')
1260
        tree.lock_write()
1261
        self.addCleanup(tree.unlock)
1262
1263
        tree.add([''], ['TREE_ROOT'])
1264
        # Revisions themselves do not require anything about revision property
1265
        # keys, other than that they are a basestring, and do not contain
1266
        # whitespace.
1267
        # However, Testaments assert than they are str(), and thus should not
1268
        # be Unicode.
1269
        tree.commit('One', rev_id='rev1',
1270
                    revprops={'omega':u'\u03a9', 'alpha':u'\u03b1'})
1271
        self.b1 = tree.branch
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
1272
        bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
2447.1.4 by John Arbash Meinel
Add a test that we properly round-trip unicode properties.
1273
        self.assertContainsRe(bundle_sio.getvalue(),
1274
                              '# properties:\n'
1275
                              '#   alpha: \xce\xb1\n'
1276
                              '#   branch-nick: tree\n'
1277
                              '#   omega: \xce\xa9\n'
1278
                             )
1279
        bundle = read_bundle(bundle_sio)
1280
        revision_info = bundle.revisions[0]
1281
        self.assertEqual('rev1', revision_info.revision_id)
1282
        rev = revision_info.as_revision()
1283
        self.assertEqual({'branch-nick':'tree', 'omega':u'\u03a9',
1284
                          'alpha':u'\u03b1'}, rev.properties)
2447.1.1 by John Arbash Meinel
For stability and ease of testing, write properties in sorted order.
1285
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1286
1910.2.59 by Aaron Bentley
Test 0.9 bundles for knit format1 and knit format2
1287
class V09BundleKnit2Tester(V08BundleTester):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
1288
1289
    format = '0.9'
1290
1291
    def bzrdir_format(self):
1292
        format = bzrdir.BzrDirMetaFormat1()
2255.2.211 by Robert Collins
Remove knit2 repository format- it has never been supported.
1293
        format.repository_format = knitrepo.RepositoryFormatKnit3()
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
1294
        return format
1295
1296
1910.2.59 by Aaron Bentley
Test 0.9 bundles for knit format1 and knit format2
1297
class V09BundleKnit1Tester(V08BundleTester):
1298
1299
    format = '0.9'
1300
1301
    def bzrdir_format(self):
1302
        format = bzrdir.BzrDirMetaFormat1()
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
1303
        format.repository_format = knitrepo.RepositoryFormatKnit1()
1910.2.59 by Aaron Bentley
Test 0.9 bundles for knit format1 and knit format2
1304
        return format
1305
1306
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1307
class V4BundleTester(BundleTester, tests.TestCaseWithTransport):
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1308
2520.4.136 by Aaron Bentley
Fix format strings
1309
    format = '4'
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1310
1311
    def get_valid_bundle(self, base_rev_id, rev_id, checkout_dir=None):
1312
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
1313
        Make sure that the text generated is valid, and that it
1314
        can be applied against the base, and generate the same information.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1315
1316
        :return: The in-memory bundle
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1317
        """
1318
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
1319
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1320
        # This should also validate the generated bundle
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1321
        bundle = read_bundle(bundle_txt)
1322
        repository = self.b1.repository
1323
        for bundle_rev in bundle.real_revisions:
1324
            # These really should have already been checked when we read the
1325
            # bundle, since it computes the sha1 hash for the revision, which
1326
            # only will match if everything is okay, but lets be explicit about
1327
            # it
1328
            branch_rev = repository.get_revision(bundle_rev.revision_id)
1329
            for a in ('inventory_sha1', 'revision_id', 'parent_ids',
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1330
                      'timestamp', 'timezone', 'message', 'committer',
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1331
                      'parent_ids', 'properties'):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1332
                self.assertEqual(getattr(branch_rev, a),
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1333
                                 getattr(bundle_rev, a))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1334
            self.assertEqual(len(branch_rev.parent_ids),
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1335
                             len(bundle_rev.parent_ids))
2520.4.29 by Aaron Bentley
Reactivate some testing, fix topo_iter
1336
        self.assertEqual(set(rev_ids),
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
1337
                         {r.revision_id for r in bundle.real_revisions})
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1338
        self.valid_apply_bundle(base_rev_id, bundle,
1339
                                   checkout_dir=checkout_dir)
1340
1341
        return bundle
1342
2520.4.34 by Aaron Bentley
Add signature support
1343
    def get_invalid_bundle(self, base_rev_id, rev_id):
1344
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
1345
        Munge the text so that it's invalid.
1346
1347
        :return: The in-memory bundle
1348
        """
1349
        from bzrlib.bundle import serializer
1350
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
1351
        new_text = self.get_raw(StringIO(''.join(bundle_txt)))
1352
        new_text = new_text.replace('<file file_id="exe-1"',
1353
                                    '<file executable="y" file_id="exe-1"')
4543.2.11 by John Arbash Meinel
Use a fixed file-id for the root to make the tests more stable.
1354
        new_text = new_text.replace('B260', 'B275')
2520.4.34 by Aaron Bentley
Add signature support
1355
        bundle_txt = StringIO()
2520.4.136 by Aaron Bentley
Fix format strings
1356
        bundle_txt.write(serializer._get_bundle_header('4'))
2520.4.34 by Aaron Bentley
Add signature support
1357
        bundle_txt.write('\n')
2520.4.76 by Aaron Bentley
Move base64-encoding into merge directives
1358
        bundle_txt.write(new_text.encode('bz2'))
2520.4.34 by Aaron Bentley
Add signature support
1359
        bundle_txt.seek(0)
1360
        bundle = read_bundle(bundle_txt)
1361
        self.valid_apply_bundle(base_rev_id, bundle)
1362
        return bundle
1363
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1364
    def create_bundle_text(self, base_rev_id, rev_id):
1365
        bundle_txt = StringIO()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1366
        rev_ids = write_bundle(self.b1.repository, rev_id, base_rev_id,
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1367
                               bundle_txt, format=self.format)
1368
        bundle_txt.seek(0)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1369
        self.assertEqual(bundle_txt.readline(),
2520.4.14 by Aaron Bentley
Get most tests passing, use format header
1370
                         '# Bazaar revision bundle v%s\n' % self.format)
1371
        self.assertEqual(bundle_txt.readline(), '#\n')
1372
        rev = self.b1.repository.get_revision(rev_id)
1373
        bundle_txt.seek(0)
1374
        return bundle_txt, rev_ids
2520.4.4 by Aaron Bentley
Get basis support for a new bundle format in place
1375
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
1376
    def get_bundle_tree(self, bundle, revision_id):
1377
        repository = self.make_repository('repo')
1378
        bundle.install_revisions(repository)
1379
        return repository.revision_tree(revision_id)
1380
2520.4.4 by Aaron Bentley
Get basis support for a new bundle format in place
1381
    def test_creation(self):
1382
        tree = self.make_branch_and_tree('tree')
2520.4.8 by Aaron Bentley
Serialize inventory
1383
        self.build_tree_contents([('tree/file', 'contents1\nstatic\n')])
2520.4.6 by Aaron Bentley
Get installation started
1384
        tree.add('file', 'fileid-2')
2520.4.4 by Aaron Bentley
Get basis support for a new bundle format in place
1385
        tree.commit('added file', rev_id='rev1')
2520.4.8 by Aaron Bentley
Serialize inventory
1386
        self.build_tree_contents([('tree/file', 'contents2\nstatic\n')])
2520.4.10 by Aaron Bentley
Enable installation of revisions
1387
        tree.commit('changed file', rev_id='rev2')
2520.4.4 by Aaron Bentley
Get basis support for a new bundle format in place
1388
        s = StringIO()
2520.4.72 by Aaron Bentley
Rename format to 4alpha
1389
        serializer = BundleSerializerV4('1.0')
2520.4.8 by Aaron Bentley
Serialize inventory
1390
        serializer.write(tree.branch.repository, ['rev1', 'rev2'], {}, s)
2520.4.5 by Aaron Bentley
Start work on reading mpbundles
1391
        s.seek(0)
2520.4.6 by Aaron Bentley
Get installation started
1392
        tree2 = self.make_branch_and_tree('target')
1393
        target_repo = tree2.branch.repository
1394
        install_bundle(target_repo, serializer.read(s))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1395
        target_repo.lock_read()
1396
        self.addCleanup(target_repo.unlock)
4202.1.1 by John Arbash Meinel
Update Repository.iter_files_bytes() to return an iterable of bytestrings.
1397
        # Turn the 'iterators_of_bytes' back into simple strings for comparison
1398
        repo_texts = dict((i, ''.join(content)) for i, content
1399
                          in target_repo.iter_files_bytes(
1400
                                [('fileid-2', 'rev1', '1'),
1401
                                 ('fileid-2', 'rev2', '2')]))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1402
        self.assertEqual({'1':'contents1\nstatic\n',
4202.1.1 by John Arbash Meinel
Update Repository.iter_files_bytes() to return an iterable of bytestrings.
1403
                          '2':'contents2\nstatic\n'},
1404
                         repo_texts)
2520.4.8 by Aaron Bentley
Serialize inventory
1405
        rtree = target_repo.revision_tree('rev2')
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1406
        inventory_vf = target_repo.inventories
1407
        # If the inventory store has a graph, it must match the revision graph.
1408
        self.assertSubset(
1409
            [inventory_vf.get_parent_map([('rev2',)])[('rev2',)]],
1410
            [None, (('rev1',),)])
2520.4.10 by Aaron Bentley
Enable installation of revisions
1411
        self.assertEqual('changed file',
1412
                         target_repo.get_revision('rev2').message)
2520.4.6 by Aaron Bentley
Get installation started
1413
2520.4.32 by Aaron Bentley
Fix test case
1414
    @staticmethod
1415
    def get_raw(bundle_file):
1416
        bundle_file.seek(0)
2520.4.70 by Aaron Bentley
Yank patch-handling functionality
1417
        line = bundle_file.readline()
1418
        line = bundle_file.readline()
2520.4.32 by Aaron Bentley
Fix test case
1419
        lines = bundle_file.readlines()
2520.4.76 by Aaron Bentley
Move base64-encoding into merge directives
1420
        return ''.join(lines).decode('bz2')
2520.4.32 by Aaron Bentley
Fix test case
1421
2520.4.34 by Aaron Bentley
Add signature support
1422
    def test_copy_signatures(self):
1423
        tree_a = self.make_branch_and_tree('tree_a')
1424
        import bzrlib.gpg
1425
        import bzrlib.commit as commit
1426
        oldstrategy = bzrlib.gpg.GPGStrategy
1427
        branch = tree_a.branch
1428
        repo_a = branch.repository
1429
        tree_a.commit("base", allow_pointless=True, rev_id='A')
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
1430
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
2520.4.34 by Aaron Bentley
Add signature support
1431
        try:
1432
            from bzrlib.testament import Testament
1433
            # monkey patch gpg signing mechanism
1434
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
6393.1.1 by Vincent Ladeuil
Provides MemoryStack to simplify configuration setup in tests
1435
            new_config = test_commit.MustSignConfig()
6351.3.3 by Jelmer Vernooij
Convert more stuff to use config stacks.
1436
            commit.Commit(config_stack=new_config).commit(message="base",
2520.4.34 by Aaron Bentley
Add signature support
1437
                                                    allow_pointless=True,
1438
                                                    rev_id='B',
1439
                                                    working_tree=tree_a)
1440
            def sign(text):
1441
                return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
1442
            self.assertTrue(repo_a.has_signature_for_revision_id('B'))
1443
        finally:
1444
            bzrlib.gpg.GPGStrategy = oldstrategy
1445
        tree_b = self.make_branch_and_tree('tree_b')
1446
        repo_b = tree_b.branch.repository
1447
        s = StringIO()
2520.4.136 by Aaron Bentley
Fix format strings
1448
        serializer = BundleSerializerV4('4')
2520.4.34 by Aaron Bentley
Add signature support
1449
        serializer.write(tree_a.branch.repository, ['A', 'B'], {}, s)
1450
        s.seek(0)
1451
        install_bundle(repo_b, serializer.read(s))
1452
        self.assertTrue(repo_b.has_signature_for_revision_id('B'))
1453
        self.assertEqual(repo_b.get_signature_text('B'),
1454
                         repo_a.get_signature_text('B'))
2520.4.100 by Aaron Bentley
Fix repeat signature installs
1455
        s.seek(0)
1456
        # ensure repeat installs are harmless
1457
        install_bundle(repo_b, serializer.read(s))
2520.4.34 by Aaron Bentley
Add signature support
1458
2520.4.4 by Aaron Bentley
Get basis support for a new bundle format in place
1459
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1460
class V4_2aBundleTester(V4BundleTester):
1461
1462
    def bzrdir_format(self):
1463
        return '2a'
1464
4543.2.8 by John Arbash Meinel
Add a custom get_invalid_bundle and allow BadBundle to be
1465
    def get_invalid_bundle(self, base_rev_id, rev_id):
1466
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
1467
        Munge the text so that it's invalid.
1468
1469
        :return: The in-memory bundle
1470
        """
1471
        from bzrlib.bundle import serializer
1472
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
1473
        new_text = self.get_raw(StringIO(''.join(bundle_txt)))
4543.2.9 by John Arbash Meinel
Down to 2 failing tests.
1474
        # We are going to be replacing some text to set the executable bit on a
1475
        # file. Make sure the text replacement actually works correctly.
4543.2.11 by John Arbash Meinel
Use a fixed file-id for the root to make the tests more stable.
1476
        self.assertContainsRe(new_text, '(?m)B244\n\ni 1\n<inventory')
4543.2.8 by John Arbash Meinel
Add a custom get_invalid_bundle and allow BadBundle to be
1477
        new_text = new_text.replace('<file file_id="exe-1"',
1478
                                    '<file executable="y" file_id="exe-1"')
4543.2.11 by John Arbash Meinel
Use a fixed file-id for the root to make the tests more stable.
1479
        new_text = new_text.replace('B244', 'B259')
4543.2.8 by John Arbash Meinel
Add a custom get_invalid_bundle and allow BadBundle to be
1480
        bundle_txt = StringIO()
1481
        bundle_txt.write(serializer._get_bundle_header('4'))
1482
        bundle_txt.write('\n')
1483
        bundle_txt.write(new_text.encode('bz2'))
1484
        bundle_txt.seek(0)
1485
        bundle = read_bundle(bundle_txt)
1486
        self.valid_apply_bundle(base_rev_id, bundle)
1487
        return bundle
1488
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1489
    def make_merged_branch(self):
4543.2.6 by John Arbash Meinel
redefinning self.bzrdir_format() automatically sets the default format.
1490
        builder = self.make_branch_builder('source')
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1491
        builder.start_series()
1492
        builder.build_snapshot('a@cset-0-1', None, [
1493
            ('add', ('', 'root-id', 'directory', None)),
1494
            ('add', ('file', 'file-id', 'file', 'original content\n')),
1495
            ])
1496
        builder.build_snapshot('a@cset-0-2a', ['a@cset-0-1'], [
1497
            ('modify', ('file-id', 'new-content\n')),
1498
            ])
1499
        builder.build_snapshot('a@cset-0-2b', ['a@cset-0-1'], [
1500
            ('add', ('other-file', 'file2-id', 'file', 'file2-content\n')),
1501
            ])
1502
        builder.build_snapshot('a@cset-0-3', ['a@cset-0-2a', 'a@cset-0-2b'], [
1503
            ('add', ('other-file', 'file2-id', 'file', 'file2-content\n')),
1504
            ])
1505
        builder.finish_series()
1506
        self.b1 = builder.get_branch()
1507
        self.b1.lock_read()
1508
        self.addCleanup(self.b1.unlock)
1509
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1510
    def make_bundle_just_inventories(self, base_revision_id,
1511
                                     target_revision_id,
1512
                                     revision_ids):
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1513
        sio = StringIO()
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1514
        writer = v4.BundleWriteOperation(base_revision_id, target_revision_id,
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1515
                                         self.b1.repository, sio)
1516
        writer.bundle.begin()
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1517
        writer._add_inventory_mpdiffs_from_serializer(revision_ids)
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1518
        writer.bundle.end()
1519
        sio.seek(0)
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1520
        return sio
1521
1522
    def test_single_inventory_multiple_parents_as_xml(self):
1523
        self.make_merged_branch()
1524
        sio = self.make_bundle_just_inventories('a@cset-0-1', 'a@cset-0-3',
1525
                                                ['a@cset-0-3'])
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1526
        reader = v4.BundleReader(sio, stream_input=False)
1527
        records = list(reader.iter_records())
1528
        self.assertEqual(1, len(records))
1529
        (bytes, metadata, repo_kind, revision_id,
1530
         file_id) = records[0]
1531
        self.assertIs(None, file_id)
1532
        self.assertEqual('a@cset-0-3', revision_id)
1533
        self.assertEqual('inventory', repo_kind)
1534
        self.assertEqual({'parents': ['a@cset-0-2a', 'a@cset-0-2b'],
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1535
                          'sha1': '09c53b0c4de0895e11a2aacc34fef60a6e70865c',
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1536
                          'storage_kind': 'mpdiff',
1537
                         }, metadata)
1538
        # We should have an mpdiff that takes some lines from both parents.
1539
        self.assertEqualDiff(
1540
            'i 1\n'
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1541
            '<inventory format="10" revision_id="a@cset-0-3">\n'
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1542
            '\n'
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1543
            'c 0 1 1 2\n'
1544
            'c 1 3 3 2\n', bytes)
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1545
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1546
    def test_single_inv_no_parents_as_xml(self):
1547
        self.make_merged_branch()
1548
        sio = self.make_bundle_just_inventories('null:', 'a@cset-0-1',
1549
                                                ['a@cset-0-1'])
1550
        reader = v4.BundleReader(sio, stream_input=False)
1551
        records = list(reader.iter_records())
1552
        self.assertEqual(1, len(records))
1553
        (bytes, metadata, repo_kind, revision_id,
1554
         file_id) = records[0]
1555
        self.assertIs(None, file_id)
1556
        self.assertEqual('a@cset-0-1', revision_id)
1557
        self.assertEqual('inventory', repo_kind)
1558
        self.assertEqual({'parents': [],
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1559
                          'sha1': 'a13f42b142d544aac9b085c42595d304150e31a2',
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1560
                          'storage_kind': 'mpdiff',
1561
                         }, metadata)
1562
        # We should have an mpdiff that takes some lines from both parents.
1563
        self.assertEqualDiff(
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1564
            'i 4\n'
1565
            '<inventory format="10" revision_id="a@cset-0-1">\n'
1566
            '<directory file_id="root-id" name=""'
1567
                ' revision="a@cset-0-1" />\n'
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1568
            '<file file_id="file-id" name="file" parent_id="root-id"'
1569
                ' revision="a@cset-0-1"'
1570
                ' text_sha1="09c2f8647e14e49e922b955c194102070597c2d1"'
1571
                ' text_size="17" />\n'
1572
            '</inventory>\n'
1573
            '\n', bytes)
1574
1575
    def test_multiple_inventories_as_xml(self):
1576
        self.make_merged_branch()
1577
        sio = self.make_bundle_just_inventories('a@cset-0-1', 'a@cset-0-3',
1578
            ['a@cset-0-2a', 'a@cset-0-2b', 'a@cset-0-3'])
1579
        reader = v4.BundleReader(sio, stream_input=False)
1580
        records = list(reader.iter_records())
1581
        self.assertEqual(3, len(records))
1582
        revision_ids = [rev_id for b, m, k, rev_id, f in records]
1583
        self.assertEqual(['a@cset-0-2a', 'a@cset-0-2b', 'a@cset-0-3'],
1584
                         revision_ids)
1585
        metadata_2a = records[0][1]
1586
        self.assertEqual({'parents': ['a@cset-0-1'],
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1587
                          'sha1': '1e105886d62d510763e22885eec733b66f5f09bf',
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1588
                          'storage_kind': 'mpdiff',
1589
                         }, metadata_2a)
1590
        metadata_2b = records[1][1]
1591
        self.assertEqual({'parents': ['a@cset-0-1'],
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1592
                          'sha1': 'f03f12574bdb5ed2204c28636c98a8547544ccd8',
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1593
                          'storage_kind': 'mpdiff',
1594
                         }, metadata_2b)
1595
        metadata_3 = records[2][1]
1596
        self.assertEqual({'parents': ['a@cset-0-2a', 'a@cset-0-2b'],
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1597
                          'sha1': '09c53b0c4de0895e11a2aacc34fef60a6e70865c',
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1598
                          'storage_kind': 'mpdiff',
1599
                         }, metadata_3)
1600
        bytes_2a = records[0][0]
1601
        self.assertEqualDiff(
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1602
            'i 1\n'
1603
            '<inventory format="10" revision_id="a@cset-0-2a">\n'
1604
            '\n'
1605
            'c 0 1 1 1\n'
1606
            'i 1\n'
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1607
            '<file file_id="file-id" name="file" parent_id="root-id"'
1608
                ' revision="a@cset-0-2a"'
1609
                ' text_sha1="50f545ff40e57b6924b1f3174b267ffc4576e9a9"'
1610
                ' text_size="12" />\n'
1611
            '\n'
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1612
            'c 0 3 3 1\n', bytes_2a)
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1613
        bytes_2b = records[1][0]
1614
        self.assertEqualDiff(
1615
            'i 1\n'
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1616
            '<inventory format="10" revision_id="a@cset-0-2b">\n'
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1617
            '\n'
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1618
            'c 0 1 1 2\n'
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1619
            'i 1\n'
1620
            '<file file_id="file2-id" name="other-file" parent_id="root-id"'
1621
                ' revision="a@cset-0-2b"'
1622
                ' text_sha1="b46c0c8ea1e5ef8e46fc8894bfd4752a88ec939e"'
1623
                ' text_size="14" />\n'
1624
            '\n'
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1625
            'c 0 3 4 1\n', bytes_2b)
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1626
        bytes_3 = records[2][0]
1627
        self.assertEqualDiff(
1628
            'i 1\n'
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1629
            '<inventory format="10" revision_id="a@cset-0-3">\n'
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1630
            '\n'
4543.2.7 by John Arbash Meinel
It turns out CHKSerializer was inheriting from xml5
1631
            'c 0 1 1 2\n'
1632
            'c 1 3 3 2\n', bytes_3)
1633
1634
    def test_creating_bundle_preserves_chk_pages(self):
1635
        self.make_merged_branch()
1636
        target = self.b1.bzrdir.sprout('target',
1637
                                       revision_id='a@cset-0-2a').open_branch()
1638
        bundle_txt, rev_ids = self.create_bundle_text('a@cset-0-2a',
1639
                                                      'a@cset-0-3')
1640
        self.assertEqual(['a@cset-0-2b', 'a@cset-0-3'], rev_ids)
1641
        bundle = read_bundle(bundle_txt)
1642
        target.lock_write()
1643
        self.addCleanup(target.unlock)
1644
        install_bundle(target.repository, bundle)
1645
        inv1 = self.b1.repository.inventories.get_record_stream([
1646
            ('a@cset-0-3',)], 'unordered',
1647
            True).next().get_bytes_as('fulltext')
1648
        inv2 = target.repository.inventories.get_record_stream([
1649
            ('a@cset-0-3',)], 'unordered',
1650
            True).next().get_bytes_as('fulltext')
1651
        self.assertEqualDiff(inv1, inv2)
4543.2.5 by John Arbash Meinel
Fix issues with keys/ids and ghost handling.
1652
4543.2.4 by John Arbash Meinel
Start working on code that will use Repository._serializer.write_inventory_to_strig.
1653
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
1654
class MungedBundleTester(object):
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1655
1656
    def build_test_bundle(self):
1657
        wt = self.make_branch_and_tree('b1')
1658
1659
        self.build_tree(['b1/one'])
1660
        wt.add('one')
1661
        wt.commit('add one', rev_id='a@cset-0-1')
1662
        self.build_tree(['b1/two'])
1663
        wt.add('two')
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
1664
        wt.commit('add two', rev_id='a@cset-0-2',
1665
                  revprops={'branch-nick':'test'})
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1666
1667
        bundle_txt = StringIO()
1668
        rev_ids = write_bundle(wt.branch.repository, 'a@cset-0-2',
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
1669
                               'a@cset-0-1', bundle_txt, self.format)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
1670
        self.assertEqual({'a@cset-0-2'}, set(rev_ids))
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1671
        bundle_txt.seek(0, 0)
1672
        return bundle_txt
1673
1674
    def check_valid(self, bundle):
1675
        """Check that after whatever munging, the final object is valid."""
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
1676
        self.assertEqual(['a@cset-0-2'],
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
1677
            [r.revision_id for r in bundle.real_revisions])
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1678
1679
    def test_extra_whitespace(self):
1680
        bundle_txt = self.build_test_bundle()
1681
1682
        # Seek to the end of the file
1683
        # Adding one extra newline used to give us
1684
        # TypeError: float() argument must be a string or a number
1685
        bundle_txt.seek(0, 2)
1686
        bundle_txt.write('\n')
1687
        bundle_txt.seek(0)
1688
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
1689
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1690
        self.check_valid(bundle)
1691
1692
    def test_extra_whitespace_2(self):
1693
        bundle_txt = self.build_test_bundle()
1694
1695
        # Seek to the end of the file
1696
        # Adding two extra newlines used to give us
1697
        # MalformedPatches: The first line of all patches should be ...
1698
        bundle_txt.seek(0, 2)
1699
        bundle_txt.write('\n\n')
1700
        bundle_txt.seek(0)
1701
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
1702
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1703
        self.check_valid(bundle)
1704
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
1705
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1706
class MungedBundleTesterV09(tests.TestCaseWithTransport, MungedBundleTester):
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
1707
1708
    format = '0.9'
1709
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1710
    def test_missing_trailing_whitespace(self):
1711
        bundle_txt = self.build_test_bundle()
1712
1713
        # Remove a trailing newline, it shouldn't kill the parser
1714
        raw = bundle_txt.getvalue()
1715
        # The contents of the bundle don't have to be this, but this
1716
        # test is concerned with the exact case where the serializer
1717
        # creates a blank line at the end, and fails if that
1718
        # line is stripped
1719
        self.assertEqual('\n\n', raw[-2:])
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
1720
        bundle_txt = StringIO(raw[:-1])
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1721
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
1722
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
1723
        self.check_valid(bundle)
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
1724
1793.3.16 by John Arbash Meinel
Add tests to ensure that we gracefully handle opening and trailing non-bundle text.
1725
    def test_opening_text(self):
1726
        bundle_txt = self.build_test_bundle()
1727
1728
        bundle_txt = StringIO("Some random\nemail comments\n"
1729
                              + bundle_txt.getvalue())
1730
1731
        bundle = read_bundle(bundle_txt)
1732
        self.check_valid(bundle)
1733
1734
    def test_trailing_text(self):
1735
        bundle_txt = self.build_test_bundle()
1736
1737
        bundle_txt = StringIO(bundle_txt.getvalue() +
1738
                              "Some trailing\nrandom\ntext\n")
1739
1740
        bundle = read_bundle(bundle_txt)
1741
        self.check_valid(bundle)
2520.4.56 by Aaron Bentley
Begin adding support for arbitrary metadata
1742
1743
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1744
class MungedBundleTesterV4(tests.TestCaseWithTransport, MungedBundleTester):
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
1745
2520.4.136 by Aaron Bentley
Fix format strings
1746
    format = '4'
2520.4.79 by Aaron Bentley
Fixed up not-really-relevant munging tests
1747
1748
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1749
class TestBundleWriterReader(tests.TestCase):
2520.4.56 by Aaron Bentley
Begin adding support for arbitrary metadata
1750
1751
    def test_roundtrip_record(self):
1752
        fileobj = StringIO()
2520.4.72 by Aaron Bentley
Rename format to 4alpha
1753
        writer = v4.BundleWriter(fileobj)
2520.4.56 by Aaron Bentley
Begin adding support for arbitrary metadata
1754
        writer.begin()
2520.4.95 by Aaron Bentley
Add support for header/info records
1755
        writer.add_info_record(foo='bar')
1756
        writer._add_record("Record body", {'parents': ['1', '3'],
1757
            'storage_kind':'fulltext'}, 'file', 'revid', 'fileid')
2520.4.56 by Aaron Bentley
Begin adding support for arbitrary metadata
1758
        writer.end()
1759
        fileobj.seek(0)
2520.4.148 by Aaron Bentley
Updates from review
1760
        reader = v4.BundleReader(fileobj, stream_input=True)
2520.4.145 by Aaron Bentley
Add memory_friendly toggle, be memory-unfriendly for merge directives
1761
        record_iter = reader.iter_records()
1762
        record = record_iter.next()
1763
        self.assertEqual((None, {'foo': 'bar', 'storage_kind': 'header'},
1764
            'info', None, None), record)
1765
        record = record_iter.next()
1766
        self.assertEqual(("Record body", {'storage_kind': 'fulltext',
1767
                          'parents': ['1', '3']}, 'file', 'revid', 'fileid'),
1768
                          record)
1769
1770
    def test_roundtrip_record_memory_hungry(self):
1771
        fileobj = StringIO()
1772
        writer = v4.BundleWriter(fileobj)
1773
        writer.begin()
1774
        writer.add_info_record(foo='bar')
1775
        writer._add_record("Record body", {'parents': ['1', '3'],
1776
            'storage_kind':'fulltext'}, 'file', 'revid', 'fileid')
1777
        writer.end()
1778
        fileobj.seek(0)
2520.4.148 by Aaron Bentley
Updates from review
1779
        reader = v4.BundleReader(fileobj, stream_input=False)
2520.4.145 by Aaron Bentley
Add memory_friendly toggle, be memory-unfriendly for merge directives
1780
        record_iter = reader.iter_records()
2520.4.95 by Aaron Bentley
Add support for header/info records
1781
        record = record_iter.next()
1782
        self.assertEqual((None, {'foo': 'bar', 'storage_kind': 'header'},
1783
            'info', None, None), record)
1784
        record = record_iter.next()
1785
        self.assertEqual(("Record body", {'storage_kind': 'fulltext',
1786
                          'parents': ['1', '3']}, 'file', 'revid', 'fileid'),
1787
                          record)
1788
2520.4.127 by Aaron Bentley
Fix up name encoding to handle revision-ids with slashes
1789
    def test_encode_name(self):
2520.4.95 by Aaron Bentley
Add support for header/info records
1790
        self.assertEqual('revision/rev1',
1791
            v4.BundleWriter.encode_name('revision', 'rev1'))
2520.4.127 by Aaron Bentley
Fix up name encoding to handle revision-ids with slashes
1792
        self.assertEqual('file/rev//1/file-id-1',
1793
            v4.BundleWriter.encode_name('file', 'rev/1', 'file-id-1'))
2520.4.95 by Aaron Bentley
Add support for header/info records
1794
        self.assertEqual('info',
1795
            v4.BundleWriter.encode_name('info', None, None))
1796
2520.4.127 by Aaron Bentley
Fix up name encoding to handle revision-ids with slashes
1797
    def test_decode_name(self):
2520.4.95 by Aaron Bentley
Add support for header/info records
1798
        self.assertEqual(('revision', 'rev1', None),
1799
            v4.BundleReader.decode_name('revision/rev1'))
2520.4.127 by Aaron Bentley
Fix up name encoding to handle revision-ids with slashes
1800
        self.assertEqual(('file', 'rev/1', 'file-id-1'),
1801
            v4.BundleReader.decode_name('file/rev//1/file-id-1'))
2520.4.95 by Aaron Bentley
Add support for header/info records
1802
        self.assertEqual(('info', None, None),
1803
                         v4.BundleReader.decode_name('info'))
2520.4.131 by Aaron Bentley
Raise BadBundle for records with wrong number of names
1804
1805
    def test_too_many_names(self):
1806
        fileobj = StringIO()
1807
        writer = v4.BundleWriter(fileobj)
1808
        writer.begin()
1809
        writer.add_info_record(foo='bar')
1810
        writer._container.add_bytes_record('blah', ['two', 'names'])
1811
        writer.end()
1812
        fileobj.seek(0)
1813
        record_iter = v4.BundleReader(fileobj).iter_records()
1814
        record = record_iter.next()
1815
        self.assertEqual((None, {'foo': 'bar', 'storage_kind': 'header'},
1816
            'info', None, None), record)
3638.3.16 by Vincent Ladeuil
Remove XFAIL from test_unicode_bundle.
1817
        self.assertRaises(errors.BadBundle, record_iter.next)
3251.4.11 by Aaron Bentley
Fix wrong local lookups
1818
1819
4241.14.13 by Vincent Ladeuil
Some more cleanup.
1820
class TestReadMergeableFromUrl(tests.TestCaseWithTransport):
3251.4.11 by Aaron Bentley
Fix wrong local lookups
1821
1822
    def test_read_mergeable_skips_local(self):
1823
        """A local bundle named like the URL should not be read.
1824
        """
1825
        out, wt = test_read_bundle.create_bundle_file(self)
1826
        class FooService(object):
1827
            """A directory service that always returns source"""
1828
1829
            def look_up(self, name, url):
1830
                return 'source'
3251.4.12 by Aaron Bentley
Updates from review
1831
        directories.register('foo:', FooService, 'Testing directory service')
4985.2.1 by Vincent Ladeuil
Deploy addAttrCleanup on the whole test suite.
1832
        self.addCleanup(directories.remove, 'foo:')
3251.4.11 by Aaron Bentley
Fix wrong local lookups
1833
        self.build_tree_contents([('./foo:bar', out.getvalue())])
1834
        self.assertRaises(errors.NotABundle, read_mergeable_from_url,
1835
                          'foo:bar')
3703.2.1 by Andrew Bennetts
Allow ConnectionReset to propagate from read_mergeable_from_url.
1836
4547.2.2 by Andrew Bennetts
Add test for read_mergeable_from_transport raising NotABundle when TooManyRedirections happens.
1837
    def test_infinite_redirects_are_not_a_bundle(self):
1838
        """If a URL causes TooManyRedirections then NotABundle is raised.
1839
        """
1840
        from bzrlib.tests.blackbox.test_push import RedirectingMemoryServer
1841
        server = RedirectingMemoryServer()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
1842
        self.start_server(server)
4547.2.2 by Andrew Bennetts
Add test for read_mergeable_from_transport raising NotABundle when TooManyRedirections happens.
1843
        url = server.get_url() + 'infinite-loop'
1844
        self.assertRaises(errors.NotABundle, read_mergeable_from_url, url)
1845
3703.2.1 by Andrew Bennetts
Allow ConnectionReset to propagate from read_mergeable_from_url.
1846
    def test_smart_server_connection_reset(self):
1847
        """If a smart server connection fails during the attempt to read a
1848
        bundle, then the ConnectionReset error should be propagated.
1849
        """
1850
        # Instantiate a server that will provoke a ConnectionReset
6206.1.9 by Vincent Ladeuil
Simpler fix for test_smart_server_connection_reset re-using more of the existing test server infrastructure.
1851
        sock_server = DisconnectingServer()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
1852
        self.start_server(sock_server)
3750.1.3 by Vincent Ladeuil
Cleanups.
1853
        # We don't really care what the url is since the server will close the
1854
        # connection without interpreting it
3703.2.1 by Andrew Bennetts
Allow ConnectionReset to propagate from read_mergeable_from_url.
1855
        url = sock_server.get_url()
1856
        self.assertRaises(errors.ConnectionReset, read_mergeable_from_url, url)
6206.1.9 by Vincent Ladeuil
Simpler fix for test_smart_server_connection_reset re-using more of the existing test server infrastructure.
1857
1858
1859
class DisconnectingHandler(SocketServer.BaseRequestHandler):
1860
    """A request handler that immediately closes any connection made to it."""
1861
1862
    def handle(self):
1863
        self.request.close()
1864
1865
1866
class DisconnectingServer(test_server.TestingTCPServerInAThread):
1867
1868
    def __init__(self):
1869
        super(DisconnectingServer, self).__init__(
1870
            ('127.0.0.1', 0),
1871
            test_server.TestingTCPServer,
1872
            DisconnectingHandler)
1873
1874
    def get_url(self):
1875
        """Return the url of the server"""
1876
        return "bzr://%s:%d/" % self.server.server_address