~abentley/bzrtools/bzrtools.dev

147.1.1 by Robert Collins
start adding baz_import unit test cases
1
# Copyright (C) 2005 Canonical Limited
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
#
4
#    This program is free software; you can redistribute it and/or modify
5
#    it under the terms of the GNU General Public License as published by
6
#    the Free Software Foundation; either version 2 of the License, or
7
#    (at your option) any later version.
8
#
9
#    This program is distributed in the hope that it will be useful,
10
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
#    GNU General Public License for more details.
13
#
14
#    You should have received a copy of the GNU General Public License
15
#    along with this program; if not, write to the Free Software
16
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
147.1.7 by Robert Collins
handle inaccessible sibling archives somewhat - note version-0 is still not handled
18
from bzrlib.selftest import TestCaseInTempDir, TestCase
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
19
from bzrlib.selftest.blackbox import has_symlinks
147.1.2 by Robert Collins
test empty import and tagged branches
20
try:
21
    import pybaz
22
except ImportError:
23
    pybaz = None
24
import os
147.1.34 by Robert Collins
wrap > 80 chars line
25
from bzrlib.plugins.bzrtools.baz_import import (import_version, revision_id, 
26
                                                cmd_baz_import)
147.1.20 by Robert Collins
handle missing ancestry
27
from bzrlib.errors import NoSuchRevision
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
28
import shutil
147.1.17 by Robert Collins
make feedback be callback based - really
29
from StringIO import StringIO
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
30
import tempfile
31
from testresources import (TestResource, TestLoader, OptimisingTestSuite,
32
                           ResourcedTestCase)
147.1.33 by Robert Collins
merge from aaron, and update test imports to import successfully.
33
from bzrlib.plugins.bzrtools.fai import namespace_previous
147.1.29 by Robert Collins
update to latest bzr api
34
from bzrlib.branch import Branch
147.1.1 by Robert Collins
start adding baz_import unit test cases
35
36
def test_suite():
147.1.2 by Robert Collins
test empty import and tagged branches
37
    if pybaz is None:
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
38
        return OptimisingTestSuite()
147.1.1 by Robert Collins
start adding baz_import unit test cases
39
    return TestLoader().loadTestsFromName(__name__)
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
40
 
41
42
class BazTreeResource(TestResource):
43
44
    def cleanUp(self):
45
        os.environ['HOME'] = self._oldhome
46
        shutil.rmtree(self._tmpdir)
47
48
    def __init__(self):
49
        self._tmpdir = tempfile.mkdtemp()
50
        self._homedir = os.path.join(self._tmpdir, 'home')
147.1.2 by Robert Collins
test empty import and tagged branches
51
        self._oldhome = os.environ['HOME']
52
        os.mkdir(self._homedir)
53
        os.environ['HOME'] = self._homedir
147.1.20 by Robert Collins
handle missing ancestry
54
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
55
        self._archiveroot = os.path.join(self._tmpdir, 'archive')
147.1.2 by Robert Collins
test empty import and tagged branches
56
        self._archive = pybaz.make_archive('demo@DONOTUSE', str(self._archiveroot))
57
        pybaz.set_my_id("Test User<test@example.org>")
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
58
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
59
        self.make_empty_import()
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
60
147.1.2 by Robert Collins
test empty import and tagged branches
61
        self._empty_tag = 'demo@DONOTUSE/c--empty-tag--0'
62
        self._empty_tag_bzr = revision_id(self._empty_tag + '--base-0')
63
        pybaz.Revision('demo@DONOTUSE/c--import--0--base-0').make_continuation(
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
64
            pybaz.Version(self._empty_tag))
65
66
        self._empty_merged_tag = 'demo@DONOTUSE/c--empty-merged-tag--0'
67
        self._empty_merged_tag_bzr_base = revision_id(self._empty_merged_tag 
68
                                                 + '--base-0')
69
        self._empty_merged_tag_bzr = revision_id(self._empty_merged_tag 
70
                                                 + '--patch-1')
71
        pybaz.Revision('demo@DONOTUSE/c--import--0--base-0').make_continuation(
72
            pybaz.Version(self._empty_merged_tag))
73
        tree = pybaz.Revision(self._empty_merged_tag + '--base-0').get(
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
74
            os.path.join(self._tmpdir, 'tree'))
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
75
        tree.star_merge(self._empty_tag,
76
                        pybaz.Version('demo@DONOTUSE/c--import--0'))
77
        msg = tree.log_message()
78
        msg["summary"]="did a merge, yarh"
79
        tree.commit(msg)
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
80
        shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
81
        
82
        # tree, two commits, includes merge of other branch
83
        self._empty_merged_tag_2 = 'demo@DONOTUSE/c--empty-tag-2--0'
84
        self._empty_merged_tag_2_bzr_base = revision_id(self._empty_merged_tag_2 + '--base-0')
85
        self._empty_merged_tag_2_bzr = revision_id(self._empty_merged_tag_2 + '--patch-1')
