// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "testing/perf/perf_result_reporter.h" #include #include #include "base/check.h" #include "base/containers/contains.h" #include "base/no_destructor.h" #include "base/notreached.h" #include "testing/perf/perf_test.h" namespace { // These characters mess with either the stdout parsing or the dashboard itself. static const base::NoDestructor> kInvalidCharacters{ {"/", ":", "="}}; void CheckForInvalidCharacters(const std::string& str) { for (const auto& invalid : *kInvalidCharacters) { CHECK(!base::Contains(str, invalid)) << "Given invalid character for perf names '" << invalid << "'"; } } } // namespace namespace perf_test { PerfResultReporter::PerfResultReporter(const std::string& metric_basename, const std::string& story_name) : metric_basename_(metric_basename), story_name_(story_name) { CheckForInvalidCharacters(metric_basename_); CheckForInvalidCharacters(story_name_); } PerfResultReporter::~PerfResultReporter() = default; void PerfResultReporter::RegisterFyiMetric(const std::string& metric_suffix, const std::string& units) { RegisterMetric(metric_suffix, units, false); } void PerfResultReporter::RegisterImportantMetric( const std::string& metric_suffix, const std::string& units) { RegisterMetric(metric_suffix, units, true); } void PerfResultReporter::AddResult(const std::string& metric_suffix, size_t value) const { auto info = GetMetricInfoOrFail(metric_suffix); PrintResult(metric_basename_, metric_suffix, story_name_, value, info.units, info.important); } void PerfResultReporter::AddResult(const std::string& metric_suffix, double value) const { auto info = GetMetricInfoOrFail(metric_suffix); PrintResult(metric_basename_, metric_suffix, story_name_, value, info.units, info.important); } void PerfResultReporter::AddResult(const std::string& metric_suffix, const std::string& value) const { auto info = GetMetricInfoOrFail(metric_suffix); PrintResult(metric_basename_, metric_suffix, story_name_, value, info.units, info.important); } void PerfResultReporter::AddResult(const std::string& metric_suffix, base::TimeDelta value) const { auto info = GetMetricInfoOrFail(metric_suffix); // Decide what time unit to convert the TimeDelta into. Units are based on // the legacy units in // https://cs.chromium.org/chromium/src/third_party/catapult/tracing/tracing/value/legacy_unit_info.py?q=legacy_unit_info double time = 0; if (info.units == "seconds") { time = value.InSecondsF(); } else if (info.units == "ms" || info.units == "milliseconds") { time = value.InMillisecondsF(); } else if (info.units == "us") { time = value.InMicrosecondsF(); } else if (info.units == "ns") { time = value.InNanoseconds(); } else { NOTREACHED() << "Attempted to use AddResult with a TimeDelta when " << "registered unit for metric " << metric_suffix << " is " << info.units; } PrintResult(metric_basename_, metric_suffix, story_name_, time, info.units, info.important); } void PerfResultReporter::AddResultList(const std::string& metric_suffix, const std::string& values) const { auto info = GetMetricInfoOrFail(metric_suffix); PrintResultList(metric_basename_, metric_suffix, story_name_, values, info.units, info.important); } void PerfResultReporter::AddResultMeanAndError( const std::string& metric_suffix, const std::string& mean_and_error) { auto info = GetMetricInfoOrFail(metric_suffix); PrintResultMeanAndError(metric_basename_, metric_suffix, story_name_, mean_and_error, info.units, info.important); } bool PerfResultReporter::GetMetricInfo(const std::string& metric_suffix, MetricInfo* out) const { auto iter = metric_map_.find(metric_suffix); if (iter == metric_map_.end()) { return false; } *out = iter->second; return true; } void PerfResultReporter::RegisterMetric(const std::string& metric_suffix, const std::string& units, bool important) { CheckForInvalidCharacters(metric_suffix); CHECK(metric_map_.count(metric_suffix) == 0); metric_map_.insert({metric_suffix, {units, important}}); } MetricInfo PerfResultReporter::GetMetricInfoOrFail( const std::string& metric_suffix) const { MetricInfo info; CHECK(GetMetricInfo(metric_suffix, &info)) << "Attempted to use unregistered metric " << metric_suffix; return info; } } // namespace perf_test