test_common.py revision d6d1beb88c846b07ef943645d282cbc86b378370
1# 2# Copyright (C) 2015 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16import os 17import tempfile 18import time 19import unittest 20import zipfile 21 22import common 23 24 25def random_string_with_holes(size, block_size, step_size): 26 data = ["\0"] * size 27 for begin in range(0, size, step_size): 28 end = begin + block_size 29 data[begin:end] = os.urandom(block_size) 30 return "".join(data) 31 32 33class CommonZipTest(unittest.TestCase): 34 def _test_ZipWrite(self, contents, extra_zipwrite_args=None): 35 extra_zipwrite_args = dict(extra_zipwrite_args or {}) 36 37 test_file = tempfile.NamedTemporaryFile(delete=False) 38 zip_file = tempfile.NamedTemporaryFile(delete=False) 39 40 test_file_name = test_file.name 41 zip_file_name = zip_file.name 42 43 # File names within an archive strip the leading slash. 44 arcname = extra_zipwrite_args.get("arcname", test_file_name) 45 if arcname[0] == "/": 46 arcname = arcname[1:] 47 48 zip_file.close() 49 zip_file = zipfile.ZipFile(zip_file_name, "w") 50 51 try: 52 test_file.write(contents) 53 test_file.close() 54 55 old_stat = os.stat(test_file_name) 56 expected_mode = extra_zipwrite_args.get("perms", 0o644) 57 58 time.sleep(5) # Make sure the atime/mtime will change measurably. 59 60 common.ZipWrite(zip_file, test_file_name, **extra_zipwrite_args) 61 62 new_stat = os.stat(test_file_name) 63 self.assertEqual(int(old_stat.st_mode), int(new_stat.st_mode)) 64 self.assertEqual(int(old_stat.st_mtime), int(new_stat.st_mtime)) 65 self.assertIsNone(zip_file.testzip()) 66 67 zip_file.close() 68 zip_file = zipfile.ZipFile(zip_file_name, "r") 69 info = zip_file.getinfo(arcname) 70 71 self.assertEqual(info.date_time, (2009, 1, 1, 0, 0, 0)) 72 mode = (info.external_attr >> 16) & 0o777 73 self.assertEqual(mode, expected_mode) 74 self.assertEqual(zip_file.read(arcname), contents) 75 self.assertIsNone(zip_file.testzip()) 76 finally: 77 os.remove(test_file_name) 78 os.remove(zip_file_name) 79 80 def test_ZipWrite(self): 81 file_contents = os.urandom(1024) 82 self._test_ZipWrite(file_contents) 83 84 def test_ZipWrite_with_opts(self): 85 file_contents = os.urandom(1024) 86 self._test_ZipWrite(file_contents, { 87 "arcname": "foobar", 88 "perms": 0o777, 89 "compress_type": zipfile.ZIP_DEFLATED, 90 }) 91 92 def test_ZipWrite_large_file(self): 93 kilobytes = 1024 94 megabytes = 1024 * kilobytes 95 gigabytes = 1024 * megabytes 96 97 size = int(2 * gigabytes + 1) 98 block_size = 4 * kilobytes 99 step_size = 4 * megabytes 100 file_contents = random_string_with_holes( 101 size, block_size, step_size) 102 self._test_ZipWrite(file_contents, { 103 "compress_type": zipfile.ZIP_DEFLATED, 104 }) 105 106 def test_ZipWrite_resets_ZIP64_LIMIT(self): 107 default_limit = (1 << 31) - 1 108 self.assertEqual(default_limit, zipfile.ZIP64_LIMIT) 109 self._test_ZipWrite('') 110 self.assertEqual(default_limit, zipfile.ZIP64_LIMIT) 111