Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: tools/binary_size/libsupersize/integration_test.py

Issue 2851473003: supersize: Track symbol aliases and shared symbols (Closed)
Patch Set: fix regression in calculate padding introduced in ps3 Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/binary_size/libsupersize/html_report.py ('k') | tools/binary_size/libsupersize/linker_map_parser.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/binary_size/libsupersize/integration_test.py
diff --git a/tools/binary_size/libsupersize/integration_test.py b/tools/binary_size/libsupersize/integration_test.py
index e9ad9254a8ce250353f30d5f69efff4dc323d461..d0f6702cd4f5e1af6095e3d47e6fab17cf469480 100755
--- a/tools/binary_size/libsupersize/integration_test.py
+++ b/tools/binary_size/libsupersize/integration_test.py
@@ -3,6 +3,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import contextlib
import copy
import difflib
import glob
@@ -10,20 +11,25 @@ import itertools
import logging
import os
import unittest
+import re
import subprocess
import sys
import tempfile
import archive
import describe
+import diff
import file_format
import models
-import paths
_SCRIPT_DIR = os.path.dirname(__file__)
_TEST_DATA_DIR = os.path.join(_SCRIPT_DIR, 'testdata')
+_TEST_OUTPUT_DIR = os.path.join(_TEST_DATA_DIR, 'mock_output_directory')
+_TEST_TOOL_PREFIX = os.path.join(
+ os.path.abspath(_TEST_DATA_DIR), 'mock_toolchain', '')
_TEST_MAP_PATH = os.path.join(_TEST_DATA_DIR, 'test.map')
+_TEST_ELF_PATH = os.path.join(_TEST_OUTPUT_DIR, 'elf')
update_goldens = False
@@ -35,66 +41,117 @@ def _AssertGolden(expected_lines, actual_lines):
''.join(difflib.unified_diff(expected, actual, 'expected', 'actual')))
-def _CompareWithGolden(func):
- name = func.__name__.replace('test_', '')
- golden_path = os.path.join(_TEST_DATA_DIR, name + '.golden')
+def _CompareWithGolden(name=None):
+ def real_decorator(func):
+ basename = name
+ if not basename:
+ basename = func.__name__.replace('test_', '')
+ golden_path = os.path.join(_TEST_DATA_DIR, basename + '.golden')
- def inner(self):
- actual_lines = func(self)
+ def inner(self):
+ actual_lines = func(self)
+ actual_lines = (re.sub(r'(elf_mtime=).*', r'\1{redacted}', l)
+ for l in actual_lines)
- if update_goldens:
- with open(golden_path, 'w') as file_obj:
- describe.WriteLines(actual_lines, file_obj.write)
- logging.info('Wrote %s', golden_path)
- else:
- with open(golden_path) as file_obj:
- _AssertGolden(file_obj, actual_lines)
- return inner
+ if update_goldens:
+ with open(golden_path, 'w') as file_obj:
+ describe.WriteLines(actual_lines, file_obj.write)
+ logging.info('Wrote %s', golden_path)
+ else:
+ with open(golden_path) as file_obj:
+ _AssertGolden(file_obj, actual_lines)
+ return inner
+ return real_decorator
+
+
+@contextlib.contextmanager
+def _AddMocksToPath():
+ prev_path = os.environ['PATH']
+ os.environ['PATH'] = _TEST_TOOL_PREFIX[:-1] + os.path.pathsep + prev_path
+ yield
+ os.environ['PATH'] = prev_path
-def _RunApp(name, *args):
+def _RunApp(name, args, debug_measures=False):
argv = [os.path.join(_SCRIPT_DIR, 'main.py'), name, '--no-pypy']
argv.extend(args)
- return subprocess.check_output(argv).splitlines()
+ with _AddMocksToPath():
+ env = None
+ if debug_measures:
+ env = os.environ.copy()
+ env['SUPERSIZE_DISABLE_ASYNC'] = '1'
+ env['SUPERSIZE_MEASURE_GZIP'] = '1'
+
+ return subprocess.check_output(argv, env=env).splitlines()
class IntegrationTest(unittest.TestCase):
- size_info = None
+ cached_size_info = [None, None, None]
- def _CloneSizeInfo(self):
- if not IntegrationTest.size_info:
- lazy_paths = paths.LazyPaths(output_directory=_TEST_DATA_DIR)
- IntegrationTest.size_info = (
- archive.CreateSizeInfo(_TEST_MAP_PATH, lazy_paths))
- return copy.deepcopy(IntegrationTest.size_info)
+ def _CloneSizeInfo(self, use_output_directory=True, use_elf=True):
+ assert not use_elf or use_output_directory
+ i = int(use_output_directory) + int(use_elf)
+ if not IntegrationTest.cached_size_info[i]:
+ elf_path = _TEST_ELF_PATH if use_elf else None
+ output_directory = _TEST_OUTPUT_DIR if use_output_directory else None
+ IntegrationTest.cached_size_info[i] = archive.CreateSizeInfo(
+ _TEST_MAP_PATH, elf_path, _TEST_TOOL_PREFIX, output_directory)
+ if use_elf:
+ with _AddMocksToPath():
+ IntegrationTest.cached_size_info[i].metadata = archive.CreateMetadata(
+ _TEST_MAP_PATH, elf_path, None, _TEST_TOOL_PREFIX,
+ output_directory)
+ return copy.deepcopy(IntegrationTest.cached_size_info[i])
- @_CompareWithGolden
- def test_Archive(self):
+ def _DoArchiveTest(self, use_output_directory=True, use_elf=True,
+ debug_measures=False):
with tempfile.NamedTemporaryFile(suffix='.size') as temp_file:
- _RunApp('archive', temp_file.name, '--output-directory', _TEST_DATA_DIR,
- '--map-file', _TEST_MAP_PATH)
+ args = [temp_file.name, '--map-file', _TEST_MAP_PATH]
+ if use_output_directory:
+ # Let autodetection find output_directory when --elf-file is used.
+ if not use_elf:
+ args += ['--output-directory', _TEST_OUTPUT_DIR]
+ else:
+ args += ['--no-source-paths']
+ if use_elf:
+ args += ['--elf-file', _TEST_ELF_PATH]
+ _RunApp('archive', args, debug_measures=debug_measures)
size_info = archive.LoadAndPostProcessSizeInfo(temp_file.name)
# Check that saving & loading is the same as directly parsing the .map.
- expected_size_info = self._CloneSizeInfo()
+ expected_size_info = self._CloneSizeInfo(
+ use_output_directory=use_output_directory, use_elf=use_elf)
self.assertEquals(expected_size_info.metadata, size_info.metadata)
- expected = '\n'.join(describe.GenerateLines(
- expected_size_info, verbose=True, recursive=True)),
- actual = '\n'.join(describe.GenerateLines(
- size_info, verbose=True, recursive=True)),
+ expected = list(describe.GenerateLines(
+ expected_size_info, verbose=True, recursive=True))
+ actual = list(describe.GenerateLines(
+ size_info, verbose=True, recursive=True))
self.assertEquals(expected, actual)
sym_strs = (repr(sym) for sym in size_info.symbols)
stats = describe.DescribeSizeInfoCoverage(size_info)
- return itertools.chain(stats, sym_strs)
+ if size_info.metadata:
+ metadata = describe.DescribeMetadata(size_info.metadata)
+ else:
+ metadata = []
+ return itertools.chain(metadata, stats, sym_strs)
- def test_Archive_NoSourcePaths(self):
- # Just tests that it doesn't crash.
- with tempfile.NamedTemporaryFile(suffix='.size') as temp_file:
- _RunApp('archive', temp_file.name, '--no-source-paths',
- '--map-file', _TEST_MAP_PATH)
- archive.LoadAndPostProcessSizeInfo(temp_file.name)
+ @_CompareWithGolden()
+ def test_Archive(self):
+ return self._DoArchiveTest(use_output_directory=False, use_elf=False)
+
+ @_CompareWithGolden()
+ def test_Archive_OutputDirectory(self):
+ return self._DoArchiveTest(use_elf=False)
+
+ @_CompareWithGolden()
+ def test_Archive_Elf(self):
+ return self._DoArchiveTest()
- @_CompareWithGolden
+ @_CompareWithGolden(name='Archive_Elf')
+ def test_Archive_Elf_DebugMeasures(self):
+ return self._DoArchiveTest(debug_measures=True)
+
+ @_CompareWithGolden()
def test_Console(self):
with tempfile.NamedTemporaryFile(suffix='.size') as size_file, \
tempfile.NamedTemporaryFile(suffix='.txt') as output_file:
@@ -104,34 +161,85 @@ class IntegrationTest(unittest.TestCase):
'ExpandRegex("_foo_")',
'Print(size_info, to_file=%r)' % output_file.name,
]
- ret = _RunApp('console', size_file.name, '--query', '; '.join(query))
+ ret = _RunApp('console', [size_file.name, '--query', '; '.join(query)])
with open(output_file.name) as f:
ret.extend(l.rstrip() for l in f)
return ret
- @_CompareWithGolden
+ @_CompareWithGolden()
def test_Diff_NullDiff(self):
with tempfile.NamedTemporaryFile(suffix='.size') as temp_file:
file_format.SaveSizeInfo(self._CloneSizeInfo(), temp_file.name)
- return _RunApp('diff', temp_file.name, temp_file.name)
+ return _RunApp('diff', [temp_file.name, temp_file.name])
- @_CompareWithGolden
- def test_ActualDiff(self):
- size_info1 = self._CloneSizeInfo()
- size_info2 = self._CloneSizeInfo()
+ @_CompareWithGolden()
+ def test_Diff_Basic(self):
+ size_info1 = self._CloneSizeInfo(use_elf=False)
+ size_info2 = self._CloneSizeInfo(use_elf=False)
size_info1.metadata = {"foo": 1, "bar": [1,2,3], "baz": "yes"}
size_info2.metadata = {"foo": 1, "bar": [1,3], "baz": "yes"}
size_info1.symbols -= size_info1.symbols[:2]
size_info2.symbols -= size_info2.symbols[-3:]
size_info1.symbols[1].size -= 10
- diff = models.Diff(size_info1, size_info2)
- return describe.GenerateLines(diff, verbose=True)
+ d = diff.Diff(size_info1, size_info2)
+ return describe.GenerateLines(d, verbose=True)
+
+ def test_Diff_Aliases1(self):
+ symbols1 = self._CloneSizeInfo().symbols
+ symbols2 = self._CloneSizeInfo().symbols
+
+ # Removing 1 alias should not change the size.
+ a1, _, _ = symbols2.Filter(lambda s: s.num_aliases == 3)[0].aliases
+ symbols2 -= [a1]
+ a1.aliases.remove(a1)
+ d = diff.Diff(symbols1, symbols2)
+ self.assertEquals(d.size, 0)
+ self.assertEquals(d.removed_count, 1)
+
+ # Adding one alias should not change size.
+ d = diff.Diff(symbols2, symbols1)
+ self.assertEquals(d.size, 0)
+ self.assertEquals(d.added_count, 1)
+
+ def test_Diff_Aliases2(self):
+ symbols1 = self._CloneSizeInfo().symbols
+ symbols2 = self._CloneSizeInfo().symbols
+
+ # Removing 2 aliases should not change the size.
+ a1, a2, _ = symbols2.Filter(lambda s: s.num_aliases == 3)[0].aliases
+ symbols2 -= [a1, a2]
+ a1.aliases.remove(a1)
+ a1.aliases.remove(a2)
+ d = diff.Diff(symbols1, symbols2)
+ self.assertEquals(d.size, 0)
+ self.assertEquals(d.removed_count, 2)
+
+ # Adding 2 aliases should not change size.
+ d = diff.Diff(symbols2, symbols1)
+ self.assertEquals(d.size, 0)
+ self.assertEquals(d.added_count, 2)
+
+ def test_Diff_Aliases3(self):
+ symbols1 = self._CloneSizeInfo().symbols
+ symbols2 = self._CloneSizeInfo().symbols
+
+ # Removing all 3 aliases should change the size.
+ a1, a2, a3 = symbols2.Filter(lambda s: s.num_aliases == 3)[0].aliases
+ symbols2 -= [a1, a2, a3]
+ d = diff.Diff(symbols1, symbols2)
+ self.assertEquals(d.size, -a1.size)
+ self.assertEquals(d.removed_count, 3)
+
+ # Adding all 3 aliases should change size.
+ d = diff.Diff(symbols2, symbols1)
+ self.assertEquals(d.size, a1.size)
+ self.assertEquals(d.added_count, 3)
- @_CompareWithGolden
+ @_CompareWithGolden()
def test_FullDescription(self):
return describe.GenerateLines(self._CloneSizeInfo())
- @_CompareWithGolden
+ @_CompareWithGolden()
def test_SymbolGroupMethods(self):
all_syms = self._CloneSizeInfo().symbols
global_syms = all_syms.WhereNameMatches('GLOBAL')
« no previous file with comments | « tools/binary_size/libsupersize/html_report.py ('k') | tools/binary_size/libsupersize/linker_map_parser.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698