• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "testing/perf/perf_result_reporter.h"
6 
7 #include <ostream>
8 #include <vector>
9 
10 #include "base/check.h"
11 #include "base/no_destructor.h"
12 #include "base/notreached.h"
13 #include "testing/perf/perf_test.h"
14 
15 namespace {
16 
17 // These characters mess with either the stdout parsing or the dashboard itself.
18 static const base::NoDestructor<std::vector<std::string>> kInvalidCharacters{
19     {"/", ":", "="}};
20 
CheckForInvalidCharacters(const std::string & str)21 void CheckForInvalidCharacters(const std::string& str) {
22   for (const auto& invalid : *kInvalidCharacters) {
23     CHECK(str.find(invalid) == std::string::npos)
24         << "Given invalid character for perf names '" << invalid << "'";
25   }
26 }
27 
28 }  // namespace
29 
30 namespace perf_test {
31 
PerfResultReporter(const std::string & metric_basename,const std::string & story_name)32 PerfResultReporter::PerfResultReporter(const std::string& metric_basename,
33                                        const std::string& story_name)
34     : metric_basename_(metric_basename), story_name_(story_name) {
35   CheckForInvalidCharacters(metric_basename_);
36   CheckForInvalidCharacters(story_name_);
37 }
38 
39 PerfResultReporter::~PerfResultReporter() = default;
40 
RegisterFyiMetric(const std::string & metric_suffix,const std::string & units)41 void PerfResultReporter::RegisterFyiMetric(const std::string& metric_suffix,
42                                            const std::string& units) {
43   RegisterMetric(metric_suffix, units, false);
44 }
45 
RegisterImportantMetric(const std::string & metric_suffix,const std::string & units)46 void PerfResultReporter::RegisterImportantMetric(
47     const std::string& metric_suffix,
48     const std::string& units) {
49   RegisterMetric(metric_suffix, units, true);
50 }
51 
AddResult(const std::string & metric_suffix,size_t value) const52 void PerfResultReporter::AddResult(const std::string& metric_suffix,
53                                    size_t value) const {
54   auto info = GetMetricInfoOrFail(metric_suffix);
55 
56   PrintResult(metric_basename_, metric_suffix, story_name_, value, info.units,
57               info.important);
58 }
59 
AddResult(const std::string & metric_suffix,double value) const60 void PerfResultReporter::AddResult(const std::string& metric_suffix,
61                                    double value) const {
62   auto info = GetMetricInfoOrFail(metric_suffix);
63 
64   PrintResult(metric_basename_, metric_suffix, story_name_, value, info.units,
65               info.important);
66 }
67 
AddResult(const std::string & metric_suffix,const std::string & value) const68 void PerfResultReporter::AddResult(const std::string& metric_suffix,
69                                    const std::string& value) const {
70   auto info = GetMetricInfoOrFail(metric_suffix);
71 
72   PrintResult(metric_basename_, metric_suffix, story_name_, value, info.units,
73               info.important);
74 }
75 
AddResult(const std::string & metric_suffix,base::TimeDelta value) const76 void PerfResultReporter::AddResult(const std::string& metric_suffix,
77                                    base::TimeDelta value) const {
78   auto info = GetMetricInfoOrFail(metric_suffix);
79 
80   // Decide what time unit to convert the TimeDelta into. Units are based on
81   // the legacy units in
82   // https://cs.chromium.org/chromium/src/third_party/catapult/tracing/tracing/value/legacy_unit_info.py?q=legacy_unit_info
83   double time = 0;
84   if (info.units == "seconds") {
85     time = value.InSecondsF();
86   } else if (info.units == "ms" || info.units == "milliseconds") {
87     time = value.InMillisecondsF();
88   } else if (info.units == "us") {
89     time = value.InMicrosecondsF();
90   } else if (info.units == "ns") {
91     time = value.InNanoseconds();
92   } else {
93     NOTREACHED() << "Attempted to use AddResult with a TimeDelta when "
94                  << "registered unit for metric " << metric_suffix << " is "
95                  << info.units;
96   }
97 
98   PrintResult(metric_basename_, metric_suffix, story_name_, time, info.units,
99               info.important);
100 }
101 
AddResultList(const std::string & metric_suffix,const std::string & values) const102 void PerfResultReporter::AddResultList(const std::string& metric_suffix,
103                                        const std::string& values) const {
104   auto info = GetMetricInfoOrFail(metric_suffix);
105 
106   PrintResultList(metric_basename_, metric_suffix, story_name_, values,
107                   info.units, info.important);
108 }
109 
AddResultMeanAndError(const std::string & metric_suffix,const std::string & mean_and_error)110 void PerfResultReporter::AddResultMeanAndError(
111     const std::string& metric_suffix,
112     const std::string& mean_and_error) {
113   auto info = GetMetricInfoOrFail(metric_suffix);
114 
115   PrintResultMeanAndError(metric_basename_, metric_suffix, story_name_,
116                           mean_and_error, info.units, info.important);
117 }
118 
GetMetricInfo(const std::string & metric_suffix,MetricInfo * out) const119 bool PerfResultReporter::GetMetricInfo(const std::string& metric_suffix,
120                                        MetricInfo* out) const {
121   auto iter = metric_map_.find(metric_suffix);
122   if (iter == metric_map_.end()) {
123     return false;
124   }
125 
126   *out = iter->second;
127   return true;
128 }
129 
RegisterMetric(const std::string & metric_suffix,const std::string & units,bool important)130 void PerfResultReporter::RegisterMetric(const std::string& metric_suffix,
131                                         const std::string& units,
132                                         bool important) {
133   CheckForInvalidCharacters(metric_suffix);
134   CHECK(metric_map_.count(metric_suffix) == 0);
135   metric_map_.insert({metric_suffix, {units, important}});
136 }
137 
GetMetricInfoOrFail(const std::string & metric_suffix) const138 MetricInfo PerfResultReporter::GetMetricInfoOrFail(
139     const std::string& metric_suffix) const {
140   MetricInfo info;
141   CHECK(GetMetricInfo(metric_suffix, &info))
142       << "Attempted to use unregistered metric " << metric_suffix;
143   return info;
144 }
145 
146 }  // namespace perf_test
147