/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6637.1.2 by Jelmer Vernooij
Add tests.
1
# Copyright (C) 2006-2012 Aaron Bentley
2
#
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.
7
#
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.
12
#
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
16
17
import os
6791.2.3 by Jelmer Vernooij
Fix more imports.
18
from ..sixish import StringIO
6637.1.2 by Jelmer Vernooij
Add tests.
19
from shutil import rmtree, copy2, copytree
20
import tarfile
21
import tempfile
6637.1.5 by Jelmer Vernooij
Ignore warning.
22
import warnings
6637.1.2 by Jelmer Vernooij
Add tests.
23
24
from .. import (
25
    osutils,
26
    revision as _mod_revision,
27
    transform
28
    )
6670.4.1 by Jelmer Vernooij
Update imports.
29
from ..bzr.bzrdir import BzrDir
6637.1.2 by Jelmer Vernooij
Add tests.
30
from ..export import export
31
from ..upstream_import import (
32
    common_directory,
33
    get_archive_type,
34
    import_archive,
35
    import_tar,
36
    import_zip,
37
    import_dir,
38
    NotArchiveType,
39
    top_path,
40
    ZipFileWrapper,
41
)
42
from . import (
43
    TestCaseInTempDir,
44
    TestCaseWithTransport,
45
    )
46
from .features import UnicodeFilenameFeature
47
48
49
def import_tar_broken(tree, tar_input):
50
    """
51
    Import a tarfile with names that that end in //, e.g. Feisty Python 2.5
52
    """
53
    tar_file = tarfile.open('lala', 'r', tar_input)
54
    for member in tar_file.members:
55
        if member.name.endswith('/'):
56
            member.name += '/'
57
    import_archive(tree, tar_file)
58
59
60
class DirFileWriter(object):
61
62
    def __init__(self, fileobj, mode):
63
        # We may be asked to 'append'.  If so, fileobj already has a path.
64
        # So we copy the existing tree, and overwrite afterward.
65
        fileobj.seek(0)
66
        existing = fileobj.read()
67
        fileobj.seek(0)
68
        path = tempfile.mkdtemp(dir=os.getcwd())
69
        if existing != '':
70
            # copytree requires the directory not to exist
71
            os.rmdir(path)
72
            copytree(existing, path)
73
        fileobj.write(path)
74
        self.root = path
75
76
    def add(self, path):
77
        target_path = os.path.join(self.root, path)
78
        parent = osutils.dirname(target_path)
79
        if not os.path.exists(parent):
80
            os.makedirs(parent)
81
        kind = osutils.file_kind(path)
82
        if kind == 'file':
83
            copy2(path, target_path)
84
        if kind == 'directory':
85
            os.mkdir(target_path)
86
87
    def close(self):
88
        pass
89
90
91
class TestImport(TestCaseInTempDir):
92
93
    def make_tar(self, mode='w'):
94
        def maker(fileobj):
95
            return tarfile.open('project-0.1.tar', mode, fileobj)
96
        return self.make_archive(maker)
97
98
    def make_archive(self, maker, subdir=True):
99
        result = StringIO()
100
        archive_file = maker(result)
101
        try:
102
            os.mkdir('project-0.1')
103
            if subdir:
104
                prefix='project-0.1/'
105
                archive_file.add('project-0.1')
106
            else:
107
                prefix=''
108
                os.chdir('project-0.1')
109
            os.mkdir(prefix + 'junk')
110
            archive_file.add(prefix + 'junk')
111
112
            f = file(prefix + 'README', 'wb')
113
            f.write('What?')
114
            f.close()
115
            archive_file.add(prefix + 'README')
116
117
            f = file(prefix + 'FEEDME', 'wb')
118
            f.write('Hungry!!')
119
            f.close()
120
            archive_file.add(prefix + 'FEEDME')
121
122
            archive_file.close()
123
        finally:
124
            if not subdir:
125
                os.chdir('..')
126
            rmtree('project-0.1')
127
        result.seek(0)
128
        return result
129
130
    def make_archive2(self, builder, subdir):
131
        result = StringIO()
132
        archive_file = builder(result)
133
        os.mkdir('project-0.2')
134
        try:
135
            if subdir:
136
                prefix='project-0.2/'
137
                archive_file.add('project-0.2')
