1#!/usr/bin/env vpython3 2# Copyright 2020 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import copy 7import os 8import tempfile 9from typing import MutableMapping, Optional 10import unittest 11 12import binary_size_differ 13import binary_sizes 14 15_EXAMPLE_BLOBS_BEFORE = """ 16{ 17 "web_engine": [ 18 { 19 "merkle": "77e876447dd2daaaab7048d646e87fe8b6d9fecef6cbfcc4af30b8fbfa50b881", 20 "path": "locales/ta.pak", 21 "bytes": 17916, 22 "is_counted": true, 23 "size": 16384 24 }, 25 { 26 "merkle": "5f1932b8c9fe954f3c3fdb34ab2089d2af34e5a0cef90cad41a1cd37d92234bf", 27 "path": "lib/libEGL.so", 28 "bytes": 226960, 29 "is_counted": true, 30 "size": 90112 31 }, 32 { 33 "merkle": "9822fc0dd95cdd1cc46b5c6632a928a6ad19b76ed0157397d82a2f908946fc34", 34 "path": "meta.far", 35 "bytes": 24576, 36 "is_counted": false, 37 "size": 16384 38 }, 39 { 40 "merkle": "090aed4593c4f7d04a3ad80e9971c0532dd5b1d2bdf4754202cde510a88fd220", 41 "path": "locales/ru.pak", 42 "bytes": 11903, 43 "is_counted": true, 44 "size": 16384 45 } 46 ] 47} 48""" 49 50 51class BinarySizeDifferTest(unittest.TestCase): 52 def ChangePackageSize( 53 self, 54 packages: MutableMapping[str, binary_sizes.PackageSizes], 55 name: str, 56 compressed_increase: int, 57 uncompressed_increase: Optional[int] = None): 58 if uncompressed_increase is None: 59 uncompressed_increase = compressed_increase 60 original_package = packages[name] 61 new_package = binary_sizes.PackageSizes( 62 compressed=original_package.compressed + compressed_increase, 63 uncompressed=original_package.uncompressed + uncompressed_increase) 64 packages[name] = new_package 65 66 def testComputePackageDiffs(self): 67 # TODO(crbug.com/40219667): Disabled on Windows because Windows doesn't allow opening a 68 # NamedTemporaryFile by name. 69 if os.name == 'nt': 70 return 71 72 SUCCESS = 0 73 FAILURE = 1 74 ROLLER_SIZE_WARNING = 2 75 with tempfile.NamedTemporaryFile(mode='w') as before_file: 76 before_file.write(_EXAMPLE_BLOBS_BEFORE) 77 before_file.flush() 78 blobs = binary_sizes.ReadPackageBlobsJson(before_file.name) 79 sizes = binary_sizes.GetPackageSizes(blobs) 80 binary_sizes.WritePackageSizesJson(before_file.name, sizes) 81 82 # No change. 83 growth = binary_size_differ.ComputePackageDiffs(before_file.name, 84 before_file.name) 85 self.assertEqual(growth['status_code'], SUCCESS) 86 self.assertEqual(growth['compressed']['web_engine'], 0) 87 88 after_file = tempfile.NamedTemporaryFile(mode='w', delete=True) 89 after_file.close() 90 try: 91 # Increase a blob, but below the limit. 92 other_sizes = copy.deepcopy(sizes) 93 self.ChangePackageSize(other_sizes, 'web_engine', 8 * 1024) 94 binary_sizes.WritePackageSizesJson(after_file.name, other_sizes) 95 96 growth = binary_size_differ.ComputePackageDiffs(before_file.name, 97 after_file.name) 98 self.assertEqual(growth['status_code'], SUCCESS) 99 self.assertEqual(growth['compressed']['web_engine'], 8 * 1024) 100 101 # Increase beyond the limit (adds another 8k) 102 self.ChangePackageSize(other_sizes, 'web_engine', 8 * 1024 + 1) 103 binary_sizes.WritePackageSizesJson(after_file.name, other_sizes) 104 growth = binary_size_differ.ComputePackageDiffs(before_file.name, 105 after_file.name) 106 self.assertEqual(growth['status_code'], FAILURE) 107 self.assertEqual(growth['compressed']['web_engine'], 16 * 1024 + 1) 108 self.assertIn('check failed', growth['summary']) 109 self.assertIn(f'web_engine (compressed) grew by {16 * 1024 + 1} bytes', 110 growth['summary']) 111 112 # Increase beyond the limit, but compressed does not increase. 113 binary_sizes.WritePackageSizesJson(before_file.name, other_sizes) 114 self.ChangePackageSize(other_sizes, 115 'web_engine', 116 16 * 1024 + 1, 117 uncompressed_increase=0) 118 binary_sizes.WritePackageSizesJson(after_file.name, other_sizes) 119 growth = binary_size_differ.ComputePackageDiffs(before_file.name, 120 after_file.name) 121 self.assertEqual(growth['uncompressed']['web_engine'], SUCCESS) 122 self.assertEqual(growth['status_code'], SUCCESS) 123 self.assertEqual(growth['compressed']['web_engine'], 16 * 1024 + 1) 124 125 # Increase beyond the limit, but compressed goes down. 126 binary_sizes.WritePackageSizesJson(before_file.name, other_sizes) 127 self.ChangePackageSize(other_sizes, 128 'web_engine', 129 16 * 1024 + 1, 130 uncompressed_increase=-4 * 1024) 131 binary_sizes.WritePackageSizesJson(after_file.name, other_sizes) 132 growth = binary_size_differ.ComputePackageDiffs(before_file.name, 133 after_file.name) 134 self.assertEqual(growth['status_code'], SUCCESS) 135 self.assertEqual(growth['compressed']['web_engine'], 16 * 1024 + 1) 136 137 # Increase beyond the second limit. Fails, regardless of uncompressed. 138 binary_sizes.WritePackageSizesJson(before_file.name, other_sizes) 139 self.ChangePackageSize(other_sizes, 140 'web_engine', 141 100 * 1024 + 1, 142 uncompressed_increase=-4 * 1024) 143 binary_sizes.WritePackageSizesJson(after_file.name, other_sizes) 144 growth = binary_size_differ.ComputePackageDiffs(before_file.name, 145 after_file.name) 146 self.assertEqual(growth['status_code'], FAILURE) 147 self.assertEqual(growth['compressed']['web_engine'], 100 * 1024 + 1) 148 149 # Increase beyond the second limit, but roller authored CL. 150 binary_sizes.WritePackageSizesJson(before_file.name, other_sizes) 151 self.ChangePackageSize(other_sizes, 152 'web_engine', 153 100 * 1024 + 1, 154 uncompressed_increase=-4 * 1024) 155 binary_sizes.WritePackageSizesJson(after_file.name, other_sizes) 156 growth = binary_size_differ.ComputePackageDiffs(before_file.name, 157 after_file.name, 158 author='big-autoroller') 159 self.assertEqual(growth['status_code'], ROLLER_SIZE_WARNING) 160 self.assertEqual(growth['compressed']['web_engine'], 100 * 1024 + 1) 161 self.assertNotIn('check failed', growth['summary']) 162 self.assertIn('growth by an autoroller will be ignored', 163 growth['summary']) 164 self.assertIn(f'web_engine (compressed) grew by {100 * 1024 + 1} bytes', 165 growth['summary']) 166 finally: 167 os.remove(after_file.name) 168 169 170if __name__ == '__main__': 171 unittest.main() 172