2
from StringIO import StringIO
3
from shutil import rmtree, copy2, copytree
6
from unittest import makeSuite
8
from bzrlib import osutils
9
from bzrlib.bzrdir import BzrDir
10
from bzrlib.plugins.bzrtools.upstream_import import (
19
from bzrlib.tests import TestCaseInTempDir
22
def import_tar_broken(tree, tar_input):
24
Import a tarfile with names that that end in //, e.g. Feisty Python 2.5
26
tar_file = tarfile.open('lala', 'r', tar_input)
27
for member in tar_file.members:
28
if member.name.endswith('/'):
30
import_archive(tree, tar_file)
33
class DirFileWriter(object):
35
def __init__(self, fileobj, mode):
36
# We may be asked to 'append'. If so, fileobj already has a path.
37
# So we copy the existing tree, and overwrite afterward.
39
existing = fileobj.read()
41
path = tempfile.mkdtemp(dir=os.getcwd())
43
# copytree requires the directory not to exist
45
copytree(existing, path)
50
target_path = os.path.join(self.root, path)
51
parent = osutils.dirname(target_path)
52
if not os.path.exists(parent):
54
kind = osutils.file_kind(path)
56
copy2(path, target_path)
57
if kind == 'directory':
64
class TestImport(TestCaseInTempDir):
66
def make_tar(self, mode='w'):
68
return tarfile.open('project-0.1.tar', mode, fileobj)
69
return self.make_archive(maker)
71
def make_archive(self, maker, subdir=True):
73
archive_file = maker(result)
75
os.mkdir('project-0.1')
78
archive_file.add('project-0.1')
81
os.chdir('project-0.1')
82
os.mkdir(prefix + 'junk')
83
archive_file.add(prefix + 'junk')
85
f = file(prefix + 'README', 'wb')
88
archive_file.add(prefix + 'README')
90
f = file(prefix + 'FEEDME', 'wb')
93
archive_file.add(prefix + 'FEEDME')
103
def make_archive2(self, builder, subdir):
105
archive_file = builder(result)
106
os.mkdir('project-0.2')
109
prefix='project-0.2/'
110
archive_file.add('project-0.2')
113
os.chdir('project-0.2')
115
os.mkdir(prefix + 'junk')
116
archive_file.add(prefix + 'junk')
118
f = file(prefix + 'README', 'wb')
121
archive_file.add(prefix + 'README')
124
archive_file = builder(result, 'a')
125
archive_file.add(prefix + 'README')
134
def make_messed_tar(self):
136
tar_file = tarfile.open('project-0.1.tar', 'w', result)
137
os.mkdir('project-0.1')
138
tar_file.add('project-0.1')
140
os.mkdir('project-0.2')
141
tar_file.add('project-0.2')
143
f = file('project-0.1/README', 'wb')
146
tar_file.add('project-0.1/README')
148
rmtree('project-0.1')
154
return ZipFileWrapper(fileobj, 'w')
155
return self.make_archive(maker)
157
def make_tar_with_bzrdir(self):
159
tar_file = tarfile.open('tar-with-bzrdir.tar', 'w', result)
160
os.mkdir('toplevel-dir')
161
tar_file.add('toplevel-dir')
162
os.mkdir('toplevel-dir/.bzr')
163
tar_file.add('toplevel-dir/.bzr')
165
rmtree('toplevel-dir')
169
def test_top_path(self):
170
self.assertEqual(top_path('ab/b/c'), 'ab')
171
self.assertEqual(top_path('etc'), 'etc')
172
self.assertEqual(top_path('project-0.1'), 'project-0.1')
174
def test_common_directory(self):
175
self.assertEqual(common_directory(['ab/c/d', 'ab/c/e']), 'ab')
176
self.assertIs(common_directory(['ab/c/d', 'ac/c/e']), None)
177
self.assertEqual('FEEDME', common_directory(['FEEDME']))
179
def test_untar(self):
180
def builder(fileobj, mode='w'):
181
return tarfile.open('project-0.1.tar', mode, fileobj)
182
self.archive_test(builder, import_tar)
184
def test_broken_tar(self):
185
def builder(fileobj, mode='w'):
186
return tarfile.open('project-0.1.tar', mode, fileobj)
187
self.archive_test(builder, import_tar_broken, subdir=True)
189
def test_unzip(self):
190
def builder(fileobj, mode='w'):
191
return ZipFileWrapper(fileobj, mode)
192
self.archive_test(builder, import_zip)
194
def test_copydir_nosub(self):
195
def builder(fileobj, mode='w'):
196
return DirFileWriter(fileobj, mode)
197
# It would be bogus to test with the result in a subdirectory,
198
# because for directories, the input root is always the output root.
199
self.archive_test(builder, import_dir)
201
def archive_test(self, builder, importer, subdir=False):
202
archive_file = self.make_archive(builder, subdir)
203
tree = BzrDir.create_standalone_workingtree('tree')
206
importer(tree, archive_file)
207
self.assertTrue(tree.path2id('README') is not None)
208
self.assertTrue(tree.path2id('FEEDME') is not None)
209
self.assertTrue(os.path.isfile(tree.abspath('README')))
210
self.assertEqual(tree.inventory[tree.path2id('README')].kind,
212
self.assertEqual(tree.inventory[tree.path2id('FEEDME')].kind,
214
f = file(tree.abspath('junk/food'), 'wb')
215
f.write('I like food\n')
218
archive_file = self.make_archive2(builder, subdir)
219
importer(tree, archive_file)
220
self.assertTrue(tree.path2id('README') is not None)
221
self.assertTrue(not os.path.exists(tree.abspath('FEEDME')))
226
def test_untar2(self):
227
tar_file = self.make_messed_tar()
228
tree = BzrDir.create_standalone_workingtree('tree')
229
import_tar(tree, tar_file)
230
self.assertTrue(tree.path2id('project-0.1/README') is not None)
232
def test_untar_gzip(self):
233
tar_file = self.make_tar(mode='w:gz')
234
tree = BzrDir.create_standalone_workingtree('tree')
235
import_tar(tree, tar_file)
236
self.assertTrue(tree.path2id('README') is not None)
238
def test_no_crash_with_bzrdir(self):
239
tar_file = self.make_tar_with_bzrdir()
240
tree = BzrDir.create_standalone_workingtree('tree')
241
import_tar(tree, tar_file)
242
# So long as it did not crash, that should be ok
245
return makeSuite(TestImport)