138
            else:
139
                prefix=''
140
                os.chdir('project-0.2')
141
142
            os.mkdir(prefix + 'junk')
143
            archive_file.add(prefix + 'junk')
144
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
145
            with file(prefix + 'README', 'wb') as f:
146
                f.write('Now?')
6637.1.2 by Jelmer Vernooij
Add tests.
147
            archive_file.add(prefix + 'README')
148
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
149
            with file(prefix + 'README', 'wb') as f:
150
                f.write('Wow?')
6637.1.2 by Jelmer Vernooij
Add tests.
151
            # Add a second entry for README with different contents.
152
            archive_file.add(prefix + 'README')
153
            archive_file.close()
154
155
        finally:
156
            if not subdir:
157
                os.chdir('..')
158
        result.seek(0)
159
        return result
160
161
    def make_messed_tar(self):
162
        result = StringIO()
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
163
        with tarfile.open('project-0.1.tar', 'w', result) as tar_file:
164
            os.mkdir('project-0.1')
165
            tar_file.add('project-0.1')
166
167
            os.mkdir('project-0.2')
168
            tar_file.add('project-0.2')
169
170
            with file('project-0.1/README', 'wb') as f:
171
                f.write('What?')
172
            tar_file.add('project-0.1/README')
6637.1.2 by Jelmer Vernooij
Add tests.
173
        rmtree('project-0.1')
174
        result.seek(0)
175
        return result
176
177
    def make_zip(self):
178
        def maker(fileobj):
179
            return ZipFileWrapper(fileobj, 'w')
180
        return self.make_archive(maker)
181
182
    def make_tar_with_bzrdir(self):
183
        result = StringIO()
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
184
        with tarfile.open('tar-with-bzrdir.tar', 'w', result) as tar_file:
185
            os.mkdir('toplevel-dir')
186
            tar_file.add('toplevel-dir')
187
            os.mkdir('toplevel-dir/.bzr')
188
            tar_file.add('toplevel-dir/.bzr')
6637.1.2 by Jelmer Vernooij
Add tests.
189
        rmtree('toplevel-dir')
190
        result.seek(0)
191
        return result
192
193
    def test_top_path(self):
194
        self.assertEqual(top_path('ab/b/c'), 'ab')
195
        self.assertEqual(top_path('etc'), 'etc')
196
        self.assertEqual(top_path('project-0.1'), 'project-0.1')
197
198
    def test_common_directory(self):
199
        self.assertEqual(common_directory(['ab/c/d', 'ab/c/e']), 'ab')
200
        self.assertIs(common_directory(['ab/c/d', 'ac/c/e']), None)
201
        self.assertEqual('FEEDME', common_directory(['FEEDME']))
202
203
    def test_untar(self):
204
        def builder(fileobj, mode='w'):
205
            return tarfile.open('project-0.1.tar', mode, fileobj)
206
        self.archive_test(builder, import_tar)
207
208
    def test_broken_tar(self):
209
        def builder(fileobj, mode='w'):
210
            return tarfile.open('project-0.1.tar', mode, fileobj)
211
        self.archive_test(builder, import_tar_broken, subdir=True)
212
213
    def test_unzip(self):
214
        def builder(fileobj, mode='w'):
215
            return ZipFileWrapper(fileobj, mode)
216
        self.archive_test(builder, import_zip)
217
218
    def test_copydir_nosub(self):
219
        def builder(fileobj, mode='w'):
220
            return DirFileWriter(fileobj, mode)
221
        # It would be bogus to test with the result in a subdirectory,
222
        # because for directories, the input root is always the output root.
223
        self.archive_test(builder, import_dir)
224
225
    def archive_test(self, builder, importer, subdir=False):
226
        archive_file = self.make_archive(builder, subdir)
227
        tree = BzrDir.create_standalone_workingtree('tree')
228
        tree.lock_write()
229
        try:
230
            importer(tree, archive_file)
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
231
            self.assertTrue(tree.is_versioned('README'))
232
            self.assertTrue(tree.is_versioned('FEEDME'))
6637.1.2 by Jelmer Vernooij
Add tests.
233
            self.assertTrue(os.path.isfile(tree.abspath('README')))
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
234
            self.assertEqual(tree.stored_kind('README'), 'file')
