1
# Copyright (C) 2005 Canonical Limited
2
# Authors: Robert Collins <robert.collins@canonical.com>
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.
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.
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
18
from bzrlib.selftest import TestCaseInTempDir, TestCase
19
from bzrlib.selftest.blackbox import has_symlinks
25
from baz_import import import_version, revision_id, cmd_baz_import
26
from bzrlib.errors import NoSuchRevision
28
from StringIO import StringIO
30
from testresources import (TestResource, TestLoader, OptimisingTestSuite,
32
from fai import namespace_previous
33
from bzrlib.branch import Branch
37
return OptimisingTestSuite()
38
return TestLoader().loadTestsFromName(__name__)
41
class BazTreeResource(TestResource):
44
os.environ['HOME'] = self._oldhome
45
shutil.rmtree(self._tmpdir)
48
self._tmpdir = tempfile.mkdtemp()
49
self._homedir = os.path.join(self._tmpdir, 'home')
50
self._oldhome = os.environ['HOME']
51
os.mkdir(self._homedir)
52
os.environ['HOME'] = self._homedir
54
self._archiveroot = os.path.join(self._tmpdir, 'archive')
55
self._archive = pybaz.make_archive('demo@DONOTUSE', str(self._archiveroot))
56
pybaz.set_my_id("Test User<test@example.org>")
58
self.make_empty_import()
60
self._empty_tag = 'demo@DONOTUSE/c--empty-tag--0'
61
self._empty_tag_bzr = revision_id(self._empty_tag + '--base-0')
62
pybaz.Revision('demo@DONOTUSE/c--import--0--base-0').make_continuation(
63
pybaz.Version(self._empty_tag))
65
self._empty_merged_tag = 'demo@DONOTUSE/c--empty-merged-tag--0'
66
self._empty_merged_tag_bzr_base = revision_id(self._empty_merged_tag
68
self._empty_merged_tag_bzr = revision_id(self._empty_merged_tag
70
pybaz.Revision('demo@DONOTUSE/c--import--0--base-0').make_continuation(
71
pybaz.Version(self._empty_merged_tag))
72
tree = pybaz.Revision(self._empty_merged_tag + '--base-0').get(
73
os.path.join(self._tmpdir, 'tree'))
74
tree.star_merge(self._empty_tag,
75
pybaz.Version('demo@DONOTUSE/c--import--0'))
76
msg = tree.log_message()
77
msg["summary"]="did a merge, yarh"
79
shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
81
# tree, two commits, includes merge of other branch
82
self._empty_merged_tag_2 = 'demo@DONOTUSE/c--empty-tag-2--0'
83
self._empty_merged_tag_2_bzr_base = revision_id(self._empty_merged_tag_2 + '--base-0')
84
self._empty_merged_tag_2_bzr = revision_id(self._empty_merged_tag_2 + '--patch-1')
85
pybaz.Revision('demo@DONOTUSE/c--import--0--base-0').make_continuation(
86
pybaz.Version(self._empty_merged_tag_2))
87
tree = pybaz.Revision(self._empty_merged_tag_2 + '--base-0').get (
88
os.path.join(self._tmpdir, 'tree'))
89
tree.star_merge(self._empty_merged_tag,
90
pybaz.Version('demo@DONOTUSE/c--import--0'))
91
msg = tree.log_message()
92
msg["summary"] = "merge in a merged tree."
94
shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
96
self.make_import_symlink()
97
self.make_missing_ancestor()
99
def make_import_symlink(self):
100
self._import_symlink = 'demo@DONOTUSE/c--import-symlink--0'
101
self._import_symlink_bzr = revision_id(self._import_symlink + '--base-0')
102
os.mkdir(os.path.join(self._tmpdir, 'tree'))
103
tree = pybaz.init_tree(os.path.join(self._tmpdir, 'tree'),
104
self._import_symlink)
105
os.symlink('missing-file-name',
106
os.path.join(self._tmpdir, 'tree', 'alink'))
107
tree.add_tag('alink')
108
id_file = open(os.path.join(tree, '.arch-ids', 'alink.id'), 'w')
109
id_file.write('symlink_tag\n')
111
msg = tree.log_message()
112
msg["summary"] = "Import with a symlink"
114
shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
116
def make_empty_import(self):
117
self._import = 'demo@DONOTUSE/c--import--0'
118
os.mkdir(os.path.join(self._tmpdir, 'tree'))
119
tree = pybaz.init_tree(os.path.join(self._tmpdir, 'tree'), self._import)
120
msg = tree.log_message()
121
msg["summary"] = "I am importing now"
123
shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
125
def make_missing_ancestor(self):
126
self._archivegoneroot = os.path.join(self._tmpdir, 'archivegone')
127
self._archive = pybaz.make_archive('demo-gone@DONOTUSE',
128
str(self._archivegoneroot))
129
self._missing_import = 'demo-gone@DONOTUSE/c--import--0'
130
self._missing_import_bzr = revision_id(self._missing_import
132
self._missing_ancestor = 'demo@DONOTUSE/c--gone--0'
133
self._missing_ancestor_bzr = revision_id(self._missing_ancestor
135
os.mkdir(os.path.join(self._tmpdir, 'tree'))
136
tree = pybaz.init_tree(os.path.join(self._tmpdir, 'tree'),
137
self._missing_import)
138
msg = tree.log_message()
139
msg["summary"] = "I am importing now"
141
shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
142
# tag into the kept archive
143
pybaz.Revision(self._missing_import + '--base-0').make_continuation(
144
pybaz.Version(self._missing_ancestor))
145
# and make it inaccessible
146
pybaz.Archive('demo-gone@DONOTUSE').unregister()
149
def _makeResource(self):
150
return BazTreeResource()
153
def _cleanResource(self, resource):
157
class TestImportBranch(TestCaseInTempDir):
159
_resources = [("_baz", BazTreeResource)]
162
TestCaseInTempDir.setUp(self)
163
ResourcedTestCase.setUpResources(self)
164
self.output = StringIO()
167
ResourcedTestCase.tearDownResources(self)
168
TestCaseInTempDir.tearDown(self)
170
def collect(self, text):
171
self.output.write(text)
172
self.output.write("\n")
174
def test_import_empty(self):
175
import_version('output', pybaz.Version(self._baz._import), self.collect)
177
# one commit, no files, revision identifier of 'demo@DONOTUSE_c--import--0--base-0'
178
branch = Branch.open('output')
179
self.assertEqual(branch.revision_history(),
180
['Arch-1:demo@DONOTUSE%c--import--0--base-0'])
181
rev = branch.get_revision('Arch-1:demo@DONOTUSE%c--import--0--base-0')
183
import_version('output2', pybaz.Version('demo@DONOTUSE/c--import--0'),
185
branch2 = Branch.open('output2')
186
self.assertEqual(branch.revision_history(), branch2.revision_history())
187
rev2 = branch2.get_revision('Arch-1:demo@DONOTUSE%c--import--0--base-0')
188
# they must be the same
189
self.assertEqual(rev, rev2)
191
# and we should get some expected values:
192
self.assertEqual(rev.committer, "Test User<test@example.org>")
193
self.assertEqual(rev.message, "I am importing now")
194
self.assertEqual(rev.revision_id,
195
"Arch-1:demo@DONOTUSE%c--import--0--base-0")
197
def test_empty_tagged(self):
198
import_version('output', pybaz.Version(self._baz._empty_tag),
201
# two commits, no files, revision identifiers of
202
# 'demo@DONOTUSE_c--import--0--base-0' and
203
# self._baz._empty_tag_bzr
204
branch = Branch.open('output')
205
self.assertEqual(branch.revision_history(),
206
['Arch-1:demo@DONOTUSE%c--import--0--base-0',
207
self._baz._empty_tag_bzr])
208
rev = branch.get_revision(self._baz._empty_tag_bzr)
210
import_version('output2', pybaz.Version(self._baz._empty_tag),
212
branch2 = Branch.open('output2')
213
self.assertEqual(branch.revision_history(), branch2.revision_history())
214
rev2 = branch2.get_revision(self._baz._empty_tag_bzr)
215
# they must be the same
216
self.assertEqual(rev, rev2)
218
# and we should get some expected values:
219
self.assertEqual(rev.committer, "Test User<test@example.org>")
220
self.assertEqual(rev.message, "tag of demo@DONOTUSE/c--import--0--base-0")
221
self.assertEqual(rev.revision_id, self._baz._empty_tag_bzr)
223
def test_empty_merged_tagged(self):
224
import_version('output', pybaz.Version(self._baz._empty_merged_tag),
227
# two commits, no files, revision identifiers of
228
# 'demo@DONOTUSE_c--import--0--base-0' and
229
# self._baz._empty_merged_tag_bzr_base
230
# self._baz._empty_merged_tag_bzr
231
# and a merged revision from the latter of
232
# self._baz._empty_tag_bzr
233
branch = Branch.open('output')
234
self.assertEqual(branch.revision_history(),
235
['Arch-1:demo@DONOTUSE%c--import--0--base-0',
236
self._baz._empty_merged_tag_bzr_base,
237
self._baz._empty_merged_tag_bzr])
239
import_version('output2', pybaz.Version(self._baz._empty_merged_tag),
241
branch2 = Branch.open('output2')
242
# and import what we should be merged up against for checking with.
243
import_version('output3', pybaz.Version(self._baz._empty_tag),
245
branch3 = Branch.open('output3')
247
self.assertEqual(branch.revision_history(), branch2.revision_history())
248
self.assertNotEqual(branch.revision_history(), branch3.revision_history())
249
# check revisions in the history.
250
rev = branch.get_revision(self._baz._empty_merged_tag_bzr_base)
251
rev2 = branch2.get_revision(self._baz._empty_merged_tag_bzr_base)
252
# they must be the same
253
self.assertEqual(rev, rev2)
254
# and we should get some expected values:
255
self.assertEqual(rev.committer, "Test User<test@example.org>")
256
self.assertEqual(rev.message, "tag of demo@DONOTUSE/c--import--0--base-0")
257
self.assertEqual(rev.revision_id, self._baz._empty_merged_tag_bzr_base)
259
# check next revisions in the history.
260
rev = branch.get_revision(self._baz._empty_merged_tag_bzr)
261
rev2 = branch2.get_revision(self._baz._empty_merged_tag_bzr)
262
# they must be the same
263
self.assertEqual(rev, rev2)
264
# and we should get some expected values:
265
self.assertEqual(rev.committer, "Test User<test@example.org>")
266
self.assertEqual(rev.message, "did a merge, yarh")
267
self.assertEqual(rev.revision_id, self._baz._empty_merged_tag_bzr)
268
self.assertEqual(rev.parent_ids[0],
269
self._baz._empty_merged_tag_bzr_base)
270
self.assertEqual(rev.parent_ids[1], self._baz._empty_tag_bzr)
272
# this tree should have nothing missing from that tree.
273
# FIXME there is no code for this right now.
274
# self.assertEqual(branch.missing_revisions(branch3), [])
276
def test_merge_branch_with_merges(self):
277
import_version('output', pybaz.Version(self._baz._empty_merged_tag_2),
280
# two commits, no files, revision identifiers of
281
# 'demo@DONOTUSE_c--import--0--base-0' and
282
# self._baz._empty_merged_tag_2_bzr_base
283
# self._baz._empty_merged_tag_2_bzr
284
# and a merged revision from the latter of
285
# self._baz._empty_merged_tag_bzr
286
branch = Branch.open('output')
287
self.assertEqual(branch.revision_history(),
288
['Arch-1:demo@DONOTUSE%c--import--0--base-0',
289
self._baz._empty_merged_tag_2_bzr_base,
290
self._baz._empty_merged_tag_2_bzr])
292
import_version('output2', pybaz.Version(self._baz._empty_merged_tag_2),
294
branch2 = Branch.open('output2')
295
# and import what we should be merged up against for checking with.
296
import_version('output3', pybaz.Version(self._baz._empty_merged_tag),
298
branch3 = Branch.open('output3')
300
self.assertEqual(branch.revision_history(), branch2.revision_history())
301
self.assertNotEqual(branch.revision_history(), branch3.revision_history())
302
# check revisions in the history.
303
rev = branch.get_revision(self._baz._empty_merged_tag_2_bzr_base)
304
rev2 = branch2.get_revision(self._baz._empty_merged_tag_2_bzr_base)
305
# they must be the same
306
self.assertEqual(rev, rev2)
307
# and we should get some expected values:
308
self.assertEqual(rev.committer, "Test User<test@example.org>")
309
self.assertEqual(rev.message, "tag of demo@DONOTUSE/c--import--0--base-0")
310
self.assertEqual(rev.revision_id, self._baz._empty_merged_tag_2_bzr_base)
312
# check next revisions in the history.
313
rev = branch.get_revision(self._baz._empty_merged_tag_2_bzr)
314
rev2 = branch2.get_revision(self._baz._empty_merged_tag_2_bzr)
315
# they must be the same
316
self.assertEqual(rev, rev2)
317
# and we should get some expected values:
318
self.assertEqual(rev.committer, "Test User<test@example.org>")
319
self.assertEqual(rev.message, "merge in a merged tree.")
320
self.assertEqual(rev.revision_id, self._baz._empty_merged_tag_2_bzr)
321
self.assertEqual(rev.parent_ids[0],
322
self._baz._empty_merged_tag_2_bzr_base)
323
self.assertEqual(rev.parent_ids[1],
324
self._baz._empty_merged_tag_bzr)
326
# this tree should have nothing missing from that tree.
327
# FIXME there is no code for this right now.
328
# self.assertEqual(branch.missing_revisions(branch3), [])
330
def test_import_symlink(self):
331
import_version('output', pybaz.Version(self._baz._import_symlink),
334
# one commit, no files, revision identifier of 'demo@DONOTUSE_c--import--0--base-0'
335
branch = Branch.open('output')
336
self.assertEqual(branch.revision_history(),
337
[self._baz._import_symlink_bzr])
338
rev = branch.get_revision(self._baz._import_symlink_bzr)
340
import_version('output2', pybaz.Version(self._baz._import_symlink),
342
branch2 = Branch.open('output2')
343
self.assertEqual(branch.revision_history(), branch2.revision_history())
344
rev2 = branch2.get_revision(self._baz._import_symlink_bzr)
345
# they must be the same
346
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, "Import with a symlink")
351
self.assertEqual(rev.revision_id, self._baz._import_symlink_bzr)
353
# and we want the symlink alink with target 'missing-file-name'
354
inv = branch.get_inventory(rev.revision_id)
355
self.assertEqual(inv.path2id('alink'), 'x_symlink_tag')
356
entry = inv['x_symlink_tag']
357
self.assertEqual(entry.kind, 'symlink')
358
self.assertEqual(entry.symlink_target, 'missing-file-name')
360
def test_missing_ancestor(self):
361
import_version('output', pybaz.Version(self._baz._missing_ancestor),
364
# one commits, no files, revision identifiers of
365
# 'demo@DONOTUSE_c--gone--0--base-0' and
366
# a merge of demo-gone@DONOTUSE%c--import--0
367
branch = Branch.open('output')
368
self.assertEqual(branch.revision_history(),
369
[self._baz._missing_ancestor_bzr])
370
rev = branch.get_revision(self._baz._missing_ancestor_bzr)
372
import_version('output2', pybaz.Version(self._baz._missing_ancestor),
374
branch2 = Branch.open('output2')
375
self.assertEqual(branch.revision_history(), branch2.revision_history())
376
rev2 = branch2.get_revision(self._baz._missing_ancestor_bzr)
377
# they must be the same
378
self.assertEqual(rev, rev2)
380
# and we should get some expected values:
381
self.assertEqual(rev.committer, "Test User<test@example.org>")
382
self.assertEqual(rev.message, "tag of demo-gone@DONOTUSE/c--import--0--base-0")
383
self.assertEqual(rev.revision_id, self._baz._missing_ancestor_bzr)
384
self.assertEqual(rev.parent_ids[0], self._baz._missing_import_bzr)
385
self.assertEqual(1, len(rev.parent_ids))
387
# must NOT be able to get the merged evision
388
self.assertRaises(NoSuchRevision, branch.get_revision,
389
self._baz._missing_import_bzr)
392
class TestNamespacePrevious(TestCase):
396
self.version = pybaz.Version('foo@example.com/c--b--0')
398
def test_base0_none(self):
399
self.assertEqual(namespace_previous(self.version['base-0']), None)
401
def test_patch1_base0(self):
402
self.assertEqual(namespace_previous(self.version['patch-1']),
403
self.version['base-0'])
405
def test_patch3000_patch2999(self):
406
self.assertEqual(namespace_previous(self.version['patch-3000']),
407
self.version['patch-2999'])
409
def test_version0_raises(self):
410
self.assertRaises(RuntimeError, namespace_previous,
411
self.version['version-0'])
413
def test_version1_version0(self):
414
self.assertEqual(namespace_previous(self.version['versionfix-1']),
415
self.version['version-0'])
417
def test_version3000_patch2999(self):
418
self.assertEqual(namespace_previous(self.version['versionfix-3000']),
419
self.version['versionfix-2999'])
421
class TestNamespaceMapping(TestCase):
423
def test_namespace_mapping_branch(self):
424
from baz_import import map_namespace
425
branch = pybaz.Branch('foo@example.com/c--b')
426
self.assertRaises(pybaz.errors.NamespaceError, map_namespace, branch)
427
self.assertEqual('c/b', map_namespace(branch['0']))
428
self.assertEqual('c/0.1/b', map_namespace(branch['0.1']))
430
def test_namespace_mapping_no_branch(self):
431
from baz_import import map_namespace
432
category = pybaz.Category('foo@example.com/c')
433
self.assertRaises(pybaz.errors.NamespaceError, map_namespace, category)
434
self.assertEqual('c/+trunk',
435
map_namespace(pybaz.Version("%s--0" % category)))
436
self.assertEqual('c/0.1/+trunk',
437
map_namespace(pybaz.Version('%s--0.1' % category)))
440
class TestImport(TestCaseInTempDir):
443
TestCaseInTempDir.setUp(self)
444
self._oldhome = os.environ['HOME']
445
self._tmpdir = tempfile.mkdtemp()
446
self._homedir = os.path.join(self._tmpdir, 'home')
447
os.mkdir(self._homedir)
448
os.environ['HOME'] = self._homedir
449
self._archiveroot = os.path.join(self._tmpdir, 'archive')
450
self._archive = pybaz.make_archive('demo@DONOTUSE',
451
str(self._archiveroot))
454
os.environ['HOME'] = self._oldhome
455
shutil.rmtree(self._tmpdir)
456
TestCaseInTempDir.tearDown(self)
458
def make_import(self, namespace):
459
self._import = 'demo@DONOTUSE/%s' % namespace
460
os.mkdir(os.path.join(self._tmpdir, 'tree'))
461
tree = pybaz.init_tree(os.path.join(self._tmpdir, 'tree'), self._import)
462
msg = tree.log_message()
463
msg["summary"] = "I am importing now"
465
shutil.rmtree(os.path.join(self._tmpdir, 'tree'))
467
def test_cmd_exists(self):
468
from baz_import import cmd_baz_import
470
def test_empty_archive(self):
471
command = cmd_baz_import()
472
command.run(os.path.join(self._tmpdir, 'output'), 'demo@DONOTUSE')
473
self.failUnless(os.path.exists(os.path.join(self._tmpdir,'output')))
475
len(list(os.walk(os.path.join(self._tmpdir,'output')))))
477
def test_two_branches(self):
478
self.make_import('c--0')
479
self.make_import('c1--branch--0.2')
480
command = cmd_baz_import()
481
command.run(os.path.join(self._tmpdir, 'output'), 'demo@DONOTUSE')
482
self.failUnless(os.path.exists(os.path.join(self._tmpdir,'output')))
483
self.failUnless(os.path.exists(os.path.join(self._tmpdir,'output', 'c','+trunk')))
484
self.failUnless(os.path.exists(os.path.join(self._tmpdir,'output', 'c1', '0.2','branch')))
486
len(list(os.walk(os.path.join(self._tmpdir,'output')))))
488
def test_run_twice(self):
489
self.make_import('c--0')
490
command = cmd_baz_import()
491
command.run(os.path.join(self._tmpdir, 'output'), 'demo@DONOTUSE')
492
command.run(os.path.join(self._tmpdir, 'output'), 'demo@DONOTUSE')