/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_export.py

  • Committer: Robert Collins
  • Date: 2007-04-19 02:27:44 UTC
  • mto: This revision was merged to the branch mainline in revision 2426.
  • Revision ID: robertc@robertcollins.net-20070419022744-pfdqz42kp1wizh43
``make docs`` now creates a man page at ``man1/bzr.1`` fixing bug 107388.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010, 2011, 2016 Canonical Ltd
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
 
"""Tests for breezy.export."""
18
 
 
19
 
import gzip
20
 
from io import BytesIO
21
 
import os
22
 
import tarfile
23
 
import time
24
 
import zipfile
25
 
 
26
 
from .. import (
27
 
    errors,
28
 
    export,
29
 
    tests,
30
 
    )
31
 
from ..export import get_root_name
32
 
from ..archive.tar import tarball_generator
33
 
from . import features
34
 
 
35
 
 
36
 
class TestDirExport(tests.TestCaseWithTransport):
37
 
 
38
 
    def test_missing_file(self):
39
 
        self.build_tree(['a/', 'a/b', 'a/c'])
40
 
        wt = self.make_branch_and_tree('.')
41
 
        wt.add(['a', 'a/b', 'a/c'])
42
 
        os.unlink('a/c')
43
 
        export.export(wt, 'target', format="dir")
44
 
        self.assertPathExists('target/a/b')
45
 
        self.assertPathDoesNotExist('target/a/c')
46
 
 
47
 
    def test_empty(self):
48
 
        wt = self.make_branch_and_tree('.')
49
 
        export.export(wt, 'target', format="dir")
50
 
        self.assertEqual([], os.listdir("target"))
51
 
 
52
 
    def test_symlink(self):
53
 
        self.requireFeature(features.SymlinkFeature)
54
 
        wt = self.make_branch_and_tree('.')
55
 
        os.symlink('source', 'link')
56
 
        wt.add(['link'])
57
 
        export.export(wt, 'target', format="dir")
58
 
        self.assertPathExists('target/link')
59
 
 
60
 
    def test_nested_tree(self):
61
 
        wt = self.make_branch_and_tree('.', format='development-subtree')
62
 
        subtree = self.make_branch_and_tree('subtree')
63
 
        self.build_tree(['subtree/file'])
64
 
        subtree.add(['file'])
65
 
        wt.add(['subtree'])
66
 
        export.export(wt, 'target', format="dir")
67
 
        self.assertPathExists('target/subtree')
68
 
        # TODO(jelmer): Once iter_entries_by_dir supports nested tree iteration:
69
 
        # self.assertPathExists('target/subtree/file')
70
 
 
71
 
    def test_to_existing_empty_dir_success(self):
72
 
        self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
73
 
        wt = self.make_branch_and_tree('source')
74
 
        wt.add(['a', 'b', 'b/c'])
75
 
        wt.commit('1')
76
 
        self.build_tree(['target/'])
77
 
        export.export(wt, 'target', format="dir")
78
 
        self.assertPathExists('target/a')
79
 
        self.assertPathExists('target/b')
80
 
        self.assertPathExists('target/b/c')
81
 
 
82
 
    def test_empty_subdir(self):
83
 
        self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
84
 
        wt = self.make_branch_and_tree('source')
85
 
        wt.add(['a', 'b', 'b/c'])
86
 
        wt.commit('1')
87
 
        self.build_tree(['target/'])
88
 
        export.export(wt, 'target', format="dir", subdir='')
89
 
        self.assertPathExists('target/a')
90
 
        self.assertPathExists('target/b')
91
 
        self.assertPathExists('target/b/c')
92
 
 
93
 
    def test_to_existing_nonempty_dir_fail(self):
94
 
        self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
95
 
        wt = self.make_branch_and_tree('source')
96
 
        wt.add(['a', 'b', 'b/c'])
97
 
        wt.commit('1')
98
 
        self.build_tree(['target/', 'target/foo'])
99
 
        self.assertRaises(errors.BzrError,
100
 
                          export.export, wt, 'target', format="dir")
101
 
 
102
 
    def test_existing_single_file(self):
103
 
        self.build_tree([
104
 
            'dir1/', 'dir1/dir2/', 'dir1/first', 'dir1/dir2/second'])
105
 
        wtree = self.make_branch_and_tree('dir1')
106
 
        wtree.add(['dir2', 'first', 'dir2/second'])
107
 
        wtree.commit('1')
108
 
        export.export(wtree, 'target1', format='dir', subdir='first')
109
 
        self.assertPathExists('target1/first')
110
 
        export.export(wtree, 'target2', format='dir', subdir='dir2/second')
111
 
        self.assertPathExists('target2/second')
112
 
 
113
 
    def test_files_same_timestamp(self):
114
 
        builder = self.make_branch_builder('source')
115
 
        builder.start_series()
116
 
        builder.build_snapshot(None, [
117
 
            ('add', ('', b'root-id', 'directory', '')),
118
 
            ('add', ('a', b'a-id', 'file', b'content\n'))])
