~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: John Arbash Meinel
  • Date: 2011-05-11 11:35:28 UTC
  • mto: This revision was merged to the branch mainline in revision 5851.
  • Revision ID: john@arbash-meinel.com-20110511113528-qepibuwxicjrbb2h
Break compatibility with python <2.6.

This includes auditing the code for places where we were doing
explicit 'sys.version' checks and removing them as appropriate.

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):
 
101
        self.requireFeature(tests.UnicodeFilenameFeature)
69
102
        tree = self.make_branch_and_tree('tar')
70
103
        # FIXME: using fname = u'\xe5.txt' below triggers a bug revealed since
71
104
        # bzr.dev revno 4216 but more related to OSX/working trees/unicode than
72
105
        # export itself --vila 20090406
73
106
        fname = u'\N{Euro Sign}.txt'
74
 
        try:
75
 
            self.build_tree(['tar/' + fname])
76
 
        except UnicodeError:
77
 
            raise tests.TestSkipped('Unable to represent path %r' % (fname,))
 
107
        self.build_tree(['tar/' + fname])
78
108
        tree.add([fname])
79
109
        tree.commit('first')
80
110
 
81
 
        os.chdir('tar')
82
 
        self.run_bzr('export test.tar')
 
111
        self.run_bzr('export test.tar -d tar')
83
112
        ball = tarfile.open('test.tar')
84
113
        # all paths are prefixed with the base name of the tarball
85
114
        self.assertEqual(['test/' + fname.encode('utf8')],
87
116
 
88
117
    def test_tar_export_unicode_basedir(self):
89
118
        """Test for bug #413406"""
 
119
        self.requireFeature(tests.UnicodeFilenameFeature)
90
120
        basedir = u'\N{euro sign}'
91
121
        os.mkdir(basedir)
92
 
        os.chdir(basedir)
93
 
        self.run_bzr(['init', 'branch'])
94
 
        os.chdir('branch')
95
 
        self.run_bzr(['export', '--format', 'tgz', u'test.tar.gz'])
96
 
 
97
 
    def test_zip_export(self):
98
 
        tree = self.make_branch_and_tree('zip')
99
 
        self.build_tree(['zip/a'])
100
 
        tree.add('a')
101
 
        self.build_tree_contents([('zip/.bzrrules', '')])
102
 
        tree.add('.bzrrules')
103
 
        self.build_tree(['zip/.bzr-adir/', 'zip/.bzr-adir/afile'])
104
 
        tree.add(['.bzr-adir/', '.bzr-adir/afile'])
105
 
 
106
 
        os.chdir('zip')
107
 
        self.run_bzr('ignore something')
108
 
        tree.commit('1')
109
 
 
110
 
        self.failUnless(tree.has_filename('.bzrignore'))
111
 
        self.failUnless(tree.has_filename('.bzrrules'))
112
 
        self.failUnless(tree.has_filename('.bzr-adir'))
113
 
        self.failUnless(tree.has_filename('.bzr-adir/afile'))
114
 
        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')
115
134
 
116
135
        zfile = zipfile.ZipFile('test.zip')
117
136
        # Make sure the zipfile contains 'a', but does not contain
118
137
        # '.bzrignore'.
119
138
        self.assertEqual(['test/a'], sorted(zfile.namelist()))
120
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
 
121
196
    def test_zip_export_unicode(self):
 
197
        self.requireFeature(tests.UnicodeFilenameFeature)
122
198
        tree = self.make_branch_and_tree('zip')
123
199
        fname = u'\N{Euro Sign}.txt'
124
 
        try:
125
 
            self.build_tree(['zip/' + fname])
126
 
        except UnicodeError:
127
 
            raise tests.TestSkipped('Unable to represent path %r' % (fname,))
 
200
        self.build_tree(['zip/' + fname])
128
201
        tree.add([fname])
129
202
        tree.commit('first')
130
203
 
151
224
        self.assertEqual(['test/a', 'test/b/', 'test/b/c', 'test/d/'], names)
152
225
 
153
226
        file_attr = stat.S_IFREG | export.zip_exporter.FILE_PERMISSIONS
154
 
        dir_attr = stat.S_IFDIR | export.zip_exporter.ZIP_DIRECTORY_BIT
 
227
        dir_attr = (stat.S_IFDIR | export.zip_exporter.ZIP_DIRECTORY_BIT |
 
228
                    export.zip_exporter.DIR_PERMISSIONS)
155
229
 
156
230
        a_info = zfile.getinfo(names[0])
157
231
        self.assertEqual(file_attr, a_info.external_attr)
178
252
        self.run_bzr('ignore something')
179
253
        tree.commit('1')
180
254
 
181
 
        self.failUnless(tree.has_filename('.bzrignore'))
182
 
        self.failUnless(tree.has_filename('.bzrrules'))
183
 
        self.failUnless(tree.has_filename('.bzr-adir'))
184
 
        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'))
185
259
        self.run_bzr('export direxport')
186
260
 
187
261
        files = sorted(os.listdir('direxport'))
224
298
        os.chdir('branch')
225
299
 
226
300
        self.run_bzr('export ../first.tar -r 1')
227
 
        self.failUnless(os.path.isfile('../first.tar'))
 
301
        self.assertTrue(os.path.isfile('../first.tar'))
228
302
        tf = tarfile.open('../first.tar')
229
303
        try:
230
304
            self.assertEqual(['first/hello'], sorted(tf.getnames()))
233
307
            tf.close()
234
308
 
235
309
        self.run_bzr('export ../first.tar.gz -r 1')
236
 
        self.failUnless(os.path.isfile('../first.tar.gz'))
 
310
        self.assertTrue(os.path.isfile('../first.tar.gz'))
237
311
        self.run_bzr('export ../first.tbz2 -r 1')
238
 
        self.failUnless(os.path.isfile('../first.tbz2'))
 
312
        self.assertTrue(os.path.isfile('../first.tbz2'))
239
313
        self.run_bzr('export ../first.tar.bz2 -r 1')
240
 
        self.failUnless(os.path.isfile('../first.tar.bz2'))
 
314
        self.assertTrue(os.path.isfile('../first.tar.bz2'))
241
315
        self.run_bzr('export ../first.tar.tbz2 -r 1')
242
 
        self.failUnless(os.path.isfile('../first.tar.tbz2'))
 
316
        self.assertTrue(os.path.isfile('../first.tar.tbz2'))
243
317
 
244
318
        tf = tarfile.open('../first.tar.tbz2', 'r:bz2')
245
319
        try:
260
334
        os.chdir('branch')
261
335
 
262
336
        self.run_bzr('export ../first.zip -r 1')
263
 
        self.failUnlessExists('../first.zip')
 
337
        self.assertPathExists('../first.zip')
264
338
        zf = zipfile.ZipFile('../first.zip')
265
339
        try:
266
340
            self.assertEqual(['first/hello'], sorted(zf.namelist()))
319
393
        self.run_bzr(['export', '--directory=branch', 'latest'])
320
394
        self.assertEqual(['goodbye', 'hello'], sorted(os.listdir('latest')))
321
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)