1 #!/usr/bin/env python 2 # Copyright 2014 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 """Check that explain_binary_size_delta seems to work.""" 7 8 import cStringIO 9 import sys 10 import unittest 11 12 import explain_binary_size_delta 13 14 15 class ExplainBinarySizeDeltaTest(unittest.TestCase): 16 17 def testCompare(self): 18 # List entries have form: symbol_name, symbol_type, symbol_size, file_path 19 symbol_list1 = ( 20 # File with one symbol, left as-is. 21 ( 'unchanged', 't', 1000, '/file_unchanged' ), 22 # File with one symbol, changed. 23 ( 'changed', 't', 1000, '/file_all_changed' ), 24 # File with one symbol, deleted. 25 ( 'removed', 't', 1000, '/file_all_deleted' ), 26 # File with two symbols, one unchanged, one changed, same bucket 27 ( 'unchanged', 't', 1000, '/file_pair_unchanged_changed' ), 28 ( 'changed', 't', 1000, '/file_pair_unchanged_changed' ), 29 # File with two symbols, one unchanged, one deleted, same bucket 30 ( 'unchanged', 't', 1000, '/file_pair_unchanged_removed' ), 31 ( 'removed', 't', 1000, '/file_pair_unchanged_removed' ), 32 # File with two symbols, one unchanged, one added, same bucket 33 ( 'unchanged', 't', 1000, '/file_pair_unchanged_added' ), 34 # File with two symbols, one unchanged, one changed, different bucket 35 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_changed' ), 36 ( 'changed', '@', 1000, '/file_pair_unchanged_diffbuck_changed' ), 37 # File with two symbols, one unchanged, one deleted, different bucket 38 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_removed' ), 39 ( 'removed', '@', 1000, '/file_pair_unchanged_diffbuck_removed' ), 40 # File with two symbols, one unchanged, one added, different bucket 41 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_added' ), 42 # File with four symbols, one added, one removed, 43 # one changed, one unchanged 44 ( 'size_changed', 't', 1000, '/file_tetra' ), 45 ( 'removed', 't', 1000, '/file_tetra' ), 46 ( 'unchanged', 't', 1000, '/file_tetra' ), 47 ) 48 49 symbol_list2 = ( 50 # File with one symbol, left as-is. 51 ( 'unchanged', 't', 1000, '/file_unchanged' ), 52 # File with one symbol, changed. 53 ( 'changed', 't', 2000, '/file_all_changed' ), 54 # File with two symbols, one unchanged, one changed, same bucket 55 ( 'unchanged', 't', 1000, '/file_pair_unchanged_changed' ), 56 ( 'changed', 't', 2000, '/file_pair_unchanged_changed' ), 57 # File with two symbols, one unchanged, one deleted, same bucket 58 ( 'unchanged', 't', 1000, '/file_pair_unchanged_removed' ), 59 # File with two symbols, one unchanged, one added, same bucket 60 ( 'unchanged', 't', 1000, '/file_pair_unchanged_added' ), 61 ( 'added', 't', 1000, '/file_pair_unchanged_added' ), 62 # File with two symbols, one unchanged, one changed, different bucket 63 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_changed' ), 64 ( 'changed', '@', 2000, '/file_pair_unchanged_diffbuck_changed' ), 65 # File with two symbols, one unchanged, one deleted, different bucket 66 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_removed' ), 67 # File with two symbols, one unchanged, one added, different bucket 68 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_added' ), 69 ( 'added', '@', 1000, '/file_pair_unchanged_diffbuck_added' ), 70 # File with four symbols, one added, one removed, 71 # one changed, one unchanged 72 ( 'size_changed', 't', 2000, '/file_tetra' ), 73 ( 'unchanged', 't', 1000, '/file_tetra' ), 74 ( 'added', 't', 1000, '/file_tetra' ), 75 # New file with one symbol added 76 ( 'added', 't', 1000, '/file_new' ), 77 ) 78 79 # Here we go 80 (added, removed, changed, unchanged) = \ 81 explain_binary_size_delta.Compare(symbol_list1, symbol_list2) 82 83 # File with one symbol, left as-is. 84 assert ('/file_unchanged', 't', 'unchanged', 1000, 1000) in unchanged 85 # File with one symbol, changed. 86 assert ('/file_all_changed', 't', 'changed', 1000, 2000) in changed 87 # File with one symbol, deleted. 88 assert ('/file_all_deleted', 't', 'removed', 1000, None) in removed 89 # New file with one symbol added 90 assert ('/file_new', 't', 'added', None, 1000) in added 91 # File with two symbols, one unchanged, one changed, same bucket 92 assert ('/file_pair_unchanged_changed', 93 't', 'unchanged', 1000, 1000) in unchanged 94 assert ('/file_pair_unchanged_changed', 95 't', 'changed', 1000, 2000) in changed 96 # File with two symbols, one unchanged, one removed, same bucket 97 assert ('/file_pair_unchanged_removed', 98 't', 'unchanged', 1000, 1000) in unchanged 99 assert ('/file_pair_unchanged_removed', 100 't', 'removed', 1000, None) in removed 101 # File with two symbols, one unchanged, one added, same bucket 102 assert ('/file_pair_unchanged_added', 103 't', 'unchanged', 1000, 1000) in unchanged 104 assert ('/file_pair_unchanged_added', 105 't', 'added', None, 1000) in added 106 # File with two symbols, one unchanged, one changed, different bucket 107 assert ('/file_pair_unchanged_diffbuck_changed', 108 't', 'unchanged', 1000, 1000) in unchanged 109 assert ('/file_pair_unchanged_diffbuck_changed', 110 '@', 'changed', 1000, 2000) in changed 111 # File with two symbols, one unchanged, one removed, different bucket 112 assert ('/file_pair_unchanged_diffbuck_removed', 113 't', 'unchanged', 1000, 1000) in unchanged 114 assert ('/file_pair_unchanged_diffbuck_removed', 115 '@', 'removed', 1000, None) in removed 116 # File with two symbols, one unchanged, one added, different bucket 117 assert ('/file_pair_unchanged_diffbuck_added', 118 't', 'unchanged', 1000, 1000) in unchanged 119 assert ('/file_pair_unchanged_diffbuck_added', 120 '@', 'added', None, 1000) in added 121 # File with four symbols, one added, one removed, one changed, one unchanged 122 assert ('/file_tetra', 't', 'size_changed', 1000, 2000) in changed 123 assert ('/file_tetra', 't', 'unchanged', 1000, 1000) in unchanged 124 assert ('/file_tetra', 't', 'added', None, 1000) in added 125 assert ('/file_tetra', 't', 'removed', 1000, None) in removed 126 127 # Now check final stats. 128 orig_stdout = sys.stdout 129 output_collector = cStringIO.StringIO() 130 sys.stdout = output_collector 131 try: 132 explain_binary_size_delta.CrunchStats(added, removed, changed, 133 unchanged, True, True) 134 finally: 135 sys.stdout = orig_stdout 136 result = output_collector.getvalue() 137 138 expected_output = """\ 139 Total change: +4000 bytes 140 ========================= 141 4 added, totalling +4000 bytes across 4 sources 142 4 removed, totalling -4000 bytes across 4 sources 143 4 grown, for a net change of +4000 bytes \ 144 (4000 bytes before, 8000 bytes after) across 4 sources 145 8 unchanged, totalling 8000 bytes 146 Source stats: 147 11 sources encountered. 148 1 completely new. 149 1 removed completely. 150 8 partially changed. 151 1 completely unchanged. 152 Per-source Analysis: 153 154 -------------------------------------------------- 155 +1000 - Source: /file_new - (gained 1000, lost 0) 156 -------------------------------------------------- 157 New symbols: 158 +1000: added type=t, size=1000 bytes 159 160 --------------------------------------------------------------------- 161 +1000 - Source: /file_pair_unchanged_changed - (gained 1000, lost 0) 162 --------------------------------------------------------------------- 163 Grown symbols: 164 +1000: changed type=t, (was 1000 bytes, now 2000 bytes) 165 166 ---------------------------------------------------------------------------- 167 +1000 - Source: /file_pair_unchanged_diffbuck_added - (gained 1000, lost 0) 168 ---------------------------------------------------------------------------- 169 New symbols: 170 +1000: added type=@, size=1000 bytes 171 172 ------------------------------------------------------------------- 173 +1000 - Source: /file_pair_unchanged_added - (gained 1000, lost 0) 174 ------------------------------------------------------------------- 175 New symbols: 176 +1000: added type=t, size=1000 bytes 177 178 ------------------------------------------------------------------------------ 179 +1000 - Source: /file_pair_unchanged_diffbuck_changed - (gained 1000, lost 0) 180 ------------------------------------------------------------------------------ 181 Grown symbols: 182 +1000: changed type=@, (was 1000 bytes, now 2000 bytes) 183 184 ---------------------------------------------------------- 185 +1000 - Source: /file_all_changed - (gained 1000, lost 0) 186 ---------------------------------------------------------- 187 Grown symbols: 188 +1000: changed type=t, (was 1000 bytes, now 2000 bytes) 189 190 ------------------------------------------------------- 191 +1000 - Source: /file_tetra - (gained 2000, lost 1000) 192 ------------------------------------------------------- 193 New symbols: 194 +1000: added type=t, size=1000 bytes 195 Removed symbols: 196 -1000: removed type=t, size=1000 bytes 197 Grown symbols: 198 +1000: size_changed type=t, (was 1000 bytes, now 2000 bytes) 199 200 ------------------------------------------------------------------------------ 201 -1000 - Source: /file_pair_unchanged_diffbuck_removed - (gained 0, lost 1000) 202 ------------------------------------------------------------------------------ 203 Removed symbols: 204 -1000: removed type=@, size=1000 bytes 205 206 ---------------------------------------------------------- 207 -1000 - Source: /file_all_deleted - (gained 0, lost 1000) 208 ---------------------------------------------------------- 209 Removed symbols: 210 -1000: removed type=t, size=1000 bytes 211 212 --------------------------------------------------------------------- 213 -1000 - Source: /file_pair_unchanged_removed - (gained 0, lost 1000) 214 --------------------------------------------------------------------- 215 Removed symbols: 216 -1000: removed type=t, size=1000 bytes 217 """ 218 219 self.maxDiff = None 220 self.assertMultiLineEqual(expected_output, result) 221 print "explain_binary_size_delta_unittest: All tests passed" 222 223 224 def testCompareStringEntries(self): 225 # List entries have form: symbol_name, symbol_type, symbol_size, file_path 226 symbol_list1 = ( 227 # File with one string. 228 ( '.L.str107', 'r', 8, '/file_with_strs' ), 229 ) 230 231 symbol_list2 = ( 232 # Two files with one string each, same name. 233 ( '.L.str107', 'r', 8, '/file_with_strs' ), 234 ( '.L.str107', 'r', 7, '/other_file_with_strs' ), 235 ) 236 237 # Here we go 238 (added, removed, changed, unchanged) = \ 239 explain_binary_size_delta.Compare(symbol_list1, symbol_list2) 240 241 242 # Now check final stats. 243 orig_stdout = sys.stdout 244 output_collector = cStringIO.StringIO() 245 sys.stdout = output_collector 246 try: 247 explain_binary_size_delta.CrunchStats(added, removed, changed, 248 unchanged, True, True) 249 finally: 250 sys.stdout = orig_stdout 251 result = output_collector.getvalue() 252 253 expected_output = """\ 254 Total change: +7 bytes 255 ====================== 256 1 added, totalling +7 bytes across 1 sources 257 1 unchanged, totalling 8 bytes 258 Source stats: 259 2 sources encountered. 260 1 completely new. 261 0 removed completely. 262 0 partially changed. 263 1 completely unchanged. 264 Per-source Analysis: 265 266 -------------------------------------------------------- 267 +7 - Source: /other_file_with_strs - (gained 7, lost 0) 268 -------------------------------------------------------- 269 New symbols: 270 +7: .L.str107 type=r, size=7 bytes 271 """ 272 273 self.maxDiff = None 274 self.assertMultiLineEqual(expected_output, result) 275 print "explain_binary_size_delta_unittest: All tests passed" 276 277 def testCompareStringEntriesWithNoFile(self): 278 # List entries have form: symbol_name, symbol_type, symbol_size, file_path 279 symbol_list1 = ( 280 ( '.L.str104', 'r', 21, '??' ), # Will change size. 281 ( '.L.str105', 'r', 17, '??' ), # Same. 282 ( '.L.str106', 'r', 13, '??' ), # Will be removed. 283 ( '.L.str106', 'r', 3, '??' ), # Same. 284 ( '.L.str106', 'r', 3, '??' ), # Will be removed. 285 ( '.L.str107', 'r', 8, '??' ), # Will be removed (other sizes). 286 ) 287 288 symbol_list2 = ( 289 # Two files with one string each, same name. 290 ( '.L.str104', 'r', 19, '??' ), # Changed. 291 ( '.L.str105', 'r', 11, '??' ), # New size for multi-symbol. 292 ( '.L.str105', 'r', 17, '??' ), # New of same size for multi-symbol. 293 ( '.L.str105', 'r', 17, '??' ), # Same. 294 ( '.L.str106', 'r', 3, '??' ), # Same. 295 ( '.L.str107', 'r', 5, '??' ), # New size for symbol. 296 ( '.L.str107', 'r', 7, '??' ), # New size for symbol. 297 ( '.L.str108', 'r', 8, '??' ), # New symbol. 298 ) 299 300 # Here we go 301 (added, removed, changed, unchanged) = \ 302 explain_binary_size_delta.Compare(symbol_list1, symbol_list2) 303 304 305 # Now check final stats. 306 orig_stdout = sys.stdout 307 output_collector = cStringIO.StringIO() 308 sys.stdout = output_collector 309 try: 310 explain_binary_size_delta.CrunchStats(added, removed, changed, 311 unchanged, True, True) 312 finally: 313 sys.stdout = orig_stdout 314 result = output_collector.getvalue() 315 316 expected_output = """\ 317 Total change: +22 bytes 318 ======================= 319 5 added, totalling +48 bytes across 1 sources 320 3 removed, totalling -24 bytes across 1 sources 321 1 shrunk, for a net change of -2 bytes (21 bytes before, 19 bytes after) \ 322 across 1 sources 323 2 unchanged, totalling 20 bytes 324 Source stats: 325 1 sources encountered. 326 0 completely new. 327 0 removed completely. 328 1 partially changed. 329 0 completely unchanged. 330 Per-source Analysis: 331 332 ---------------------------------------- 333 +22 - Source: ?? - (gained 48, lost 26) 334 ---------------------------------------- 335 New symbols: 336 +17: .L.str105 type=r, size=17 bytes 337 +11: .L.str105 type=r, size=11 bytes 338 +8: .L.str108 type=r, size=8 bytes 339 +7: .L.str107 type=r, size=7 bytes 340 +5: .L.str107 type=r, size=5 bytes 341 Removed symbols: 342 -3: .L.str106 type=r, size=3 bytes 343 -8: .L.str107 type=r, size=8 bytes 344 -13: .L.str106 type=r, size=13 bytes 345 Shrunk symbols: 346 -2: .L.str104 type=r, (was 21 bytes, now 19 bytes) 347 """ 348 349 self.maxDiff = None 350 self.assertMultiLineEqual(expected_output, result) 351 print "explain_binary_size_delta_unittest: All tests passed" 352 353 if __name__ == '__main__': 354 unittest.main() 355