119
 
        builder.build_snapshot(None, [
120
 
            ('add', ('b', b'b-id', 'file', b'content\n'))])
121
 
        builder.finish_series()
122
 
        b = builder.get_branch()
123
 
        b.lock_read()
124
 
        self.addCleanup(b.unlock)
125
 
        tree = b.basis_tree()
126
 
        orig_iter_files_bytes = tree.iter_files_bytes
127
 
 
128
 
        # Make iter_files_bytes slower, so we provoke mtime skew
129
 
        def iter_files_bytes(to_fetch):
130
 
            for thing in orig_iter_files_bytes(to_fetch):
131
 
                yield thing
132
 
                time.sleep(1)
133
 
        tree.iter_files_bytes = iter_files_bytes
134
 
        export.export(tree, 'target', format='dir')
135
 
        t = self.get_transport('target')
136
 
        st_a = t.stat('a')
137
 
        st_b = t.stat('b')
138
 
        # All files must be given the same mtime.
139
 
        self.assertEqual(st_a.st_mtime, st_b.st_mtime)
140
 
 
141
 
    def test_files_per_file_timestamps(self):
142
 
        builder = self.make_branch_builder('source')
143
 
        builder.start_series()
144
 
        # Earliest allowable date on FAT32 filesystems is 1980-01-01
145
 
        a_time = time.mktime((1999, 12, 12, 0, 0, 0, 0, 0, 0))
146
 
        b_time = time.mktime((1980, 0o1, 0o1, 0, 0, 0, 0, 0, 0))
147
 
        builder.build_snapshot(None, [
148
 
            ('add', ('', b'root-id', 'directory', '')),
149
 
            ('add', ('a', b'a-id', 'file', b'content\n'))],
150
 
            timestamp=a_time)
151
 
        builder.build_snapshot(None, [
152
 
            ('add', ('b', b'b-id', 'file', b'content\n'))],
153
 
            timestamp=b_time)
154
 
        builder.finish_series()
155
 
        b = builder.get_branch()
156
 
        b.lock_read()
157
 
        self.addCleanup(b.unlock)
158
 
        tree = b.basis_tree()
159
 
        export.export(tree, 'target', format='dir', per_file_timestamps=True)
160
 
        t = self.get_transport('target')
161
 
        self.assertEqual(a_time, t.stat('a').st_mtime)
162
 
        self.assertEqual(b_time, t.stat('b').st_mtime)
163
 
 
164
 
    def test_subdir_files_per_timestamps(self):
165
 
        builder = self.make_branch_builder('source')
166
 
        builder.start_series()
167
 
        foo_time = time.mktime((1999, 12, 12, 0, 0, 0, 0, 0, 0))
168
 
        builder.build_snapshot(None, [
169
 
            ('add', ('', b'root-id', 'directory', '')),
170
 
            ('add', ('subdir', b'subdir-id', 'directory', '')),
171
 
            ('add', ('subdir/foo.txt', b'foo-id', 'file', b'content\n'))],
172
 
            timestamp=foo_time)
173
 
        builder.finish_series()
174
 
        b = builder.get_branch()
175
 
        b.lock_read()
176
 
        self.addCleanup(b.unlock)
177
 
        tree = b.basis_tree()
178
 
        export.export(tree, 'target', format='dir', subdir='subdir',
179
 
                      per_file_timestamps=True)
180
 
        t = self.get_transport('target')
181
 
        self.assertEqual(foo_time, t.stat('foo.txt').st_mtime)
182
 
 
183
 
 
184
 
class TarExporterTests(tests.TestCaseWithTransport):
185
 
 
186
 
    def test_xz(self):
187
 
        self.requireFeature(features.lzma)
188
 
        import lzma
189
 
        wt = self.make_branch_and_tree('.')
190
 
        self.build_tree(['a'])
191
 
        wt.add(["a"])
192
 
        wt.commit("1")
193
 
        export.export(wt, 'target.tar.xz', format="txz")
194
 
        tf = tarfile.open(fileobj=lzma.LZMAFile('target.tar.xz'))
195
 
        self.assertEqual(["target/a"], tf.getnames())
196
 
 
197
 
    def test_lzma(self):
198
 
        self.requireFeature(features.lzma)
199
 
        import lzma
200
 
        wt = self.make_branch_and_tree('.')
201
 
        self.build_tree(['a'])
202
 
        wt.add(["a"])
203
 
        wt.commit("1")
204
 
        export.export(wt, 'target.tar.lzma', format="tlzma")
205
 
        tf = tarfile.open(fileobj=lzma.LZMAFile('target.tar.lzma'))
206
 
        self.assertEqual(["target/a"], tf.getnames())
207
 
 
208
 
    def test_tgz(self):
209
 
        wt = self.make_branch_and_tree('.')
210
 
        self.build_tree(['a'])
211
 
        wt.add(["a"])
212
 
        wt.commit("1")
213
 
        export.export(wt, 'target.tar.gz', format="tgz")
214
 
        tf = tarfile.open('target.tar.gz')
215
 
        self.assertEqual(["target/a"], tf.getnames())
