~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_export.py

  • Committer: Jelmer Vernooij
  • Date: 2011-05-10 07:46:15 UTC
  • mfrom: (5844 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5845.
  • Revision ID: jelmer@samba.org-20110510074615-eptod049ndjxc4i7
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
23
23
import stat
24
24
import sys
25
25
import tarfile
 
26
import time
26
27
import zipfile
27
28
 
28
29
 
29
30
from bzrlib import (
30
31
    export,
 
32
    osutils,
31
33
    tests,
32
34
    )
33
35
from bzrlib.tests import TestCaseWithTransport
35
37
 
36
38
class TestExport(TestCaseWithTransport):
37
39
 
38
 
    def test_tar_export(self):
39
 
        tree = self.make_branch_and_tree('tar')
40
 
        self.build_tree(['tar/a'])
 
40
    # On Windows, if we fail to set the binary bit, and a '\r' or '\n'
 
41
    # ends up in the data stream, we will get corruption. Add a fair amount
 
42
    # of random data, to help ensure there is at least one.
 
43
    _file_content = ('!\r\n\t\n \r'
 
44
        + 'r29trp9i1r8k0e24c2o7mcx2isrlaw7toh1hv2mtst3o1udkl36v9xn2z8kt\n'
 
45
          'tvjn7e3i9cj1qs1rw9gcye9w72cbdueiufw8nky7bs08lwggir59d62knecp\n'
 
46
          '7s0537r8sg3e8hdnidji49rswo47c3j8190nh8emef2b6j1mf5kdq45nt3f5\n'
 
47
          '1sz9u7fuzrm4w8bebre7p62sh5os2nkj2iiyuk9n0w0pjpdulu9k2aajejah\n'
 
48
          'ini90ny40qzs12ajuy0ua6l178n93lvy2atqngnntsmtlmqx7yhp0q9a1xr4\n'
 
49
          '1n69kgbo6qu9osjpqq83446r00jijtcstzybfqwm1lnt9spnri2j07bt7bbh\n'
 
50
          'rf3ejatdxta83te2s0pt9rc4hidgy3d2pc53p4wscdt2b1dfxdj9utf5m17f\n'
 
51
          'f03oofcau950o090vyx6m72vfkywo7gp3ajzi6uk02dwqwtumq4r44xx6ho7\n'
 
52
          'nhynborjdjep5j53f9548msb7gd3x9a1xveb4s8zfo6cbdw2kdngcrbakwu8\n'
 
53
          'ql5a8l94gplkwr7oypw5nt1gj5i3xwadyjfr3lb61tfkz31ba7uda9knb294\n'
 
54
          '1azhfta0q3ry9x36lxyanvhp0g5z0t5a0i4wnoc8p4htexi915y1cnw4nznn\n'
 
55
          'aj70dvp88ifiblv2bsp98hz570teinj8g472ddxni9ydmazfzwtznbf3hrg6\n'
 
56
          '84gigirjt6n2yagf70036m8d73cz0jpcighpjtxsmbgzbxx7nb4ewq6jbgnc\n'
 
57
          'hux1b0qtsdi0zfhj6g1otf5jcldmtdvuon8y1ttszkqw3ograwi25yl921hy\n'
 
58
          'izgscmfha9xdhxxabs07b40secpw22ah9iwpbmsns6qz0yr6fswto3ft2ez5\n'
 
59
          'ngn48pdfxj1pw246drmj1y2ll5af5w7cz849rapzd9ih7qvalw358co0yzrs\n'
 
60
          'xan9291d1ivjku4o5gjrsnmllrqwxwy86pcivinbmlnzasa9v3o22lgv4uyd\n'
 
61
          'q8kw77bge3hr5rr5kzwjxk223bkmo3z9oju0954undsz8axr3kb3730otrcr\n'
 
62
          '9cwhu37htnizdwxmpoc5qmobycfm7ubbykfumv6zgkl6b8zlslwl7a8b81vz\n'
 
63
          '3weqkvv5csfza9xvwypr6lo0t03fwp0ihmci3m1muh0lf2u30ze0hjag691j\n'
 
64
          '27fjtd3e3zbiin5n2hq21iuo09ukbs73r5rt7vaw6axvoilvdciir9ugjh2c\n'
 
65
          'na2b8dr0ptftoyhyxv1iwg661y338e28fhz4xxwgv3hnoe98ydfa1oou45vj\n'
 
66
          'ln74oac2keqt0agbylrqhfscin7ireae2bql7z2le823ksy47ud57z8ctomp\n'
 
67
          '31s1vwbczdjwqp0o2jc7mkrurvzg8mj2zwcn2iily4gcl4sy4fsh4rignlyz\n')
 
68
 
 
69
    def make_basic_tree(self):
 
70
        tree = self.make_branch_and_tree('tree')
 
71
        self.build_tree_contents([('tree/a', self._file_content)])
41
72
        tree.add('a')
42
 
        self.build_tree_contents([('tar/.bzrrules', '')])
43
 
        tree.add('.bzrrules')
44
 
        self.build_tree(['tar/.bzr-adir/', 'tar/.bzr-adir/afile'])
45
 
        tree.add(['.bzr-adir/', '.bzr-adir/afile'])
46
 
 
47
 
        os.chdir('tar')
48
 
        self.run_bzr('ignore something')
49
73
        tree.commit('1')
50
 
 
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')
 
74
        return tree
 
75
 
 
76
    def make_tree_with_extra_bzr_files(self):
 
77
        tree = self.make_basic_tree()
 
78
        self.build_tree_contents([('tree/.bzrrules', '')])
 
79
        self.build_tree(['tree/.bzr-adir/', 'tree/.bzr-adir/afile'])
 
80
        tree.add(['.bzrrules', '.bzr-adir/', '.bzr-adir/afile'])
 
81
 
 
82
        self.run_bzr('ignore something -d tree')
 
83
        tree.commit('2')
 
84
        return tree
 
85
 
 
86
    def test_tar_export_ignores_bzr(self):
 
87
        tree = self.make_tree_with_extra_bzr_files()
 
88
 
 
89
        self.assertTrue(tree.has_filename('.bzrignore'))
 
90
        self.assertTrue(tree.has_filename('.bzrrules'))
 
91
        self.assertTrue(tree.has_filename('.bzr-adir'))
 
92
        self.assertTrue(tree.has_filename('.bzr-adir/afile'))
 
93
        self.run_bzr('export test.tar.gz -d tree')
56
94
        ball = tarfile.open('test.tar.gz')
57
95
        # Make sure the tarball contains 'a', but does not contain
58
96
        # '.bzrignore'.
59
 
        self.assertEqual(['test/a'], sorted(ball.getnames()))
60
 
 
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()))
67
 
 
68
 
    def test_tar_export_unicode(self):
 