235
            self.assertEqual(tree.stored_kind('FEEDME'), 'file')
6855.4.5 by Jelmer Vernooij
Fix more bees, use with rather than try/finally for some files.
236
            with file(tree.abspath('junk/food'), 'wb') as f:
237
                f.write('I like food\n')
6637.1.2 by Jelmer Vernooij
Add tests.
238
6637.1.5 by Jelmer Vernooij
Ignore warning.
239
            with warnings.catch_warnings():
240
                warnings.simplefilter('ignore')
241
                archive_file = self.make_archive2(builder, subdir)
242
                importer(tree, archive_file)
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
243
            self.assertTrue(tree.is_versioned('README'))
6637.1.2 by Jelmer Vernooij
Add tests.
244
            # Ensure the second version of the file is used.
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
245
            self.assertEqual(tree.get_file_text('README'), 'Wow?')
6637.1.2 by Jelmer Vernooij
Add tests.
246
            self.assertTrue(not os.path.exists(tree.abspath('FEEDME')))
247
        finally:
248
            tree.unlock()
249
250
251
    def test_untar2(self):
252
        tar_file = self.make_messed_tar()
253
        tree = BzrDir.create_standalone_workingtree('tree')
254
        import_tar(tree, tar_file)
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
255
        self.assertTrue(tree.is_versioned('project-0.1/README'))
6637.1.2 by Jelmer Vernooij
Add tests.
256
257
    def test_untar_gzip(self):
258
        tar_file = self.make_tar(mode='w:gz')
259
        tree = BzrDir.create_standalone_workingtree('tree')
260
        import_tar(tree, tar_file)
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
261
        self.assertTrue(tree.is_versioned('README'))
6637.1.2 by Jelmer Vernooij
Add tests.
262
263
    def test_no_crash_with_bzrdir(self):
264
        tar_file = self.make_tar_with_bzrdir()
265
        tree = BzrDir.create_standalone_workingtree('tree')
266
        import_tar(tree, tar_file)
267
        # So long as it did not crash, that should be ok
268
269
    def test_get_archive_type(self):
270
        self.assertEqual(('tar', None), get_archive_type('foo.tar'))
271
        self.assertEqual(('zip', None), get_archive_type('foo.zip'))
272
        self.assertRaises(NotArchiveType, get_archive_type, 'foo.gif')
273
        self.assertEqual(('tar', 'gz'), get_archive_type('foo.tar.gz'))
274
        self.assertRaises(NotArchiveType, get_archive_type,
275
                          'foo.zip.gz')
276
        self.assertEqual(('tar', 'gz'), get_archive_type('foo.tgz'))
277
        self.assertEqual(('tar', 'lzma'), get_archive_type('foo.tar.lzma'))
278
        self.assertEqual(('tar', 'lzma'), get_archive_type('foo.tar.xz'))
279
        self.assertEqual(('tar', 'bz2'), get_archive_type('foo.tar.bz2'))
280
281
282
class TestWithStuff(TestCaseWithTransport):
283
284
    def transform_to_tar(self, tt):
285
        stream = StringIO()
286
        export(tt.get_preview_tree(), root='', fileobj=stream, format='tar',
287
               dest=None)
288
        return stream
289
290
    def get_empty_tt(self):
291
        b = self.make_repository('foo')
292
        null_tree = b.revision_tree(_mod_revision.NULL_REVISION)
293
        tt = transform.TransformPreview(null_tree)
294
        root = tt.new_directory('', transform.ROOT_PARENT, 'tree-root')
295
        tt.fixup_new_roots()
296
        self.addCleanup(tt.finalize)
297
        return tt
298
299
    def test_nonascii_paths(self):
300
        self.requireFeature(UnicodeFilenameFeature)
301
        tt = self.get_empty_tt()
302
        encoded_file = tt.new_file(
303
            u'\u1234file', tt.root, 'contents', 'new-file')
304
        encoded_file = tt.new_file(
305
            'other', tt.root, 'contents', 'other-file')
306
        tarfile = self.transform_to_tar(tt)
307
        tarfile.seek(0)
308
        tree = self.make_branch_and_tree('bar')
309
        import_tar(tree, tarfile)
310
        self.assertPathExists(u'bar/\u1234file')