/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
2
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.
7
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.
12
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
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
18
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
19
from bzrlib.builtins import merge
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
20
from bzrlib.bzrdir import BzrDir
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
21
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
1793.2.3 by Aaron Bentley
Rename read_bundle.py to bundle_data.py
22
from bzrlib.bundle.bundle_data import BundleTree
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
23
from bzrlib.bundle.serializer import write_bundle, read_bundle
1185.82.90 by Aaron Bentley
Reorganized test suite
24
from bzrlib.diff import internal_diff
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
25
from bzrlib.errors import BzrError, TestamentMismatch, NotABundle
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
26
from bzrlib.merge import Merge3Merger
1185.82.87 by Aaron Bentley
Got symlink adding working
27
from bzrlib.osutils import has_symlinks, sha_file
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
28
from bzrlib.tests import (TestCaseInTempDir, TestCaseWithTransport,
29
                          TestCase, TestSkipped)
1185.82.66 by Aaron Bentley
Handle new executable files
30
from bzrlib.transform import TreeTransform
1185.82.17 by Aaron Bentley
More API updates
31
from bzrlib.workingtree import WorkingTree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
32
1185.82.90 by Aaron Bentley
Reorganized test suite
33
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
34
class MockTree(object):
35
    def __init__(self):
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
36
        from bzrlib.inventory import RootEntry, ROOT_ID
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
37
        object.__init__(self)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
38
        self.paths = {ROOT_ID: ""}
39
        self.ids = {"": ROOT_ID}
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
40
        self.contents = {}
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
41
        self.root = RootEntry(ROOT_ID)
42
43
    inventory = property(lambda x:x)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
44
45
    def __iter__(self):
46
        return self.paths.iterkeys()
47
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
48
    def __getitem__(self, file_id):
49
        if file_id == self.root.file_id:
50
            return self.root
51
        else:
52
            return self.make_entry(file_id, self.paths[file_id])
53
54
    def parent_id(self, file_id):
55
        from os.path import dirname
56
        parent_dir = dirname(self.paths[file_id])
57
        if parent_dir == "":
58
            return None
59
        return self.ids[parent_dir]
60
61
    def iter_entries(self):
62
        for path, file_id in self.ids.iteritems():
63
            yield path, self[file_id]
64
65
    def get_file_kind(self, file_id):
66
        if file_id in self.contents:
67
            kind = 'file'
68
        else:
69
            kind = 'directory'
70
        return kind
71
72
    def make_entry(self, file_id, path):
73
        from os.path import basename
0.5.119 by John Arbash Meinel
Recreated the factory. We really need InventoryEntry.create()
74
        from bzrlib.inventory import (InventoryEntry, InventoryFile
75
                                    , InventoryDirectory, InventoryLink)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
76
        name = basename(path)
77
        kind = self.get_file_kind(file_id)
78
        parent_id = self.parent_id(file_id)
79
        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()
80
        if kind == 'directory':
81
            ie = InventoryDirectory(file_id, name, parent_id)
82
        elif kind == 'file':
83
            ie = InventoryFile(file_id, name, parent_id)
84
        elif kind == 'symlink':
85
            ie = InventoryLink(file_id, name, parent_id)
86
        else:
87
            raise BzrError('unknown kind %r' % kind)
0.5.91 by Aaron Bentley
Updated to match API change
88
        ie.text_sha1 = text_sha_1
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
89
        ie.text_size = text_size
90
        return ie
91
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
92
    def add_dir(self, file_id, path):
93
        self.paths[file_id] = path
94
        self.ids[path] = file_id
95
    
96
    def add_file(self, file_id, path, contents):
97
        self.add_dir(file_id, path)
98
        self.contents[file_id] = contents
99
100
    def path2id(self, path):
101
        return self.ids.get(path)
102
103
    def id2path(self, file_id):
104
        return self.paths.get(file_id)
105
106
    def has_id(self, file_id):
107
        return self.id2path(file_id) is not None
108
109
    def get_file(self, file_id):
110
        result = StringIO()
111
        result.write(self.contents[file_id])
112
        result.seek(0,0)
113
        return result
114
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
115
    def contents_stats(self, file_id):
116
        if file_id not in self.contents:
117
            return None, None
118
        text_sha1 = sha_file(self.get_file(file_id))
119
        return text_sha1, len(self.contents[file_id])
