1
# Copyright (C) 2005-2010 Canonical Ltd
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
"""Black-box tests for bzr export.
21
from StringIO import StringIO
33
from bzrlib.tests.blackbox import ExternalBase
36
class TestExport(ExternalBase):
38
def test_tar_export(self):
39
tree = self.make_branch_and_tree('tar')
40
self.build_tree(['tar/a'])
42
self.build_tree_contents([('tar/.bzrrules', '')])
44
self.build_tree(['tar/.bzr-adir/', 'tar/.bzr-adir/afile'])
45
tree.add(['.bzr-adir/', '.bzr-adir/afile'])
48
self.run_bzr('ignore something')
51
self.failUnless(tree.has_filename('.bzrignore'))
52
self.failUnless(tree.has_filename('.bzrrules'))
53
self.failUnless(tree.has_filename('.bzr-adir'))
54
self.failUnless(tree.has_filename('.bzr-adir/afile'))
55
self.run_bzr('export test.tar.gz')
56
ball = tarfile.open('test.tar.gz')
57
# Make sure the tarball contains 'a', but does not contain
59
self.assertEqual(['test/a'], sorted(ball.getnames()))
61
if sys.version_info < (2, 5, 2) and sys.platform == 'darwin':
62
raise tests.KnownFailure('python %r has a tar related bug, upgrade'
63
% (sys.version_info,))
64
out, err = self.run_bzr('export --format=tgz --root=test -')
65
ball = tarfile.open('', fileobj=StringIO(out))
66
self.assertEqual(['test/a'], sorted(ball.getnames()))
68
def test_tar_export_unicode(self):
69
tree = self.make_branch_and_tree('tar')
70
# FIXME: using fname = u'\xe5.txt' below triggers a bug revealed since
71
# bzr.dev revno 4216 but more related to OSX/working trees/unicode than
72
# export itself --vila 20090406
73
fname = u'\N{Euro Sign}.txt'
75
self.build_tree(['tar/' + fname])
77
raise tests.TestSkipped('Unable to represent path %r' % (fname,))
82
self.run_bzr('export test.tar')
83
ball = tarfile.open('test.tar')
84
# all paths are prefixed with the base name of the tarball
85
self.assertEqual(['test/' + fname.encode('utf8')],
86
sorted(ball.getnames()))
88
def test_zip_export(self):
89
tree = self.make_branch_and_tree('zip')
90
self.build_tree(['zip/a'])
92
self.build_tree_contents([('zip/.bzrrules', '')])
94
self.build_tree(['zip/.bzr-adir/', 'zip/.bzr-adir/afile'])
95
tree.add(['.bzr-adir/', '.bzr-adir/afile'])
98
self.run_bzr('ignore something')
101
self.failUnless(tree.has_filename('.bzrignore'))
102
self.failUnless(tree.has_filename('.bzrrules'))
103
self.failUnless(tree.has_filename('.bzr-adir'))
104
self.failUnless(tree.has_filename('.bzr-adir/afile'))
105
self.run_bzr('export test.zip')
107
zfile = zipfile.ZipFile('test.zip')
108
# Make sure the zipfile contains 'a', but does not contain
110
self.assertEqual(['test/a'], sorted(zfile.namelist()))
112
def test_zip_export_unicode(self):
113
tree = self.make_branch_and_tree('zip')
114
fname = u'\N{Euro Sign}.txt'
116
self.build_tree(['zip/' + fname])
118
raise tests.TestSkipped('Unable to represent path %r' % (fname,))
123
self.run_bzr('export test.zip')
124
zfile = zipfile.ZipFile('test.zip')
125
# all paths are prefixed with the base name of the zipfile
126
self.assertEqual(['test/' + fname.encode('utf8')],
127
sorted(zfile.namelist()))
129
def test_zip_export_directories(self):
130
tree = self.make_branch_and_tree('zip')
131
self.build_tree(['zip/a', 'zip/b/', 'zip/b/c', 'zip/d/'])
132
tree.add(['a', 'b', 'b/c', 'd'])
136
self.run_bzr('export test.zip')
137
zfile = zipfile.ZipFile('test.zip')
138
names = sorted(zfile.namelist())
140
# even on win32, zipfile.ZipFile changes all names to use
142
self.assertEqual(['test/a', 'test/b/', 'test/b/c', 'test/d/'], names)
144
file_attr = stat.S_IFREG | export.zip_exporter.FILE_PERMISSIONS
145
dir_attr = stat.S_IFDIR | export.zip_exporter.ZIP_DIRECTORY_BIT
147
a_info = zfile.getinfo(names[0])
148
self.assertEqual(file_attr, a_info.external_attr)
150
b_info = zfile.getinfo(names[1])
151
self.assertEqual(dir_attr, b_info.external_attr)
153
c_info = zfile.getinfo(names[2])
154
self.assertEqual(file_attr, c_info.external_attr)
156
d_info = zfile.getinfo(names[3])
157
self.assertEqual(dir_attr, d_info.external_attr)
159
def test_dir_export(self):
160
tree = self.make_branch_and_tree('dir')
161
self.build_tree(['dir/a'])
163
self.build_tree_contents([('dir/.bzrrules', '')])
164
tree.add('.bzrrules')
165
self.build_tree(['dir/.bzr-adir/', 'dir/.bzr-adir/afile'])
166
tree.add(['.bzr-adir/', '.bzr-adir/afile'])
169
self.run_bzr('ignore something')
172
self.failUnless(tree.has_filename('.bzrignore'))
173
self.failUnless(tree.has_filename('.bzrrules'))
174
self.failUnless(tree.has_filename('.bzr-adir'))
175
self.failUnless(tree.has_filename('.bzr-adir/afile'))
176
self.run_bzr('export direxport')
178
files = sorted(os.listdir('direxport'))
179
# Make sure the exported directory contains 'a', but does not contain
181
self.assertEqual(['a'], files)
183
def example_branch(self):
184
"""Create a branch a 'branch' containing hello and goodbye."""
185
tree = self.make_branch_and_tree('branch')
186
self.build_tree_contents([('branch/hello', 'foo')])
190
self.build_tree_contents([('branch/goodbye', 'baz')])
195
def test_basic_directory_export(self):
196
self.example_branch()
200
self.run_bzr('export ../latest')
201
self.assertEqual(['goodbye', 'hello'], sorted(os.listdir('../latest')))
202
self.check_file_contents('../latest/goodbye', 'baz')
203
self.run_bzr('export ../first -r 1')
204
self.assertEqual(['hello'], sorted(os.listdir('../first')))
205
self.check_file_contents('../first/hello', 'foo')
207
# Even with .gz and .bz2 it is still a directory
208
self.run_bzr('export ../first.gz -r 1')
209
self.check_file_contents('../first.gz/hello', 'foo')
210
self.run_bzr('export ../first.bz2 -r 1')
211
self.check_file_contents('../first.bz2/hello', 'foo')
213
def test_basic_tarfile_export(self):
214
self.example_branch()
217
self.run_bzr('export ../first.tar -r 1')
218
self.failUnless(os.path.isfile('../first.tar'))
219
tf = tarfile.open('../first.tar')
221
self.assertEqual(['first/hello'], sorted(tf.getnames()))
222
self.assertEqual('foo', tf.extractfile('first/hello').read())
226
self.run_bzr('export ../first.tar.gz -r 1')
227
self.failUnless(os.path.isfile('../first.tar.gz'))
228
self.run_bzr('export ../first.tbz2 -r 1')
229
self.failUnless(os.path.isfile('../first.tbz2'))
230
self.run_bzr('export ../first.tar.bz2 -r 1')
231
self.failUnless(os.path.isfile('../first.tar.bz2'))
232
self.run_bzr('export ../first.tar.tbz2 -r 1')
233
self.failUnless(os.path.isfile('../first.tar.tbz2'))
235
tf = tarfile.open('../first.tar.tbz2', 'r:bz2')
237
self.assertEqual(['first.tar/hello'], sorted(tf.getnames()))
238
self.assertEqual('foo', tf.extractfile('first.tar/hello').read())
241
self.run_bzr('export ../first2.tar -r 1 --root pizza')
242
tf = tarfile.open('../first2.tar')
244
self.assertEqual(['pizza/hello'], sorted(tf.getnames()))
245
self.assertEqual('foo', tf.extractfile('pizza/hello').read())
249
def test_basic_zipfile_export(self):
250
self.example_branch()
253
self.run_bzr('export ../first.zip -r 1')
254
self.failUnlessExists('../first.zip')
255
zf = zipfile.ZipFile('../first.zip')
257
self.assertEqual(['first/hello'], sorted(zf.namelist()))
258
self.assertEqual('foo', zf.read('first/hello'))
262
self.run_bzr('export ../first2.zip -r 1 --root pizza')
263
zf = zipfile.ZipFile('../first2.zip')
265
self.assertEqual(['pizza/hello'], sorted(zf.namelist()))
266
self.assertEqual('foo', zf.read('pizza/hello'))
270
self.run_bzr('export ../first-zip --format=zip -r 1')
271
zf = zipfile.ZipFile('../first-zip')
273
self.assertEqual(['first-zip/hello'], sorted(zf.namelist()))
274
self.assertEqual('foo', zf.read('first-zip/hello'))
278
def test_export_from_outside_branch(self):
279
self.example_branch()
281
# Use directory exports to test stating the branch location
282
self.run_bzr('export latest branch')
283
self.assertEqual(['goodbye', 'hello'], sorted(os.listdir('latest')))
284
self.check_file_contents('latest/goodbye', 'baz')
285
self.run_bzr('export first -r 1 branch')
286
self.assertEqual(['hello'], sorted(os.listdir('first')))
287
self.check_file_contents('first/hello', 'foo')
289
def test_export_partial_tree(self):
290
tree = self.example_branch()
291
self.build_tree(['branch/subdir/', 'branch/subdir/foo.txt'])
292
tree.smart_add(['branch'])
293
tree.commit('more setup')
294
out, err = self.run_bzr('export exported branch/subdir')
295
self.assertEqual(['foo.txt'], os.listdir('exported'))