/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
1
# Copyright (C) 2004-2006 by 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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
19
import sys
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
20
import tempfile
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
21
1910.2.64 by Aaron Bentley
Changes from review
22
from bzrlib import (
23
    bzrdir, 
24
    errors, 
25
    inventory, 
26
    repository, 
27
    treebuilder,
28
    )
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
29
from bzrlib.builtins import merge
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
30
from bzrlib.bzrdir import BzrDir
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
31
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
1793.2.3 by Aaron Bentley
Rename read_bundle.py to bundle_data.py
32
from bzrlib.bundle.bundle_data import BundleTree
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
33
from bzrlib.bundle.serializer import write_bundle, read_bundle
1910.2.49 by Aaron Bentley
Ensure that 0.8 bundles aren't used with KnitRepository2
34
from bzrlib.bundle.serializer.v08 import BundleSerializerV08
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
35
from bzrlib.bundle.serializer.v09 import BundleSerializerV09
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
36
from bzrlib.branch import Branch
1185.82.90 by Aaron Bentley
Reorganized test suite
37
from bzrlib.diff import internal_diff
1910.2.3 by Aaron Bentley
All tests pass
38
from bzrlib.errors import (BzrError, TestamentMismatch, NotABundle, BadBundle, 
39
                           NoSuchFile,)
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
40
from bzrlib.merge import Merge3Merger
1185.82.87 by Aaron Bentley
Got symlink adding working
41
from bzrlib.osutils import has_symlinks, sha_file
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
42
from bzrlib.tests import (TestCaseInTempDir, TestCaseWithTransport,
43
                          TestCase, TestSkipped)
1185.82.66 by Aaron Bentley
Handle new executable files
44
from bzrlib.transform import TreeTransform
1185.82.17 by Aaron Bentley
More API updates
45
from bzrlib.workingtree import WorkingTree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
46
1185.82.90 by Aaron Bentley
Reorganized test suite
47
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
48
class MockTree(object):
49
    def __init__(self):
1731.1.4 by Aaron Bentley
merge from bzr.dev
50
        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)
51
        object.__init__(self)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
52
        self.paths = {ROOT_ID: ""}
53
        self.ids = {"": ROOT_ID}
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
54
        self.contents = {}
1731.1.4 by Aaron Bentley
merge from bzr.dev
55
        self.root = InventoryDirectory(ROOT_ID, '', None)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
56
57
    inventory = property(lambda x:x)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
58
59
    def __iter__(self):
60
        return self.paths.iterkeys()
61
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
62
    def __getitem__(self, file_id):
63
        if file_id == self.root.file_id:
64
            return self.root
65
        else:
66
            return self.make_entry(file_id, self.paths[file_id])
67
68
    def parent_id(self, file_id):
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
69
        parent_dir = os.path.dirname(self.paths[file_id])
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
70
        if parent_dir == "":
71
            return None
72
        return self.ids[parent_dir]
73
74
    def iter_entries(self):
75
        for path, file_id in self.ids.iteritems():
76
            yield path, self[file_id]
77
78
    def get_file_kind(self, file_id):
79
        if file_id in self.contents:
80
            kind = 'file'
81
        else:
82
            kind = 'directory'
83
        return kind
84
85
    def make_entry(self, file_id, path):
0.5.119 by John Arbash Meinel
Recreated the factory. We really need InventoryEntry.create()
86
        from bzrlib.inventory import (InventoryEntry, InventoryFile
87
                                    , InventoryDirectory, InventoryLink)
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
88
        name = os.path.basename(path)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
89
        kind = self.get_file_kind(file_id)
90
        parent_id = self.parent_id(file_id)
91
        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()
92
        if kind == 'directory':
93
            ie = InventoryDirectory(file_id, name, parent_id)
94
        elif kind == 'file':
95
            ie = InventoryFile(file_id, name, parent_id)
96
        elif kind == 'symlink':
97
            ie = InventoryLink(file_id, name, parent_id)
98
        else:
99
            raise BzrError('unknown kind %r' % kind)
0.5.91 by Aaron Bentley
Updated to match API change
100
        ie.text_sha1 = text_sha_1
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
101
        ie.text_size = text_size
102
        return ie
103
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
104
    def add_dir(self, file_id, path):
105
        self.paths[file_id] = path
106
        self.ids[path] = file_id
107
    
108
    def add_file(self, file_id, path, contents):
109
        self.add_dir(file_id, path)
110
        self.contents[file_id] = contents
111
112
    def path2id(self, path):
113
        return self.ids.get(path)
114
115
    def id2path(self, file_id):
116
        return self.paths.get(file_id)
117
118
    def has_id(self, file_id):
119
        return self.id2path(file_id) is not None
120
121
    def get_file(self, file_id):
122
        result = StringIO()
123
        result.write(self.contents[file_id])
124
        result.seek(0,0)
125
        return result
126
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
127
    def contents_stats(self, file_id):
128
        if file_id not in self.contents:
129
            return None, None
130
        text_sha1 = sha_file(self.get_file(file_id))
131
        return text_sha1, len(self.contents[file_id])
132
133
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
134
class BTreeTester(TestCase):
135
    """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)
136
137
    def make_tree_1(self):
138
        mtree = MockTree()
139
        mtree.add_dir("a", "grandparent")
140
        mtree.add_dir("b", "grandparent/parent")
141
        mtree.add_file("c", "grandparent/parent/file", "Hello\n")
142
        mtree.add_dir("d", "grandparent/alt_parent")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
143
        return BundleTree(mtree, ''), mtree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
144
        
145
    def test_renames(self):
146
        """Ensure that file renames have the proper effect on children"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
147
        btree = self.make_tree_1()[0]
148
        self.assertEqual(btree.old_path("grandparent"), "grandparent")
149
        self.assertEqual(btree.old_path("grandparent/parent"), 
150
                         "grandparent/parent")