86
        pybaz.Revision('demo@DONOTUSE/c--import--0--base-0').make_continuation(
87
            pybaz.Version(self._empty_merged_tag_2))
88
        tree = pybaz.Revision(self._empty_merged_tag_2 + '--base-0').get (
89
            os.path.join(self._tmpdir, 'tree'))
90
        tree.star_merge(self._empty_merged_tag,
91
                        pybaz.Version('demo@DONOTUSE/c--import--0'))
92
        msg = tree.log_message()
93
        msg["summary"] = "merge in a merged tree."
94
        tree.commit(msg)
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
95
        shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
96
147.4.1 by Robert Collins
test escaping of file ids is working
97
        self._bad_id_tag = 'demo@DONOTUSE/c--bad-id--0'
98
        self._bad_id_tag_bzr_base = revision_id(self._bad_id_tag + '--base-0')
99
        self._bad_id_tag_bzr = revision_id(self._bad_id_tag + '--patch-1')
100
        pybaz.Revision('demo@DONOTUSE/c--import--0--base-0').make_continuation(
101
            pybaz.Version(self._bad_id_tag))
102
        tree = pybaz.Revision(self._bad_id_tag + '--base-0').get(
103
            os.path.join(self._tmpdir, 'tree'))
104
        from bzrlib.plugins.bzrtools.baz_import import add_file
105
        add_file(os.path.join(self._tmpdir,'tree/path'), 'text', 'this_id/needs%escaping')
106
        msg = tree.log_message()
107
        msg["summary"] = "commit something which needs escaping."
108
        tree.commit(msg)
109
        shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
110
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
111
        self.make_import_symlink()
147.1.20 by Robert Collins
handle missing ancestry
112
        self.make_missing_ancestor()
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
113
114
    def make_import_symlink(self):
115
        self._import_symlink = 'demo@DONOTUSE/c--import-symlink--0'
116
        self._import_symlink_bzr = revision_id(self._import_symlink + '--base-0')
117
        os.mkdir(os.path.join(self._tmpdir, 'tree'))
118
        tree = pybaz.init_tree(os.path.join(self._tmpdir, 'tree'),
119
                               self._import_symlink)
120
        os.symlink('missing-file-name',
121
                   os.path.join(self._tmpdir, 'tree', 'alink'))
122
        tree.add_tag('alink')
123
        id_file = open(os.path.join(tree, '.arch-ids', 'alink.id'), 'w')
124
        id_file.write('symlink_tag\n')
125
        id_file.close()
126
        msg = tree.log_message()
127
        msg["summary"] = "Import with a symlink"
128
        tree.import_(msg)
129
        shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
130
131
    def make_empty_import(self):
132
        self._import = 'demo@DONOTUSE/c--import--0'
133
        os.mkdir(os.path.join(self._tmpdir, 'tree'))
134
        tree = pybaz.init_tree(os.path.join(self._tmpdir, 'tree'), self._import)
135
        msg = tree.log_message()
136
        msg["summary"] = "I am importing now"
137
        tree.import_(msg)
138
        shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
147.1.2 by Robert Collins
test empty import and tagged branches
139
147.1.20 by Robert Collins
handle missing ancestry
140
    def make_missing_ancestor(self):
141
        self._archivegoneroot = os.path.join(self._tmpdir, 'archivegone')
142
        self._archive = pybaz.make_archive('demo-gone@DONOTUSE',
143
                                           str(self._archivegoneroot))
144
        self._missing_import = 'demo-gone@DONOTUSE/c--import--0'
145
        self._missing_import_bzr = revision_id(self._missing_import 
146
                                                 + '--base-0')
147
        self._missing_ancestor = 'demo@DONOTUSE/c--gone--0'
148
        self._missing_ancestor_bzr = revision_id(self._missing_ancestor 
149
                                                 + '--base-0')
150
        os.mkdir(os.path.join(self._tmpdir, 'tree'))
151
        tree = pybaz.init_tree(os.path.join(self._tmpdir, 'tree'), 
152
                               self._missing_import)
153
        msg = tree.log_message()
154
        msg["summary"] = "I am importing now"
155
        tree.import_(msg)
156
        shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
157
        # tag into the kept archive
158
        pybaz.Revision(self._missing_import + '--base-0').make_continuation(
159
            pybaz.Version(self._missing_ancestor))
147.4.6 by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import
160
161
        # make an import for testing history-reuse logic.
162
        def collect(text):
163
            pass
164
        # note the use of a namespace layout here.
165
        self._missing_import_imported = os.path.join(self._tmpdir, 
166
                                                     'archivegone-bzr')
167
        os.mkdir(os.path.join(self._tmpdir, 'archivegone-bzr'))
168
        os.mkdir(os.path.join(self._tmpdir, 'archivegone-bzr', 'c'))
169
        import_version(os.path.join(self._tmpdir, 'archivegone-bzr', 
170
                                    'c', 'import'),
171
                       pybaz.Version(self._missing_import),
172
                       collect)
147.1.20 by Robert Collins
handle missing ancestry
173
        # and make it inaccessible