216
 
 
217
 
    def test_tgz_consistent_mtime(self):
218
 
        wt = self.make_branch_and_tree('.')
219
 
        self.build_tree(['a'])
220
 
        wt.add(["a"])
221
 
        timestamp = 1547400500
222
 
        revid = wt.commit("1", timestamp=timestamp)
223
 
        revtree = wt.branch.repository.revision_tree(revid)
224
 
        export.export(revtree, 'target.tar.gz', format="tgz")
225
 
        with gzip.GzipFile('target.tar.gz', 'r') as f:
226
 
            f.read()
227
 
            self.assertEqual(int(f.mtime), timestamp)
228
 
 
229
 
    def test_tgz_ignores_dest_path(self):
230
 
        # The target path should not be a part of the target file.
231
 
        # (bug #102234)
232
 
        wt = self.make_branch_and_tree('.')
233
 
        self.build_tree(['a'])
234
 
        wt.add(["a"])
235
 
        wt.commit("1")
236
 
        os.mkdir("testdir1")
237
 
        os.mkdir("testdir2")
238
 
        export.export(wt, 'testdir1/target.tar.gz', format="tgz",
239
 
                      per_file_timestamps=True)
240
 
        export.export(wt, 'testdir2/target.tar.gz', format="tgz",
241
 
                      per_file_timestamps=True)
242
 
        file1 = open('testdir1/target.tar.gz', 'rb')
243
 
        self.addCleanup(file1.close)
244
 
        file2 = open('testdir1/target.tar.gz', 'rb')
245
 
        self.addCleanup(file2.close)
246
 
        content1 = file1.read()
247
 
        content2 = file2.read()
248
 
        self.assertEqualDiff(content1, content2)
249
 
        # the gzip module doesn't have a way to read back to the original
250
 
        # filename, but it's stored as-is in the tarfile.
251
 
        self.assertFalse(b"testdir1" in content1)
252
 
        self.assertFalse(b"target.tar.gz" in content1)
253
 
        self.assertTrue(b"target.tar" in content1)
254
 
 
255
 
    def test_tbz2(self):
256
 
        wt = self.make_branch_and_tree('.')
257
 
        self.build_tree(['a'])
258
 
        wt.add(["a"])
259
 
        wt.commit("1")
260
 
        export.export(wt, 'target.tar.bz2', format="tbz2")
261
 
        tf = tarfile.open('target.tar.bz2')
262
 
        self.assertEqual(["target/a"], tf.getnames())
263
 
 
264
 
    def test_export_tarball_generator(self):
265
 
        wt = self.make_branch_and_tree('.')
266
 
        self.build_tree(['a'])
267
 
        wt.add(["a"])
268
 
        wt.commit("1", timestamp=42)
269
 
        target = BytesIO()
270
 
        with wt.lock_read():
271
 
            target.writelines(tarball_generator(wt, "bar"))
272
 
        # Ball should now be closed.
273
 
        target.seek(0)
274
 
        ball2 = tarfile.open(None, "r", target)
275
 
        self.addCleanup(ball2.close)
276
 
        self.assertEqual(["bar/a"], ball2.getnames())
277
 
 
278
 
 
279
 
class ZipExporterTests(tests.TestCaseWithTransport):
280
 
 
281
 
    def test_per_file_timestamps(self):
282
 
        tree = self.make_branch_and_tree('.')
283
 
        self.build_tree_contents([('har', b'foo')])
284
 
        tree.add('har')
285
 
        # Earliest allowable date on FAT32 filesystems is 1980-01-01
286
 
        timestamp = 347151600
287
 
        tree.commit('setup', timestamp=timestamp)
288
 
        export.export(tree.basis_tree(), 'test.zip', format='zip',
289
 
                      per_file_timestamps=True)
290
 
        zfile = zipfile.ZipFile('test.zip')
291
 
        info = zfile.getinfo("test/har")
292
 
        self.assertEqual(time.localtime(timestamp)[:6], info.date_time)
293
 
 
294
 
 
295
 
class RootNameTests(tests.TestCase):
296
 
 
297
 
    def test_root_name(self):
298
 
        self.assertEqual('mytest', get_root_name('../mytest.tar'))
299
 
        self.assertEqual('mytar', get_root_name('mytar.tar'))
300
 
        self.assertEqual('mytar', get_root_name('mytar.tar.bz2'))
301
 
        self.assertEqual('tar.tar.tar', get_root_name('tar.tar.tar.tgz'))
302
 
        self.assertEqual('bzr-0.0.5', get_root_name('bzr-0.0.5.tar.gz'))
303
 
        self.assertEqual('bzr-0.0.5', get_root_name('bzr-0.0.5.zip'))
304
 
        self.assertEqual('bzr-0.0.5', get_root_name('bzr-0.0.5'))
305
 
        self.assertEqual('mytar', get_root_name('a/long/path/mytar.tgz'))
306
 
        self.assertEqual('other',
307
 
                         get_root_name('../parent/../dir/other.tbz2'))
308
 
        self.assertEqual('', get_root_name('-'))