1# Copyright (C) 2011 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
17import os
18import tarfile
19import zipfile
20
21from breezy import (
22    errors,
23    osutils,
24    tests,
25    )
26from breezy.tests.per_tree import TestCaseWithTree
27from breezy.tests import (
28    features,
29    )
30
31
32class ArchiveTests(object):
33
34    def test_export(self):
35        work_a = self.make_branch_and_tree('wta')
36        self.build_tree_contents(
37            [('wta/file', b'a\nb\nc\nd\n'), ('wta/dir', b'')])
38        work_a.add('file')
39        work_a.add('dir')
40        work_a.commit('add file')
41        tree_a = self.workingtree_to_test_tree(work_a)
42        output_path = 'output'
43        with open(output_path, 'wb') as f:
44            f.writelines(tree_a.archive(self.format, output_path))
45        names = self.get_export_names(output_path)
46        self.assertIn('file', names)
47        self.assertIn('dir', names)
48
49    def test_export_symlink(self):
50        self.requireFeature(features.SymlinkFeature)
51        work_a = self.make_branch_and_tree('wta')
52        os.symlink('target', 'wta/link')
53        work_a.add('link')
54        work_a.commit('add link')
55        tree_a = self.workingtree_to_test_tree(work_a)
56        output_path = 'output'
57        with open(output_path, 'wb') as f:
58            f.writelines(tree_a.archive(self.format, output_path))
59        names = self.get_export_names(output_path)
60        self.assertIn('link', names)
61
62    def get_output_names(self, path):
63        raise NotImplementedError(self.get_output_names)
64
65
66class TestTar(ArchiveTests, TestCaseWithTree):
67
68    format = 'tar'
69
70    def get_export_names(self, path):
71        tf = tarfile.open(path)
72        try:
73            return tf.getnames()
74        finally:
75            tf.close()
76
77
78class TestTgz(ArchiveTests, TestCaseWithTree):
79
80    format = 'tgz'
81
82    def get_export_names(self, path):
83        tf = tarfile.open(path)
84        try:
85            return tf.getnames()
86        finally:
87            tf.close()
88
89
90class TestZip(ArchiveTests, TestCaseWithTree):
91
92    format = 'zip'
93
94    def get_export_names(self, path):
95        zf = zipfile.ZipFile(path)
96        try:
97            return zf.namelist()
98        finally:
99            zf.close()
100
101    def test_export_symlink(self):
102        self.requireFeature(features.SymlinkFeature)
103        work_a = self.make_branch_and_tree('wta')
104        os.symlink('target', 'wta/link')
105        work_a.add('link')
106        work_a.commit('add link')
107        tree_a = self.workingtree_to_test_tree(work_a)
108        output_path = 'output'
109        with open(output_path, 'wb') as f:
110            f.writelines(tree_a.archive(self.format, output_path))
111        names = self.get_export_names(output_path)
112        self.assertIn('link.lnk', names)
113
114
115class GenericArchiveTests(TestCaseWithTree):
116
117    def test_dir_invalid(self):
118        work_a = self.make_branch_and_tree('wta')
119        self.build_tree_contents(
120            [('wta/file', b'a\nb\nc\nd\n'), ('wta/dir', b'')])
121        work_a.add('file')
122        work_a.add('dir')
123        work_a.commit('add file')
124        tree_a = self.workingtree_to_test_tree(work_a)
125
126        self.assertRaises(
127            errors.NoSuchExportFormat,
128            tree_a.archive, 'dir', 'foo')
129