/brz/remove-bazaar

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