aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2020-07-13 17:53:01 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-07-13 17:53:01 +0000
commitcb290e283dc4f8b0b9b83963507831d11ba7b92c (patch)
treed03f477e6aca73e0795c2bfc64026a3cc5af19f4
parenta089bf3939184223f72ec5c8e02b18b5e0251ea9 (diff)
parent1c12faf75d74e933af10361bb5d264f28dad4747 (diff)
downloadgoogle-benchmark-cb290e283dc4f8b0b9b83963507831d11ba7b92c.tar.gz
Upgrade google-benchmark to 37177a84b7e8d33696ea1e1854513cb0de3b4dc3 am: 1c12faf75d
Original change: https://android-review.googlesource.com/c/platform/external/google-benchmark/+/1361218 Change-Id: I93b588e5cb8f35b4a64e9083557b47c4c6b1a9f9
-rw-r--r--.gitignore4
-rw-r--r--.travis.yml4
-rw-r--r--METADATA6
-rw-r--r--WORKSPACE7
-rw-r--r--bindings/python/google_benchmark/BUILD (renamed from bindings/python/benchmark/BUILD)4
-rw-r--r--bindings/python/google_benchmark/__init__.py (renamed from bindings/python/benchmark/__init__.py)9
-rw-r--r--bindings/python/google_benchmark/benchmark.cc (renamed from bindings/python/benchmark/benchmark.cc)3
-rw-r--r--bindings/python/google_benchmark/example.py (renamed from bindings/python/benchmark/example.py)20
-rw-r--r--docs/releasing.md (renamed from releasing.md)0
-rw-r--r--docs/tools.md6
-rw-r--r--mingw.py320
-rw-r--r--setup.py7
-rw-r--r--src/timers.cc69
-rw-r--r--test/reporter_output_test.cc2
-rwxr-xr-xtools/compare.py10
-rw-r--r--tools/requirements.txt1
16 files changed, 113 insertions, 359 deletions
diff --git a/.gitignore b/.gitignore
index a7716e3..be55d77 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,3 +60,7 @@ CMakeSettings.json
# Visual Studio Code cache/options directory
.vscode/
+
+# Python build stuff
+dist/
+*.egg-info*
diff --git a/.travis.yml b/.travis.yml
index f220a7d..36e343d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -211,11 +211,11 @@ install:
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
sudo apt-get update -qq;
sudo apt-get install -qq unzip cmake3;
- wget https://github.com/bazelbuild/bazel/releases/download/0.10.1/bazel-0.10.1-installer-linux-x86_64.sh --output-document bazel-installer.sh;
+ wget https://github.com/bazelbuild/bazel/releases/download/3.2.0/bazel-3.2.0-installer-linux-x86_64.sh --output-document bazel-installer.sh;
travis_wait sudo bash bazel-installer.sh;
fi
- if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
- curl -L -o bazel-installer.sh https://github.com/bazelbuild/bazel/releases/download/0.10.1/bazel-0.10.1-installer-darwin-x86_64.sh;
+ curl -L -o bazel-installer.sh https://github.com/bazelbuild/bazel/releases/download/3.2.0/bazel-3.2.0-installer-darwin-x86_64.sh;
travis_wait sudo bash bazel-installer.sh;
fi
diff --git a/METADATA b/METADATA
index cfcfea7..9b8648f 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/google/benchmark.git"
}
- version: "d3ad0b9d11c190cb58de5fb17c3555def61fdc96"
+ version: "37177a84b7e8d33696ea1e1854513cb0de3b4dc3"
license_type: NOTICE
last_upgrade_date {
year: 2020
- month: 5
- day: 13
+ month: 7
+ day: 10
}
}
diff --git a/WORKSPACE b/WORKSPACE
index dc6ea02..5438ad3 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -9,6 +9,13 @@ http_archive(
)
http_archive(
+ name = "com_google_absl",
+ sha256 = "f41868f7a938605c92936230081175d1eae87f6ea2c248f41077c8f88316f111",
+ strip_prefix = "abseil-cpp-20200225.2",
+ urls = ["https://github.com/abseil/abseil-cpp/archive/20200225.2.tar.gz"],
+)
+
+http_archive(
name = "com_google_googletest",
strip_prefix = "googletest-3f0cf6b62ad1eb50d8736538363d3580dd640c3e",
urls = ["https://github.com/google/googletest/archive/3f0cf6b62ad1eb50d8736538363d3580dd640c3e.zip"],
diff --git a/bindings/python/benchmark/BUILD b/bindings/python/google_benchmark/BUILD
index 49f536e..3c1561f 100644
--- a/bindings/python/benchmark/BUILD
+++ b/bindings/python/google_benchmark/BUILD
@@ -1,7 +1,7 @@
load("//bindings/python:build_defs.bzl", "py_extension")
py_library(
- name = "benchmark",
+ name = "google_benchmark",
srcs = ["__init__.py"],
visibility = ["//visibility:public"],
deps = [
@@ -32,7 +32,7 @@ py_test(
srcs_version = "PY3",
visibility = ["//visibility:public"],
deps = [
- ":benchmark",
+ ":google_benchmark",
],
)
diff --git a/bindings/python/benchmark/__init__.py b/bindings/python/google_benchmark/__init__.py
index 27f76e0..c3a93bf 100644
--- a/bindings/python/benchmark/__init__.py
+++ b/bindings/python/google_benchmark/__init__.py
@@ -14,7 +14,7 @@
"""Python benchmarking utilities.
Example usage:
- import benchmark
+ import google_benchmark as benchmark
@benchmark.register
def my_benchmark(state):
@@ -28,7 +28,7 @@ Example usage:
"""
from absl import app
-from benchmark import _benchmark
+from google_benchmark import _benchmark
__all__ = [
"register",
@@ -60,3 +60,8 @@ def _run_benchmarks(argv):
def main(argv=None):
return app.run(_run_benchmarks, argv=argv, flags_parser=_flags_parser)
+
+
+# Methods for use with custom main function.
+initialize = _benchmark.Initialize
+run_benchmarks = _benchmark.RunSpecifiedBenchmarks
diff --git a/bindings/python/benchmark/benchmark.cc b/bindings/python/google_benchmark/benchmark.cc
index ef95559..374bf54 100644
--- a/bindings/python/benchmark/benchmark.cc
+++ b/bindings/python/google_benchmark/benchmark.cc
@@ -42,6 +42,7 @@ PYBIND11_MODULE(_benchmark, m) {
py::class_<benchmark::State>(m, "State")
.def("__bool__", &benchmark::State::KeepRunning)
- .def_property_readonly("keep_running", &benchmark::State::KeepRunning);
+ .def_property_readonly("keep_running", &benchmark::State::KeepRunning)
+ .def("skip_with_error", &benchmark::State::SkipWithError);
};
} // namespace
diff --git a/bindings/python/benchmark/example.py b/bindings/python/google_benchmark/example.py
index 24da127..e968462 100644
--- a/bindings/python/benchmark/example.py
+++ b/bindings/python/google_benchmark/example.py
@@ -11,9 +11,16 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-"""Example of Python using C++ benchmark framework."""
+"""Example of Python using C++ benchmark framework.
-import benchmark
+To run this example, you must first install the `google_benchmark` Python package.
+
+To install using `setup.py`, download and extract the `google_benchmark` source.
+In the extracted directory, execute:
+ python setup.py install
+"""
+
+import google_benchmark as benchmark
@benchmark.register
@@ -28,5 +35,14 @@ def sum_million(state):
sum(range(1_000_000))
+@benchmark.register
+def skipped(state):
+ if True: # Test some predicate here.
+ state.skip_with_error('some error')
+ return # NOTE: You must explicitly return, or benchmark will continue.
+
+ ... # Benchmark code would be here.
+
+
if __name__ == '__main__':
benchmark.main()
diff --git a/releasing.md b/docs/releasing.md
index f0cd701..f0cd701 100644
--- a/releasing.md
+++ b/docs/releasing.md
diff --git a/docs/tools.md b/docs/tools.md
index 4a3b2e9..f2d0c49 100644
--- a/docs/tools.md
+++ b/docs/tools.md
@@ -4,7 +4,11 @@
The `compare.py` can be used to compare the result of benchmarks.
-**NOTE**: the utility relies on the scipy package which can be installed using [these instructions](https://www.scipy.org/install.html).
+### Dependencies
+The utility relies on the [scipy](https://www.scipy.org) package which can be installed using pip:
+```bash
+pip3 install -r requirements.txt
+```
### Displaying aggregates only
diff --git a/mingw.py b/mingw.py
deleted file mode 100644
index 65cf4b8..0000000
--- a/mingw.py
+++ /dev/null
@@ -1,320 +0,0 @@
-#! /usr/bin/env python
-# encoding: utf-8
-
-import argparse
-import errno
-import logging
-import os
-import platform
-import re
-import sys
-import subprocess
-import tempfile
-
-try:
- import winreg
-except ImportError:
- import _winreg as winreg
-try:
- import urllib.request as request
-except ImportError:
- import urllib as request
-try:
- import urllib.parse as parse
-except ImportError:
- import urlparse as parse
-
-class EmptyLogger(object):
- '''
- Provides an implementation that performs no logging
- '''
- def debug(self, *k, **kw):
- pass
- def info(self, *k, **kw):
- pass
- def warn(self, *k, **kw):
- pass
- def error(self, *k, **kw):
- pass
- def critical(self, *k, **kw):
- pass
- def setLevel(self, *k, **kw):
- pass
-
-urls = (
- 'http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20'
- 'targetting%20Win32/Personal%20Builds/mingw-builds/installer/'
- 'repository.txt',
- 'http://downloads.sourceforge.net/project/mingwbuilds/host-windows/'
- 'repository.txt'
-)
-'''
-A list of mingw-build repositories
-'''
-
-def repository(urls = urls, log = EmptyLogger()):
- '''
- Downloads and parse mingw-build repository files and parses them
- '''
- log.info('getting mingw-builds repository')
- versions = {}
- re_sourceforge = re.compile(r'http://sourceforge.net/projects/([^/]+)/files')
- re_sub = r'http://downloads.sourceforge.net/project/\1'
- for url in urls:
- log.debug(' - requesting: %s', url)
- socket = request.urlopen(url)
- repo = socket.read()
- if not isinstance(repo, str):
- repo = repo.decode();
- socket.close()
- for entry in repo.split('\n')[:-1]:
- value = entry.split('|')
- version = tuple([int(n) for n in value[0].strip().split('.')])
- version = versions.setdefault(version, {})
- arch = value[1].strip()
- if arch == 'x32':
- arch = 'i686'
- elif arch == 'x64':
- arch = 'x86_64'
- arch = version.setdefault(arch, {})
- threading = arch.setdefault(value[2].strip(), {})
- exceptions = threading.setdefault(value[3].strip(), {})
- revision = exceptions.setdefault(int(value[4].strip()[3:]),
- re_sourceforge.sub(re_sub, value[5].strip()))
- return versions
-
-def find_in_path(file, path=None):
- '''
- Attempts to find an executable in the path
- '''
- if platform.system() == 'Windows':
- file += '.exe'
- if path is None:
- path = os.environ.get('PATH', '')
- if type(path) is type(''):
- path = path.split(os.pathsep)
- return list(filter(os.path.exists,
- map(lambda dir, file=file: os.path.join(dir, file), path)))
-
-def find_7zip(log = EmptyLogger()):
- '''
- Attempts to find 7zip for unpacking the mingw-build archives
- '''
- log.info('finding 7zip')
- path = find_in_path('7z')
- if not path:
- key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\7-Zip')
- path, _ = winreg.QueryValueEx(key, 'Path')
- path = [os.path.join(path, '7z.exe')]
- log.debug('found \'%s\'', path[0])
- return path[0]
-
-find_7zip()
-
-def unpack(archive, location, log = EmptyLogger()):
- '''
- Unpacks a mingw-builds archive
- '''
- sevenzip = find_7zip(log)
- log.info('unpacking %s', os.path.basename(archive))
- cmd = [sevenzip, 'x', archive, '-o' + location, '-y']
- log.debug(' - %r', cmd)
- with open(os.devnull, 'w') as devnull:
- subprocess.check_call(cmd, stdout = devnull)
-
-def download(url, location, log = EmptyLogger()):
- '''
- Downloads and unpacks a mingw-builds archive
- '''
- log.info('downloading MinGW')
- log.debug(' - url: %s', url)
- log.debug(' - location: %s', location)
-
- re_content = re.compile(r'attachment;[ \t]*filename=(")?([^"]*)(")?[\r\n]*')
-
- stream = request.urlopen(url)
- try:
- content = stream.getheader('Content-Disposition') or ''
- except AttributeError:
- content = stream.headers.getheader('Content-Disposition') or ''
- matches = re_content.match(content)
- if matches:
- filename = matches.group(2)
- else:
- parsed = parse.urlparse(stream.geturl())
- filename = os.path.basename(parsed.path)
-
- try:
- os.makedirs(location)
- except OSError as e:
- if e.errno == errno.EEXIST and os.path.isdir(location):
- pass
- else:
- raise
-
- archive = os.path.join(location, filename)
- with open(archive, 'wb') as out:
- while True:
- buf = stream.read(1024)
- if not buf:
- break
- out.write(buf)
- unpack(archive, location, log = log)
- os.remove(archive)
-
- possible = os.path.join(location, 'mingw64')
- if not os.path.exists(possible):
- possible = os.path.join(location, 'mingw32')
- if not os.path.exists(possible):
- raise ValueError('Failed to find unpacked MinGW: ' + possible)
- return possible
-
-def root(location = None, arch = None, version = None, threading = None,
- exceptions = None, revision = None, log = EmptyLogger()):
- '''
- Returns the root folder of a specific version of the mingw-builds variant
- of gcc. Will download the compiler if needed
- '''
-
- # Get the repository if we don't have all the information
- if not (arch and version and threading and exceptions and revision):
- versions = repository(log = log)
-
- # Determine some defaults
- version = version or max(versions.keys())
- if not arch:
- arch = platform.machine().lower()
- if arch == 'x86':
- arch = 'i686'
- elif arch == 'amd64':
- arch = 'x86_64'
- if not threading:
- keys = versions[version][arch].keys()
- if 'posix' in keys:
- threading = 'posix'
- elif 'win32' in keys:
- threading = 'win32'
- else:
- threading = keys[0]
- if not exceptions:
- keys = versions[version][arch][threading].keys()
- if 'seh' in keys:
- exceptions = 'seh'
- elif 'sjlj' in keys:
- exceptions = 'sjlj'
- else:
- exceptions = keys[0]
- if revision is None:
- revision = max(versions[version][arch][threading][exceptions].keys())
- if not location:
- location = os.path.join(tempfile.gettempdir(), 'mingw-builds')
-
- # Get the download url
- url = versions[version][arch][threading][exceptions][revision]
-
- # Tell the user whatzzup
- log.info('finding MinGW %s', '.'.join(str(v) for v in version))
- log.debug(' - arch: %s', arch)
- log.debug(' - threading: %s', threading)
- log.debug(' - exceptions: %s', exceptions)
- log.debug(' - revision: %s', revision)
- log.debug(' - url: %s', url)
-
- # Store each specific revision differently
- slug = '{version}-{arch}-{threading}-{exceptions}-rev{revision}'
- slug = slug.format(
- version = '.'.join(str(v) for v in version),
- arch = arch,
- threading = threading,
- exceptions = exceptions,
- revision = revision
- )
- if arch == 'x86_64':
- root_dir = os.path.join(location, slug, 'mingw64')
- elif arch == 'i686':
- root_dir = os.path.join(location, slug, 'mingw32')
- else:
- raise ValueError('Unknown MinGW arch: ' + arch)
-
- # Download if needed
- if not os.path.exists(root_dir):
- downloaded = download(url, os.path.join(location, slug), log = log)
- if downloaded != root_dir:
- raise ValueError('The location of mingw did not match\n%s\n%s'
- % (downloaded, root_dir))
-
- return root_dir
-
-def str2ver(string):
- '''
- Converts a version string into a tuple
- '''
- try:
- version = tuple(int(v) for v in string.split('.'))
- if len(version) is not 3:
- raise ValueError()
- except ValueError:
- raise argparse.ArgumentTypeError(
- 'please provide a three digit version string')
- return version
-
-def main():
- '''
- Invoked when the script is run directly by the python interpreter
- '''
- parser = argparse.ArgumentParser(
- description = 'Downloads a specific version of MinGW',
- formatter_class = argparse.ArgumentDefaultsHelpFormatter
- )
- parser.add_argument('--location',
- help = 'the location to download the compiler to',
- default = os.path.join(tempfile.gettempdir(), 'mingw-builds'))
- parser.add_argument('--arch', required = True, choices = ['i686', 'x86_64'],
- help = 'the target MinGW architecture string')
- parser.add_argument('--version', type = str2ver,
- help = 'the version of GCC to download')
- parser.add_argument('--threading', choices = ['posix', 'win32'],
- help = 'the threading type of the compiler')
- parser.add_argument('--exceptions', choices = ['sjlj', 'seh', 'dwarf'],
- help = 'the method to throw exceptions')
- parser.add_argument('--revision', type=int,
- help = 'the revision of the MinGW release')
- group = parser.add_mutually_exclusive_group()
- group.add_argument('-v', '--verbose', action='store_true',
- help='increase the script output verbosity')
- group.add_argument('-q', '--quiet', action='store_true',
- help='only print errors and warning')
- args = parser.parse_args()
-
- # Create the logger
- logger = logging.getLogger('mingw')
- handler = logging.StreamHandler()
- formatter = logging.Formatter('%(message)s')
- handler.setFormatter(formatter)
- logger.addHandler(handler)
- logger.setLevel(logging.INFO)
- if args.quiet:
- logger.setLevel(logging.WARN)
- if args.verbose:
- logger.setLevel(logging.DEBUG)
-
- # Get MinGW
- root_dir = root(location = args.location, arch = args.arch,
- version = args.version, threading = args.threading,
- exceptions = args.exceptions, revision = args.revision,
- log = logger)
-
- sys.stdout.write('%s\n' % os.path.join(root_dir, 'bin'))
-
-if __name__ == '__main__':
- try:
- main()
- except IOError as e:
- sys.stderr.write('IO error: %s\n' % e)
- sys.exit(1)
- except OSError as e:
- sys.stderr.write('OS error: %s\n' % e)
- sys.exit(1)
- except KeyboardInterrupt as e:
- sys.stderr.write('Killed\n')
- sys.exit(1)
diff --git a/setup.py b/setup.py
index f4c0633..a2b0b91 100644
--- a/setup.py
+++ b/setup.py
@@ -17,7 +17,7 @@ IS_WINDOWS = sys.platform.startswith('win')
def _get_version():
"""Parse the version string from __init__.py."""
- with open(os.path.join(here, 'bindings', 'python', 'benchmark', '__init__.py')) as f:
+ with open(os.path.join(here, 'bindings', 'python', 'google_benchmark', '__init__.py')) as f:
try:
version_line = next(
line for line in f if line.startswith('__version__'))
@@ -95,7 +95,7 @@ class BuildBazelExtension(build_ext.build_ext):
setuptools.setup(
- name='google-benchmark',
+ name='google_benchmark',
version=_get_version(),
url='https://github.com/google/benchmark',
description='A library to benchmark code snippets.',
@@ -106,7 +106,7 @@ setuptools.setup(
packages=setuptools.find_packages('bindings/python'),
install_requires=_parse_requirements('bindings/python/requirements.txt'),
cmdclass=dict(build_ext=BuildBazelExtension),
- ext_modules=[BazelExtension('benchmark._benchmark', '//bindings/python/benchmark:_benchmark')],
+ ext_modules=[BazelExtension('google_benchmark._benchmark', '//bindings/python/google_benchmark:_benchmark')],
zip_safe=False,
# PyPI package information.
classifiers=[
@@ -116,6 +116,7 @@ setuptools.setup(
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
'Topic :: Software Development :: Testing',
'Topic :: System :: Benchmark',
],
diff --git a/src/timers.cc b/src/timers.cc
index 7613ff9..4f76edd 100644
--- a/src/timers.cc
+++ b/src/timers.cc
@@ -178,40 +178,67 @@ double ThreadCPUUsage() {
#endif
}
-namespace {
-
-std::string DateTimeString(bool local) {
+std::string LocalDateTimeString() {
+ // Write the local time in RFC3339 format yyyy-mm-ddTHH:MM:SS+/-HH:MM.
typedef std::chrono::system_clock Clock;
std::time_t now = Clock::to_time_t(Clock::now());
- const std::size_t kStorageSize = 128;
- char storage[kStorageSize];
- std::size_t written;
+ const std::size_t kTzOffsetLen = 6;
+ const std::size_t kTimestampLen = 19;
+
+ std::size_t tz_len;
+ std::size_t timestamp_len;
+ long int offset_minutes;
+ char tz_offset_sign = '+';
+ // Long enough buffers to avoid format-overflow warnings
+ char tz_offset[128];
+ char storage[128];
- if (local) {
#if defined(BENCHMARK_OS_WINDOWS)
- written =
- std::strftime(storage, sizeof(storage), "%x %X", ::localtime(&now));
+ std::tm *timeinfo_p = ::localtime(&now);
#else
- std::tm timeinfo;
- ::localtime_r(&now, &timeinfo);
- written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo);
+ std::tm timeinfo;
+ std::tm *timeinfo_p = &timeinfo;
+ ::localtime_r(&now, &timeinfo);
#endif
+
+ tz_len = std::strftime(tz_offset, sizeof(tz_offset), "%z", timeinfo_p);
+
+ if (tz_len < kTzOffsetLen && tz_len > 1) {
+ // Timezone offset was written. strftime writes offset as +HHMM or -HHMM,
+ // RFC3339 specifies an offset as +HH:MM or -HH:MM. To convert, we parse
+ // the offset as an integer, then reprint it to a string.
+
+ offset_minutes = ::strtol(tz_offset, NULL, 10);
+ if (offset_minutes < 0) {
+ offset_minutes *= -1;
+ tz_offset_sign = '-';
+ }
+
+ tz_len = ::snprintf(tz_offset, sizeof(tz_offset), "%c%02li:%02li",
+ tz_offset_sign, offset_minutes / 100, offset_minutes % 100);
+ CHECK(tz_len == kTzOffsetLen);
+ ((void)tz_len); // Prevent unused variable warning in optimized build.
} else {
+ // Unknown offset. RFC3339 specifies that unknown local offsets should be
+ // written as UTC time with -00:00 timezone.
#if defined(BENCHMARK_OS_WINDOWS)
- written = std::strftime(storage, sizeof(storage), "%x %X", ::gmtime(&now));
+ // Potential race condition if another thread calls localtime or gmtime.
+ timeinfo_p = ::gmtime(&now);
#else
- std::tm timeinfo;
::gmtime_r(&now, &timeinfo);
- written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo);
#endif
+
+ strncpy(tz_offset, "-00:00", kTzOffsetLen + 1);
}
- CHECK(written < kStorageSize);
- ((void)written); // prevent unused variable in optimized mode.
- return std::string(storage);
-}
-} // end namespace
+ timestamp_len = std::strftime(storage, sizeof(storage), "%Y-%m-%dT%H:%M:%S",
+ timeinfo_p);
+ CHECK(timestamp_len == kTimestampLen);
+ // Prevent unused variable warning in optimized build.
+ ((void)kTimestampLen);
-std::string LocalDateTimeString() { return DateTimeString(true); }
+ std::strncat(storage, tz_offset, sizeof(storage) - timestamp_len - 1);
+ return std::string(storage);
+}
} // end namespace benchmark
diff --git a/test/reporter_output_test.cc b/test/reporter_output_test.cc
index 1a96b5f..d806a4e 100644
--- a/test/reporter_output_test.cc
+++ b/test/reporter_output_test.cc
@@ -15,7 +15,7 @@ ADD_CASES(TC_ConsoleOut, {{"^[-]+$", MR_Next},
static int AddContextCases() {
AddCases(TC_ConsoleErr,
{
- {"%int[-/]%int[-/]%int %int:%int:%int$", MR_Default},
+ {"^%int-%int-%intT%int:%int:%int[-+]%int:%int$", MR_Default},
{"Running .*/reporter_output_test(\\.exe)?$", MR_Next},
{"Run on \\(%int X %float MHz CPU s?\\)", MR_Next},
});
diff --git a/tools/compare.py b/tools/compare.py
index 539ace6..bd01be5 100755
--- a/tools/compare.py
+++ b/tools/compare.py
@@ -48,6 +48,14 @@ def create_parser():
"of repetitions. Do note that only the display is affected. "
"Internally, all the actual runs are still used, e.g. for U test.")
+ parser.add_argument(
+ '--no-color',
+ dest='color',
+ default=True,
+ action="store_false",
+ help="Do not use colors in the terminal output"
+ )
+
utest = parser.add_argument_group()
utest.add_argument(
'--no-utest',
@@ -239,7 +247,7 @@ def main():
# Diff and output
output_lines = gbench.report.generate_difference_report(
json1, json2, args.display_aggregates_only,
- args.utest, args.utest_alpha)
+ args.utest, args.utest_alpha, args.color)
print(description)
for ln in output_lines:
print(ln)
diff --git a/tools/requirements.txt b/tools/requirements.txt
new file mode 100644
index 0000000..3b3331b
--- /dev/null
+++ b/tools/requirements.txt
@@ -0,0 +1 @@
+scipy>=1.5.0 \ No newline at end of file