151
        self.assertEqual(btree.old_path("grandparent/parent/file"),
152
                         "grandparent/parent/file")
153
154
        self.assertEqual(btree.id2path("a"), "grandparent")
155
        self.assertEqual(btree.id2path("b"), "grandparent/parent")
156
        self.assertEqual(btree.id2path("c"), "grandparent/parent/file")
157
158
        self.assertEqual(btree.path2id("grandparent"), "a")
159
        self.assertEqual(btree.path2id("grandparent/parent"), "b")
160
        self.assertEqual(btree.path2id("grandparent/parent/file"), "c")
161
162
        assert btree.path2id("grandparent2") is None
163
        assert btree.path2id("grandparent2/parent") is None
164
        assert btree.path2id("grandparent2/parent/file") is None
165
166
        btree.note_rename("grandparent", "grandparent2")
167
        assert btree.old_path("grandparent") is None
168
        assert btree.old_path("grandparent/parent") is None
169
        assert btree.old_path("grandparent/parent/file") is None
170
171
        self.assertEqual(btree.id2path("a"), "grandparent2")
172
        self.assertEqual(btree.id2path("b"), "grandparent2/parent")
173
        self.assertEqual(btree.id2path("c"), "grandparent2/parent/file")
174
175
        self.assertEqual(btree.path2id("grandparent2"), "a")
176
        self.assertEqual(btree.path2id("grandparent2/parent"), "b")
177
        self.assertEqual(btree.path2id("grandparent2/parent/file"), "c")
178
179
        assert btree.path2id("grandparent") is None
180
        assert btree.path2id("grandparent/parent") is None
181
        assert btree.path2id("grandparent/parent/file") is None
182
183
        btree.note_rename("grandparent/parent", "grandparent2/parent2")
184
        self.assertEqual(btree.id2path("a"), "grandparent2")
185
        self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
186
        self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file")
187
188
        self.assertEqual(btree.path2id("grandparent2"), "a")
189
        self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
190
        self.assertEqual(btree.path2id("grandparent2/parent2/file"), "c")
191
192
        assert btree.path2id("grandparent2/parent") is None
193
        assert btree.path2id("grandparent2/parent/file") is None
194
195
        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)
196
                          "grandparent2/parent2/file2")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
197
        self.assertEqual(btree.id2path("a"), "grandparent2")
198
        self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
199
        self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file2")
200
201
        self.assertEqual(btree.path2id("grandparent2"), "a")
202
        self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
203
        self.assertEqual(btree.path2id("grandparent2/parent2/file2"), "c")
204
205
        assert 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)
206
207
    def test_moves(self):
208
        """Ensure that file moves have the proper effect on children"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
209
        btree = self.make_tree_1()[0]
210
        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)
211
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
212
        self.assertEqual(btree.id2path("c"), "grandparent/alt_parent/file")
213
        self.assertEqual(btree.path2id("grandparent/alt_parent/file"), "c")
214
        assert 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)
215
216
    def unified_diff(self, old, new):
217
        out = StringIO()
218
        internal_diff("old", old, "new", new, out)
219
        out.seek(0,0)
220
        return out.read()
221
222
    def make_tree_2(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
223
        btree = self.make_tree_1()[0]
224
        btree.note_rename("grandparent/parent/file", 
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
225
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
226
        assert btree.id2path("e") is None
227
        assert btree.path2id("grandparent/parent/file") is None
228
        btree.note_id("e", "grandparent/parent/file")
229
        return btree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
230
231
    def test_adds(self):
232
        """File/inventory adds"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
233
        btree = self.make_tree_2()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