174
        pybaz.Archive('demo-gone@DONOTUSE').unregister()
175
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
176
    @classmethod
177
    def _makeResource(self):
178
        return BazTreeResource()
179
180
    @classmethod
181
    def _cleanResource(self, resource):
182
        resource.cleanUp()
183
184
147.1.12 by Robert Collins
create the output directory
185
class TestImportBranch(TestCaseInTempDir):
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
186
187
    _resources = [("_baz", BazTreeResource)]
188
189
    def setUp(self):
190
        TestCaseInTempDir.setUp(self)
191
        ResourcedTestCase.setUpResources(self)
147.1.36 by Robert Collins
updates for bzr api changes
192
        os.environ['HOME'] = self._baz._homedir
147.1.17 by Robert Collins
make feedback be callback based - really
193
        self.output = StringIO()
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
194
147.1.2 by Robert Collins
test empty import and tagged branches
195
    def tearDown(self):
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
196
        ResourcedTestCase.tearDownResources(self)
197
        TestCaseInTempDir.tearDown(self)
147.1.17 by Robert Collins
make feedback be callback based - really
198
 
199
    def collect(self, text):
200
        self.output.write(text)
201
        self.output.write("\n")
202
 
147.1.2 by Robert Collins
test empty import and tagged branches
203
    def test_import_empty(self):
147.1.17 by Robert Collins
make feedback be callback based - really
204
        import_version('output', pybaz.Version(self._baz._import), self.collect)
147.1.2 by Robert Collins
test empty import and tagged branches
205
        # expected results:
206
        # one commit, no files, revision identifier of 'demo@DONOTUSE_c--import--0--base-0'
147.1.29 by Robert Collins
update to latest bzr api
207
        branch = Branch.open('output')
147.1.2 by Robert Collins
test empty import and tagged branches
208
        self.assertEqual(branch.revision_history(),
209
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0'])
210
        rev = branch.get_revision('Arch-1:demo@DONOTUSE%c--import--0--base-0')
211
        # and again.
147.1.17 by Robert Collins
make feedback be callback based - really
212
        import_version('output2', pybaz.Version('demo@DONOTUSE/c--import--0'),
213
                       self.collect)
147.1.29 by Robert Collins
update to latest bzr api
214
        branch2 = Branch.open('output2')
147.1.2 by Robert Collins
test empty import and tagged branches
215
        self.assertEqual(branch.revision_history(), branch2.revision_history())
216
        rev2 = branch2.get_revision('Arch-1:demo@DONOTUSE%c--import--0--base-0')
217
        # they must be the same
218
        self.assertEqual(rev, rev2)
219
220
        # and we should get some expected values:
221
        self.assertEqual(rev.committer, "Test User<test@example.org>")
222
        self.assertEqual(rev.message, "I am importing now")
223
        self.assertEqual(rev.revision_id,
224
                         "Arch-1:demo@DONOTUSE%c--import--0--base-0")
225
226
    def test_empty_tagged(self):
147.1.17 by Robert Collins
make feedback be callback based - really
227
        import_version('output', pybaz.Version(self._baz._empty_tag),
228
                       self.collect)
147.1.2 by Robert Collins
test empty import and tagged branches
229
        # expected results:
230
        # two commits, no files, revision identifiers of 
231
        # 'demo@DONOTUSE_c--import--0--base-0' and
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
232
        # self._baz._empty_tag_bzr
147.1.29 by Robert Collins
update to latest bzr api
233
        branch = Branch.open('output')
147.1.2 by Robert Collins
test empty import and tagged branches
234
        self.assertEqual(branch.revision_history(),
235
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0',
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
236
                          self._baz._empty_tag_bzr])
237
        rev = branch.get_revision(self._baz._empty_tag_bzr)
147.1.2 by Robert Collins
test empty import and tagged branches
238
        # and again.
147.1.17 by Robert Collins
make feedback be callback based - really
239
        import_version('output2', pybaz.Version(self._baz._empty_tag),
240
                       self.collect)
147.1.29 by Robert Collins
update to latest bzr api
241
        branch2 = Branch.open('output2')
147.1.2 by Robert Collins
test empty import and tagged branches
242
        self.assertEqual(branch.revision_history(), branch2.revision_history())
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
243
        rev2 = branch2.get_revision(self._baz._empty_tag_bzr)
147.1.2 by Robert Collins
test empty import and tagged branches
244
        # they must be the same
245
        self.assertEqual(rev, rev2)
246
247
        # and we should get some expected values:
248
        self.assertEqual(rev.committer, "Test User<test@example.org>")
249
        self.assertEqual(rev.message, "tag of demo@DONOTUSE/c--import--0--base-0")
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
250
        self.assertEqual(rev.revision_id, self._baz._empty_tag_bzr)
147.1.2 by Robert Collins
test empty import and tagged branches
251
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
252
    def test_empty_merged_tagged(self):
147.1.17 by Robert Collins
make feedback be callback based - really
253
        import_version('output', pybaz.Version(self._baz._empty_merged_tag),
254
                       self.collect)
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
255
        # expected results:
256
        # two commits, no files, revision identifiers of 
257
        # 'demo@DONOTUSE_c--import--0--base-0' and
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
258
        # self._baz._empty_merged_tag_bzr_base
259
        # self._baz._empty_merged_tag_bzr
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
260
        # and a merged revision from the latter of
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
261
        # self._baz._empty_tag_bzr
147.1.29 by Robert Collins
update to latest bzr api
262
        branch = Branch.open('output')
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
263
        self.assertEqual(branch.revision_history(),
264
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0',
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
265
                          self._baz._empty_merged_tag_bzr_base,
266
                          self._baz._empty_merged_tag_bzr])
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
267
        # and again.
147.1.17 by Robert Collins
make feedback be callback based - really
268
        import_version('output2', pybaz.Version(self._baz._empty_merged_tag),
269
                       self.collect)
147.1.29 by Robert Collins
update to latest bzr api
270
        branch2 = Branch.open('output2')
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
271
        # and import what we should be merged up against for checking with.
147.1.17 by Robert Collins
make feedback be callback based - really
272
        import_version('output3', pybaz.Version(self._baz._empty_tag),
273
                       self.collect)
147.1.29 by Robert Collins
update to latest bzr api
274
        branch3 = Branch.open('output3')
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
275
        
276
        self.assertEqual(branch.revision_history(), branch2.revision_history())
277
        self.assertNotEqual(branch.revision_history(), branch3.revision_history())
278
        # check revisions in the history.
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
279
        rev = branch.get_revision(self._baz._empty_merged_tag_bzr_base)
280
        rev2 = branch2.get_revision(self._baz._empty_merged_tag_bzr_base)
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
281
        # they must be the same
282
        self.assertEqual(rev, rev2)
283
        # and we should get some expected values:
284
        self.assertEqual(rev.committer, "Test User<test@example.org>")
285
        self.assertEqual(rev.message, "tag of demo@DONOTUSE/c--import--0--base-0")
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
286
        self.assertEqual(rev.revision_id, self._baz._empty_merged_tag_bzr_base)
147.4.6 by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import
287
        self.assertEqual(['Arch-1:demo@DONOTUSE%c--import--0--base-0'],
288
                         rev.parent_ids)
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
289
290
        # check next revisions in the history.
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
291
        rev = branch.get_revision(self._baz._empty_merged_tag_bzr)
292
        rev2 = branch2.get_revision(self._baz._empty_merged_tag_bzr)
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
293
        # they must be the same
294
        self.assertEqual(rev, rev2)
295
        # and we should get some expected values:
296
        self.assertEqual(rev.committer, "Test User<test@example.org>")
297
        self.assertEqual(rev.message, "did a merge, yarh")
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
298
        self.assertEqual(rev.revision_id, self._baz._empty_merged_tag_bzr)
147.1.31 by Robert Collins
update to weave api
299
        self.assertEqual(rev.parent_ids[0],
147.1.4 by Robert Collins
start using testresources to coordinate import tests, saves 10 seconds
300
                         self._baz._empty_merged_tag_bzr_base)
147.1.31 by Robert Collins
update to weave api
301
        self.assertEqual(rev.parent_ids[1], self._baz._empty_tag_bzr)
147.1.3 by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded
302
303
        # this tree should have nothing missing from that tree.   
304
        # FIXME there is no code for this right now.
305
        # self.assertEqual(branch.missing_revisions(branch3), [])
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
306
        
307
    def test_merge_branch_with_merges(self):
147.1.17 by Robert Collins
make feedback be callback based - really
308
        import_version('output', pybaz.Version(self._baz._empty_merged_tag_2),
309
                       self.collect)
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
310
        # expected results:
311
        # two commits, no files, revision identifiers of 
312
        # 'demo@DONOTUSE_c--import--0--base-0' and
313
        # self._baz._empty_merged_tag_2_bzr_base
314
        # self._baz._empty_merged_tag_2_bzr
315
        # and a merged revision from the latter of
316
        # self._baz._empty_merged_tag_bzr
147.1.29 by Robert Collins
update to latest bzr api
317
        branch = Branch.open('output')
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
318
        self.assertEqual(branch.revision_history(),
319
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0',
320
                          self._baz._empty_merged_tag_2_bzr_base,
321
                          self._baz._empty_merged_tag_2_bzr])
322
        # and again.
147.1.17 by Robert Collins
make feedback be callback based - really
323
        import_version('output2', pybaz.Version(self._baz._empty_merged_tag_2),
324
                       self.collect)
147.1.29 by Robert Collins
update to latest bzr api
325
        branch2 = Branch.open('output2')
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
326
        # and import what we should be merged up against for checking with.
147.1.17 by Robert Collins
make feedback be callback based - really
327
        import_version('output3', pybaz.Version(self._baz._empty_merged_tag),
328
                       self.collect)
147.1.29 by Robert Collins
update to latest bzr api
329
        branch3 = Branch.open('output3')
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
330
        
331
        self.assertEqual(branch.revision_history(), branch2.revision_history())