97
        self.assertEqual(['test/a'],
 
98
                         sorted(ball.getnames()))
 
99
 
 
100
    def test_tar_export_unicode_filename(self):
69
101
        self.requireFeature(tests.UnicodeFilenameFeature)
70
102
        tree = self.make_branch_and_tree('tar')
71
103
        # FIXME: using fname = u'\xe5.txt' below triggers a bug revealed since
76
108
        tree.add([fname])
77
109
        tree.commit('first')
78
110
 
79
 
        os.chdir('tar')
80
 
        self.run_bzr('export test.tar')
 
111
        self.run_bzr('export test.tar -d tar')
81
112
        ball = tarfile.open('test.tar')
82
113
        # all paths are prefixed with the base name of the tarball
83
114
        self.assertEqual(['test/' + fname.encode('utf8')],
88
119
        self.requireFeature(tests.UnicodeFilenameFeature)
89
120
        basedir = u'\N{euro sign}'
90
121
        os.mkdir(basedir)
91
 
        os.chdir(basedir)
92
 
        self.run_bzr(['init', 'branch'])
93
 
        os.chdir('branch')
94
 
        self.run_bzr(['export', '--format', 'tgz', u'test.tar.gz'])
95
 
 
96
 
    def test_zip_export(self):
97
 
        tree = self.make_branch_and_tree('zip')
98
 
        self.build_tree(['zip/a'])
99
 
        tree.add('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'])
