# Copyright 2017 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import math import os import shutil import tempfile import unittest import common from autotest_lib.client.bin.result_tools import result_info from autotest_lib.client.bin.result_tools import unittest_lib from autotest_lib.client.bin.result_tools import utils_lib from autotest_lib.client.bin.result_tools import zip_file_throttler ORIGINAL_SIZE_BYTE = 1000 # Set max result size to 0 to force all files being compressed if possible. MAX_RESULT_SIZE_KB = 0 FILE_SIZE_THRESHOLD_BYTE = 512 SUMMARY_AFTER_TRIMMING = { '': {utils_lib.DIRS: [ {'BUILD_INFO-x': {utils_lib.ORIGINAL_SIZE_BYTES: ORIGINAL_SIZE_BYTE}}, {'file1.xml.tgz': {utils_lib.ORIGINAL_SIZE_BYTES: ORIGINAL_SIZE_BYTE, utils_lib.TRIMMED_SIZE_BYTES: 148}}, {'file2.jpg': {utils_lib.ORIGINAL_SIZE_BYTES: ORIGINAL_SIZE_BYTE}}, {'file3.log.tgz': {utils_lib.ORIGINAL_SIZE_BYTES: ORIGINAL_SIZE_BYTE, utils_lib.TRIMMED_SIZE_BYTES: 148}}, {'folder1': { utils_lib.DIRS: [ {'file4.tgz': { utils_lib.ORIGINAL_SIZE_BYTES: ORIGINAL_SIZE_BYTE, utils_lib.TRIMMED_SIZE_BYTES: 140}}], utils_lib.ORIGINAL_SIZE_BYTES: ORIGINAL_SIZE_BYTE, utils_lib.TRIMMED_SIZE_BYTES: 140}}], utils_lib.ORIGINAL_SIZE_BYTES: 5 * ORIGINAL_SIZE_BYTE, utils_lib.TRIMMED_SIZE_BYTES: 2 * ORIGINAL_SIZE_BYTE + 435} } class ZipFileThrottleTest(unittest.TestCase): """Test class for zip_file_throttler.throttle method.""" def setUp(self): """Setup directory for test.""" self.test_dir = tempfile.mkdtemp() self.files_not_zip = [] self.files_to_zip = [] build_info = os.path.join(self.test_dir, 'BUILD_INFO-x') unittest_lib.create_file(build_info, ORIGINAL_SIZE_BYTE) self.files_not_zip.append(build_info) file1 = os.path.join(self.test_dir, 'file1.xml') unittest_lib.create_file(file1, ORIGINAL_SIZE_BYTE) self.files_to_zip.append(file1) file2 = os.path.join(self.test_dir, 'file2.jpg') unittest_lib.create_file(file2, ORIGINAL_SIZE_BYTE) self.files_not_zip.append(file2) file3 = os.path.join(self.test_dir, 'file3.log') unittest_lib.create_file(file3, ORIGINAL_SIZE_BYTE) self.files_to_zip.append(file3) folder1 = os.path.join(self.test_dir, 'folder1') os.mkdir(folder1) file4 = os.path.join(folder1, 'file4') unittest_lib.create_file(file4, ORIGINAL_SIZE_BYTE) self.files_to_zip.append(file4) def tearDown(self): """Cleanup the test directory.""" shutil.rmtree(self.test_dir, ignore_errors=True) def compareSummary(self, expected, actual): """Compare two summaries with tolerance on trimmed sizes. @param expected: The expected directory summary. @param actual: The actual directory summary after trimming. """ self.assertEqual(expected.original_size, actual.original_size) diff = math.fabs(expected.trimmed_size - actual.trimmed_size) # Compression may generate different sizes of tgz file, but the # difference shouldn't be more than 100 bytes. self.assertTrue( diff < 100, 'Compression failed to be verified. Expected size: %d, actual ' 'size: %d' % (expected.trimmed_size, actual.trimmed_size)) # Match files inside the directories. if expected.is_dir: expected_info_map = {info.name: info for info in expected.files} actual_info_map = {info.name: info for info in actual.files} self.assertEqual(set(expected_info_map.keys()), set(actual_info_map.keys())) for name in expected_info_map: self.compareSummary( expected_info_map[name], actual_info_map[name]) def testTrim(self): """Test throttle method.""" summary = result_info.ResultInfo.build_from_path(self.test_dir) zip_file_throttler.throttle( summary, max_result_size_KB=MAX_RESULT_SIZE_KB, file_size_threshold_byte=FILE_SIZE_THRESHOLD_BYTE) expected_summary = result_info.ResultInfo( parent_dir=self.test_dir, original_info=SUMMARY_AFTER_TRIMMING) self.compareSummary(expected_summary, summary) # Verify files that should not be compressed are not changed. for f in self.files_not_zip: self.assertEqual(ORIGINAL_SIZE_BYTE, os.stat(f).st_size, 'File %s should not be compressed!' % f) # Verify files that should be zipped are updated. for f in self.files_to_zip: stat = os.stat(f + '.tgz') self.assertTrue(FILE_SIZE_THRESHOLD_BYTE >= stat.st_size, 'File %s is not compressed!' % f) # this is so the test can be run in standalone mode if __name__ == '__main__': """Main""" unittest.main()