332
        self.assertNotEqual(branch.revision_history(), branch3.revision_history())
333
        # check revisions in the history.
334
        rev = branch.get_revision(self._baz._empty_merged_tag_2_bzr_base)
335
        rev2 = branch2.get_revision(self._baz._empty_merged_tag_2_bzr_base)
336
        # they must be the same
337
        self.assertEqual(rev, rev2)
338
        # and we should get some expected values:
339
        self.assertEqual(rev.committer, "Test User<test@example.org>")
340
        self.assertEqual(rev.message, "tag of demo@DONOTUSE/c--import--0--base-0")
341
        self.assertEqual(rev.revision_id, self._baz._empty_merged_tag_2_bzr_base)
342
343
        # check next revisions in the history.
344
        rev = branch.get_revision(self._baz._empty_merged_tag_2_bzr)
345
        rev2 = branch2.get_revision(self._baz._empty_merged_tag_2_bzr)
346
        # they must be the same
347
        self.assertEqual(rev, rev2)
348
        # and we should get some expected values:
349
        self.assertEqual(rev.committer, "Test User<test@example.org>")
350
        self.assertEqual(rev.message, "merge in a merged tree.")
351
        self.assertEqual(rev.revision_id, self._baz._empty_merged_tag_2_bzr)
147.1.31 by Robert Collins
update to weave api
352
        self.assertEqual(rev.parent_ids[0],
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
353
                         self._baz._empty_merged_tag_2_bzr_base)
147.1.31 by Robert Collins
update to weave api
354
        self.assertEqual(rev.parent_ids[1],
147.1.5 by Robert Collins
test and implement direct merge support of 2-in-a-row patches
355
                         self._baz._empty_merged_tag_bzr)
356
357
        # this tree should have nothing missing from that tree.   
358
        # FIXME there is no code for this right now.
359
        # self.assertEqual(branch.missing_revisions(branch3), [])
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
360
        
361
    def test_import_symlink(self):
147.1.17 by Robert Collins
make feedback be callback based - really
362
        import_version('output', pybaz.Version(self._baz._import_symlink),
363
                       self.collect)
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
364
        # expected results:
365
        # one commit, no files, revision identifier of 'demo@DONOTUSE_c--import--0--base-0'
147.1.29 by Robert Collins
update to latest bzr api
366
        branch = Branch.open('output')
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
367
        self.assertEqual(branch.revision_history(),
368
                         [self._baz._import_symlink_bzr])
369
        rev = branch.get_revision(self._baz._import_symlink_bzr)
370
        # and again.
147.1.17 by Robert Collins
make feedback be callback based - really
371
        import_version('output2', pybaz.Version(self._baz._import_symlink),
372
                       self.collect)
147.1.29 by Robert Collins
update to latest bzr api
373
        branch2 = Branch.open('output2')
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
374
        self.assertEqual(branch.revision_history(), branch2.revision_history())
375
        rev2 = branch2.get_revision(self._baz._import_symlink_bzr)
376
        # they must be the same
377
        self.assertEqual(rev, rev2)
378
379
        # and we should get some expected values:
380
        self.assertEqual(rev.committer, "Test User<test@example.org>")
381
        self.assertEqual(rev.message, "Import with a symlink")
382
        self.assertEqual(rev.revision_id, self._baz._import_symlink_bzr)
383
384
        # and we want the symlink alink with target 'missing-file-name'
147.1.31 by Robert Collins
update to weave api
385
        inv = branch.get_inventory(rev.revision_id)
147.1.6 by Robert Collins
import symlinks (needs symlink enabled bzr)
386
        self.assertEqual(inv.path2id('alink'), 'x_symlink_tag')
387
        entry = inv['x_symlink_tag']
388
        self.assertEqual(entry.kind, 'symlink')
389
        self.assertEqual(entry.symlink_target, 'missing-file-name')
147.1.7 by Robert Collins
handle inaccessible sibling archives somewhat - note version-0 is still not handled
390
147.1.20 by Robert Collins
handle missing ancestry
391
    def test_missing_ancestor(self):
392
        import_version('output', pybaz.Version(self._baz._missing_ancestor),
393
                       self.collect)
394
        # expected results:
395
        # one commits, no files, revision identifiers of 
396
        # 'demo@DONOTUSE_c--gone--0--base-0' and
397
        # a merge of demo-gone@DONOTUSE%c--import--0
147.1.29 by Robert Collins
update to latest bzr api
398
        branch = Branch.open('output')
147.1.20 by Robert Collins
handle missing ancestry
399
        self.assertEqual(branch.revision_history(),
400
                         [self._baz._missing_ancestor_bzr])
401
        rev = branch.get_revision(self._baz._missing_ancestor_bzr)
402
        # and again.
403
        import_version('output2', pybaz.Version(self._baz._missing_ancestor),
404
                       self.collect)
147.1.29 by Robert Collins
update to latest bzr api
405
        branch2 = Branch.open('output2')
