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