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