blob: 158f1cd76808459fb325e7cc8b2e86445746e8b6 [file] [log] [blame]
/*
* Copyright (c) 2020 The WebRTC 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 in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "test/testsupport/perf_result_reporter.h"
#include <vector>
#include "absl/strings/string_view.h"
namespace {
// These characters mess with either the stdout parsing or the dashboard itself.
const std::vector<std::string>& InvalidCharacters() {
static const std::vector<std::string> kInvalidCharacters({"/", ":", "="});
return kInvalidCharacters;
}
void CheckForInvalidCharacters(absl::string_view str) {
for (const auto& invalid : InvalidCharacters()) {
RTC_CHECK(str.find(invalid) == std::string::npos)
<< "Given invalid character for perf names '" << invalid << "'";
}
}
} // namespace
namespace webrtc {
namespace test {
namespace {
// For now, mark all tests as "not important". This distinction mostly goes away
// in histograms anyway.
const bool kNotImportant = false;
std::string UnitToString(Unit unit) {
// Down the line, we should convert directly from Unit to the histogram.proto
// enum values. We need to convert to strings until all uses of perf_test.h
// have been eliminated. We're not using the proto enum directly in the .h of
// this file because we don't want to limit the exposure of the proto.
//
// Keep this list up to date with kJsonToProtoUnit in histogram.cc in the
// Catapult repo.
switch (unit) {
case Unit::kMs:
return "ms";
case Unit::kMsBestFitFormat:
return "msBestFitFormat";
case Unit::kMsTs:
return "tsMs";
case Unit::kNPercent:
return "n%";
case Unit::kSizeInBytes:
return "sizeInBytes";
case Unit::kBytesPerSecond:
return "bytesPerSecond";
case Unit::kHertz:
return "Hz";
case Unit::kUnitless:
return "unitless";
case Unit::kCount:
return "count";
case Unit::kSigma:
return "sigma";
default:
RTC_NOTREACHED() << "Unknown unit " << unit;
return "unitless";
}
}
} // namespace
PerfResultReporter::PerfResultReporter(absl::string_view metric_basename,
absl::string_view story_name)
: metric_basename_(metric_basename), story_name_(story_name) {
CheckForInvalidCharacters(metric_basename_);
CheckForInvalidCharacters(story_name_);
}
PerfResultReporter::~PerfResultReporter() = default;
void PerfResultReporter::RegisterMetric(absl::string_view metric_suffix,
Unit unit) {
RegisterMetric(metric_suffix, unit, ImproveDirection::kNone);
}
void PerfResultReporter::RegisterMetric(absl::string_view metric_suffix,
Unit unit,
ImproveDirection improve_direction) {
CheckForInvalidCharacters(metric_suffix);
std::string metric(metric_suffix);
RTC_CHECK(metric_map_.count(metric) == 0);
metric_map_.insert({std::move(metric), {unit, improve_direction}});
}
void PerfResultReporter::AddResult(absl::string_view metric_suffix,
size_t value) const {
auto info = GetMetricInfoOrFail(metric_suffix);
PrintResult(metric_basename_, metric_suffix, story_name_, value,
UnitToString(info.unit), kNotImportant, info.improve_direction);
}
void PerfResultReporter::AddResult(absl::string_view metric_suffix,
double value) const {
auto info = GetMetricInfoOrFail(metric_suffix);
PrintResult(metric_basename_, metric_suffix, story_name_, value,
UnitToString(info.unit), kNotImportant, info.improve_direction);
}
void PerfResultReporter::AddResultList(
absl::string_view metric_suffix,
rtc::ArrayView<const double> values) const {
auto info = GetMetricInfoOrFail(metric_suffix);
PrintResultList(metric_basename_, metric_suffix, story_name_, values,
UnitToString(info.unit), kNotImportant,
info.improve_direction);
}
void PerfResultReporter::AddResultMeanAndError(absl::string_view metric_suffix,
const double mean,
const double error) {
auto info = GetMetricInfoOrFail(metric_suffix);
PrintResultMeanAndError(metric_basename_, metric_suffix, story_name_, mean,
error, UnitToString(info.unit), kNotImportant,
info.improve_direction);
}
absl::optional<MetricInfo> PerfResultReporter::GetMetricInfo(
absl::string_view metric_suffix) const {
auto iter = metric_map_.find(std::string(metric_suffix));
if (iter == metric_map_.end()) {
return absl::optional<MetricInfo>();
}
return absl::optional<MetricInfo>(iter->second);
}
MetricInfo PerfResultReporter::GetMetricInfoOrFail(
absl::string_view metric_suffix) const {
absl::optional<MetricInfo> info = GetMetricInfo(metric_suffix);
RTC_CHECK(info.has_value())
<< "Attempted to use unregistered metric " << metric_suffix;
return *info;
}
} // namespace test
} // namespace webrtc