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