234
        add_patch = self.unified_diff([], ["Extra cheese\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
235
        btree.note_patch("grandparent/parent/file", add_patch)
236
        btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
237
        btree.note_target('grandparent/parent/symlink', 'venus')
238
        self.adds_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
239
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
240
    def adds_test(self, btree):
241
        self.assertEqual(btree.id2path("e"), "grandparent/parent/file")
242
        self.assertEqual(btree.path2id("grandparent/parent/file"), "e")
243
        self.assertEqual(btree.get_file("e").read(), "Extra cheese\n")
244
        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)
245
246
    def test_adds2(self):
247
        """File/inventory adds, with patch-compatibile renames"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
248
        btree = self.make_tree_2()
249
        btree.contents_by_id = False
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
250
        add_patch = self.unified_diff(["Hello\n"], ["Extra cheese\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
251
        btree.note_patch("grandparent/parent/file", add_patch)
252
        btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
253
        btree.note_target('grandparent/parent/symlink', 'venus')
254
        self.adds_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
255
256
    def make_tree_3(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
257
        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)
258
        mtree.add_file("e", "grandparent/parent/topping", "Anchovies\n")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
259
        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)
260
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
261
        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)
262
                          "grandparent/alt_parent/stopping")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
263
        return btree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
264
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
265
    def get_file_test(self, btree):
266
        self.assertEqual(btree.get_file("e").read(), "Lemon\n")
267
        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)
268
269
    def test_get_file(self):
270
        """Get file contents"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
271
        btree = self.make_tree_3()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
272
        mod_patch = self.unified_diff(["Anchovies\n"], ["Lemon\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
273
        btree.note_patch("grandparent/alt_parent/stopping", mod_patch)
274
        self.get_file_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
275
276
    def test_get_file2(self):
277
        """Get file contents, with patch-compatibile renames"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
278
        btree = self.make_tree_3()
279
        btree.contents_by_id = False
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
280
        mod_patch = self.unified_diff([], ["Lemon\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
281
        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)
282
        mod_patch = self.unified_diff([], ["Hello\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
283
        btree.note_patch("grandparent/alt_parent/file", mod_patch)
284
        self.get_file_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
285
286
    def test_delete(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
287
        "Deletion by bundle"
288
        btree = self.make_tree_1()[0]
289
        self.assertEqual(btree.get_file("c").read(), "Hello\n")
290
        btree.note_deletion("grandparent/parent/file")
291
        assert btree.id2path("c") is None
292
        assert 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)
293
294
    def sorted_ids(self, tree):
295
        ids = list(tree)
296
        ids.sort()
297
        return ids
298
299
    def test_iteration(self):
300
        """Ensure that iteration through ids works properly"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
301
        btree = self.make_tree_1()[0]
1852.6.3 by Robert Collins
Make iter(Tree) consistent for all tree types.
302
        self.assertEqual(self.sorted_ids(btree),
303
            [inventory.ROOT_ID, 'a', 'b', 'c', 'd'])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
304
        btree.note_deletion("grandparent/parent/file")
305
        btree.note_id("e", "grandparent/alt_parent/fool", kind="directory")
306
        btree.note_last_changed("grandparent/alt_parent/fool", 
1185.82.95 by Aaron Bentley
Restore path-orientation of ChangesetTree
307
                                "revisionidiguess")
1852.6.3 by Robert Collins
Make iter(Tree) consistent for all tree types.
308
        self.assertEqual(self.sorted_ids(btree),
309
            [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)
310
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
311
1910.2.49 by Aaron Bentley
Ensure that 0.8 bundles aren't used with KnitRepository2
312
class BundleTester1(TestCaseWithTransport):
313
314
    def test_mismatched_bundle(self):
315
        format = bzrdir.BzrDirMetaFormat1()
316
        format.repository_format = repository.RepositoryFormatKnit2()
317
        serializer = BundleSerializerV08('0.8')
318
        b = self.make_branch('.', format=format)
319
        self.assertRaises(errors.IncompatibleFormat, serializer.write, 
320
                          b.repository, [], {}, StringIO())
321
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
322
    def test_matched_bundle(self):
323
        """Don't raise IncompatibleFormat for knit2 and bundle0.9"""
324
        format = bzrdir.BzrDirMetaFormat1()
325
        format.repository_format = repository.RepositoryFormatKnit2()
326
        serializer = BundleSerializerV09('0.9')
327
        b = self.make_branch('.', format=format)
328
        serializer.write(b.repository, [], {}, StringIO())
329
1910.2.60 by Aaron Bentley
Ensure that new-model revisions aren't installed into old-model repos
330
    def test_mismatched_model(self):
331
        """Try copying a bundle from knit2 to knit1"""
332
        format = bzrdir.BzrDirMetaFormat1()
333
        format.repository_format = repository.RepositoryFormatKnit2()
334
        source = self.make_branch_and_tree('source', format=format)
335
        source.commit('one', rev_id='one-id')
336
        source.commit('two', rev_id='two-id')
337
        text = StringIO()
338
        write_bundle(source.branch.repository, 'two-id', None, text, 
339
                     format='0.9')
340
        text.seek(0)
341
342
        format = bzrdir.BzrDirMetaFormat1()
343
        format.repository_format = repository.RepositoryFormatKnit1()
344
        target = self.make_branch('target', format=format)
345
        self.assertRaises(errors.IncompatibleRevision, install_bundle, 
346
                          target.repository, read_bundle(text))
347
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
348
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
349
class V08BundleTester(TestCaseWithTransport):
350
351
    format = '0.8'
352
353
    def bzrdir_format(self):
354
        format = bzrdir.BzrDirMetaFormat1()
355
        format.repository_format = repository.RepositoryFormatKnit1()
356
        return format
357
358
    def make_branch_and_tree(self, path, format=None):
359
        if format is None:
360
            format = self.bzrdir_format()
361
        return TestCaseWithTransport.make_branch_and_tree(self, path, format)
362
363
    def make_branch(self, path, format=None):
364
        if format is None:
365
            format = self.bzrdir_format()
366
        return 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.
367
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
368
    def create_bundle_text(self, base_rev_id, rev_id):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
369
        bundle_txt = StringIO()
370
        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
371
                               bundle_txt, format=self.format)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
372
        bundle_txt.seek(0)
373
        self.assertEqual(bundle_txt.readline(), 
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
374
                         '# Bazaar revision bundle v%s\n' % self.format)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
375
        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.
376
1185.82.14 by Aaron Bentley
API updates
377
        rev = self.b1.repository.get_revision(rev_id)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
378
        self.assertEqual(bundle_txt.readline().decode('utf-8'),
379
                         u'# message:\n')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
380
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
381
        open(',,bundle', 'wb').write(bundle_txt.getvalue())
382
        bundle_txt.seek(0)
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
383
        return bundle_txt, rev_ids
384
385
    def get_valid_bundle(self, base_rev_id, rev_id, checkout_dir=None):
386
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
387
        Make sure that the text generated is valid, and that it
388
        can be applied against the base, and generate the same information.
389
        
390
        :return: The in-memory bundle 
391
        """
392
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
393
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
394
        # This should also validate the generated bundle 
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
395
        bundle = read_bundle(bundle_txt)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
396
        repository = self.b1.repository
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
397
        for bundle_rev in bundle.real_revisions:
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
398
            # These really should have already been checked when we read the
399
            # bundle, since it computes the sha1 hash for the revision, which
400
            # only will match if everything is okay, but lets be explicit about
401
            # it
402
            branch_rev = repository.get_revision(bundle_rev.revision_id)
1185.82.33 by Aaron Bentley
Strengthen tests
403
            for a in ('inventory_sha1', 'revision_id', 'parent_ids',
404
                      'timestamp', 'timezone', 'message', 'committer', 
405
                      'parent_ids', 'properties'):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
406
                self.assertEqual(getattr(branch_rev, a), 
407
                                 getattr(bundle_rev, a))
408
            self.assertEqual(len(branch_rev.parent_ids), 
409
                             len(bundle_rev.parent_ids))
1185.82.47 by Aaron Bentley
Ensure all intended rev_ids end up in the revision
410
        self.assertEqual(rev_ids, 
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
411
                         [r.revision_id for r in bundle.real_revisions])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
412
        self.valid_apply_bundle(base_rev_id, bundle,
1185.82.89 by Aaron Bentley
Remove auto_commit stuff
413
                                   checkout_dir=checkout_dir)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
414
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
415
        return bundle
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
416
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
417
    def get_invalid_bundle(self, base_rev_id, rev_id):
418
        """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
419
        Munge the text so that it's invalid.
420
        
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
421
        :return: The in-memory bundle
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
422
        """
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
423
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
424
        new_text = bundle_txt.getvalue().replace('executable:no', 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
425
                                               'executable:yes')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
426
        bundle_txt = StringIO(new_text)
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
427
        bundle = read_bundle(bundle_txt)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
428
        self.valid_apply_bundle(base_rev_id, bundle)
429
        return bundle 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
430
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
431
    def test_non_bundle(self):
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
432
        self.assertRaises(NotABundle, read_bundle, StringIO('#!/bin/sh\n'))
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
433
1793.2.7 by Aaron Bentley
Fix reporting of malformed, (especially, crlf) bundles
434
    def test_malformed(self):
435
        self.assertRaises(BadBundle, read_bundle, 
436
                          StringIO('# Bazaar revision bundle v'))
437
438
    def test_crlf_bundle(self):
1793.2.9 by Aaron Bentley
Don't use assertNotRaises-- instead, catch BadBundle and pass
439
        try:
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
440
            read_bundle(StringIO('# Bazaar revision bundle v0.8\r\n'))
1793.2.9 by Aaron Bentley
Don't use assertNotRaises-- instead, catch BadBundle and pass
441
        except BadBundle:
442
            # It is currently permitted for bundles with crlf line endings to
443
            # make read_bundle raise a BadBundle, but this should be fixed.
1793.2.10 by Aaron Bentley
Whitespace/comment fix
444
            # Anything else, especially NotABundle, is an error.
1793.2.9 by Aaron Bentley
Don't use assertNotRaises-- instead, catch BadBundle and pass
445
            pass
446
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
447
    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.
448
        """Get a new tree, with the specified revision in it.
449
        """
450
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
451
        if checkout_dir is None:
452
            checkout_dir = tempfile.mkdtemp(prefix='test-branch-', dir='.')
0.5.89 by John Arbash Meinel
Updating for explicitly defined directories.
453
        else:
454
            if not os.path.exists(checkout_dir):
455
                os.mkdir(checkout_dir)
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
456
        tree = self.make_branch_and_tree(checkout_dir)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
457
        s = StringIO()
1910.2.64 by Aaron Bentley
Changes from review
458
        ancestors = write_bundle(self.b1.repository, rev_id, None, s,
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
459
                                 format=self.format)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
460
        s.seek(0)
1185.82.135 by Aaron Bentley
Ensure that bundles are bytestrings
461
        assert isinstance(s.getvalue(), str), (
462
            "Bundle isn't a bytestring:\n %s..." % repr(s.getvalue())[:40])
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
463
        install_bundle(tree.branch.repository, read_bundle(s))
1185.82.41 by Aaron Bentley
More work on installing changesets
464
        for ancestor in ancestors:
465
            old = self.b1.repository.revision_tree(ancestor)
466
            new = tree.branch.repository.revision_tree(ancestor)
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
467
468
            # Check that there aren't any inventory level changes
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
469
            delta = new.changes_from(old)
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
470
            self.assertFalse(delta.has_changed(),
471
                             'Revision %s not copied correctly.'
472
                             % (ancestor,))
1711.7.27 by John Arbash Meinel
Investigating why test_bundle fails, something isn't transmitting properly.
473
474
            # Now check that the file contents are all correct
1185.82.41 by Aaron Bentley
More work on installing changesets
475
            for inventory_id in old:
476
                try:
477
                    old_file = old.get_file(inventory_id)
1910.2.3 by Aaron Bentley
All tests pass
478
                except NoSuchFile:
1185.82.41 by Aaron Bentley
More work on installing changesets
479
                    continue
480
                if old_file is None:
481
                    continue
482
                self.assertEqual(old_file.read(),
483
                                 new.get_file(inventory_id).read())
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
484
        if rev_id is not None:
485
            rh = self.b1.revision_history()
486
            tree.branch.set_revision_history(rh[:rh.index(rev_id)+1])
487
            tree.update()
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
488
            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.
489
            self.assertFalse(delta.has_changed(),
490
                             'Working tree has modifications')
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
491
        return tree
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
492
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
493
    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.
494
        """Get the base revision, apply the changes, and make
495
        sure everything matches the builtin branch.
496
        """
1185.82.17 by Aaron Bentley
More API updates
497
        to_tree = self.get_checkout(base_rev_id, checkout_dir=checkout_dir)
1908.6.4 by Robert Collins
Update to replaced parent checking api bzrlib/merge.py
498
        original_parents = to_tree.get_parent_ids()
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
499
        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.
500
        original_parents = to_tree.get_parent_ids()
1185.82.41 by Aaron Bentley
More work on installing changesets
501
        self.assertIs(repository.has_revision(base_rev_id), True)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
502
        for rev in info.real_revisions:
503
            self.assert_(not repository.has_revision(rev.revision_id),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
504
                'Revision {%s} present before applying bundle' 
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
505
                % rev.revision_id)
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
506
        merge_bundle(info, to_tree, True, Merge3Merger, False, False)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
507
508
        for rev in info.real_revisions:
1185.82.17 by Aaron Bentley
More API updates
509
            self.assert_(repository.has_revision(rev.revision_id),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
510
                '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.
511
                % rev.revision_id)
512
1185.82.17 by Aaron Bentley
More API updates
513
        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.
514
        # 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.
515
1908.6.4 by Robert Collins
Update to replaced parent checking api bzrlib/merge.py
516
        self.assertEqual(original_parents + [info.target],
517
            to_tree.get_parent_ids())
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
518
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
519
        rev = info.real_revisions[-1]
1185.82.17 by Aaron Bentley
More API updates
520
        base_tree = self.b1.repository.revision_tree(rev.revision_id)
521
        to_tree = to_tree.branch.repository.revision_tree(rev.revision_id)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
522
        
523
        # 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.
524
        #       we might also check the working tree.
525
526
        base_files = list(base_tree.list_files())
527
        to_files = list(to_tree.list_files())
528
        self.assertEqual(len(base_files), len(to_files))
1185.82.66 by Aaron Bentley
Handle new executable files
529
        for base_file, to_file in zip(base_files, to_files):
530
            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.
531
0.5.117 by John Arbash Meinel
Almost there. Just need to track down a few remaining bugs.
532
        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.
533
            # Check that the meta information is the same
534
            self.assertEqual(base_tree.get_file_size(fileid),
535
                    to_tree.get_file_size(fileid))
536
            self.assertEqual(base_tree.get_file_sha1(fileid),
537
                    to_tree.get_file_sha1(fileid))
538
            # Check that the contents are the same
539
            # This is pretty expensive
540
            # self.assertEqual(base_tree.get_file(fileid).read(),
541
            #         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.
542
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
543
    def test_bundle(self):
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
544
        self.tree1 = self.make_branch_and_tree('b1')
1185.82.14 by Aaron Bentley
API updates
545
        self.b1 = self.tree1.branch
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
546
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
547
        open('b1/one', 'wb').write('one\n')
1185.82.14 by Aaron Bentley
API updates
548
        self.tree1.add('one')
549
        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.
550
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
551
        bundle = self.get_valid_bundle(None, 'a@cset-0-1')
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
552
        # FIXME: The current write_bundle api no longer supports
553
        #        setting a custom summary message
554
        #        We should re-introduce the ability, and update
555
        #        the tests to make sure it works.
556
        # bundle = self.get_valid_bundle(None, 'a@cset-0-1',
557
        #         message='With a specialized message')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
558
559
        # Make sure we can handle files with spaces, tabs, other
560
        # bogus characters
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
561
        self.build_tree([
0.5.84 by John Arbash Meinel
(broken) problem with removes.
562
                'b1/with space.txt'
563
                , 'b1/dir/'
564
                , 'b1/dir/filein subdir.c'
565
                , 'b1/dir/WithCaps.txt'
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
566
                , 'b1/dir/ pre space'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
567
                , 'b1/sub/'
568
                , 'b1/sub/sub/'
569
                , '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
570
                ])
0.5.84 by John Arbash Meinel
(broken) problem with removes.
571
        open('b1/sub/sub/emptyfile.txt', 'wb').close()
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
572
        open('b1/dir/nolastnewline.txt', 'wb').write('bloop')
1185.82.66 by Aaron Bentley
Handle new executable files
573
        tt = TreeTransform(self.tree1)
574
        tt.new_file('executable', tt.root, '#!/bin/sh\n', 'exe-1', True)
575
        tt.apply()
1185.82.14 by Aaron Bentley
API updates
576
        self.tree1.add([
0.5.84 by John Arbash Meinel
(broken) problem with removes.
577
                'with space.txt'
578
                , 'dir'
579
                , 'dir/filein subdir.c'
580
                , 'dir/WithCaps.txt'
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
581
                , 'dir/ pre space'
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
582
                , 'dir/nolastnewline.txt'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
583
                , 'sub'
584
                , 'sub/sub'
585
                , 'sub/sub/nonempty.txt'
586
                , 'sub/sub/emptyfile.txt'
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
587
                ])
1185.82.14 by Aaron Bentley
API updates
588
        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.
589
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
590
        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.
591
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
592
        # Check a rollup bundle 
593
        bundle = self.get_valid_bundle(None, 'a@cset-0-2')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
594
595
        # Now delete entries
1185.82.21 by Aaron Bentley
Stop using deprecated function
596
        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.
597
                ['sub/sub/nonempty.txt'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
598
                , '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.
599
                , 'sub/sub'
600
                ])
1185.82.68 by Aaron Bentley
Handle execute bit on modified files
601
        tt = TreeTransform(self.tree1)
602
        trans_id = tt.trans_id_tree_file_id('exe-1')
603
        tt.set_executability(False, trans_id)
604
        tt.apply()
1185.82.19 by Aaron Bentley
More API updates
605
        self.tree1.commit('removed', rev_id='a@cset-0-3')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
606
        
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
607
        bundle = self.get_valid_bundle('a@cset-0-2', 'a@cset-0-3')
608
        self.assertRaises(TestamentMismatch, self.get_invalid_bundle, 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
609
                          'a@cset-0-2', 'a@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
610
        # Check a rollup bundle 
611
        bundle = self.get_valid_bundle(None, 'a@cset-0-3')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
612
613
        # Now move the directory
1185.82.19 by Aaron Bentley
More API updates
614
        self.tree1.rename_one('dir', 'sub/dir')
615
        self.tree1.commit('rename dir', rev_id='a@cset-0-4')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
616
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
617
        bundle = self.get_valid_bundle('a@cset-0-3', 'a@cset-0-4')
618
        # Check a rollup bundle 
619
        bundle = self.get_valid_bundle(None, 'a@cset-0-4')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
620
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
621
        # Modified files
622
        open('b1/sub/dir/WithCaps.txt', 'ab').write('\nAdding some text\n')
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
623
        open('b1/sub/dir/ pre space', 'ab').write('\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
624
        open('b1/sub/dir/nolastnewline.txt', 'ab').write('\n')
1711.7.32 by John Arbash Meinel
Switch from a trailing space to a beginning space, which is supported everywhere.
625
        self.tree1.rename_one('sub/dir/ pre space', 
626
                              'sub/ start space')
1185.82.19 by Aaron Bentley
More API updates
627
        self.tree1.commit('Modified files', rev_id='a@cset-0-5')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
628
        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.
629
1185.82.70 by Aaron Bentley
Handle renamed files better
630
        self.tree1.rename_one('sub/dir/WithCaps.txt', 'temp')
631
        self.tree1.rename_one('with space.txt', 'WithCaps.txt')
632
        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.
633
        self.tree1.commit(u'swap filenames', rev_id='a@cset-0-6',
634
                          verbose=False)
635
        bundle = self.get_valid_bundle('a@cset-0-5', 'a@cset-0-6')
636
        other = self.get_checkout('a@cset-0-5')
1910.2.62 by Aaron Bentley
Cleanups
637
        tree1_inv = self.tree1.branch.repository.get_inventory_xml(
638
            'a@cset-0-5')
1910.2.54 by Aaron Bentley
Implement testament format 3 strict
639
        tree2_inv = other.branch.repository.get_inventory_xml('a@cset-0-5')
640
        self.assertEqualDiff(tree1_inv, tree2_inv)
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
641
        other.rename_one('sub/dir/nolastnewline.txt', 'sub/nolastnewline.txt')
642
        other.commit('rename file', rev_id='a@cset-0-6b')
643
        merge([other.basedir, -1], [None, None], this_dir=self.tree1.basedir)
644
        self.tree1.commit(u'Merge', rev_id='a@cset-0-7',
1185.82.70 by Aaron Bentley
Handle renamed files better
645
                          verbose=False)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
646
        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
647
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
648
    def test_symlink_bundle(self):
1185.82.87 by Aaron Bentley
Got symlink adding working
649
        if not has_symlinks():
650
            raise TestSkipped("No symlink support")
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
651
        self.tree1 = self.make_branch_and_tree('b1')
1185.82.87 by Aaron Bentley
Got symlink adding working
652
        self.b1 = self.tree1.branch
653
        tt = TreeTransform(self.tree1)
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
654
        tt.new_symlink('link', tt.root, 'bar/foo', 'link-1')
1185.82.87 by Aaron Bentley
Got symlink adding working
655
        tt.apply()
656
        self.tree1.commit('add symlink', rev_id='l@cset-0-1')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
657
        self.get_valid_bundle(None, 'l@cset-0-1')
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
658
        tt = TreeTransform(self.tree1)
659
        trans_id = tt.trans_id_tree_file_id('link-1')
660
        tt.adjust_path('link2', tt.root, trans_id)
661
        tt.delete_contents(trans_id)
662
        tt.create_symlink('mars', trans_id)
663
        tt.apply()
664
        self.tree1.commit('rename and change symlink', rev_id='l@cset-0-2')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
665
        self.get_valid_bundle('l@cset-0-1', 'l@cset-0-2')
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
666
        tt = TreeTransform(self.tree1)
667
        trans_id = tt.trans_id_tree_file_id('link-1')
668
        tt.delete_contents(trans_id)
669
        tt.create_symlink('jupiter', trans_id)
670
        tt.apply()
671
        self.tree1.commit('just change symlink target', rev_id='l@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
672
        self.get_valid_bundle('l@cset-0-2', 'l@cset-0-3')
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
673
        tt = TreeTransform(self.tree1)
674
        trans_id = tt.trans_id_tree_file_id('link-1')
675
        tt.delete_contents(trans_id)
676
        tt.apply()
677
        self.tree1.commit('Delete symlink', rev_id='l@cset-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
678
        self.get_valid_bundle('l@cset-0-3', 'l@cset-0-4')
1185.82.96 by Aaron Bentley
Got first binary test passing
679
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
680
    def test_binary_bundle(self):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
681
        self.tree1 = self.make_branch_and_tree('b1')
1185.82.96 by Aaron Bentley
Got first binary test passing
682
        self.b1 = self.tree1.branch
683
        tt = TreeTransform(self.tree1)
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
684
        
685
        # Add
686
        tt.new_file('file', tt.root, '\x00\n\x00\r\x01\n\x02\r\xff', 'binary-1')
687
        tt.new_file('file2', tt.root, '\x01\n\x02\r\x03\n\x04\r\xff', 'binary-2')
1185.82.96 by Aaron Bentley
Got first binary test passing
688
        tt.apply()
689
        self.tree1.commit('add binary', rev_id='b@cset-0-1')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
690
        self.get_valid_bundle(None, 'b@cset-0-1')
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
691
692
        # Delete
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
693
        tt = TreeTransform(self.tree1)
694
        trans_id = tt.trans_id_tree_file_id('binary-1')
695
        tt.delete_contents(trans_id)
696
        tt.apply()
697
        self.tree1.commit('delete binary', rev_id='b@cset-0-2')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
698
        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.
699
700
        # Rename & modify
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
701
        tt = TreeTransform(self.tree1)
702
        trans_id = tt.trans_id_tree_file_id('binary-2')
703
        tt.adjust_path('file3', tt.root, trans_id)
704
        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.
705
        tt.create_file('file\rcontents\x00\n\x00', trans_id)
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
706
        tt.apply()
707
        self.tree1.commit('rename and modify binary', rev_id='b@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
708
        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.
709
710
        # Modify
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
711
        tt = TreeTransform(self.tree1)
712
        trans_id = tt.trans_id_tree_file_id('binary-2')
713
        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.
714
        tt.create_file('\x00file\rcontents', trans_id)
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
715
        tt.apply()
716
        self.tree1.commit('just modify binary', rev_id='b@cset-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
717
        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
718
1848.1.1 by John Arbash Meinel
fix bug in bundle handling of binary files with just '\r' in them.
719
        # Rollup
720
        self.get_valid_bundle(None, 'b@cset-0-4')
721
1185.82.115 by Aaron Bentley
Add test for last-changed special cases
722
    def test_last_modified(self):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
723
        self.tree1 = self.make_branch_and_tree('b1')
1185.82.115 by Aaron Bentley
Add test for last-changed special cases
724
        self.b1 = self.tree1.branch
725
        tt = TreeTransform(self.tree1)
726
        tt.new_file('file', tt.root, 'file', 'file')
727
        tt.apply()
728
        self.tree1.commit('create file', rev_id='a@lmod-0-1')
729
730
        tt = TreeTransform(self.tree1)
731
        trans_id = tt.trans_id_tree_file_id('file')
732
        tt.delete_contents(trans_id)
733
        tt.create_file('file2', trans_id)
734
        tt.apply()
735
        self.tree1.commit('modify text', rev_id='a@lmod-0-2a')
736
737
        other = self.get_checkout('a@lmod-0-1')
738
        tt = TreeTransform(other)
739
        trans_id = tt.trans_id_tree_file_id('file')
740
        tt.delete_contents(trans_id)
741
        tt.create_file('file2', trans_id)
742
        tt.apply()
743
        other.commit('modify text in another tree', rev_id='a@lmod-0-2b')
744
        merge([other.basedir, -1], [None, None], this_dir=self.tree1.basedir)
745
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-3',
746
                          verbose=False)
747
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
748
        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
749
750
    def test_hide_history(self):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
751
        self.tree1 = self.make_branch_and_tree('b1')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
752
        self.b1 = self.tree1.branch
753
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
754
        open('b1/one', 'wb').write('one\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
755
        self.tree1.add('one')
756
        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.
757
        open('b1/one', 'wb').write('two\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
758
        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.
759
        open('b1/one', 'wb').write('three\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
760
        self.tree1.commit('modify', rev_id='a@cset-0-3')
761
        bundle_file = StringIO()
762
        rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
1910.2.51 by Aaron Bentley
Bundles now corrupt repositories
763
                               'a@cset-0-1', bundle_file, format=self.format)
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
764
        self.assertNotContainsRe(bundle_file.getvalue(), 'two')
765
        self.assertContainsRe(bundle_file.getvalue(), 'one')
766
        self.assertContainsRe(bundle_file.getvalue(), 'three')
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
767
1711.7.35 by John Arbash Meinel
Factor out i18n bundle tests, so we don't always skip.
768
    def test_unicode_bundle(self):
769
        # Handle international characters
770
        os.mkdir('b1')
771
        try:
772
            f = open(u'b1/with Dod\xe9', 'wb')
773
        except UnicodeEncodeError:
774
            raise TestSkipped("Filesystem doesn't support unicode")
775
776
        self.tree1 = self.make_branch_and_tree('b1')
777
        self.b1 = self.tree1.branch
778
779
        f.write((u'A file\n'
780
            u'With international man of mystery\n'
781
            u'William Dod\xe9\n').encode('utf-8'))
782
        f.close()
783
784
        self.tree1.add([u'with Dod\xe9'])
785
        self.tree1.commit(u'i18n commit from William Dod\xe9', 
786
                          rev_id='i18n-1', committer=u'William Dod\xe9')
787
788
        # Add
789
        bundle = self.get_valid_bundle(None, 'i18n-1')
790
791
        # Modified
792
        f = open(u'b1/with Dod\xe9', 'wb')
793
        f.write(u'Modified \xb5\n'.encode('utf8'))
794
        f.close()
795
        self.tree1.commit(u'modified', rev_id='i18n-2')
796
797
        bundle = self.get_valid_bundle('i18n-1', 'i18n-2')
798
        
799
        # Renamed
800
        self.tree1.rename_one(u'with Dod\xe9', u'B\xe5gfors')
801
        self.tree1.commit(u'renamed, the new i18n man', rev_id='i18n-3',
802
                          committer=u'Erik B\xe5gfors')
803
804
        bundle = self.get_valid_bundle('i18n-2', 'i18n-3')
805
806
        # Removed
807
        self.tree1.remove([u'B\xe5gfors'])
808
        self.tree1.commit(u'removed', rev_id='i18n-4')
809
810
        bundle = self.get_valid_bundle('i18n-3', 'i18n-4')
811
812
        # Rollup
813
        bundle = self.get_valid_bundle(None, 'i18n-4')
814
815
1711.7.34 by John Arbash Meinel
Include a test to ensure bundles handle trailing whitespace.
816
    def test_whitespace_bundle(self):
817
        if sys.platform in ('win32', 'cygwin'):
818
            raise TestSkipped('Windows doesn\'t support filenames'
819
                              ' with tabs or trailing spaces')
820
        self.tree1 = self.make_branch_and_tree('b1')
821
        self.b1 = self.tree1.branch
822
823
        self.build_tree(['b1/trailing space '])
824
        self.tree1.add(['trailing space '])
825
        # TODO: jam 20060701 Check for handling files with '\t' characters
826
        #       once we actually support them
827
828
        # Added
829
        self.tree1.commit('funky whitespace', rev_id='white-1')
830
831
        bundle = self.get_valid_bundle(None, 'white-1')
832
833
        # Modified
834
        open('b1/trailing space ', 'ab').write('add some text\n')
835
        self.tree1.commit('add text', rev_id='white-2')
836
837
        bundle = self.get_valid_bundle('white-1', 'white-2')
838
839
        # Renamed
840
        self.tree1.rename_one('trailing space ', ' start and end space ')
841
        self.tree1.commit('rename', rev_id='white-3')
842
843
        bundle = self.get_valid_bundle('white-2', 'white-3')
844
845
        # Removed
846
        self.tree1.remove([' start and end space '])
847
        self.tree1.commit('removed', rev_id='white-4')
848
849
        bundle = self.get_valid_bundle('white-3', 'white-4')
850
        
851
        # Now test a complet roll-up
852
        bundle = self.get_valid_bundle(None, 'white-4')
853
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
854
    def test_alt_timezone_bundle(self):
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
855
        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
856
        self.b1 = self.tree1.branch
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
857
        builder = treebuilder.TreeBuilder()
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
858
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
859
        self.tree1.lock_write()
860
        builder.start_tree(self.tree1)
861
        builder.build(['newfile'])
862
        builder.finish_tree()
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
863
864
        # Asia/Colombo offset = 5 hours 30 minutes
865
        self.tree1.commit('non-hour offset timezone', rev_id='tz-1',
866
                          timezone=19800, timestamp=1152544886.0)
867
868
        bundle = self.get_valid_bundle(None, 'tz-1')
869
        
870
        rev = bundle.revisions[0]
871
        self.assertEqual('Mon 2006-07-10 20:51:26.000000000 +0530', rev.date)
872
        self.assertEqual(19800, rev.timezone)
873
        self.assertEqual(1152544886.0, rev.timestamp)
1986.1.2 by Robert Collins
Various changes to allow non-workingtree specific tests to run entirely
874
        self.tree1.unlock()
1793.3.9 by John Arbash Meinel
Add a test to timezone for non integer tz offsets
875
1910.2.1 by Aaron Bentley
Ensure root entry always has a revision
876
    def test_bundle_root_id(self):
877
        self.tree1 = self.make_branch_and_tree('b1')
878
        self.b1 = self.tree1.branch
879
        self.tree1.commit('message', rev_id='revid1')
880
        bundle = self.get_valid_bundle(None, 'revid1')
881
        tree = bundle.revision_tree(self.b1.repository, 'revid1')
1910.2.6 by Aaron Bentley
Update for merge review, handle deprecations
882
        self.assertEqual('revid1', tree.inventory.root.revision)
1910.2.1 by Aaron Bentley
Ensure root entry always has a revision
883
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
884
1910.2.59 by Aaron Bentley
Test 0.9 bundles for knit format1 and knit format2
885
class V09BundleKnit2Tester(V08BundleTester):
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
886
887
    format = '0.9'
888
889
    def bzrdir_format(self):
890
        format = bzrdir.BzrDirMetaFormat1()
891
        format.repository_format = repository.RepositoryFormatKnit2()
892
        return format
893
894
1910.2.59 by Aaron Bentley
Test 0.9 bundles for knit format1 and knit format2
895
class V09BundleKnit1Tester(V08BundleTester):
896
897
    format = '0.9'
898
899
    def bzrdir_format(self):
900
        format = bzrdir.BzrDirMetaFormat1()
901
        format.repository_format = repository.RepositoryFormatKnit1()
902
        return format
903
904
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
905
class MungedBundleTester(TestCaseWithTransport):
906
907
    def build_test_bundle(self):
908
        wt = self.make_branch_and_tree('b1')
909
910
        self.build_tree(['b1/one'])
911
        wt.add('one')
912
        wt.commit('add one', rev_id='a@cset-0-1')
913
        self.build_tree(['b1/two'])
914
        wt.add('two')
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
915
        wt.commit('add two', rev_id='a@cset-0-2',
916
                  revprops={'branch-nick':'test'})
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
917
918
        bundle_txt = StringIO()
919
        rev_ids = write_bundle(wt.branch.repository, 'a@cset-0-2',
920
                               'a@cset-0-1', bundle_txt)
921
        self.assertEqual(['a@cset-0-2'], rev_ids)
922
        bundle_txt.seek(0, 0)
923
        return bundle_txt
924
925
    def check_valid(self, bundle):
926
        """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
927
        self.assertEqual(['a@cset-0-2'],
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
928
            [r.revision_id for r in bundle.real_revisions])
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
929
930
    def test_extra_whitespace(self):
931
        bundle_txt = self.build_test_bundle()
932
933
        # Seek to the end of the file
934
        # Adding one extra newline used to give us
935
        # TypeError: float() argument must be a string or a number
936
        bundle_txt.seek(0, 2)
937
        bundle_txt.write('\n')
938
        bundle_txt.seek(0)
939
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
940
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
941
        self.check_valid(bundle)
942
943
    def test_extra_whitespace_2(self):
944
        bundle_txt = self.build_test_bundle()
945
946
        # Seek to the end of the file
947
        # Adding two extra newlines used to give us
948
        # MalformedPatches: The first line of all patches should be ...
949
        bundle_txt.seek(0, 2)
950
        bundle_txt.write('\n\n')
951
        bundle_txt.seek(0)
952
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
953
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
954
        self.check_valid(bundle)
955
956
    def test_missing_trailing_whitespace(self):
957
        bundle_txt = self.build_test_bundle()
958
959
        # Remove a trailing newline, it shouldn't kill the parser
960
        raw = bundle_txt.getvalue()
961
        # The contents of the bundle don't have to be this, but this
962
        # test is concerned with the exact case where the serializer
963
        # creates a blank line at the end, and fails if that
964
        # line is stripped
965
        self.assertEqual('\n\n', raw[-2:])
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
966
        bundle_txt = StringIO(raw[:-1])
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
967
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
968
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
969
        self.check_valid(bundle)
1793.3.14 by John Arbash Meinel
Actually fix the bug with missing trailing newline bug #49182
970
1793.3.16 by John Arbash Meinel
Add tests to ensure that we gracefully handle opening and trailing non-bundle text.
971
    def test_opening_text(self):
972
        bundle_txt = self.build_test_bundle()
973
974
        bundle_txt = StringIO("Some random\nemail comments\n"
975
                              + bundle_txt.getvalue())
976
977
        bundle = read_bundle(bundle_txt)
978
        self.check_valid(bundle)
979
980
    def test_trailing_text(self):
981
        bundle_txt = self.build_test_bundle()
982
983
        bundle_txt = StringIO(bundle_txt.getvalue() +
984
                              "Some trailing\nrandom\ntext\n")
985
986
        bundle = read_bundle(bundle_txt)
987
        self.check_valid(bundle)
988