120
121
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
122
class BTreeTester(TestCase):
123
    """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)
124
125
    def make_tree_1(self):
126
        mtree = MockTree()
127
        mtree.add_dir("a", "grandparent")
128
        mtree.add_dir("b", "grandparent/parent")
129
        mtree.add_file("c", "grandparent/parent/file", "Hello\n")
130
        mtree.add_dir("d", "grandparent/alt_parent")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
131
        return BundleTree(mtree, ''), mtree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
132
        
133
    def test_renames(self):
134
        """Ensure that file renames have the proper effect on children"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
135
        btree = self.make_tree_1()[0]
136
        self.assertEqual(btree.old_path("grandparent"), "grandparent")
137
        self.assertEqual(btree.old_path("grandparent/parent"), 
138
                         "grandparent/parent")
139
        self.assertEqual(btree.old_path("grandparent/parent/file"),
140
                         "grandparent/parent/file")
141
142
        self.assertEqual(btree.id2path("a"), "grandparent")
143
        self.assertEqual(btree.id2path("b"), "grandparent/parent")
144
        self.assertEqual(btree.id2path("c"), "grandparent/parent/file")
145
146
        self.assertEqual(btree.path2id("grandparent"), "a")
147
        self.assertEqual(btree.path2id("grandparent/parent"), "b")
148
        self.assertEqual(btree.path2id("grandparent/parent/file"), "c")
149
150
        assert btree.path2id("grandparent2") is None
151
        assert btree.path2id("grandparent2/parent") is None
152
        assert btree.path2id("grandparent2/parent/file") is None
153
154
        btree.note_rename("grandparent", "grandparent2")
155
        assert btree.old_path("grandparent") is None
156
        assert btree.old_path("grandparent/parent") is None
157
        assert btree.old_path("grandparent/parent/file") is None
158
159
        self.assertEqual(btree.id2path("a"), "grandparent2")
160
        self.assertEqual(btree.id2path("b"), "grandparent2/parent")
161
        self.assertEqual(btree.id2path("c"), "grandparent2/parent/file")
162
163
        self.assertEqual(btree.path2id("grandparent2"), "a")
164
        self.assertEqual(btree.path2id("grandparent2/parent"), "b")
165
        self.assertEqual(btree.path2id("grandparent2/parent/file"), "c")
166
167
        assert btree.path2id("grandparent") is None
168
        assert btree.path2id("grandparent/parent") is None
169
        assert btree.path2id("grandparent/parent/file") is None
170
171
        btree.note_rename("grandparent/parent", "grandparent2/parent2")
172
        self.assertEqual(btree.id2path("a"), "grandparent2")
173
        self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
174
        self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file")
175
176
        self.assertEqual(btree.path2id("grandparent2"), "a")
177
        self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
178
        self.assertEqual(btree.path2id("grandparent2/parent2/file"), "c")
179
180
        assert btree.path2id("grandparent2/parent") is None
181
        assert btree.path2id("grandparent2/parent/file") is None
182
183
        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)
184
                          "grandparent2/parent2/file2")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
185
        self.assertEqual(btree.id2path("a"), "grandparent2")
186
        self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
187
        self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file2")
188
189
        self.assertEqual(btree.path2id("grandparent2"), "a")
190
        self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
191
        self.assertEqual(btree.path2id("grandparent2/parent2/file2"), "c")
192
193
        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)
194
195
    def test_moves(self):
196
        """Ensure that file moves have the proper effect on children"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
197
        btree = self.make_tree_1()[0]
198
        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)
199
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
200
        self.assertEqual(btree.id2path("c"), "grandparent/alt_parent/file")
201
        self.assertEqual(btree.path2id("grandparent/alt_parent/file"), "c")
202
        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)
203
204
    def unified_diff(self, old, new):
205
        out = StringIO()
206
        internal_diff("old", old, "new", new, out)
207
        out.seek(0,0)
208
        return out.read()
209
210
    def make_tree_2(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
211
        btree = self.make_tree_1()[0]
212
        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)
213
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
214
        assert btree.id2path("e") is None
215
        assert btree.path2id("grandparent/parent/file") is None
216
        btree.note_id("e", "grandparent/parent/file")
217
        return btree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
218
219
    def test_adds(self):
220
        """File/inventory adds"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
221
        btree = self.make_tree_2()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
