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 import TestCaseWithTransport
36
class TestExport(TestCaseWithTransport):
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
self.requireFeature(tests.UnicodeFilenameFeature)
70
tree = self.make_branch_and_tree('tar')
71
# FIXME: using fname = u'\xe5.txt' below triggers a bug revealed since
72
# bzr.dev revno 4216 but more related to OSX/working trees/unicode than
73
# export itself --vila 20090406
74
fname = u'\N{Euro Sign}.txt'
75
self.build_tree(['tar/' + fname])
80
self.run_bzr('export test.tar')
81
ball = tarfile.open('test.tar')
82
# all paths are prefixed with the base name of the tarball
83
self.assertEqual(['test/' + fname.encode('utf8')],
84
sorted(ball.getnames()))
86
def test_tar_export_unicode_basedir(self):
87
"""Test for bug #413406"""
88
self.requireFeature(tests.UnicodeFilenameFeature)
89
basedir = u'\N{euro sign}'
92
self.run_bzr(['init', 'branch'])
94
self.run_bzr(['export', '--format', 'tgz', u'test.tar.gz'])
96
def test_zip_export(self):
97
tree = self.make_branch_and_tree('zip')
98
self.build_tree(['zip/a'])
100
self.build_tree_contents([('zip/.bzrrules', '')])
101
tree.add('.bzrrules')
102
self.build_tree(['zip/.bzr-adir/', 'zip/.bzr-adir/afile'])
103
tree.add(['.bzr-adir/', '.bzr-adir/afile'])
106
self.run_bzr('ignore something')
109
self.failUnless(tree.has_filename('.bzrignore'))
110
self.failUnless(tree.has_filename('.bzrrules'))
111
self.failUnless(tree.has_filename('.bzr-adir'))
112
self.failUnless(tree.has_filename('.bzr-adir/afile'))
113
self.run_bzr('export test.zip')
115
zfile = zipfile.ZipFile('test.zip')
116
# Make sure the zipfile contains 'a', but does not contain
118
self.assertEqual(['test/a'], sorted(zfile.namelist()))
120
def test_zip_export_unicode(self):
121
self.requireFeature(tests.UnicodeFilenameFeature)
122
tree = self.make_branch_and_tree('zip')
123
fname = u'\N{Euro Sign}.txt'
124
self.build_tree(['zip/' + fname])
129
self.run_bzr('export test.zip')
130
zfile = zipfile.ZipFile('test.zip')
131
# all paths are prefixed with the base name of the zipfile
132
self.assertEqual(['test/' + fname.encode('utf8')],
133
sorted(zfile.namelist()))
135
def test_zip_export_directories(self):
136
tree = self.make_branch_and_tree('zip')
137
self.build_tree(['zip/a', 'zip/b/', 'zip/b/c', 'zip/d/'])
138
tree.add(['a', 'b', 'b/c', 'd'])
142
self.run_bzr('export test.zip')
143
zfile = zipfile.ZipFile('test.zip')
144
names = sorted(zfile.namelist())
146
# even on win32, zipfile.ZipFile changes all names to use
148
self.assertEqual(['test/a', 'test/b/', 'test/b/c', 'test/d/'], names)
150
file_attr = stat.S_IFREG | export.zip_exporter.FILE_PERMISSIONS
151
dir_attr = stat.S_IFDIR | export.zip_exporter.ZIP_DIRECTORY_BIT
153
a_info = zfile.getinfo(names[0])
154
self.assertEqual(file_attr, a_info.external_attr)
156
b_info = zfile.getinfo(names[1])
157
self.assertEqual(dir_attr, b_info.external_attr)
159
c_info = zfile.getinfo(names[2])
160
self.assertEqual(file_attr, c_info.external_attr)
162
d_info = zfile.getinfo(names[3])
163
self.assertEqual(dir_attr, d_info.external_attr)
165
def test_dir_export(self):
166
tree = self.make_branch_and_tree('dir')
167
self.build_tree(['dir/a'])
169
self.build_tree_contents([('dir/.bzrrules', '')])
170
tree.add('.bzrrules')
171
self.build_tree(['dir/.bzr-adir/', 'dir/.bzr-adir/afile'])
172
tree.add(['.bzr-adir/', '.bzr-adir/afile'])
175
self.run_bzr('ignore something')
178
self.failUnless(tree.has_filename('.bzrignore'))
179
self.failUnless(tree.has_filename('.bzrrules'))
180
self.failUnless(tree.has_filename('.bzr-adir'))
181
self.failUnless(tree.has_filename('.bzr-adir/afile'))
182
self.run_bzr('export direxport')
184
files = sorted(os.listdir('direxport'))
185
# Make sure the exported directory contains 'a', but does not contain
187
self.assertEqual(['a'], files)
189
def example_branch(self):
190
"""Create a branch a 'branch' containing hello and goodbye."""
191
tree = self.make_branch_and_tree('branch')
192
self.build_tree_contents([('branch/hello', 'foo')])
196
self.build_tree_contents([('branch/goodbye', 'baz')])
201
def test_basic_directory_export(self):
202
self.example_branch()
206
self.run_bzr('export ../latest')
207
self.assertEqual(['goodbye', 'hello'], sorted(os.listdir('../latest')))
208
self.check_file_contents('../latest/goodbye', 'baz')
209
self.run_bzr('export ../first -r 1')
210
self.assertEqual(['hello'], sorted(os.listdir('../first')))
211
self.check_file_contents('../first/hello', 'foo')
213
# Even with .gz and .bz2 it is still a directory
214
self.run_bzr('export ../first.gz -r 1')
215
self.check_file_contents('../first.gz/hello', 'foo')
216
self.run_bzr('export ../first.bz2 -r 1')
217
self.check_file_contents('../first.bz2/hello', 'foo')
219
def test_basic_tarfile_export(self):
220
self.example_branch()
223
self.run_bzr('export ../first.tar -r 1')
224
self.failUnless(os.path.isfile('../first.tar'))
225
tf = tarfile.open('../first.tar')
227
self.assertEqual(['first/hello'], sorted(tf.getnames()))
228
self.assertEqual('foo', tf.extractfile('first/hello').read())
232
self.run_bzr('export ../first.tar.gz -r 1')
233
self.failUnless(os.path.isfile('../first.tar.gz'))
234
self.run_bzr('export ../first.tbz2 -r 1')
235
self.failUnless(os.path.isfile('../first.tbz2'))
236
self.run_bzr('export ../first.tar.bz2 -r 1')
237
self.failUnless(os.path.isfile('../first.tar.bz2'))
238
self.run_bzr('export ../first.tar.tbz2 -r 1')
239
self.failUnless(os.path.isfile('../first.tar.tbz2'))
241
tf = tarfile.open('../first.tar.tbz2', 'r:bz2')
243
self.assertEqual(['first.tar/hello'], sorted(tf.getnames()))
244
self.assertEqual('foo', tf.extractfile('first.tar/hello').read())
247
self.run_bzr('export ../first2.tar -r 1 --root pizza')
248
tf = tarfile.open('../first2.tar')
250
self.assertEqual(['pizza/hello'], sorted(tf.getnames()))
251
self.assertEqual('foo', tf.extractfile('pizza/hello').read())
255
def test_basic_zipfile_export(self):
256
self.example_branch()
259
self.run_bzr('export ../first.zip -r 1')
260
self.failUnlessExists('../first.zip')
261
zf = zipfile.ZipFile('../first.zip')
263
self.assertEqual(['first/hello'], sorted(zf.namelist()))
264
self.assertEqual('foo', zf.read('first/hello'))
268
self.run_bzr('export ../first2.zip -r 1 --root pizza')
269
zf = zipfile.ZipFile('../first2.zip')
271
self.assertEqual(['pizza/hello'], sorted(zf.namelist()))
272
self.assertEqual('foo', zf.read('pizza/hello'))
276
self.run_bzr('export ../first-zip --format=zip -r 1')
277
zf = zipfile.ZipFile('../first-zip')
279
self.assertEqual(['first-zip/hello'], sorted(zf.namelist()))
280
self.assertEqual('foo', zf.read('first-zip/hello'))
284
def test_export_from_outside_branch(self):
285
self.example_branch()
287
# Use directory exports to test stating the branch location
288
self.run_bzr('export latest branch')
289
self.assertEqual(['goodbye', 'hello'], sorted(os.listdir('latest')))
290
self.check_file_contents('latest/goodbye', 'baz')
291
self.run_bzr('export first -r 1 branch')
292
self.assertEqual(['hello'], sorted(os.listdir('first')))
293
self.check_file_contents('first/hello', 'foo')
295
def test_export_partial_tree(self):
296
tree = self.example_branch()
297
self.build_tree(['branch/subdir/', 'branch/subdir/foo.txt'])
298
tree.smart_add(['branch'])
299
tree.commit('more setup')
300
out, err = self.run_bzr('export exported branch/subdir')
301
self.assertEqual(['foo.txt'], os.listdir('exported'))
303
def test_dir_export_per_file_timestamps(self):
304
tree = self.example_branch()
305
self.build_tree_contents([('branch/har', 'foo')])
307
# Earliest allowable date on FAT32 filesystems is 1980-01-01
308
tree.commit('setup', timestamp=315532800)
309
self.run_bzr('export --per-file-timestamps t branch')
310
har_st = os.stat('t/har')
311
self.assertEquals(315532800, har_st.st_mtime)
313
def test_export_directory(self):
314
"""Test --directory option"""
315
self.example_branch()
316
self.run_bzr(['export', '--directory=branch', 'latest'])
317
self.assertEqual(['goodbye', 'hello'], sorted(os.listdir('latest')))
318
self.check_file_contents('latest/goodbye', 'baz')