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