~bzr-pqm/bzr/bzr.dev

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