| Index: tools/sanitizers/sancov_formatter_test.py
|
| diff --git a/tools/sanitizers/sancov_formatter_test.py b/tools/sanitizers/sancov_formatter_test.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4ed61848c0557f59026ff4b9a2259e3851613ec0
|
| --- /dev/null
|
| +++ b/tools/sanitizers/sancov_formatter_test.py
|
| @@ -0,0 +1,159 @@
|
| +# Copyright 2016 the V8 project authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +# Requires python-coverage. Native python coverage version >= 3.7.1 should
|
| +# be installed to get the best speed.
|
| +
|
| +import copy
|
| +import coverage
|
| +import logging
|
| +import os
|
| +import sys
|
| +import unittest
|
| +
|
| +
|
| +# Directory of this file.
|
| +LOCATION = os.path.dirname(os.path.abspath(__file__))
|
| +
|
| +# V8 checkout directory.
|
| +BASE_DIR = os.path.dirname(os.path.dirname(LOCATION))
|
| +
|
| +# Executable location.
|
| +BUILD_DIR = os.path.join(BASE_DIR, 'out', 'Release')
|
| +
|
| +def abs_line(line):
|
| + """Absolute paths as output by the llvm symbolizer."""
|
| + return '%s/%s' % (BUILD_DIR, line)
|
| +
|
| +
|
| +#------------------------------------------------------------------------------
|
| +
|
| +# Data for test_process_symbolizer_output. This simulates output from the
|
| +# llvm symbolizer. The paths are not normlized.
|
| +SYMBOLIZER_OUTPUT = (
|
| + abs_line('../../src/foo.cc:87:7\n') +
|
| + abs_line('../../src/foo.cc:92:0\n') + # Test sorting.
|
| + abs_line('../../src/baz/bar.h:1234567:0\n') + # Test large line numbers.
|
| + abs_line('../../src/foo.cc:92:0\n') + # Test duplicates.
|
| + abs_line('../../src/baz/bar.h:0:0\n') + # Test subdirs.
|
| + '/usr/include/cool_stuff.h:14:2\n' + # Test dropping absolute paths.
|
| + abs_line('../../src/foo.cc:87:10\n') + # Test dropping character indexes.
|
| + abs_line('../../third_party/icu.cc:0:0\n') + # Test dropping excluded dirs.
|
| + abs_line('../../src/baz/bar.h:11:0\n')
|
| +)
|
| +
|
| +# The expected post-processed output maps relative file names to line numbers.
|
| +# The numbers are sorted and unique.
|
| +EXPECTED_PROCESSED_OUTPUT = {
|
| + 'src/baz/bar.h': [0, 11, 1234567],
|
| + 'src/foo.cc': [87, 92],
|
| +}
|
| +
|
| +
|
| +#------------------------------------------------------------------------------
|
| +
|
| +# Data for test_merge_instrumented_line_results. A list of absolute paths to
|
| +# all executables.
|
| +EXE_LIST = [
|
| + '/path/to/d8',
|
| + '/path/to/cctest',
|
| + '/path/to/unittests',
|
| +]
|
| +
|
| +# Post-processed llvm symbolizer output as returned by
|
| +# process_symbolizer_output. These are lists of this output for merging.
|
| +INSTRUMENTED_LINE_RESULTS = [
|
| + {
|
| + 'src/baz/bar.h': [0, 3, 7],
|
| + 'src/foo.cc': [11],
|
| + },
|
| + {
|
| + 'src/baz/bar.h': [3, 7, 8],
|
| + 'src/baz.cc': [2],
|
| + 'src/foo.cc': [1, 92],
|
| + },
|
| + {
|
| + 'src/baz.cc': [1],
|
| + 'src/foo.cc': [92, 93],
|
| + },
|
| +]
|
| +
|
| +# This shows initial instrumentation. No lines are covered, hence,
|
| +# the coverage mask is 0 for all lines. The line tuples remain sorted by
|
| +# line number and contain no duplicates.
|
| +EXPECTED_INSTRUMENTED_LINES_DATA = {
|
| + 'version': 1,
|
| + 'tests': ['cctest', 'd8', 'unittests'],
|
| + 'files': {
|
| + 'src/baz/bar.h': [[0, 0], [3, 0], [7, 0], [8, 0]],
|
| + 'src/baz.cc': [[1, 0], [2, 0]],
|
| + 'src/foo.cc': [[1, 0], [11, 0], [92, 0], [93, 0]],
|
| + },
|
| +}
|
| +
|
| +
|
| +#------------------------------------------------------------------------------
|
| +
|
| +# Data for test_merge_covered_line_results. List of post-processed
|
| +# llvm-symbolizer output as a tuple including the executable name of each data
|
| +# set.
|
| +COVERED_LINE_RESULTS = [
|
| + ({
|
| + 'src/baz/bar.h': [3, 7],
|
| + 'src/foo.cc': [11],
|
| + }, 'd8'),
|
| + ({
|
| + 'src/baz/bar.h': [3, 7],
|
| + 'src/baz.cc': [2],
|
| + 'src/foo.cc': [1],
|
| + }, 'cctest'),
|
| + ({
|
| + 'src/foo.cc': [92],
|
| + 'src/baz.cc': [2],
|
| + }, 'unittests'),
|
| +]
|
| +
|
| +# This shows initial instrumentation + coverage. The mask bits are:
|
| +# cctest: 1, d8: 2, unittests:4. So a line covered by cctest and unittests
|
| +# has a coverage mask of 0b101, e.g. line 2 in src/baz.cc.
|
| +EXPECTED_COVERED_LINES_DATA = {
|
| + 'version': 1,
|
| + 'tests': ['cctest', 'd8', 'unittests'],
|
| + 'files': {
|
| + 'src/baz/bar.h': [[0, 0b0], [3, 0b11], [7, 0b11], [8, 0b0]],
|
| + 'src/baz.cc': [[1, 0b0], [2, 0b101]],
|
| + 'src/foo.cc': [[1, 0b1], [11, 0b10], [92, 0b100], [93, 0b0]],
|
| + },
|
| +}
|
| +
|
| +
|
| +class FormatterTests(unittest.TestCase):
|
| + @classmethod
|
| + def setUpClass(cls):
|
| + sys.path.append(LOCATION)
|
| + cls._cov = coverage.coverage(
|
| + include=([os.path.join(LOCATION, 'sancov_formatter.py')]))
|
| + cls._cov.start()
|
| + import sancov_formatter
|
| + global sancov_formatter
|
| +
|
| + @classmethod
|
| + def tearDownClass(cls):
|
| + cls._cov.stop()
|
| + cls._cov.report()
|
| +
|
| + def test_process_symbolizer_output(self):
|
| + result = sancov_formatter.process_symbolizer_output(SYMBOLIZER_OUTPUT)
|
| + self.assertEquals(EXPECTED_PROCESSED_OUTPUT, result)
|
| +
|
| + def test_merge_instrumented_line_results(self):
|
| + result = sancov_formatter.merge_instrumented_line_results(
|
| + EXE_LIST, INSTRUMENTED_LINE_RESULTS)
|
| + self.assertEquals(EXPECTED_INSTRUMENTED_LINES_DATA, result)
|
| +
|
| + def test_merge_covered_line_results(self):
|
| + data = copy.deepcopy(EXPECTED_INSTRUMENTED_LINES_DATA)
|
| + sancov_formatter.merge_covered_line_results(
|
| + data, COVERED_LINE_RESULTS)
|
| + self.assertEquals(EXPECTED_COVERED_LINES_DATA, data)
|
|
|