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