104
 
 
105
 
        os.chdir('zip')
106
 
        self.run_bzr('ignore something')
107
 
        tree.commit('1')
108
 
 
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')
 
122
        self.run_bzr(['init', basedir])
 
123
        self.run_bzr(['export', '--format', 'tgz', u'test.tar.gz',
 
124
                      '-d', basedir])
 
125
 
 
126
    def test_zip_export_ignores_bzr(self):
 
127
        tree = self.make_tree_with_extra_bzr_files()
 
128
 
 
129
        self.assertTrue(tree.has_filename('.bzrignore'))
 
130
        self.assertTrue(tree.has_filename('.bzrrules'))
 
131
        self.assertTrue(tree.has_filename('.bzr-adir'))
 
132
        self.assertTrue(tree.has_filename('.bzr-adir/afile'))
 
133
        self.run_bzr('export test.zip -d tree')
114
134
 
115
135
        zfile = zipfile.ZipFile('test.zip')
116
136
        # Make sure the zipfile contains 'a', but does not contain
117
137
        # '.bzrignore'.
118
138
        self.assertEqual(['test/a'], sorted(zfile.namelist()))
119
139
 
 
140
    # TODO: This really looks like something that should be using permutation
 
141
    #       testing. Though the actual setup and teardown functions are pretty
 
142
    #       different for each
 
143
    def assertZipANameAndContent(self, zfile, root=''):
 
144
        """The file should only contain name 'a' and _file_content"""
 
145
        fname = root + 'a'
 
146
        self.assertEqual([fname], sorted(zfile.namelist()))
 
147
        zfile.testzip()
 
148
        self.assertEqualDiff(self._file_content, zfile.read(fname))
 
149
 
 
150
    def test_zip_export_stdout(self):
 
151
        tree = self.make_basic_tree()
 
152
        contents = self.run_bzr('export -d tree --format=zip -')[0]
 
153
        self.assertZipANameAndContent(zipfile.ZipFile(StringIO(contents)))
 
154
 
 
155
    def test_zip_export_file(self):
 
156
        tree = self.make_basic_tree()
 
157
        self.run_bzr('export -d tree test.zip')
 
158
        self.assertZipANameAndContent(zipfile.ZipFile('test.zip'),
 
159
                                      root='test/')
 
160
 
 
161
    def assertTarANameAndContent(self, ball, root=''):
 
162
        fname = root + 'a'
 
163
        tar_info = ball.next()
 
164
        self.assertEqual(fname, tar_info.name)
 
165
        self.assertEqual(tarfile.REGTYPE, tar_info.type)
 
166
        self.assertEqual(len(self._file_content), tar_info.size)
 
167
        f = ball.extractfile(tar_info)
 
168
        if self._file_content != f.read():
 
169
            self.fail('File content has been corrupted.'
 
170
                      ' Check that all streams are handled in binary mode.')
 
171
        # There should be no other files in the tarball
 
172
        self.assertIs(None, ball.next())
 
173
 
 
174
    def run_tar_export_disk_and_stdout(self, extension, tarfile_flags):
 
175
        tree = self.make_basic_tree()
 
176
        fname = 'test.%s' % (extension,)
 
177
        mode = 'r|%s' % (tarfile_flags,)
 
178
        self.run_bzr('export -d tree %s' % (fname,))
 
179
        ball = tarfile.open(fname, mode=mode)
 
180
        self.assertTarANameAndContent(ball, root='test/')
 
181
        content = self.run_bzr('export -d tree --format=%s -' % (extension,))[0]
 
182
        ball = tarfile.open(mode=mode, fileobj=StringIO(content))
 
183
        self.assertTarANameAndContent(ball, root='')
 
184
 
 
185
    def test_tar_export(self):
 
186
        self.run_tar_export_disk_and_stdout('tar', '')
 
187
 
 
188
    def test_tgz_export(self):
 
189
        self.run_tar_export_disk_and_stdout('tgz', 'gz')
 
190
 
 
191
    def test_tbz2_export(self):
 
