1*27162e4eSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*27162e4eSAndroid Build Coastguard Workerimport subprocess 3*27162e4eSAndroid Build Coastguard Workerimport time 4*27162e4eSAndroid Build Coastguard Workerimport glob 5*27162e4eSAndroid Build Coastguard Workerimport os 6*27162e4eSAndroid Build Coastguard Workerimport tempfile 7*27162e4eSAndroid Build Coastguard Workerimport unittest 8*27162e4eSAndroid Build Coastguard Workerimport sys 9*27162e4eSAndroid Build Coastguard Worker 10*27162e4eSAndroid Build Coastguard WorkerSIZES = [3, 11] # Always 2 sizes 11*27162e4eSAndroid Build Coastguard WorkerMIB = 1048576 12*27162e4eSAndroid Build Coastguard WorkerLZ4 = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../lz4") 13*27162e4eSAndroid Build Coastguard Workerif not os.path.exists(LZ4): 14*27162e4eSAndroid Build Coastguard Worker LZ4 = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../programs/lz4") 15*27162e4eSAndroid Build Coastguard WorkerTEMP = tempfile.gettempdir() 16*27162e4eSAndroid Build Coastguard Worker 17*27162e4eSAndroid Build Coastguard Worker 18*27162e4eSAndroid Build Coastguard Workerclass NVerboseFileInfo: 19*27162e4eSAndroid Build Coastguard Worker def __init__(self, line_in): 20*27162e4eSAndroid Build Coastguard Worker self.line = line_in 21*27162e4eSAndroid Build Coastguard Worker splitlines = line_in.split() 22*27162e4eSAndroid Build Coastguard Worker if len(splitlines) != 7: 23*27162e4eSAndroid Build Coastguard Worker errout(f"Unexpected line: {line_in}") 24*27162e4eSAndroid Build Coastguard Worker self.frames, self.type, self.block, self.compressed, self.uncompressed, self.ratio, self.filename = splitlines 25*27162e4eSAndroid Build Coastguard Worker self.exp_unc_size = 0 26*27162e4eSAndroid Build Coastguard Worker # Get real file sizes 27*27162e4eSAndroid Build Coastguard Worker if "concat-all" in self.filename or "2f--content-size" in self.filename: 28*27162e4eSAndroid Build Coastguard Worker for i in SIZES: 29*27162e4eSAndroid Build Coastguard Worker self.exp_unc_size += os.path.getsize(f"{TEMP}/test_list_{i}M") 30*27162e4eSAndroid Build Coastguard Worker else: 31*27162e4eSAndroid Build Coastguard Worker uncompressed_filename = self.filename.split("-")[0] 32*27162e4eSAndroid Build Coastguard Worker self.exp_unc_size += os.path.getsize(f"{TEMP}/{uncompressed_filename}") 33*27162e4eSAndroid Build Coastguard Worker self.exp_comp_size = os.path.getsize(f"{TEMP}/{self.filename}") 34*27162e4eSAndroid Build Coastguard Worker 35*27162e4eSAndroid Build Coastguard Worker 36*27162e4eSAndroid Build Coastguard Workerclass TestNonVerbose(unittest.TestCase): 37*27162e4eSAndroid Build Coastguard Worker @classmethod 38*27162e4eSAndroid Build Coastguard Worker def setUpClass(self): 39*27162e4eSAndroid Build Coastguard Worker self.nvinfo_list = [] 40*27162e4eSAndroid Build Coastguard Worker test_list_files = glob.glob(f"{TEMP}/test_list_*.lz4") 41*27162e4eSAndroid Build Coastguard Worker # One of the files has 2 frames so duplicate it in this list to map each frame 1 to a single file 42*27162e4eSAndroid Build Coastguard Worker for i, filename in enumerate(test_list_files): 43*27162e4eSAndroid Build Coastguard Worker for i, line in enumerate(execute(f"{LZ4} --list -m {filename}", print_output=True)): 44*27162e4eSAndroid Build Coastguard Worker if i > 0: 45*27162e4eSAndroid Build Coastguard Worker self.nvinfo_list.append(NVerboseFileInfo(line)) 46*27162e4eSAndroid Build Coastguard Worker 47*27162e4eSAndroid Build Coastguard Worker def test_frames(self): 48*27162e4eSAndroid Build Coastguard Worker all_concat_frames = 0 49*27162e4eSAndroid Build Coastguard Worker all_concat_index = None 50*27162e4eSAndroid Build Coastguard Worker for i, nvinfo in enumerate(self.nvinfo_list): 51*27162e4eSAndroid Build Coastguard Worker if "concat-all" in nvinfo.filename: 52*27162e4eSAndroid Build Coastguard Worker all_concat_index = i 53*27162e4eSAndroid Build Coastguard Worker elif "2f--content-size" in nvinfo.filename: 54*27162e4eSAndroid Build Coastguard Worker self.assertEqual("2", nvinfo.frames, nvinfo.line) 55*27162e4eSAndroid Build Coastguard Worker all_concat_frames += 2 56*27162e4eSAndroid Build Coastguard Worker else: 57*27162e4eSAndroid Build Coastguard Worker self.assertEqual("1", nvinfo.frames, nvinfo.line) 58*27162e4eSAndroid Build Coastguard Worker all_concat_frames += 1 59*27162e4eSAndroid Build Coastguard Worker self.assertNotEqual(None, all_concat_index, "Couldn't find concat-all file index.") 60*27162e4eSAndroid Build Coastguard Worker self.assertEqual(self.nvinfo_list[all_concat_index].frames, str(all_concat_frames), self.nvinfo_list[all_concat_index].line) 61*27162e4eSAndroid Build Coastguard Worker 62*27162e4eSAndroid Build Coastguard Worker def test_frame_types(self): 63*27162e4eSAndroid Build Coastguard Worker for nvinfo in self.nvinfo_list: 64*27162e4eSAndroid Build Coastguard Worker if "-lz4f-" in nvinfo.filename: 65*27162e4eSAndroid Build Coastguard Worker self.assertEqual(nvinfo.type, "LZ4Frame", nvinfo.line) 66*27162e4eSAndroid Build Coastguard Worker elif "-legc-" in nvinfo.filename: 67*27162e4eSAndroid Build Coastguard Worker self.assertEqual(nvinfo.type, "LegacyFrame", nvinfo.line) 68*27162e4eSAndroid Build Coastguard Worker elif "-skip-" in nvinfo.filename: 69*27162e4eSAndroid Build Coastguard Worker self.assertEqual(nvinfo.type, "SkippableFrame", nvinfo.line) 70*27162e4eSAndroid Build Coastguard Worker 71*27162e4eSAndroid Build Coastguard Worker def test_block(self): 72*27162e4eSAndroid Build Coastguard Worker for nvinfo in self.nvinfo_list: 73*27162e4eSAndroid Build Coastguard Worker # if "-leg" in nvinfo.filename or "-skip" in nvinfo.filename: 74*27162e4eSAndroid Build Coastguard Worker # self.assertEqual(nvinfo.block, "-", nvinfo.line) 75*27162e4eSAndroid Build Coastguard Worker if "--BD" in nvinfo.filename: 76*27162e4eSAndroid Build Coastguard Worker self.assertRegex(nvinfo.block, "^B[0-9]+D$", nvinfo.line) 77*27162e4eSAndroid Build Coastguard Worker elif "--BI" in nvinfo.filename: 78*27162e4eSAndroid Build Coastguard Worker self.assertRegex(nvinfo.block, "^B[0-9]+I$", nvinfo.line) 79*27162e4eSAndroid Build Coastguard Worker 80*27162e4eSAndroid Build Coastguard Worker def test_compressed_size(self): 81*27162e4eSAndroid Build Coastguard Worker for nvinfo in self.nvinfo_list: 82*27162e4eSAndroid Build Coastguard Worker self.assertEqual(nvinfo.compressed, to_human(nvinfo.exp_comp_size), nvinfo.line) 83*27162e4eSAndroid Build Coastguard Worker 84*27162e4eSAndroid Build Coastguard Worker def test_ratio(self): 85*27162e4eSAndroid Build Coastguard Worker for nvinfo in self.nvinfo_list: 86*27162e4eSAndroid Build Coastguard Worker if "--content-size" in nvinfo.filename: 87*27162e4eSAndroid Build Coastguard Worker self.assertEqual(nvinfo.ratio, f"{float(nvinfo.exp_comp_size) / float(nvinfo.exp_unc_size) * 100:.2f}%", nvinfo.line) 88*27162e4eSAndroid Build Coastguard Worker 89*27162e4eSAndroid Build Coastguard Worker def test_uncompressed_size(self): 90*27162e4eSAndroid Build Coastguard Worker for nvinfo in self.nvinfo_list: 91*27162e4eSAndroid Build Coastguard Worker if "--content-size" in nvinfo.filename: 92*27162e4eSAndroid Build Coastguard Worker self.assertEqual(nvinfo.uncompressed, to_human(nvinfo.exp_unc_size), nvinfo.line) 93*27162e4eSAndroid Build Coastguard Worker 94*27162e4eSAndroid Build Coastguard Worker 95*27162e4eSAndroid Build Coastguard Workerclass VerboseFileInfo: 96*27162e4eSAndroid Build Coastguard Worker def __init__(self, lines): 97*27162e4eSAndroid Build Coastguard Worker # Parse lines 98*27162e4eSAndroid Build Coastguard Worker self.frame_list = [] 99*27162e4eSAndroid Build Coastguard Worker self.file_frame_map = [] 100*27162e4eSAndroid Build Coastguard Worker for i, line in enumerate(lines): 101*27162e4eSAndroid Build Coastguard Worker if i == 0: 102*27162e4eSAndroid Build Coastguard Worker self.filename = line 103*27162e4eSAndroid Build Coastguard Worker continue 104*27162e4eSAndroid Build Coastguard Worker elif i == 1: 105*27162e4eSAndroid Build Coastguard Worker # Skip header 106*27162e4eSAndroid Build Coastguard Worker continue 107*27162e4eSAndroid Build Coastguard Worker frame_info = dict(zip(["frame", "type", "block", "checksum", "compressed", "uncompressed", "ratio"], line.split())) 108*27162e4eSAndroid Build Coastguard Worker frame_info["line"] = line 109*27162e4eSAndroid Build Coastguard Worker self.frame_list.append(frame_info) 110*27162e4eSAndroid Build Coastguard Worker 111*27162e4eSAndroid Build Coastguard Worker 112*27162e4eSAndroid Build Coastguard Workerclass TestVerbose(unittest.TestCase): 113*27162e4eSAndroid Build Coastguard Worker @classmethod 114*27162e4eSAndroid Build Coastguard Worker def setUpClass(self): 115*27162e4eSAndroid Build Coastguard Worker # Even do we're listing 2 files to test multiline working as expected. 116*27162e4eSAndroid Build Coastguard Worker # we're only really interested in testing the output of the concat-all file. 117*27162e4eSAndroid Build Coastguard Worker self.vinfo_list = [] 118*27162e4eSAndroid Build Coastguard Worker start = end = 0 119*27162e4eSAndroid Build Coastguard Worker test_list_SM_lz4f = glob.glob(f"{TEMP}/test_list_*M-lz4f-2f--content-size.lz4") 120*27162e4eSAndroid Build Coastguard Worker for i, filename in enumerate(test_list_SM_lz4f): 121*27162e4eSAndroid Build Coastguard Worker output = execute(f"{LZ4} --list -m -v {TEMP}/test_list_concat-all.lz4 {filename}", print_output=True) 122*27162e4eSAndroid Build Coastguard Worker for i, line in enumerate(output): 123*27162e4eSAndroid Build Coastguard Worker if line.startswith("test_list"): 124*27162e4eSAndroid Build Coastguard Worker if start != 0 and end != 0: 125*27162e4eSAndroid Build Coastguard Worker self.vinfo_list.append(VerboseFileInfo(output[start:end])) 126*27162e4eSAndroid Build Coastguard Worker start = i 127*27162e4eSAndroid Build Coastguard Worker if not line: 128*27162e4eSAndroid Build Coastguard Worker end = i 129*27162e4eSAndroid Build Coastguard Worker self.vinfo_list.append(VerboseFileInfo(output[start:end])) 130*27162e4eSAndroid Build Coastguard Worker # Populate file_frame_map as a reference of the expected info 131*27162e4eSAndroid Build Coastguard Worker concat_file_list = glob.glob(f"{TEMP}/test_list_[!concat]*.lz4") 132*27162e4eSAndroid Build Coastguard Worker # One of the files has 2 frames so duplicate it in this list to map each frame 1 to a single file 133*27162e4eSAndroid Build Coastguard Worker for i, filename in enumerate(concat_file_list): 134*27162e4eSAndroid Build Coastguard Worker if "2f--content-size" in filename: 135*27162e4eSAndroid Build Coastguard Worker concat_file_list.insert(i, filename) 136*27162e4eSAndroid Build Coastguard Worker break 137*27162e4eSAndroid Build Coastguard Worker self.cvinfo = self.vinfo_list[0] 138*27162e4eSAndroid Build Coastguard Worker self.cvinfo.file_frame_map = concat_file_list 139*27162e4eSAndroid Build Coastguard Worker self.cvinfo.compressed_size = os.path.getsize(f"{TEMP}/test_list_concat-all.lz4") 140*27162e4eSAndroid Build Coastguard Worker 141*27162e4eSAndroid Build Coastguard Worker def test_frame_number(self): 142*27162e4eSAndroid Build Coastguard Worker for vinfo in self.vinfo_list: 143*27162e4eSAndroid Build Coastguard Worker for i, frame_info in enumerate(vinfo.frame_list): 144*27162e4eSAndroid Build Coastguard Worker self.assertEqual(frame_info["frame"], str(i + 1), frame_info["line"]) 145*27162e4eSAndroid Build Coastguard Worker 146*27162e4eSAndroid Build Coastguard Worker def test_block(self): 147*27162e4eSAndroid Build Coastguard Worker for i, frame_info in enumerate(self.cvinfo.frame_list): 148*27162e4eSAndroid Build Coastguard Worker if "--BD" in self.cvinfo.file_frame_map[i]: 149*27162e4eSAndroid Build Coastguard Worker self.assertRegex(self.cvinfo.frame_list[i]["block"], "^B[0-9]+D$", self.cvinfo.frame_list[i]["line"]) 150*27162e4eSAndroid Build Coastguard Worker elif "--BI" in self.cvinfo.file_frame_map[i]: 151*27162e4eSAndroid Build Coastguard Worker self.assertEqual(self.cvinfo.frame_list[i]["block"], "^B[0-9]+I$", self.cvinfo.frame_list[i]["line"]) 152*27162e4eSAndroid Build Coastguard Worker 153*27162e4eSAndroid Build Coastguard Worker def test_checksum(self): 154*27162e4eSAndroid Build Coastguard Worker for i, frame_info in enumerate(self.cvinfo.frame_list): 155*27162e4eSAndroid Build Coastguard Worker if "-lz4f-" in self.cvinfo.file_frame_map[i] and "--no-frame-crc" not in self.cvinfo.file_frame_map[i]: 156*27162e4eSAndroid Build Coastguard Worker self.assertEqual(self.cvinfo.frame_list[i]["checksum"], "XXH32", self.cvinfo.frame_list[i]["line"]) 157*27162e4eSAndroid Build Coastguard Worker 158*27162e4eSAndroid Build Coastguard Worker def test_uncompressed(self): 159*27162e4eSAndroid Build Coastguard Worker for i, frame_info in enumerate(self.cvinfo.frame_list): 160*27162e4eSAndroid Build Coastguard Worker ffm = self.cvinfo.file_frame_map[i] 161*27162e4eSAndroid Build Coastguard Worker if "-2f-" not in ffm and "--content-size" in ffm: 162*27162e4eSAndroid Build Coastguard Worker expected_size_unc = int(ffm[ffm.rindex("_") + 1:ffm.index("M")]) * 1048576 163*27162e4eSAndroid Build Coastguard Worker self.assertEqual(self.cvinfo.frame_list[i]["uncompressed"], str(expected_size_unc), self.cvinfo.frame_list[i]["line"]) 164*27162e4eSAndroid Build Coastguard Worker 165*27162e4eSAndroid Build Coastguard Worker def test_ratio(self): 166*27162e4eSAndroid Build Coastguard Worker for i, frame_info in enumerate(self.cvinfo.frame_list): 167*27162e4eSAndroid Build Coastguard Worker if "--content-size" in self.cvinfo.file_frame_map[i]: 168*27162e4eSAndroid Build Coastguard Worker self.assertEqual(self.cvinfo.frame_list[i]['ratio'], 169*27162e4eSAndroid Build Coastguard Worker f"{float(self.cvinfo.frame_list[i]['compressed']) / float(self.cvinfo.frame_list[i]['uncompressed']) * 100:.2f}%", 170*27162e4eSAndroid Build Coastguard Worker self.cvinfo.frame_list[i]["line"]) 171*27162e4eSAndroid Build Coastguard Worker 172*27162e4eSAndroid Build Coastguard Worker 173*27162e4eSAndroid Build Coastguard Workerdef to_human(size): 174*27162e4eSAndroid Build Coastguard Worker for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']: 175*27162e4eSAndroid Build Coastguard Worker if size < 1024.0: 176*27162e4eSAndroid Build Coastguard Worker break 177*27162e4eSAndroid Build Coastguard Worker size /= 1024.0 178*27162e4eSAndroid Build Coastguard Worker return f"{size:.2f}{unit}" 179*27162e4eSAndroid Build Coastguard Worker 180*27162e4eSAndroid Build Coastguard Worker 181*27162e4eSAndroid Build Coastguard Workerdef log(text): 182*27162e4eSAndroid Build Coastguard Worker print(time.strftime("%Y/%m/%d %H:%M:%S") + ' - ' + text) 183*27162e4eSAndroid Build Coastguard Worker 184*27162e4eSAndroid Build Coastguard Worker 185*27162e4eSAndroid Build Coastguard Workerdef errout(text, err=1): 186*27162e4eSAndroid Build Coastguard Worker log(text) 187*27162e4eSAndroid Build Coastguard Worker exit(err) 188*27162e4eSAndroid Build Coastguard Worker 189*27162e4eSAndroid Build Coastguard Worker 190*27162e4eSAndroid Build Coastguard Workerdef execute(command, print_command=True, print_output=False, print_error=True): 191*27162e4eSAndroid Build Coastguard Worker if os.environ.get('QEMU_SYS'): 192*27162e4eSAndroid Build Coastguard Worker command = f"{os.environ['QEMU_SYS']} {command}" 193*27162e4eSAndroid Build Coastguard Worker if print_command: 194*27162e4eSAndroid Build Coastguard Worker log("> " + command) 195*27162e4eSAndroid Build Coastguard Worker popen = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE) 196*27162e4eSAndroid Build Coastguard Worker stdout_lines, stderr_lines = popen.communicate() 197*27162e4eSAndroid Build Coastguard Worker stderr_lines = stderr_lines.decode("utf-8") 198*27162e4eSAndroid Build Coastguard Worker stdout_lines = stdout_lines.decode("utf-8") 199*27162e4eSAndroid Build Coastguard Worker if print_output: 200*27162e4eSAndroid Build Coastguard Worker if stdout_lines: 201*27162e4eSAndroid Build Coastguard Worker print(stdout_lines) 202*27162e4eSAndroid Build Coastguard Worker if stderr_lines: 203*27162e4eSAndroid Build Coastguard Worker print(stderr_lines) 204*27162e4eSAndroid Build Coastguard Worker if popen.returncode is not None and popen.returncode != 0: 205*27162e4eSAndroid Build Coastguard Worker if stderr_lines and not print_output and print_error: 206*27162e4eSAndroid Build Coastguard Worker print(stderr_lines) 207*27162e4eSAndroid Build Coastguard Worker errout(f"Failed to run: {command}, {stdout_lines + stderr_lines}\n") 208*27162e4eSAndroid Build Coastguard Worker return (stdout_lines).splitlines() 209*27162e4eSAndroid Build Coastguard Worker 210*27162e4eSAndroid Build Coastguard Worker 211*27162e4eSAndroid Build Coastguard Workerdef cleanup(silent=False): 212*27162e4eSAndroid Build Coastguard Worker for f in glob.glob(f"{TEMP}/test_list*"): 213*27162e4eSAndroid Build Coastguard Worker if not silent: 214*27162e4eSAndroid Build Coastguard Worker log(f"Deleting {f}") 215*27162e4eSAndroid Build Coastguard Worker os.unlink(f) 216*27162e4eSAndroid Build Coastguard Worker 217*27162e4eSAndroid Build Coastguard Worker 218*27162e4eSAndroid Build Coastguard Workerdef datagen(file_name, size): 219*27162e4eSAndroid Build Coastguard Worker non_sparse_size = size // 2 220*27162e4eSAndroid Build Coastguard Worker sparse_size = size - non_sparse_size 221*27162e4eSAndroid Build Coastguard Worker with open(file_name, "wb") as f: 222*27162e4eSAndroid Build Coastguard Worker f.seek(sparse_size) 223*27162e4eSAndroid Build Coastguard Worker f.write(os.urandom(non_sparse_size)) 224*27162e4eSAndroid Build Coastguard Worker 225*27162e4eSAndroid Build Coastguard Worker 226*27162e4eSAndroid Build Coastguard Workerdef generate_files(): 227*27162e4eSAndroid Build Coastguard Worker # file format ~ test_list<frametype>-<no_frames>f<create-args>.lz4 ~ 228*27162e4eSAndroid Build Coastguard Worker # Generate LZ4Frames 229*27162e4eSAndroid Build Coastguard Worker for i in SIZES: 230*27162e4eSAndroid Build Coastguard Worker filename = f"{TEMP}/test_list_{i}M" 231*27162e4eSAndroid Build Coastguard Worker log(f"Generating {filename}") 232*27162e4eSAndroid Build Coastguard Worker datagen(filename, i * MIB) 233*27162e4eSAndroid Build Coastguard Worker for j in ["--content-size", "-BI", "-BD", "-BX", "--no-frame-crc"]: 234*27162e4eSAndroid Build Coastguard Worker lz4file = f"{filename}-lz4f-1f{j}.lz4" 235*27162e4eSAndroid Build Coastguard Worker execute(f"{LZ4} {j} {filename} {lz4file}") 236*27162e4eSAndroid Build Coastguard Worker # Generate skippable frames 237*27162e4eSAndroid Build Coastguard Worker lz4file = f"{filename}-skip-1f.lz4" 238*27162e4eSAndroid Build Coastguard Worker skipsize = i * 1024 239*27162e4eSAndroid Build Coastguard Worker skipbytes = bytes([80, 42, 77, 24]) + skipsize.to_bytes(4, byteorder='little', signed=False) 240*27162e4eSAndroid Build Coastguard Worker with open(lz4file, 'wb') as f: 241*27162e4eSAndroid Build Coastguard Worker f.write(skipbytes) 242*27162e4eSAndroid Build Coastguard Worker f.write(os.urandom(skipsize)) 243*27162e4eSAndroid Build Coastguard Worker # Generate legacy frames 244*27162e4eSAndroid Build Coastguard Worker lz4file = f"{filename}-legc-1f.lz4" 245*27162e4eSAndroid Build Coastguard Worker execute(f"{LZ4} -l {filename} {lz4file}") 246*27162e4eSAndroid Build Coastguard Worker 247*27162e4eSAndroid Build Coastguard Worker # Concatenate --content-size files 248*27162e4eSAndroid Build Coastguard Worker file_list = glob.glob(f"{TEMP}/test_list_*-lz4f-1f--content-size.lz4") 249*27162e4eSAndroid Build Coastguard Worker with open(f"{TEMP}/test_list_{sum(SIZES)}M-lz4f-2f--content-size.lz4", 'ab') as outfile: 250*27162e4eSAndroid Build Coastguard Worker for fname in file_list: 251*27162e4eSAndroid Build Coastguard Worker with open(fname, 'rb') as infile: 252*27162e4eSAndroid Build Coastguard Worker outfile.write(infile.read()) 253*27162e4eSAndroid Build Coastguard Worker 254*27162e4eSAndroid Build Coastguard Worker # Concatenate all files 255*27162e4eSAndroid Build Coastguard Worker file_list = glob.glob(f"{TEMP}/test_list_*.lz4") 256*27162e4eSAndroid Build Coastguard Worker with open(f"{TEMP}/test_list_concat-all.lz4", 'ab') as outfile: 257*27162e4eSAndroid Build Coastguard Worker for fname in file_list: 258*27162e4eSAndroid Build Coastguard Worker with open(fname, 'rb') as infile: 259*27162e4eSAndroid Build Coastguard Worker outfile.write(infile.read()) 260*27162e4eSAndroid Build Coastguard Worker 261*27162e4eSAndroid Build Coastguard Worker 262*27162e4eSAndroid Build Coastguard Workerif __name__ == '__main__': 263*27162e4eSAndroid Build Coastguard Worker cleanup() 264*27162e4eSAndroid Build Coastguard Worker generate_files() 265*27162e4eSAndroid Build Coastguard Worker ret = unittest.main(verbosity=2, exit=False) 266*27162e4eSAndroid Build Coastguard Worker cleanup(silent=True) 267*27162e4eSAndroid Build Coastguard Worker sys.exit(not ret.result.wasSuccessful()) 268