andrew@webrtc.org | 2009f6b | 2012-11-20 00:20:20 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2012 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 | |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 11 | #include "test/testsupport/perf_test.h" |
andrew@webrtc.org | 2009f6b | 2012-11-20 00:20:20 | [diff] [blame] | 12 | |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 13 | #include <algorithm> |
Oleh Prypin | d136b28 | 2018-10-03 11:53:44 | [diff] [blame] | 14 | #include <limits> |
andrew@webrtc.org | 2009f6b | 2012-11-20 00:20:20 | [diff] [blame] | 15 | #include <string> |
| 16 | |
Mirko Bonadei | d2637a3 | 2021-12-24 10:27:55 | [diff] [blame] | 17 | #include "test/gmock.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 18 | #include "test/gtest.h" |
Artem Titov | 9dc209a | 2019-11-28 16:09:30 | [diff] [blame] | 19 | #include "test/testsupport/rtc_expect_death.h" |
andrew@webrtc.org | 2009f6b | 2012-11-20 00:20:20 | [diff] [blame] | 20 | |
Patrik Höglund | 7f585b3 | 2020-01-31 10:22:42 | [diff] [blame] | 21 | #if WEBRTC_ENABLE_PROTOBUF |
| 22 | #include "third_party/catapult/tracing/tracing/value/histogram.h" |
| 23 | namespace proto = catapult::tracing::tracing::proto; |
| 24 | #endif |
| 25 | |
andrew@webrtc.org | 2009f6b | 2012-11-20 00:20:20 | [diff] [blame] | 26 | namespace webrtc { |
| 27 | namespace test { |
| 28 | |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 29 | class PerfTest : public ::testing::Test { |
| 30 | protected: |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 31 | void TearDown() override { ClearPerfResults(); } |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 32 | }; |
| 33 | |
Edward Lemur | f49a56b | 2017-11-29 19:29:30 | [diff] [blame] | 34 | #if defined(WEBRTC_IOS) |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 35 | #define MAYBE_TestPrintResult DISABLED_TestPrintResult |
Edward Lemur | f49a56b | 2017-11-29 19:29:30 | [diff] [blame] | 36 | #else |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 37 | #define MAYBE_TestPrintResult TestPrintResult |
Edward Lemur | f49a56b | 2017-11-29 19:29:30 | [diff] [blame] | 38 | #endif |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 39 | TEST_F(PerfTest, MAYBE_TestPrintResult) { |
Mirko Bonadei | 6a489f2 | 2019-04-09 13:11:12 | [diff] [blame] | 40 | ::testing::internal::CaptureStdout(); |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 41 | std::string expected; |
| 42 | |
| 43 | expected += "RESULT measurementmodifier: trace= 42 units\n"; |
Edward Lemur | f7ff3e8 | 2017-11-22 15:32:01 | [diff] [blame] | 44 | PrintResult("measurement", "modifier", "trace", 42, "units", false); |
andrew@webrtc.org | 2009f6b | 2012-11-20 00:20:20 | [diff] [blame] | 45 | |
Edward Lemur | cb666f5 | 2017-12-04 12:21:01 | [diff] [blame] | 46 | expected += "*RESULT foobar: baz_v= 1423730 widgets\n"; |
| 47 | PrintResult("foo", "bar", "baz_v", 1423730, "widgets", true); |
Edward Lemur | 2f06168 | 2017-11-24 12:40:01 | [diff] [blame] | 48 | |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 49 | expected += "RESULT foobar: baz_me= {1,2} lemurs\n"; |
| 50 | PrintResultMeanAndError("foo", "bar", "baz_me", 1, 2, "lemurs", false); |
Edward Lemur | 2f06168 | 2017-11-24 12:40:01 | [diff] [blame] | 51 | |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 52 | const double kListOfScalars[] = {1, 2, 3}; |
| 53 | expected += "RESULT foobar: baz_vl= [1,2,3] units\n"; |
| 54 | PrintResultList("foo", "bar", "baz_vl", kListOfScalars, "units", false); |
Edward Lemur | f7ff3e8 | 2017-11-22 15:32:01 | [diff] [blame] | 55 | |
Mirko Bonadei | 6a489f2 | 2019-04-09 13:11:12 | [diff] [blame] | 56 | EXPECT_EQ(expected, ::testing::internal::GetCapturedStdout()); |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 57 | } |
| 58 | |
Edward Lemur | 936dfb1 | 2017-11-30 10:43:42 | [diff] [blame] | 59 | TEST_F(PerfTest, TestClearPerfResults) { |
| 60 | PrintResult("measurement", "modifier", "trace", 42, "units", false); |
| 61 | ClearPerfResults(); |
Patrik Höglund | 36b35d5 | 2020-03-27 13:05:08 | [diff] [blame] | 62 | EXPECT_EQ("", GetPerfResults()); |
andrew@webrtc.org | 2009f6b | 2012-11-20 00:20:20 | [diff] [blame] | 63 | } |
| 64 | |
Patrik Höglund | 7f585b3 | 2020-01-31 10:22:42 | [diff] [blame] | 65 | #if WEBRTC_ENABLE_PROTOBUF |
| 66 | |
| 67 | TEST_F(PerfTest, TestGetPerfResultsHistograms) { |
Mirko Bonadei | 9ff23ba | 2020-12-14 11:01:59 | [diff] [blame] | 68 | ClearPerfResults(); |
Patrik Höglund | 7f585b3 | 2020-01-31 10:22:42 | [diff] [blame] | 69 | PrintResult("measurement", "_modifier", "story_1", 42, "ms", false); |
| 70 | PrintResult("foo", "bar", "story_1", 7, "sigma", true); |
| 71 | // Note: the error will be ignored, not supported by histograms. |
| 72 | PrintResultMeanAndError("foo", "bar", "story_1", 1, 2000, "sigma", false); |
| 73 | const double kListOfScalars[] = {1, 2, 3}; |
| 74 | PrintResultList("foo", "bar", "story_1", kListOfScalars, "sigma", false); |
| 75 | |
| 76 | proto::HistogramSet histogram_set; |
| 77 | EXPECT_TRUE(histogram_set.ParseFromString(GetPerfResults())) |
| 78 | << "Expected valid histogram set"; |
| 79 | |
| 80 | ASSERT_EQ(histogram_set.histograms_size(), 2) |
| 81 | << "Should be two histograms: foobar and measurement_modifier"; |
| 82 | const proto::Histogram& hist1 = histogram_set.histograms(0); |
| 83 | const proto::Histogram& hist2 = histogram_set.histograms(1); |
| 84 | |
| 85 | EXPECT_EQ(hist1.name(), "foobar"); |
| 86 | |
| 87 | // Spot check some things in here (there's a more thorough test on the |
| 88 | // histogram writer itself). |
| 89 | EXPECT_EQ(hist1.unit().unit(), proto::SIGMA); |
| 90 | EXPECT_EQ(hist1.sample_values_size(), 5); |
| 91 | EXPECT_EQ(hist1.sample_values(0), 7); |
| 92 | EXPECT_EQ(hist1.sample_values(1), 1); |
| 93 | EXPECT_EQ(hist1.sample_values(2), 1); |
| 94 | EXPECT_EQ(hist1.sample_values(3), 2); |
| 95 | EXPECT_EQ(hist1.sample_values(4), 3); |
| 96 | |
| 97 | EXPECT_EQ(hist1.diagnostics().diagnostic_map().count("stories"), 1u); |
| 98 | const proto::Diagnostic& stories = |
| 99 | hist1.diagnostics().diagnostic_map().at("stories"); |
| 100 | ASSERT_EQ(stories.generic_set().values_size(), 1); |
| 101 | EXPECT_EQ(stories.generic_set().values(0), "\"story_1\""); |
| 102 | |
| 103 | EXPECT_EQ(hist2.name(), "measurement_modifier"); |
| 104 | EXPECT_EQ(hist2.unit().unit(), proto::MS_BEST_FIT_FORMAT); |
Patrik Höglund | 7f585b3 | 2020-01-31 10:22:42 | [diff] [blame] | 105 | } |
| 106 | |
Artem Titov | eecc4f5 | 2021-03-20 11:27:43 | [diff] [blame] | 107 | TEST_F(PerfTest, TestGetPerfResultsHistogramsWithEmptyCounter) { |
| 108 | ClearPerfResults(); |
| 109 | ::testing::internal::CaptureStdout(); |
| 110 | |
| 111 | SamplesStatsCounter empty_counter; |
| 112 | PrintResult("measurement", "_modifier", "story", empty_counter, "ms", false); |
| 113 | |
| 114 | proto::HistogramSet histogram_set; |
| 115 | EXPECT_TRUE(histogram_set.ParseFromString(GetPerfResults())) |
| 116 | << "Expected valid histogram set"; |
| 117 | |
| 118 | ASSERT_EQ(histogram_set.histograms_size(), 1) |
| 119 | << "Should be one histogram: measurement_modifier"; |
| 120 | const proto::Histogram& hist = histogram_set.histograms(0); |
| 121 | |
| 122 | EXPECT_EQ(hist.name(), "measurement_modifier"); |
| 123 | |
| 124 | // Spot check some things in here (there's a more thorough test on the |
| 125 | // histogram writer itself). |
| 126 | EXPECT_EQ(hist.unit().unit(), proto::MS_BEST_FIT_FORMAT); |
| 127 | EXPECT_EQ(hist.sample_values_size(), 1); |
| 128 | EXPECT_EQ(hist.sample_values(0), 0); |
| 129 | |
| 130 | EXPECT_EQ(hist.diagnostics().diagnostic_map().count("stories"), 1u); |
| 131 | const proto::Diagnostic& stories = |
| 132 | hist.diagnostics().diagnostic_map().at("stories"); |
| 133 | ASSERT_EQ(stories.generic_set().values_size(), 1); |
| 134 | EXPECT_EQ(stories.generic_set().values(0), "\"story\""); |
| 135 | |
| 136 | std::string expected = "RESULT measurement_modifier: story= {0,0} ms\n"; |
| 137 | EXPECT_EQ(expected, ::testing::internal::GetCapturedStdout()); |
| 138 | } |
| 139 | |
| 140 | TEST_F(PerfTest, TestGetPerfResultsHistogramsWithStatsCounter) { |
| 141 | ClearPerfResults(); |
| 142 | ::testing::internal::CaptureStdout(); |
| 143 | |
| 144 | SamplesStatsCounter counter; |
| 145 | counter.AddSample(1); |
| 146 | counter.AddSample(2); |
| 147 | counter.AddSample(3); |
| 148 | counter.AddSample(4); |
| 149 | counter.AddSample(5); |
| 150 | PrintResult("measurement", "_modifier", "story", counter, "ms", false); |
| 151 | |
| 152 | proto::HistogramSet histogram_set; |
| 153 | EXPECT_TRUE(histogram_set.ParseFromString(GetPerfResults())) |
| 154 | << "Expected valid histogram set"; |
| 155 | |
| 156 | ASSERT_EQ(histogram_set.histograms_size(), 1) |
| 157 | << "Should be one histogram: measurement_modifier"; |
| 158 | const proto::Histogram& hist = histogram_set.histograms(0); |
| 159 | |
| 160 | EXPECT_EQ(hist.name(), "measurement_modifier"); |
| 161 | |
| 162 | // Spot check some things in here (there's a more thorough test on the |
| 163 | // histogram writer itself). |
| 164 | EXPECT_EQ(hist.unit().unit(), proto::MS_BEST_FIT_FORMAT); |
| 165 | EXPECT_EQ(hist.sample_values_size(), 5); |
Mirko Bonadei | d2637a3 | 2021-12-24 10:27:55 | [diff] [blame] | 166 | EXPECT_THAT(hist.sample_values(), testing::ElementsAre(1, 2, 3, 4, 5)); |
Artem Titov | eecc4f5 | 2021-03-20 11:27:43 | [diff] [blame] | 167 | |
| 168 | EXPECT_EQ(hist.diagnostics().diagnostic_map().count("stories"), 1u); |
| 169 | const proto::Diagnostic& stories = |
| 170 | hist.diagnostics().diagnostic_map().at("stories"); |
| 171 | ASSERT_EQ(stories.generic_set().values_size(), 1); |
| 172 | EXPECT_EQ(stories.generic_set().values(0), "\"story\""); |
| 173 | |
| 174 | // mean = 3; std = sqrt(2) |
| 175 | std::string expected = |
| 176 | "RESULT measurement_modifier: story= {3,1.4142136} ms\n"; |
| 177 | EXPECT_EQ(expected, ::testing::internal::GetCapturedStdout()); |
| 178 | } |
| 179 | |
Patrik Höglund | 7f585b3 | 2020-01-31 10:22:42 | [diff] [blame] | 180 | #endif // WEBRTC_ENABLE_PROTOBUF |
| 181 | |
Oleh Prypin | d136b28 | 2018-10-03 11:53:44 | [diff] [blame] | 182 | #if GTEST_HAS_DEATH_TEST |
| 183 | using PerfDeathTest = PerfTest; |
| 184 | |
| 185 | TEST_F(PerfDeathTest, TestFiniteResultError) { |
| 186 | const double kNan = std::numeric_limits<double>::quiet_NaN(); |
| 187 | const double kInf = std::numeric_limits<double>::infinity(); |
| 188 | |
Artem Titov | 9dc209a | 2019-11-28 16:09:30 | [diff] [blame] | 189 | RTC_EXPECT_DEATH(PrintResult("a", "b", "c", kNan, "d", false), "finit"); |
| 190 | RTC_EXPECT_DEATH(PrintResult("a", "b", "c", kInf, "d", false), "finit"); |
Oleh Prypin | d136b28 | 2018-10-03 11:53:44 | [diff] [blame] | 191 | |
Artem Titov | 9dc209a | 2019-11-28 16:09:30 | [diff] [blame] | 192 | RTC_EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", kNan, 1, "d", false), |
| 193 | ""); |
| 194 | RTC_EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", 1, kInf, "d", false), |
| 195 | ""); |
Oleh Prypin | d136b28 | 2018-10-03 11:53:44 | [diff] [blame] | 196 | |
| 197 | const double kNanList[] = {kNan, kNan}; |
Artem Titov | 9dc209a | 2019-11-28 16:09:30 | [diff] [blame] | 198 | RTC_EXPECT_DEATH(PrintResultList("a", "b", "c", kNanList, "d", false), ""); |
Oleh Prypin | d136b28 | 2018-10-03 11:53:44 | [diff] [blame] | 199 | const double kInfList[] = {0, kInf}; |
Artem Titov | 9dc209a | 2019-11-28 16:09:30 | [diff] [blame] | 200 | RTC_EXPECT_DEATH(PrintResultList("a", "b", "c", kInfList, "d", false), ""); |
Oleh Prypin | d136b28 | 2018-10-03 11:53:44 | [diff] [blame] | 201 | } |
| 202 | #endif |
| 203 | |
andrew@webrtc.org | 2009f6b | 2012-11-20 00:20:20 | [diff] [blame] | 204 | } // namespace test |
| 205 | } // namespace webrtc |