More Python 3 support
[zeroinstall/solver.git] / tests / testunpack.py
blob864ccb93cc32c22b9d2f5b6a605abba5baeb0195
1 #!/usr/bin/env python
3 from __future__ import print_function
5 from basetest import BaseTest
6 import sys, tempfile, os
7 import unittest, logging
9 sys.path.insert(0, '..')
10 from zeroinstall.zerostore import unpack, manifest, Store, BadDigest
11 from zeroinstall import SafeException, support
12 from zeroinstall.support import find_in_path
14 def skipIf(condition, reason):
15 def wrapped(underlying):
16 if condition:
17 if hasattr(underlying, 'func_name'):
18 print("Skipped %s: %s" % (underlying.func_name, reason)) # Python 2
19 else:
20 print("Skipped %s: %s" % (underlying.__name__, reason)) # Python 3
21 def run(self): pass
22 return run
23 else:
24 return underlying
25 return wrapped
27 class AbstractTestUnpack():
28 def setUp(self):
29 BaseTest.setUp(self)
31 self.tmpdir = tempfile.mkdtemp('-testunpack')
33 os.umask(0o022)
35 def tearDown(self):
36 BaseTest.tearDown(self)
38 support.ro_rmtree(self.tmpdir)
40 assert os.umask(0o022) == 0o022
42 def testBadExt(self):
43 try:
44 with open('HelloWorld.tgz', 'rb') as stream:
45 unpack.unpack_archive('ftp://foo/file.foo', stream, self.tmpdir)
46 assert False
47 except SafeException as ex:
48 assert 'Unknown extension' in str(ex)
50 def testTgz(self):
51 with open('HelloWorld.tgz', 'rb') as stream:
52 unpack.unpack_archive('ftp://foo/file.tgz', stream, self.tmpdir)
53 self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a')
55 @skipIf(not find_in_path('hdiutil'), "not running on MacOS X; no hdiutil")
56 def testDmg(self):
57 with open('HelloWorld.dmg', 'rb') as stream:
58 unpack.unpack_archive('ftp://foo/file.dmg', stream, self.tmpdir)
59 self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a')
61 def testZip(self):
62 with open('HelloWorld.zip', 'rb') as stream:
63 unpack.unpack_archive('ftp://foo/file.zip', stream, self.tmpdir)
64 self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a')
66 def testExtract(self):
67 with open('HelloWorld.tgz', 'rb') as stream:
68 unpack.unpack_archive('ftp://foo/file.tgz', stream, self.tmpdir, extract = 'HelloWorld')
69 self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a')
71 def testExtractOver(self):
72 with open('HelloWorld.tgz', 'rb') as stream:
73 unpack.unpack_archive_over('ftp://foo/file.tgz', stream, self.tmpdir, extract = 'HelloWorld')
74 self.assert_manifest('sha1=491678c37f77fadafbaae66b13d48d237773a68f')
76 def testExtractZip(self):
77 with open('HelloWorld.zip', 'rb') as stream:
78 unpack.unpack_archive('ftp://foo/file.zip', stream, self.tmpdir, extract = 'HelloWorld')
79 self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a')
81 def testExtractIllegal(self):
82 try:
83 with open('HelloWorld.tgz', 'rb') as stream:
84 unpack.unpack_archive('ftp://foo/file.tgz', stream, self.tmpdir, extract = 'Hello`World`')
85 assert False
86 except SafeException as ex:
87 assert 'Illegal' in str(ex)
89 def testExtractFails(self):
90 stderr = os.dup(2)
91 try:
92 null = os.open(os.devnull, os.O_WRONLY)
93 os.close(2)
94 os.dup2(null, 2)
95 try:
96 with open('HelloWorld.tgz', 'rb') as stream:
97 unpack.unpack_archive('ftp://foo/file.tgz', stream, self.tmpdir, extract = 'HelloWorld2')
98 assert False
99 except SafeException as ex:
100 if ('Failed to extract' not in str(ex) and # GNU tar
101 'Unable to find' not in str(ex)): # Python tar
102 raise ex
103 finally:
104 os.dup2(stderr, 2)
106 def testTargz(self):
107 with open('HelloWorld.tgz', 'rb') as stream:
108 unpack.unpack_archive('ftp://foo/file.tar.GZ', stream, self.tmpdir)
109 self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a')
111 def testTbz(self):
112 with open('HelloWorld.tar.bz2', 'rb') as stream:
113 unpack.unpack_archive('ftp://foo/file.tar.bz2', stream, self.tmpdir)
114 self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a')
116 def testTar(self):
117 with open('HelloWorld.tar', 'rb') as stream:
118 unpack.unpack_archive('ftp://foo/file.tar', stream, self.tmpdir)
119 self.assert_manifest('sha1new=290eb133e146635fe37713fd58174324a16d595f')
121 def testRPM(self):
122 with open('dummy-1-1.noarch.rpm', 'rb') as stream:
123 unpack.unpack_archive('ftp://foo/file.rpm', stream, self.tmpdir)
124 self.assert_manifest('sha1=7be9228c8fe2a1434d4d448c4cf130e3c8a4f53d')
126 def testDeb(self):
127 with open('dummy_1-1_all.deb', 'rb') as stream:
128 unpack.unpack_archive('ftp://foo/file.deb', stream, self.tmpdir)
129 self.assert_manifest('sha1new=2c725156ec3832b7980a3de2270b3d8d85d4e3ea')
131 def testGem(self):
132 with open('hello-0.1.gem', 'rb') as stream:
133 unpack.unpack_archive('ftp://foo/file.gem', stream, self.tmpdir)
134 self.assert_manifest('sha1new=fbd4827be7a18f9821790bdfd83132ee60d54647')
136 def testSpecial(self):
137 os.chmod(self.tmpdir, 0o2755)
138 store = Store(self.tmpdir)
139 with open('HelloWorld.tgz', 'rb') as stream:
140 store.add_archive_to_cache('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a',
141 stream,
142 'http://foo/foo.tgz')
144 def testBad(self):
145 logging.getLogger('').setLevel(logging.ERROR)
147 store = Store(self.tmpdir)
148 try:
149 with open('HelloWorld.tgz', 'rb') as stream:
150 store.add_archive_to_cache('sha1=3ce644dc725f1d21cfcf02562c76f375944b266b',
151 stream,
152 'http://foo/foo.tgz')
153 assert 0
154 except BadDigest:
155 pass
157 logging.getLogger('').setLevel(logging.INFO)
159 def assert_manifest(self, required):
160 alg_name = required.split('=', 1)[0]
161 manifest.fixup_permissions(self.tmpdir)
162 sha1 = alg_name + '=' + manifest.add_manifest_file(self.tmpdir, manifest.get_algorithm(alg_name)).hexdigest()
163 self.assertEqual(sha1, required)
165 # Check permissions are sensible
166 for root, dirs, files in os.walk(self.tmpdir):
167 for f in files + dirs:
168 full = os.path.join(root, f)
169 if os.path.islink(full): continue
170 full_mode = os.stat(full).st_mode
171 self.assertEqual(0o444, full_mode & 0o666) # Must be r-?r-?r-?
173 class TestUnpackPython(AbstractTestUnpack, BaseTest):
174 def setUp(self):
175 AbstractTestUnpack.setUp(self)
176 unpack._tar_version = 'Solaris tar'
177 assert not unpack._gnu_tar()
179 class TestUnpackGNU(AbstractTestUnpack, BaseTest):
180 def setUp(self):
181 AbstractTestUnpack.setUp(self)
182 unpack._tar_version = None
183 assert unpack._gnu_tar()
185 # Only available with GNU tar
186 def testLzma(self):
187 with open('HelloWorld.tar.lzma', 'rb') as stream:
188 unpack.unpack_archive('ftp://foo/file.tar.lzma', stream, self.tmpdir)
189 self.assert_manifest('sha1new=290eb133e146635fe37713fd58174324a16d595f')
191 if not unpack._gnu_tar():
192 print("No GNU tar: SKIPPING tests")
193 del globals()['TestUnpackGNU']
195 if __name__ == '__main__':
196 unittest.main()