147.1.20 by Robert Collins
handle missing ancestry
406
        self.assertEqual(branch.revision_history(), branch2.revision_history())
407
        rev2 = branch2.get_revision(self._baz._missing_ancestor_bzr)
408
        # they must be the same
409
        self.assertEqual(rev, rev2)
410
411
        # and we should get some expected values:
412
        self.assertEqual(rev.committer, "Test User<test@example.org>")
413
        self.assertEqual(rev.message, "tag of demo-gone@DONOTUSE/c--import--0--base-0")
414
        self.assertEqual(rev.revision_id, self._baz._missing_ancestor_bzr)
147.1.31 by Robert Collins
update to weave api
415
        self.assertEqual(rev.parent_ids[0], self._baz._missing_import_bzr)
416
        self.assertEqual(1, len(rev.parent_ids))
147.1.20 by Robert Collins
handle missing ancestry
417
418
        # must NOT be able to get the merged evision
419
        self.assertRaises(NoSuchRevision, branch.get_revision, 
420
                          self._baz._missing_import_bzr)
421
147.4.6 by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import
422
    def test_missing_ancestor_reusing_history(self):
423
        import_version('output', pybaz.Version(self._baz._missing_ancestor),
424
                       self.collect,
425
                       reuse_history_from=[self._baz._missing_import_imported])
426
        # expected results:
427
        # one commits, no files, revision identifiers of 
428
        # 'demo-gone@DONOTUSE%c--import--0--base-0' and 
429
        # 'demo@DONOTUSE%c--gone--0--base-0'
430
        branch = Branch.open('output')
431
        self.assertEqual(branch.revision_history(),
432
                         [self._baz._missing_import_bzr,
433
                          self._baz._missing_ancestor_bzr])
434
        rev = branch.get_revision(self._baz._missing_ancestor_bzr)
435
        # and again.
436
        import_version('output2', pybaz.Version(self._baz._missing_ancestor),
437
                       self.collect,
438
                       reuse_history_from=[self._baz._missing_import_imported])
439
        branch2 = Branch.open('output2')
440
        self.assertEqual(branch.revision_history(), branch2.revision_history())
441
        rev2 = branch2.get_revision(self._baz._missing_ancestor_bzr)
442
        # they must be the same
443
        self.assertEqual(rev, rev2)
444
445
        # must be able to get the missing base revision
446
        branch.get_revision(self._baz._missing_import_bzr)
447
448
        # and we should get some expected values:
449
        self.assertEqual(rev.committer, "Test User<test@example.org>")
450
        self.assertEqual(rev.message, "tag of demo-gone@DONOTUSE/c--import--0--base-0")
451
        self.assertEqual(rev.revision_id, self._baz._missing_ancestor_bzr)
452
        self.assertEqual(rev.parent_ids[0], self._baz._missing_import_bzr)
453
        self.assertEqual(1, len(rev.parent_ids))
454
147.4.1 by Robert Collins
test escaping of file ids is working
455
    def test_bad_file_id(self):
456
        import_version('output', pybaz.Version(self._baz._bad_id_tag),
457
                       self.collect)
458
        # expected results:
459
        # three commits, one files, revision identifiers of 
460
        # 'demo@DONOTUSE_c--import--0--base-0' ,
461
        # 'demo@DONOTUSE/c--bad-id--0--base-0' ,
462
        # ''demo@DONOTUSE/c--bad-id--0--patch-1'
463
        branch = Branch.open('output')
464
        self.assertEqual(branch.revision_history(),
465
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0',
466
                          self._baz._bad_id_tag_bzr_base,
467
                          self._baz._bad_id_tag_bzr])
468
        rev = branch.get_revision(self._baz._bad_id_tag_bzr)
469
        inv = branch.get_inventory(self._baz._bad_id_tag_bzr)
470
        self.assertEqual(inv.path2id('path'), 'x_this_id%2fneeds%25escaping')
471
        self.assertEqual('path', inv.id2path('x_this_id%2fneeds%25escaping'))
472
147.4.5 by Robert Collins
When an import finds a revision it needs already in the branch, just append it to the revision history
473
    def test_appending_revisions_already_present(self):
474
        import_version('output', pybaz.Version(self._baz._bad_id_tag),
475
                       self.collect, max_count=2)
476
        # expected results:
477
        # three commits, one files, revision identifiers of 
478
        # 'demo@DONOTUSE_c--import--0--base-0' ,
479
        # 'demo@DONOTUSE/c--bad-id--0--base-0' ,
480
        # ''demo@DONOTUSE/c--bad-id--0--patch-1'
481
        branch = Branch.open('output')
482
        self.assertEqual(branch.revision_history(),
483
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0',
484
                          self._baz._bad_id_tag_bzr_base])
485
        branch.set_revision_history(
486
            ['Arch-1:demo@DONOTUSE%c--import--0--base-0'])
487
        del branch
488
        branch = Branch.open('output')
