# 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()