222
        add_patch = self.unified_diff([], ["Extra cheese\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
223
        btree.note_patch("grandparent/parent/file", add_patch)
224
        btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
225
        btree.note_target('grandparent/parent/symlink', 'venus')
226
        self.adds_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
227
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
228
    def adds_test(self, btree):
229
        self.assertEqual(btree.id2path("e"), "grandparent/parent/file")
230
        self.assertEqual(btree.path2id("grandparent/parent/file"), "e")
231
        self.assertEqual(btree.get_file("e").read(), "Extra cheese\n")
232
        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)
233
234
    def test_adds2(self):
235
        """File/inventory adds, with patch-compatibile renames"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
236
        btree = self.make_tree_2()
237
        btree.contents_by_id = False
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
238
        add_patch = self.unified_diff(["Hello\n"], ["Extra cheese\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
239
        btree.note_patch("grandparent/parent/file", add_patch)
240
        btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
241
        btree.note_target('grandparent/parent/symlink', 'venus')
242
        self.adds_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
243
244
    def make_tree_3(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
245
        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)
246
        mtree.add_file("e", "grandparent/parent/topping", "Anchovies\n")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
247
        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)
248
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
249
        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)
250
                          "grandparent/alt_parent/stopping")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
251
        return btree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
252
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
253
    def get_file_test(self, btree):
254
        self.assertEqual(btree.get_file("e").read(), "Lemon\n")
255
        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)
256
257
    def test_get_file(self):
258
        """Get file contents"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
259
        btree = self.make_tree_3()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
260
        mod_patch = self.unified_diff(["Anchovies\n"], ["Lemon\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
261
        btree.note_patch("grandparent/alt_parent/stopping", mod_patch)
262
        self.get_file_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
263
264
    def test_get_file2(self):
265
        """Get file contents, with patch-compatibile renames"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
266
        btree = self.make_tree_3()
267
        btree.contents_by_id = False
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
268
        mod_patch = self.unified_diff([], ["Lemon\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
269
        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)
270
        mod_patch = self.unified_diff([], ["Hello\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
271
        btree.note_patch("grandparent/alt_parent/file", mod_patch)
272
        self.get_file_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
273
274
    def test_delete(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
275
        "Deletion by bundle"
276
        btree = self.make_tree_1()[0]
277
        self.assertEqual(btree.get_file("c").read(), "Hello\n")
278
        btree.note_deletion("grandparent/parent/file")
279
        assert btree.id2path("c") is None
280
        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)
281
282
    def sorted_ids(self, tree):
283
        ids = list(tree)
284
        ids.sort()
285
        return ids
286
287
    def test_iteration(self):
288
        """Ensure that iteration through ids works properly"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
289
        btree = self.make_tree_1()[0]
290
        self.assertEqual(self.sorted_ids(btree), ['a', 'b', 'c', 'd'])
291
        btree.note_deletion("grandparent/parent/file")
292
        btree.note_id("e", "grandparent/alt_parent/fool", kind="directory")
293
        btree.note_last_changed("grandparent/alt_parent/fool", 
1185.82.95 by Aaron Bentley
Restore path-orientation of ChangesetTree
294
                                "revisionidiguess")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
295
        self.assertEqual(self.sorted_ids(btree), ['a', 'b', 'd', 'e'])
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
296
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
297
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
298
class BundleTester(TestCaseInTempDir):
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
299
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
300
    def create_bundle_text(self, base_rev_id, rev_id):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
301
        bundle_txt = StringIO()
302
        rev_ids = write_bundle(self.b1.repository, rev_id, base_rev_id, 
303
                               bundle_txt)
304
        bundle_txt.seek(0)
305
        self.assertEqual(bundle_txt.readline(), 
1551.7.3 by Aaron Bentley
Fix strict testaments, as_sha1
306
                         '# Bazaar revision bundle v0.8\n')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
307
        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.
308
1185.82.14 by Aaron Bentley
API updates
309
        rev = self.b1.repository.get_revision(rev_id)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
310
        self.assertEqual(bundle_txt.readline().decode('utf-8'),
311
                         u'# message:\n')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
312
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
313
        open(',,bundle', 'wb').write(bundle_txt.getvalue())
314
        bundle_txt.seek(0)
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
315
        return bundle_txt, rev_ids
316
317
    def get_valid_bundle(self, base_rev_id, rev_id, checkout_dir=None):
318
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
319
        Make sure that the text generated is valid, and that it
320
        can be applied against the base, and generate the same information.
321
        
322
        :return: The in-memory bundle 
323
        """
324
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
325
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
326
        # This should also validate the generated bundle 
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
327
        bundle = read_bundle(bundle_txt)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
328
        repository = self.b1.repository
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
329
        for bundle_rev in bundle.real_revisions:
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
330
            # These really should have already been checked when we read the
331
            # bundle, since it computes the sha1 hash for the revision, which
332
            # only will match if everything is okay, but lets be explicit about
333
            # it
334
            branch_rev = repository.get_revision(bundle_rev.revision_id)
1185.82.33 by Aaron Bentley
Strengthen tests
335
            for a in ('inventory_sha1', 'revision_id', 'parent_ids',
336
                      'timestamp', 'timezone', 'message', 'committer', 
337
                      'parent_ids', 'properties'):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
338
                self.assertEqual(getattr(branch_rev, a), 
339
                                 getattr(bundle_rev, a))
340
            self.assertEqual(len(branch_rev.parent_ids), 
341
                             len(bundle_rev.parent_ids))
1185.82.47 by Aaron Bentley
Ensure all intended rev_ids end up in the revision
342
        self.assertEqual(rev_ids, 
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
343
                         [r.revision_id for r in bundle.real_revisions])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
344
        self.valid_apply_bundle(base_rev_id, bundle,
1185.82.89 by Aaron Bentley
Remove auto_commit stuff
345
                                   checkout_dir=checkout_dir)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
346
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
347
        return bundle
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
348
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
349
    def get_invalid_bundle(self, base_rev_id, rev_id):
350
        """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
351
        Munge the text so that it's invalid.
352
        
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
353
        :return: The in-memory bundle
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
354
        """
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
355
        bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
356
        new_text = bundle_txt.getvalue().replace('executable:no', 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
357
                                               'executable:yes')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
358
        bundle_txt = StringIO(new_text)
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
359
        bundle = read_bundle(bundle_txt)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
360
        self.valid_apply_bundle(base_rev_id, bundle)
361
        return bundle 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
362
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
363
    def test_non_bundle(self):
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
364
        self.assertRaises(NotABundle, read_bundle, StringIO('#!/bin/sh\n'))
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
365
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
366
    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.
367
        """Get a new tree, with the specified revision in it.
368
        """
0.5.102 by John Arbash Meinel
Updated to latest bzr.dev changes (serialization, test cases, etc)
369
        from bzrlib.branch import Branch
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
370
        import tempfile
371
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
372
        if checkout_dir is None:
373
            checkout_dir = tempfile.mkdtemp(prefix='test-branch-', dir='.')
0.5.89 by John Arbash Meinel
Updating for explicitly defined directories.
374
        else:
375
            import os
376
            if not os.path.exists(checkout_dir):
377
                os.mkdir(checkout_dir)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
378
        tree = BzrDir.create_standalone_workingtree(checkout_dir)
379
        s = StringIO()
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
380
        ancestors = write_bundle(self.b1.repository, rev_id, None, s)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
381
        s.seek(0)
1185.82.135 by Aaron Bentley
Ensure that bundles are bytestrings
382
        assert isinstance(s.getvalue(), str), (
383
            "Bundle isn't a bytestring:\n %s..." % repr(s.getvalue())[:40])
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
384
        install_bundle(tree.branch.repository, read_bundle(s))
1185.82.41 by Aaron Bentley
More work on installing changesets
385
        for ancestor in ancestors:
386
            old = self.b1.repository.revision_tree(ancestor)
387
            new = tree.branch.repository.revision_tree(ancestor)
388
            for inventory_id in old:
389
                try:
390
                    old_file = old.get_file(inventory_id)
391
                except:
392
                    continue
393
                if old_file is None:
394
                    continue
395
                self.assertEqual(old_file.read(),
396
                                 new.get_file(inventory_id).read())
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
397
        if rev_id is not None:
398
            rh = self.b1.revision_history()
399
            tree.branch.set_revision_history(rh[:rh.index(rev_id)+1])
400
            tree.update()
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
401
        return tree
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
402
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
403
    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.
404
        """Get the base revision, apply the changes, and make
405
        sure everything matches the builtin branch.
406
        """
1185.82.17 by Aaron Bentley
More API updates
407
        to_tree = self.get_checkout(base_rev_id, checkout_dir=checkout_dir)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
408
        repository = to_tree.branch.repository
1185.82.41 by Aaron Bentley
More work on installing changesets
409
        self.assertIs(repository.has_revision(base_rev_id), True)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
410
        for rev in info.real_revisions:
411
            self.assert_(not repository.has_revision(rev.revision_id),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
412
                'Revision {%s} present before applying bundle' 
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
413
                % rev.revision_id)
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
414
        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.
415
416
        for rev in info.real_revisions:
1185.82.17 by Aaron Bentley
More API updates
417
            self.assert_(repository.has_revision(rev.revision_id),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
418
                '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.
419
                % rev.revision_id)
420
1185.82.17 by Aaron Bentley
More API updates
421
        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.
422
        # 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.
423
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
424
        self.assert_(info.target in to_tree.pending_merges())
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
425
426
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
427
        rev = info.real_revisions[-1]
1185.82.17 by Aaron Bentley
More API updates
428
        base_tree = self.b1.repository.revision_tree(rev.revision_id)
429
        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.
430
        
431
        # 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.
432
        #       we might also check the working tree.
433
434
        base_files = list(base_tree.list_files())
435
        to_files = list(to_tree.list_files())
436
        self.assertEqual(len(base_files), len(to_files))
1185.82.66 by Aaron Bentley
Handle new executable files
437
        for base_file, to_file in zip(base_files, to_files):
438
            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.
439
0.5.117 by John Arbash Meinel
Almost there. Just need to track down a few remaining bugs.
440
        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.
441
            # Check that the meta information is the same
442
            self.assertEqual(base_tree.get_file_size(fileid),
443
                    to_tree.get_file_size(fileid))
444
            self.assertEqual(base_tree.get_file_sha1(fileid),
445
                    to_tree.get_file_sha1(fileid))
446
            # Check that the contents are the same
447
            # This is pretty expensive
448
            # self.assertEqual(base_tree.get_file(fileid).read(),
449
            #         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.
450
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
451
    def test_bundle(self):
1185.82.14 by Aaron Bentley
API updates
452
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
453
        self.b1 = self.tree1.branch
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
454
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
455
        open('b1/one', 'wb').write('one\n')
1185.82.14 by Aaron Bentley
API updates
456
        self.tree1.add('one')
457
        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.
458
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
459
        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.
460
        # FIXME: The current write_bundle api no longer supports
461
        #        setting a custom summary message
462
        #        We should re-introduce the ability, and update
463
        #        the tests to make sure it works.
464
        # bundle = self.get_valid_bundle(None, 'a@cset-0-1',
465
        #         message='With a specialized message')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
466
467
        # Make sure we can handle files with spaces, tabs, other
468
        # bogus characters
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
469
        self.build_tree([
0.5.84 by John Arbash Meinel
(broken) problem with removes.
470
                'b1/with space.txt'
471
                , 'b1/dir/'
472
                , 'b1/dir/filein subdir.c'
473
                , 'b1/dir/WithCaps.txt'
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
474
                , 'b1/dir/trailing space '
0.5.84 by John Arbash Meinel
(broken) problem with removes.
475
                , 'b1/sub/'
476
                , 'b1/sub/sub/'
477
                , '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
478
                # Tabs are not valid in filenames on windows
479
                #'b1/with\ttab.txt'
480
                ])
0.5.84 by John Arbash Meinel
(broken) problem with removes.
481
        open('b1/sub/sub/emptyfile.txt', 'wb').close()
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
482
        open('b1/dir/nolastnewline.txt', 'wb').write('bloop')
1185.82.66 by Aaron Bentley
Handle new executable files
483
        tt = TreeTransform(self.tree1)
484
        tt.new_file('executable', tt.root, '#!/bin/sh\n', 'exe-1', True)
485
        tt.apply()
1185.82.14 by Aaron Bentley
API updates
486
        self.tree1.add([
0.5.84 by John Arbash Meinel
(broken) problem with removes.
487
                'with space.txt'
488
                , 'dir'
489
                , 'dir/filein subdir.c'
490
                , 'dir/WithCaps.txt'
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
491
                , 'dir/trailing space '
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
492
                , 'dir/nolastnewline.txt'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
493
                , 'sub'
494
                , 'sub/sub'
495
                , 'sub/sub/nonempty.txt'
496
                , 'sub/sub/emptyfile.txt'
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
497
                ])
1185.82.14 by Aaron Bentley
API updates
498
        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.
499
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
500
        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.
501
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
502
        # Check a rollup bundle 
503
        bundle = self.get_valid_bundle(None, 'a@cset-0-2')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
504
505
        # Now delete entries
1185.82.21 by Aaron Bentley
Stop using deprecated function
506
        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.
507
                ['sub/sub/nonempty.txt'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
508
                , '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.
509
                , 'sub/sub'
510
                ])
1185.82.68 by Aaron Bentley
Handle execute bit on modified files
511
        tt = TreeTransform(self.tree1)
512
        trans_id = tt.trans_id_tree_file_id('exe-1')
513
        tt.set_executability(False, trans_id)
514
        tt.apply()
1185.82.19 by Aaron Bentley
More API updates
515
        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.
516
        
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
517
        bundle = self.get_valid_bundle('a@cset-0-2', 'a@cset-0-3')
518
        self.assertRaises(TestamentMismatch, self.get_invalid_bundle, 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
519
                          'a@cset-0-2', 'a@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
520
        # Check a rollup bundle 
521
        bundle = self.get_valid_bundle(None, 'a@cset-0-3')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
522
523
524
        # Now move the directory
1185.82.19 by Aaron Bentley
More API updates
525
        self.tree1.rename_one('dir', 'sub/dir')
526
        self.tree1.commit('rename dir', rev_id='a@cset-0-4')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
527
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
528
        bundle = self.get_valid_bundle('a@cset-0-3', 'a@cset-0-4')
529
        # Check a rollup bundle 
530
        bundle = self.get_valid_bundle(None, 'a@cset-0-4')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
531
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
532
        # Modified files
533
        open('b1/sub/dir/WithCaps.txt', 'ab').write('\nAdding some text\n')
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
534
        open('b1/sub/dir/trailing space ', 'ab').write('\nAdding some\nDOS format lines\n')
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
535
        open('b1/sub/dir/nolastnewline.txt', 'ab').write('\n')
1185.82.19 by Aaron Bentley
More API updates
536
        self.tree1.rename_one('sub/dir/trailing space ', 
537
                              'sub/ start and end space ')
538
        self.tree1.commit('Modified files', rev_id='a@cset-0-5')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
539
        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.
540
541
        # Handle international characters
1185.82.137 by Aaron Bentley
Skip unicode changeset test
542
        try:
543
            f = open(u'b1/with Dod\xe9', 'wb')
544
        except UnicodeEncodeError:
545
            raise TestSkipped("Filesystem doesn't support unicode")
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
546
        f.write((u'A file\n'
547
            u'With international man of mystery\n'
548
            u'William Dod\xe9\n').encode('utf-8'))
1185.82.19 by Aaron Bentley
More API updates
549
        self.tree1.add([u'with Dod\xe9'])
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
550
        # BUG: (sort of) You must set verbose=False, so that python doesn't try
551
        #       and print the name of William Dode as part of the commit
1185.82.19 by Aaron Bentley
More API updates
552
        self.tree1.commit(u'i18n commit from William Dod\xe9', 
553
                          rev_id='a@cset-0-6', committer=u'William Dod\xe9',
554
                          verbose=False)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
555
        bundle = self.get_valid_bundle('a@cset-0-5', 'a@cset-0-6')
1185.82.70 by Aaron Bentley
Handle renamed files better
556
        self.tree1.rename_one('sub/dir/WithCaps.txt', 'temp')
557
        self.tree1.rename_one('with space.txt', 'WithCaps.txt')
558
        self.tree1.rename_one('temp', 'with space.txt')
1185.82.72 by Aaron Bentley
Always use leftmost base for changesets
559
        self.tree1.commit(u'swap filenames', rev_id='a@cset-0-7',
1185.82.70 by Aaron Bentley
Handle renamed files better
560
                          verbose=False)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
561
        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
562
        other = self.get_checkout('a@cset-0-6')
563
        other.rename_one('sub/dir/nolastnewline.txt', 'sub/nolastnewline.txt')
564
        other.commit('rename file', rev_id='a@cset-0-7b')
565
        merge([other.basedir, -1], [None, None], this_dir=self.tree1.basedir)
566
        self.tree1.commit(u'Merge', rev_id='a@cset-0-8',
567
                          verbose=False)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
568
        bundle = self.get_valid_bundle('a@cset-0-7', 'a@cset-0-8')
1185.82.72 by Aaron Bentley
Always use leftmost base for changesets
569
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
570
    def test_symlink_bundle(self):
1185.82.87 by Aaron Bentley
Got symlink adding working
571
        if not has_symlinks():
572
            raise TestSkipped("No symlink support")
573
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
574
        self.b1 = self.tree1.branch
575
        tt = TreeTransform(self.tree1)
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
576
        tt.new_symlink('link', tt.root, 'bar/foo', 'link-1')
1185.82.87 by Aaron Bentley
Got symlink adding working
577
        tt.apply()
578
        self.tree1.commit('add symlink', rev_id='l@cset-0-1')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
579
        self.get_valid_bundle(None, 'l@cset-0-1')
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
580
        tt = TreeTransform(self.tree1)
581
        trans_id = tt.trans_id_tree_file_id('link-1')
582
        tt.adjust_path('link2', tt.root, trans_id)
583
        tt.delete_contents(trans_id)
584
        tt.create_symlink('mars', trans_id)
585
        tt.apply()
586
        self.tree1.commit('rename and change symlink', rev_id='l@cset-0-2')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
587
        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
588
        tt = TreeTransform(self.tree1)
589
        trans_id = tt.trans_id_tree_file_id('link-1')
590
        tt.delete_contents(trans_id)
591
        tt.create_symlink('jupiter', trans_id)
592
        tt.apply()
593
        self.tree1.commit('just change symlink target', rev_id='l@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
594
        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
595
        tt = TreeTransform(self.tree1)
596
        trans_id = tt.trans_id_tree_file_id('link-1')
597
        tt.delete_contents(trans_id)
598
        tt.apply()
599
        self.tree1.commit('Delete symlink', rev_id='l@cset-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
600
        self.get_valid_bundle('l@cset-0-3', 'l@cset-0-4')
1185.82.96 by Aaron Bentley
Got first binary test passing
601
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
602
    def test_binary_bundle(self):
1185.82.96 by Aaron Bentley
Got first binary test passing
603
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
604
        self.b1 = self.tree1.branch
605
        tt = TreeTransform(self.tree1)
606
        tt.new_file('file', tt.root, '\x00\xff', 'binary-1')
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
607
        tt.new_file('file2', tt.root, '\x00\xff', 'binary-2')
1185.82.96 by Aaron Bentley
Got first binary test passing
608
        tt.apply()
609
        self.tree1.commit('add binary', rev_id='b@cset-0-1')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
610
        self.get_valid_bundle(None, 'b@cset-0-1')
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
611
        tt = TreeTransform(self.tree1)
612
        trans_id = tt.trans_id_tree_file_id('binary-1')
613
        tt.delete_contents(trans_id)
614
        tt.apply()
615
        self.tree1.commit('delete binary', rev_id='b@cset-0-2')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
616
        self.get_valid_bundle('b@cset-0-1', 'b@cset-0-2')
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
617
        tt = TreeTransform(self.tree1)
618
        trans_id = tt.trans_id_tree_file_id('binary-2')
619
        tt.adjust_path('file3', tt.root, trans_id)
620
        tt.delete_contents(trans_id)
621
        tt.create_file('filecontents\x00', trans_id)
622
        tt.apply()
623
        self.tree1.commit('rename and modify binary', rev_id='b@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
624
        self.get_valid_bundle('b@cset-0-2', 'b@cset-0-3')
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
625
        tt = TreeTransform(self.tree1)
626
        trans_id = tt.trans_id_tree_file_id('binary-2')
627
        tt.delete_contents(trans_id)
628
        tt.create_file('\x00filecontents', trans_id)
629
        tt.apply()
630
        self.tree1.commit('just modify binary', rev_id='b@cset-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
631
        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
632
633
    def test_last_modified(self):
634
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
635
        self.b1 = self.tree1.branch
636
        tt = TreeTransform(self.tree1)
637
        tt.new_file('file', tt.root, 'file', 'file')
638
        tt.apply()
639
        self.tree1.commit('create file', rev_id='a@lmod-0-1')
640
641
        tt = TreeTransform(self.tree1)
642
        trans_id = tt.trans_id_tree_file_id('file')
643
        tt.delete_contents(trans_id)
644
        tt.create_file('file2', trans_id)
645
        tt.apply()
646
        self.tree1.commit('modify text', rev_id='a@lmod-0-2a')
647
648
        other = self.get_checkout('a@lmod-0-1')
649
        tt = TreeTransform(other)
650
        trans_id = tt.trans_id_tree_file_id('file')
651
        tt.delete_contents(trans_id)
652
        tt.create_file('file2', trans_id)
653
        tt.apply()
654
        other.commit('modify text in another tree', rev_id='a@lmod-0-2b')
655
        merge([other.basedir, -1], [None, None], this_dir=self.tree1.basedir)
656
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-3',
657
                          verbose=False)
658
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
659
        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
660
661
    def test_hide_history(self):
662
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
663
        self.b1 = self.tree1.branch
664
1793.3.1 by John Arbash Meinel
Clean up the bundle tests a little bit.
665
        open('b1/one', 'wb').write('one\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
666
        self.tree1.add('one')
667
        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.
668
        open('b1/one', 'wb').write('two\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
669
        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.
670
        open('b1/one', 'wb').write('three\n')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
671
        self.tree1.commit('modify', rev_id='a@cset-0-3')
672
        bundle_file = StringIO()
673
        rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
674
                               'a@cset-0-1', bundle_file)
675
        self.assertNotContainsRe(bundle_file.getvalue(), 'two')
676
        self.assertContainsRe(bundle_file.getvalue(), 'one')
677
        self.assertContainsRe(bundle_file.getvalue(), 'three')
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
678
679
680
class MungedBundleTester(TestCaseWithTransport):
681
682
    def build_test_bundle(self):
683
        wt = self.make_branch_and_tree('b1')
684
685
        self.build_tree(['b1/one'])
686
        wt.add('one')
687
        wt.commit('add one', rev_id='a@cset-0-1')
688
        self.build_tree(['b1/two'])
689
        wt.add('two')
690
        wt.commit('add two', rev_id='a@cset-0-2')
691
692
        bundle_txt = StringIO()
693
        rev_ids = write_bundle(wt.branch.repository, 'a@cset-0-2',
694
                               'a@cset-0-1', bundle_txt)
695
        self.assertEqual(['a@cset-0-2'], rev_ids)
696
        bundle_txt.seek(0, 0)
697
        return bundle_txt
698
699
    def check_valid(self, bundle):
700
        """Check that after whatever munging, the final object is valid."""
701
        self.assertEqual(['a@cset-0-2'], 
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
702
            [r.revision_id for r in bundle.real_revisions])
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
703
704
    def test_extra_whitespace(self):
705
        bundle_txt = self.build_test_bundle()
706
707
        # Seek to the end of the file
708
        # Adding one extra newline used to give us
709
        # TypeError: float() argument must be a string or a number
710
        bundle_txt.seek(0, 2)
711
        bundle_txt.write('\n')
712
        bundle_txt.seek(0)
713
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
714
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
715
        self.check_valid(bundle)
716
717
    def test_extra_whitespace_2(self):
718
        bundle_txt = self.build_test_bundle()
719
720
        # Seek to the end of the file
721
        # Adding two extra newlines used to give us
722
        # MalformedPatches: The first line of all patches should be ...
723
        bundle_txt.seek(0, 2)
724
        bundle_txt.write('\n\n')
725
        bundle_txt.seek(0)
726
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
727
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
728
        self.check_valid(bundle)
729
730
    def test_missing_trailing_whitespace(self):
731
        bundle_txt = self.build_test_bundle()
732
733
        # Remove a trailing newline, it shouldn't kill the parser
734
        raw = bundle_txt.getvalue()
735
        # The contents of the bundle don't have to be this, but this
736
        # test is concerned with the exact case where the serializer
737
        # creates a blank line at the end, and fails if that
738
        # line is stripped
739
        self.assertEqual('\n\n', raw[-2:])
740
        bundle_text = StringIO(raw[:-1])
741
1793.3.4 by John Arbash Meinel
[merge] bzr.dev 1804 and fix conflicts.
742
        bundle = read_bundle(bundle_txt)
1793.3.2 by John Arbash Meinel
(failing) add some tests which munge trailing whitespace
743
        self.check_valid(bundle)