489
        self.assertEqual(branch.revision_history(),
490
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0'])
491
        del branch
492
        import_version('output', pybaz.Version(self._baz._bad_id_tag),
493
                       self.collect)
494
        branch = Branch.open('output')
495
        self.assertEqual(branch.revision_history(),
496
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0',
497
                          self._baz._bad_id_tag_bzr_base,
498
                          self._baz._bad_id_tag_bzr])
499
        rev = branch.get_revision(self._baz._bad_id_tag_bzr)
500
        inv = branch.get_inventory(self._baz._bad_id_tag_bzr)
501
        self.assertEqual(inv.path2id('path'), 'x_this_id%2fneeds%25escaping')
502
        self.assertEqual('path', inv.id2path('x_this_id%2fneeds%25escaping'))
503
504
    def test_appending_revisions_all_already_present(self):
505
        import_version('output', pybaz.Version(self._baz._bad_id_tag),
506
                       self.collect)
507
        # expected results:
508
        # three commits, one files, revision identifiers of 
509
        # 'demo@DONOTUSE_c--import--0--base-0' ,
510
        # 'demo@DONOTUSE/c--bad-id--0--base-0' ,
511
        # ''demo@DONOTUSE/c--bad-id--0--patch-1'
512
        branch = Branch.open('output')
513
        self.assertEqual(branch.revision_history(),
514
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0',
515
                          self._baz._bad_id_tag_bzr_base,
516
                          self._baz._bad_id_tag_bzr])
517
        branch.set_revision_history(
518
            ['Arch-1:demo@DONOTUSE%c--import--0--base-0'])
519
        del branch
520
        branch = Branch.open('output')
