/brz/remove-bazaar

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