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