| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2017 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 import copy | |
| 7 import difflib | |
| 8 import itertools | |
| 9 import logging | |
| 10 import os | |
| 11 import unittest | |
| 12 import subprocess | |
| 13 import sys | |
| 14 import tempfile | |
| 15 | |
| 16 import describe | |
| 17 import file_format | |
| 18 import map2size | |
| 19 import models | |
| 20 import paths | |
| 21 | |
| 22 | |
| 23 _SCRIPT_DIR = os.path.dirname(__file__) | |
| 24 _TEST_DATA_DIR = os.path.join(_SCRIPT_DIR, 'testdata') | |
| 25 _TEST_MAP_PATH = os.path.join(_TEST_DATA_DIR, 'test.map') | |
| 26 | |
| 27 update_goldens = False | |
| 28 | |
| 29 | |
| 30 def _AssertGolden(expected_lines, actual_lines): | |
| 31 expected = list(expected_lines) | |
| 32 actual = list(l + '\n' for l in actual_lines) | |
| 33 assert actual == expected, ('Did not match .golden.\n' + | |
| 34 ''.join(difflib.unified_diff(expected, actual, 'expected', 'actual'))) | |
| 35 | |
| 36 | |
| 37 def _CompareWithGolden(func): | |
| 38 name = func.__name__.replace('test_', '') | |
| 39 golden_path = os.path.join(_TEST_DATA_DIR, name + '.golden') | |
| 40 | |
| 41 def inner(self): | |
| 42 actual_lines = func(self) | |
| 43 | |
| 44 if update_goldens: | |
| 45 with open(golden_path, 'w') as file_obj: | |
| 46 describe.WriteLines(actual_lines, file_obj.write) | |
| 47 logging.info('Wrote %s', golden_path) | |
| 48 else: | |
| 49 with open(golden_path) as file_obj: | |
| 50 _AssertGolden(file_obj, actual_lines) | |
| 51 return inner | |
| 52 | |
| 53 | |
| 54 def _RunApp(name, *args): | |
| 55 argv = [os.path.join(_SCRIPT_DIR, name), '--no-pypy'] | |
| 56 argv.extend(args) | |
| 57 return subprocess.check_output(argv).splitlines() | |
| 58 | |
| 59 | |
| 60 class IntegrationTest(unittest.TestCase): | |
| 61 size_info = None | |
| 62 | |
| 63 def _CloneSizeInfo(self): | |
| 64 if not IntegrationTest.size_info: | |
| 65 lazy_paths = paths.LazyPaths(output_directory=_TEST_DATA_DIR) | |
| 66 IntegrationTest.size_info = ( | |
| 67 map2size.CreateSizeInfo(_TEST_MAP_PATH, lazy_paths)) | |
| 68 return copy.deepcopy(IntegrationTest.size_info) | |
| 69 | |
| 70 @_CompareWithGolden | |
| 71 def test_Map2Size(self): | |
| 72 with tempfile.NamedTemporaryFile(suffix='.size') as temp_file: | |
| 73 _RunApp('map2size.py', '--output-directory', _TEST_DATA_DIR, | |
| 74 '--map-file', _TEST_MAP_PATH, '--elf-file', '', | |
| 75 '--output-file', temp_file.name) | |
| 76 size_info = map2size.LoadAndPostProcessSizeInfo(temp_file.name) | |
| 77 # Check that saving & loading is the same as directly parsing the .map. | |
| 78 expected_size_info = self._CloneSizeInfo() | |
| 79 self.assertEquals(expected_size_info.metadata, size_info.metadata) | |
| 80 expected = '\n'.join(describe.GenerateLines( | |
| 81 expected_size_info, verbose=True, recursive=True)), | |
| 82 actual = '\n'.join(describe.GenerateLines( | |
| 83 size_info, verbose=True, recursive=True)), | |
| 84 self.assertEquals(expected, actual) | |
| 85 | |
| 86 sym_strs = (repr(sym) for sym in size_info.symbols) | |
| 87 stats = describe.DescribeSizeInfoCoverage(size_info) | |
| 88 return itertools.chain(stats, sym_strs) | |
| 89 | |
| 90 def test_Map2Size_NoSourcePaths(self): | |
| 91 # Just tests that it doesn't crash. | |
| 92 with tempfile.NamedTemporaryFile(suffix='.size') as temp_file: | |
| 93 _RunApp('map2size.py', '--no-source-paths', | |
| 94 '--map-file', _TEST_MAP_PATH, '--elf-file', '', | |
| 95 '--output-file', temp_file.name) | |
| 96 map2size.LoadAndPostProcessSizeInfo(temp_file.name) | |
| 97 | |
| 98 @_CompareWithGolden | |
| 99 def test_ConsoleNullDiff(self): | |
| 100 with tempfile.NamedTemporaryFile(suffix='.size') as temp_file: | |
| 101 file_format.SaveSizeInfo(self._CloneSizeInfo(), temp_file.name) | |
| 102 return _RunApp('console.py', '--query', 'Diff(size_info1, size_info2)', | |
| 103 temp_file.name, temp_file.name) | |
| 104 | |
| 105 @_CompareWithGolden | |
| 106 def test_ActualDiff(self): | |
| 107 size_info1 = self._CloneSizeInfo() | |
| 108 size_info2 = self._CloneSizeInfo() | |
| 109 size_info1.metadata = {"foo": 1, "bar": [1,2,3], "baz": "yes"} | |
| 110 size_info2.metadata = {"foo": 1, "bar": [1,3], "baz": "yes"} | |
| 111 size_info1.symbols -= size_info1.symbols[:2] | |
| 112 size_info2.symbols -= size_info2.symbols[-3:] | |
| 113 size_info1.symbols[1].size -= 10 | |
| 114 diff = models.Diff(size_info1, size_info2) | |
| 115 return describe.GenerateLines(diff, verbose=True) | |
| 116 | |
| 117 @_CompareWithGolden | |
| 118 def test_FullDescription(self): | |
| 119 return describe.GenerateLines(self._CloneSizeInfo()) | |
| 120 | |
| 121 @_CompareWithGolden | |
| 122 def test_SymbolGroupMethods(self): | |
| 123 all_syms = self._CloneSizeInfo().symbols | |
| 124 global_syms = all_syms.WhereNameMatches('GLOBAL') | |
| 125 # Tests Filter(), Inverted(), and __sub__(). | |
| 126 non_global_syms = global_syms.Inverted() | |
| 127 self.assertEqual(non_global_syms, (all_syms - global_syms)) | |
| 128 # Tests Sorted() and __add__(). | |
| 129 self.assertEqual(all_syms.Sorted(), | |
| 130 (global_syms + non_global_syms).Sorted()) | |
| 131 # Tests GroupByNamespace() and __len__(). | |
| 132 return itertools.chain( | |
| 133 ['GroupByNamespace()'], | |
| 134 describe.GenerateLines(all_syms.GroupByNamespace()), | |
| 135 ['GroupByNamespace(depth=1)'], | |
| 136 describe.GenerateLines(all_syms.GroupByNamespace(depth=1)), | |
| 137 ['GroupByNamespace(depth=1, fallback=None)'], | |
| 138 describe.GenerateLines(all_syms.GroupByNamespace(depth=1, | |
| 139 fallback=None)), | |
| 140 ['GroupByNamespace(depth=1, min_count=2)'], | |
| 141 describe.GenerateLines(all_syms.GroupByNamespace(depth=1, min_count=2)), | |
| 142 ) | |
| 143 | |
| 144 | |
| 145 def main(): | |
| 146 argv = sys.argv | |
| 147 if len(argv) > 1 and argv[1] == '--update': | |
| 148 argv.pop(0) | |
| 149 global update_goldens | |
| 150 update_goldens = True | |
| 151 | |
| 152 unittest.main(argv=argv, verbosity=2) | |
| 153 | |
| 154 | |
| 155 if __name__ == '__main__': | |
| 156 main() | |
| OLD | NEW |