521
        self.assertEqual(branch.revision_history(),
522
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0'])
523
        del branch
524
        import_version('output', pybaz.Version(self._baz._bad_id_tag),
525
                       self.collect)
526
        branch = Branch.open('output')
527
        self.assertEqual(branch.revision_history(),
528
                         ['Arch-1:demo@DONOTUSE%c--import--0--base-0',
529
                          self._baz._bad_id_tag_bzr_base,
530
                          self._baz._bad_id_tag_bzr])
531
        rev = branch.get_revision(self._baz._bad_id_tag_bzr)
532
        inv = branch.get_inventory(self._baz._bad_id_tag_bzr)
533
        self.assertEqual(inv.path2id('path'), 'x_this_id%2fneeds%25escaping')
534
        self.assertEqual('path', inv.id2path('x_this_id%2fneeds%25escaping'))
535
147.1.7 by Robert Collins
handle inaccessible sibling archives somewhat - note version-0 is still not handled
536
537
class TestNamespacePrevious(TestCase):
538
539
    def setUp(self):
540
        TestCase.setUp(self)
541
        self.version = pybaz.Version('foo@example.com/c--b--0')
542
543
    def test_base0_none(self):
544
        self.assertEqual(namespace_previous(self.version['base-0']), None)
545
546
    def test_patch1_base0(self):
547
        self.assertEqual(namespace_previous(self.version['patch-1']),
548
                         self.version['base-0'])
549
        
550
    def test_patch3000_patch2999(self):
551
        self.assertEqual(namespace_previous(self.version['patch-3000']),
552
                         self.version['patch-2999'])
553
        
554
    def test_version0_raises(self):
555
        self.assertRaises(RuntimeError, namespace_previous,
556
                          self.version['version-0'])
557
558
    def test_version1_version0(self):
147.1.29 by Robert Collins
update to latest bzr api
559
        self.assertEqual(namespace_previous(self.version['versionfix-1']),
147.1.7 by Robert Collins
handle inaccessible sibling archives somewhat - note version-0 is still not handled
560
                         self.version['version-0'])
147.1.8 by Robert Collins
handle version-xxx and base-0 correctly in namespace_previous
561
562
    def test_version3000_patch2999(self):
147.1.29 by Robert Collins
update to latest bzr api
563
        self.assertEqual(namespace_previous(self.version['versionfix-3000']),
564
                         self.version['versionfix-2999'])
147.1.11 by Robert Collins
move baz-import to baz-import-branch
565
147.1.13 by Robert Collins
create the output directory
566
class TestNamespaceMapping(TestCase):
567
568
    def test_namespace_mapping_branch(self):
147.1.37 by Robert Collins
get all tests passing again, and disable importing the body of continuation log messages
569
        from bzrlib.plugins.bzrtools.baz_import import map_namespace
147.1.13 by Robert Collins
create the output directory
570
        branch = pybaz.Branch('foo@example.com/c--b')
147.1.14 by Robert Collins
implement a namespace mapper
571
        self.assertRaises(pybaz.errors.NamespaceError, map_namespace, branch)
147.1.13 by Robert Collins
create the output directory
572
        self.assertEqual('c/b', map_namespace(branch['0']))
573
        self.assertEqual('c/0.1/b', map_namespace(branch['0.1']))
574
575
    def test_namespace_mapping_no_branch(self):
147.1.37 by Robert Collins
get all tests passing again, and disable importing the body of continuation log messages
576
        from bzrlib.plugins.bzrtools.baz_import import map_namespace
147.1.13 by Robert Collins
create the output directory
577
        category = pybaz.Category('foo@example.com/c')
147.1.14 by Robert Collins
implement a namespace mapper
578
        self.assertRaises(pybaz.errors.NamespaceError, map_namespace, category)
579
        self.assertEqual('c/+trunk', 
580
                         map_namespace(pybaz.Version("%s--0" % category)))
581
        self.assertEqual('c/0.1/+trunk',
582
                         map_namespace(pybaz.Version('%s--0.1' % category)))
147.1.13 by Robert Collins
create the output directory
583
147.1.12 by Robert Collins
create the output directory
584
147.4.1 by Robert Collins
test escaping of file ids is working
585
class TestFileIdMapping(TestCase):
586
587
    def test_slash(self):
588
        from bzrlib.plugins.bzrtools.baz_import import map_file_id
589
        self.assertEqual('c%2fc', map_file_id('c/c'))
590
        self.assertEqual('c%25c', map_file_id('c%c'))
591
592
147.1.11 by Robert Collins
move baz-import to baz-import-branch
593
class TestImport(TestCaseInTempDir):
594
147.1.15 by Robert Collins
archive at a time imports
595
    def setUp(self):
596
        TestCaseInTempDir.setUp(self)
597
        self._oldhome = os.environ['HOME']
598
        self._tmpdir = tempfile.mkdtemp()
599
        self._homedir = os.path.join(self._tmpdir, 'home')
600
        os.mkdir(self._homedir)
601
        os.environ['HOME'] = self._homedir
602
        self._archiveroot = os.path.join(self._tmpdir, 'archive')
603
        self._archive = pybaz.make_archive('demo@DONOTUSE', 
604
                                           str(self._archiveroot))
605
606
    def tearDown(self):
607
        os.environ['HOME'] = self._oldhome
608
        shutil.rmtree(self._tmpdir)
609
        TestCaseInTempDir.tearDown(self)
610
611
    def make_import(self, namespace):
612
        self._import = 'demo@DONOTUSE/%s' % namespace
613
        os.mkdir(os.path.join(self._tmpdir, 'tree'))
614
        tree = pybaz.init_tree(os.path.join(self._tmpdir, 'tree'), self._import)
615
        msg = tree.log_message()
616
        msg["summary"] = "I am importing now"
617
        tree.import_(msg)
618
        shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
619
147.1.11 by Robert Collins
move baz-import to baz-import-branch
620
    def test_cmd_exists(self):
147.1.37 by Robert Collins
get all tests passing again, and disable importing the body of continuation log messages
621
        from bzrlib.plugins.bzrtools.baz_import import cmd_baz_import
147.1.12 by Robert Collins
create the output directory
622
623
    def test_empty_archive(self):
147.1.15 by Robert Collins
archive at a time imports
624
        command = cmd_baz_import()
625
        command.run(os.path.join(self._tmpdir, 'output'), 'demo@DONOTUSE')
626
        self.failUnless(os.path.exists(os.path.join(self._tmpdir,'output')))
627
        self.assertEqual(1, 
628
                        len(list(os.walk(os.path.join(self._tmpdir,'output')))))
147.1.12 by Robert Collins
create the output directory
629
147.1.15 by Robert Collins
archive at a time imports
630
    def test_two_branches(self):
631
        self.make_import('c--0')
632
        self.make_import('c1--branch--0.2')
633
        command = cmd_baz_import()
634
        command.run(os.path.join(self._tmpdir, 'output'), 'demo@DONOTUSE')
635
        self.failUnless(os.path.exists(os.path.join(self._tmpdir,'output')))
636
        self.failUnless(os.path.exists(os.path.join(self._tmpdir,'output', 'c','+trunk')))
637
        self.failUnless(os.path.exists(os.path.join(self._tmpdir,'output', 'c1', '0.2','branch')))
147.1.37 by Robert Collins
get all tests passing again, and disable importing the body of continuation log messages
638
        self.assertEqual(14,
147.1.15 by Robert Collins
archive at a time imports
639
                        len(list(os.walk(os.path.join(self._tmpdir,'output')))))
147.1.18 by Robert Collins
baz-import twice should work
640
641
    def test_run_twice(self):
642
        self.make_import('c--0')
643
        command = cmd_baz_import()
644
        command.run(os.path.join(self._tmpdir, 'output'), 'demo@DONOTUSE')
645
        command.run(os.path.join(self._tmpdir, 'output'), 'demo@DONOTUSE')
147.4.8 by Robert Collins
Enable reuse of history on archive imports, just append the history locations to the command line
646
        
647
    def test_accepts_reuse_history(self):
648
        self.make_import('c--0')
649
        self.run_bzr('baz-import', os.path.join(self._tmpdir, 'output'),
650
                     'demo@DONOTUSE', '.', '.')
147.4.9 by Robert Collins
But do not require a history location.
651
        
652
    def test_does_not_need_reuse_history(self):
653
        self.make_import('c--0')
654
        self.run_bzr('baz-import', os.path.join(self._tmpdir, 'output'),
655
                     'demo@DONOTUSE')