192
        self.run_tar_export_disk_and_stdout('tbz2', 'bz2')
 
193
 
 
194
    # TODO: test_xz_export, I don't have pylzma working here to test it.
 
195
 
120
196
    def test_zip_export_unicode(self):
121
197
        self.requireFeature(tests.UnicodeFilenameFeature)
122
198
        tree = self.make_branch_and_tree('zip')
176
252
        self.run_bzr('ignore something')
177
253
        tree.commit('1')
178
254
 
179
 
        self.failUnless(tree.has_filename('.bzrignore'))
180
 
        self.failUnless(tree.has_filename('.bzrrules'))
181
 
        self.failUnless(tree.has_filename('.bzr-adir'))
182
 
        self.failUnless(tree.has_filename('.bzr-adir/afile'))
 
255
        self.assertTrue(tree.has_filename('.bzrignore'))
 
256
        self.assertTrue(tree.has_filename('.bzrrules'))
 
257
        self.assertTrue(tree.has_filename('.bzr-adir'))
 
258
        self.assertTrue(tree.has_filename('.bzr-adir/afile'))
183
259
        self.run_bzr('export direxport')
184
260
 
185
261
        files = sorted(os.listdir('direxport'))
222
298
        os.chdir('branch')
223
299
 
224
300
        self.run_bzr('export ../first.tar -r 1')
225
 
        self.failUnless(os.path.isfile('../first.tar'))
 
301
        self.assertTrue(os.path.isfile('../first.tar'))
226
302
        tf = tarfile.open('../first.tar')
227
303
        try:
228
304
            self.assertEqual(['first/hello'], sorted(tf.getnames()))
231
307
            tf.close()
232
308
 
233
309
        self.run_bzr('export ../first.tar.gz -r 1')
234
 
        self.failUnless(os.path.isfile('../first.tar.gz'))
 
310
        self.assertTrue(os.path.isfile('../first.tar.gz'))
235
311
        self.run_bzr('export ../first.tbz2 -r 1')
236
 
        self.failUnless(os.path.isfile('../first.tbz2'))
 
312
        self.assertTrue(os.path.isfile('../first.tbz2'))
237
313
        self.run_bzr('export ../first.tar.bz2 -r 1')
238
 
        self.failUnless(os.path.isfile('../first.tar.bz2'))
 
314
        self.assertTrue(os.path.isfile('../first.tar.bz2'))
239
315
        self.run_bzr('export ../first.tar.tbz2 -r 1')
240
 
        self.failUnless(os.path.isfile('../first.tar.tbz2'))
 
316
        self.assertTrue(os.path.isfile('../first.tar.tbz2'))
241
317
 
242
318
        tf = tarfile.open('../first.tar.tbz2', 'r:bz2')
243
319
        try:
258
334
        os.chdir('branch')
259
335
 
260
336
        self.run_bzr('export ../first.zip -r 1')
261
 
        self.failUnlessExists('../first.zip')
 
337
        self.assertPathExists('../first.zip')
262
338
        zf = zipfile.ZipFile('../first.zip')
263
339
        try:
264
340
            self.assertEqual(['first/hello'], sorted(zf.namelist()))
317
393
        self.run_bzr(['export', '--directory=branch', 'latest'])
318
394
        self.assertEqual(['goodbye', 'hello'], sorted(os.listdir('latest')))
319
395
        self.check_file_contents('latest/goodbye', 'baz')
 
396
 
 
397
    def test_zip_export_per_file_timestamps(self):
 
398
        tree = self.example_branch()
 
399
        self.build_tree_contents([('branch/har', 'foo')])
 
400
        tree.add('har')
 
401
        # Earliest allowable date on FAT32 filesystems is 1980-01-01
 
402
        timestamp = 347151600
 
403
        tree.commit('setup', timestamp=timestamp)
 
404
        self.run_bzr('export --per-file-timestamps test.zip branch')
 
405
        zfile = zipfile.ZipFile('test.zip')
 
406
        info = zfile.getinfo("test/har")
 
407
        self.assertEquals(time.localtime(timestamp)[:6], info.date_time)