1import os 2 3import infra.basetest 4 5 6class TestCompressorBase(infra.basetest.BRTest): 7 """Common class to test a data compression/decompression package. 8 9 Build an image containing the package enabled in config, start the 10 emulator, login to it. It prepares a test data file with some 11 redundancy to let compression program reduce the file size. 12 13 Each test case that inherits from this class must have: 14 __test__ = True - to let nose2 know that it is a test case 15 config - defconfig fragment with the packages to run the test 16 compress_cmd - the compression program command (ex: "gzip") 17 it can also contain arguments (ex: "gzip -9") 18 It also can have: 19 decompress_cmd - the decompression program (ex: "gunzip") 20 if unset, the default value is "un" appended with the 21 value of "compress_cmd". 22 check_integrity_cmd 23 - the integrity check command (ex: "gzip -t") 24 in unset, the default value is "compress_cmd" appended 25 with " -t". 26 compressed_file_ext 27 - the file extention of compressed files created by the 28 compress command. (ex: ".gz") 29 if unset, the default value is a dot "." appended with 30 the value of "compress_cmd". 31 timeout - timeout to the compression command. Some compression 32 program can take more time than the default value 33 (set to 5 seconds). 34 """ 35 __test__ = False 36 config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \ 37 """ 38 BR2_TARGET_ROOTFS_CPIO=y 39 # BR2_TARGET_ROOTFS_TAR is not set 40 """ 41 compress_cmd = "compressor-unknown" 42 decompress_cmd = None 43 check_integrity_cmd = None 44 compressed_file_ext = None 45 timeout = 5 46 47 def __init__(self, names): 48 """Setup common test variables.""" 49 super(TestCompressorBase, self).__init__(names) 50 51 if self.decompress_cmd is None: 52 self.decompress_cmd = "un" + self.compress_cmd 53 54 if self.check_integrity_cmd is None: 55 self.check_integrity_cmd = self.compress_cmd + " -t" 56 57 if self.compressed_file_ext is None: 58 self.compressed_file_ext = "." + self.compress_cmd 59 60 self.ref_file = "reference.bin" 61 self.test_file = "test.bin" 62 self.comp_test_file = self.test_file + self.compressed_file_ext 63 64 def login(self): 65 cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio") 66 self.emulator.boot(arch="armv5", 67 kernel="builtin", 68 options=["-initrd", cpio_file]) 69 self.emulator.login() 70 71 def test_run(self): 72 self.login() 73 self.prepare_data() 74 self.compress_test() 75 self.check_integrity_test() 76 self.uncompress_test() 77 self.compare_test() 78 79 def prepare_data(self): 80 # Create a data file composed of: 128kB of random data, then 81 # 128kB of zeroes, then a repetition of the 1st 128kB of 82 # random. 83 self.assertRunOk("dd if=/dev/urandom of=rand.bin bs=128k count=1") 84 self.assertRunOk("dd if=/dev/zero of=zeroes.bin bs=128k count=1") 85 self.assertRunOk(f"cat rand.bin zeroes.bin rand.bin > {self.ref_file}") 86 87 # Keep a copy of the reference data since 88 # compressor/decompressor programs usually unlink source data 89 # file. 90 self.assertRunOk(f"cp {self.ref_file} {self.test_file}") 91 92 def compress_test(self): 93 # Run the compression 94 self.assertRunOk(f"{self.compress_cmd} {self.test_file}", timeout=self.timeout) 95 96 # Check that the compressed file was created with the expected name 97 self.assertRunOk(f"test -e {self.comp_test_file}") 98 99 # Remove the input test file. Some compressors (like gzip) are 100 # removing it automatically by default. Some others (like lz4) 101 # are keeping those by default. We always remove it to make 102 # sure a new file will be recreated by the decompression. 103 self.assertRunOk(f"rm -f {self.test_file}") 104 105 # Check the compressed file is smaller than the input. 106 # The "ls -l" command is for simplifying debugging 107 self.assertRunOk(f"ls -l {self.ref_file} {self.comp_test_file}") 108 ref_sz_cmd = f"wc -c < {self.ref_file}" 109 comp_sz_cmd = f"wc -c < {self.comp_test_file}" 110 self.assertRunOk(f"test $({ref_sz_cmd}) -gt $({comp_sz_cmd})") 111 112 def check_integrity_test(self): 113 # Check the compressed file integrity 114 self.assertRunOk(f"{self.check_integrity_cmd} {self.comp_test_file}") 115 116 def uncompress_test(self): 117 # Run the decompression 118 self.assertRunOk(f"{self.decompress_cmd} {self.comp_test_file}") 119 120 # Check the decompressed file was created with the correct name 121 self.assertRunOk(f"test -e {self.test_file}") 122 123 def compare_test(self): 124 # Check the decompressed file is exactly the same as the 125 # reference created at the beginning 126 self.assertRunOk(f"cmp {self.test_file} {self.ref_file}") 127