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