• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "test/testsupport/perf_result_reporter.h"
12 
13 #include <vector>
14 
15 namespace {
16 
17 // These characters mess with either the stdout parsing or the dashboard itself.
InvalidCharacters()18 const std::vector<std::string>& InvalidCharacters() {
19   static const std::vector<std::string> kInvalidCharacters({"/", ":", "="});
20 
21   return kInvalidCharacters;
22 }
23 
CheckForInvalidCharacters(const std::string & str)24 void CheckForInvalidCharacters(const std::string& str) {
25   for (const auto& invalid : InvalidCharacters()) {
26     RTC_CHECK(str.find(invalid) == std::string::npos)
27         << "Given invalid character for perf names '" << invalid << "'";
28   }
29 }
30 
31 }  // namespace
32 
33 namespace webrtc {
34 namespace test {
35 
36 namespace {
37 
38 // For now, mark all tests as "not important". This distinction mostly goes away
39 // in histograms anyway.
40 const bool kNotImportant = false;
41 
UnitToString(Unit unit)42 std::string UnitToString(Unit unit) {
43   // Down the line, we should convert directly from Unit to the histogram.proto
44   // enum values. We need to convert to strings until all uses of perf_test.h
45   // have been eliminated. We're not using the proto enum directly in the .h of
46   // this file because we don't want to limit the exposure of the proto.
47   //
48   // Keep this list up to date with kJsonToProtoUnit in histogram.cc in the
49   // Catapult repo.
50   switch (unit) {
51     case Unit::kMs:
52       return "ms";
53     case Unit::kMsBestFitFormat:
54       return "msBestFitFormat";
55     case Unit::kMsTs:
56       return "tsMs";
57     case Unit::kNPercent:
58       return "n%";
59     case Unit::kSizeInBytes:
60       return "sizeInBytes";
61     case Unit::kBytesPerSecond:
62       return "bytesPerSecond";
63     case Unit::kHertz:
64       return "Hz";
65     case Unit::kUnitless:
66       return "unitless";
67     case Unit::kCount:
68       return "count";
69     case Unit::kSigma:
70       return "sigma";
71     default:
72       RTC_NOTREACHED() << "Unknown unit " << unit;
73       return "unitless";
74   }
75 }
76 
77 }  // namespace
78 
PerfResultReporter(const std::string & metric_basename,const std::string & story_name)79 PerfResultReporter::PerfResultReporter(const std::string& metric_basename,
80                                        const std::string& story_name)
81     : metric_basename_(metric_basename), story_name_(story_name) {
82   CheckForInvalidCharacters(metric_basename_);
83   CheckForInvalidCharacters(story_name_);
84 }
85 
86 PerfResultReporter::~PerfResultReporter() = default;
87 
RegisterMetric(const std::string & metric_suffix,Unit unit)88 void PerfResultReporter::RegisterMetric(const std::string& metric_suffix,
89                                         Unit unit) {
90   RegisterMetric(metric_suffix, unit, ImproveDirection::kNone);
91 }
RegisterMetric(const std::string & metric_suffix,Unit unit,ImproveDirection improve_direction)92 void PerfResultReporter::RegisterMetric(const std::string& metric_suffix,
93                                         Unit unit,
94                                         ImproveDirection improve_direction) {
95   CheckForInvalidCharacters(metric_suffix);
96   RTC_CHECK(metric_map_.count(metric_suffix) == 0);
97   metric_map_.insert({metric_suffix, {unit, improve_direction}});
98 }
99 
AddResult(const std::string & metric_suffix,size_t value) const100 void PerfResultReporter::AddResult(const std::string& metric_suffix,
101                                    size_t value) const {
102   auto info = GetMetricInfoOrFail(metric_suffix);
103 
104   PrintResult(metric_basename_, metric_suffix, story_name_, value,
105               UnitToString(info.unit), kNotImportant, info.improve_direction);
106 }
107 
AddResult(const std::string & metric_suffix,double value) const108 void PerfResultReporter::AddResult(const std::string& metric_suffix,
109                                    double value) const {
110   auto info = GetMetricInfoOrFail(metric_suffix);
111 
112   PrintResult(metric_basename_, metric_suffix, story_name_, value,
113               UnitToString(info.unit), kNotImportant, info.improve_direction);
114 }
115 
AddResultList(const std::string & metric_suffix,rtc::ArrayView<const double> values) const116 void PerfResultReporter::AddResultList(
117     const std::string& metric_suffix,
118     rtc::ArrayView<const double> values) const {
119   auto info = GetMetricInfoOrFail(metric_suffix);
120 
121   PrintResultList(metric_basename_, metric_suffix, story_name_, values,
122                   UnitToString(info.unit), kNotImportant,
123                   info.improve_direction);
124 }
125 
AddResultMeanAndError(const std::string & metric_suffix,const double mean,const double error)126 void PerfResultReporter::AddResultMeanAndError(const std::string& metric_suffix,
127                                                const double mean,
128                                                const double error) {
129   auto info = GetMetricInfoOrFail(metric_suffix);
130 
131   PrintResultMeanAndError(metric_basename_, metric_suffix, story_name_, mean,
132                           error, UnitToString(info.unit), kNotImportant,
133                           info.improve_direction);
134 }
135 
GetMetricInfo(const std::string & metric_suffix) const136 absl::optional<MetricInfo> PerfResultReporter::GetMetricInfo(
137     const std::string& metric_suffix) const {
138   auto iter = metric_map_.find(metric_suffix);
139   if (iter == metric_map_.end()) {
140     return absl::optional<MetricInfo>();
141   }
142 
143   return absl::optional<MetricInfo>(iter->second);
144 }
145 
GetMetricInfoOrFail(const std::string & metric_suffix) const146 MetricInfo PerfResultReporter::GetMetricInfoOrFail(
147     const std::string& metric_suffix) const {
148   absl::optional<MetricInfo> info = GetMetricInfo(metric_suffix);
149   RTC_CHECK(info.has_value())
150       << "Attempted to use unregistered metric " << metric_suffix;
151   return *info;
152 }
153 
154 }  // namespace test
155 }  // namespace webrtc
156