blob: de3e18c4e05c5dbc74298f9a8fd370b8982ca573 [file] [log] [blame]
hbos615d3012016-08-24 01:33:13 -07001/*
2 * Copyright 2016 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 Bonadei92ea95e2017-09-15 06:47:31 +020011#include "api/stats/rtcstats.h"
hbos615d3012016-08-24 01:33:13 -070012
ehmaldonado35a872c2017-07-28 07:29:12 -070013#include <cmath>
hbosfdafab82016-09-14 06:02:13 -070014#include <cstring>
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/checks.h"
17#include "rtc_base/gunit.h"
18#include "rtc_base/json.h"
19#include "stats/test/rtcteststats.h"
hbos615d3012016-08-24 01:33:13 -070020
21namespace webrtc {
22
ehmaldonado35a872c2017-07-28 07:29:12 -070023namespace {
24
25// JSON stores numbers as floating point numbers with 53 significant bits, which
26// amounts to about 15.95 decimal digits. Thus, when comparing large numbers
27// processed by JSON, that's all the precision we should expect.
28const double JSON_EPSILON = 1e-15;
29
30// We do this since Google Test doesn't support relative error.
31// This is computed as follows:
32// If |a - b| / |a| < EPS, then |a - b| < |a| * EPS, so |a| * EPS is the
33// maximum expected error.
34double GetExpectedError(const double expected_value) {
35 return JSON_EPSILON * fabs(expected_value);
36}
37
38} // namespace
39
hbos615d3012016-08-24 01:33:13 -070040class RTCChildStats : public RTCStats {
41 public:
hbosfc5e0502016-10-06 02:06:10 -070042 WEBRTC_RTCSTATS_DECL();
43
hbos0e6758d2016-08-31 07:57:36 -070044 RTCChildStats(const std::string& id, int64_t timestamp_us)
Yves Gerey665174f2018-06-19 15:03:05 +020045 : RTCStats(id, timestamp_us), child_int("childInt") {}
hbos615d3012016-08-24 01:33:13 -070046
hbos615d3012016-08-24 01:33:13 -070047 RTCStatsMember<int32_t> child_int;
48};
49
Yves Gerey665174f2018-06-19 15:03:05 +020050WEBRTC_RTCSTATS_IMPL(RTCChildStats, RTCStats, "child-stats", &child_int);
hbos615d3012016-08-24 01:33:13 -070051
52class RTCGrandChildStats : public RTCChildStats {
53 public:
hbosfc5e0502016-10-06 02:06:10 -070054 WEBRTC_RTCSTATS_DECL();
55
hbos0e6758d2016-08-31 07:57:36 -070056 RTCGrandChildStats(const std::string& id, int64_t timestamp_us)
Yves Gerey665174f2018-06-19 15:03:05 +020057 : RTCChildStats(id, timestamp_us), grandchild_int("grandchildInt") {}
hbos615d3012016-08-24 01:33:13 -070058
hbos615d3012016-08-24 01:33:13 -070059 RTCStatsMember<int32_t> grandchild_int;
60};
61
Yves Gerey665174f2018-06-19 15:03:05 +020062WEBRTC_RTCSTATS_IMPL(RTCGrandChildStats,
63 RTCChildStats,
64 "grandchild-stats",
65 &grandchild_int);
hbos615d3012016-08-24 01:33:13 -070066
67TEST(RTCStatsTest, RTCStatsAndMembers) {
hbos0e6758d2016-08-31 07:57:36 -070068 RTCTestStats stats("testId", 42);
hbos615d3012016-08-24 01:33:13 -070069 EXPECT_EQ(stats.id(), "testId");
hbos0e6758d2016-08-31 07:57:36 -070070 EXPECT_EQ(stats.timestamp_us(), static_cast<int64_t>(42));
hbos615d3012016-08-24 01:33:13 -070071 std::vector<const RTCStatsMemberInterface*> members = stats.Members();
hbosb20f3872016-10-04 14:37:11 -070072 EXPECT_EQ(members.size(), static_cast<size_t>(14));
hbos615d3012016-08-24 01:33:13 -070073 for (const RTCStatsMemberInterface* member : members) {
74 EXPECT_FALSE(member->is_defined());
75 }
hbosb20f3872016-10-04 14:37:11 -070076 stats.m_bool = true;
hbos615d3012016-08-24 01:33:13 -070077 stats.m_int32 = 123;
78 stats.m_uint32 = 123;
79 stats.m_int64 = 123;
80 stats.m_uint64 = 123;
81 stats.m_double = 123.0;
hbos615d3012016-08-24 01:33:13 -070082 stats.m_string = std::string("123");
hbosfdafab82016-09-14 06:02:13 -070083
hbosb20f3872016-10-04 14:37:11 -070084 std::vector<bool> sequence_bool;
85 sequence_bool.push_back(true);
hbosfdafab82016-09-14 06:02:13 -070086 std::vector<int32_t> sequence_int32;
87 sequence_int32.push_back(static_cast<int32_t>(1));
88 std::vector<uint32_t> sequence_uint32;
89 sequence_uint32.push_back(static_cast<uint32_t>(2));
90 std::vector<int64_t> sequence_int64;
91 sequence_int64.push_back(static_cast<int64_t>(3));
92 std::vector<uint64_t> sequence_uint64;
93 sequence_uint64.push_back(static_cast<uint64_t>(4));
94 std::vector<double> sequence_double;
95 sequence_double.push_back(5.0);
hbosfdafab82016-09-14 06:02:13 -070096 std::vector<std::string> sequence_string;
hbos8faf9e02016-09-15 06:52:43 -070097 sequence_string.push_back(std::string("six"));
hbosfdafab82016-09-14 06:02:13 -070098
hbosb20f3872016-10-04 14:37:11 -070099 stats.m_sequence_bool = sequence_bool;
hbosfdafab82016-09-14 06:02:13 -0700100 stats.m_sequence_int32 = sequence_int32;
101 stats.m_sequence_uint32 = sequence_uint32;
hbos615d3012016-08-24 01:33:13 -0700102 EXPECT_FALSE(stats.m_sequence_int64.is_defined());
hbosfdafab82016-09-14 06:02:13 -0700103 stats.m_sequence_int64 = sequence_int64;
104 stats.m_sequence_uint64 = sequence_uint64;
105 stats.m_sequence_double = sequence_double;
hbosfdafab82016-09-14 06:02:13 -0700106 stats.m_sequence_string = sequence_string;
hbos615d3012016-08-24 01:33:13 -0700107 for (const RTCStatsMemberInterface* member : members) {
108 EXPECT_TRUE(member->is_defined());
109 }
hbosb20f3872016-10-04 14:37:11 -0700110 EXPECT_EQ(*stats.m_bool, true);
hbos615d3012016-08-24 01:33:13 -0700111 EXPECT_EQ(*stats.m_int32, static_cast<int32_t>(123));
112 EXPECT_EQ(*stats.m_uint32, static_cast<uint32_t>(123));
113 EXPECT_EQ(*stats.m_int64, static_cast<int64_t>(123));
114 EXPECT_EQ(*stats.m_uint64, static_cast<uint64_t>(123));
115 EXPECT_EQ(*stats.m_double, 123.0);
hbos615d3012016-08-24 01:33:13 -0700116 EXPECT_EQ(*stats.m_string, std::string("123"));
hbosb20f3872016-10-04 14:37:11 -0700117 EXPECT_EQ(*stats.m_sequence_bool, sequence_bool);
hbosfdafab82016-09-14 06:02:13 -0700118 EXPECT_EQ(*stats.m_sequence_int32, sequence_int32);
119 EXPECT_EQ(*stats.m_sequence_uint32, sequence_uint32);
120 EXPECT_EQ(*stats.m_sequence_int64, sequence_int64);
121 EXPECT_EQ(*stats.m_sequence_uint64, sequence_uint64);
122 EXPECT_EQ(*stats.m_sequence_double, sequence_double);
hbosfdafab82016-09-14 06:02:13 -0700123 EXPECT_EQ(*stats.m_sequence_string, sequence_string);
124
Yves Gerey665174f2018-06-19 15:03:05 +0200125 int32_t numbers[] = {4, 8, 15, 16, 23, 42};
hbosfdafab82016-09-14 06:02:13 -0700126 std::vector<int32_t> numbers_sequence(&numbers[0], &numbers[6]);
127 stats.m_sequence_int32->clear();
hbos615d3012016-08-24 01:33:13 -0700128 stats.m_sequence_int32->insert(stats.m_sequence_int32->end(),
129 numbers_sequence.begin(),
130 numbers_sequence.end());
131 EXPECT_EQ(*stats.m_sequence_int32, numbers_sequence);
132}
133
hbos67c8bc42016-10-25 04:31:23 -0700134TEST(RTCStatsTest, EqualityOperator) {
135 RTCTestStats empty_stats("testId", 123);
136 EXPECT_EQ(empty_stats, empty_stats);
137
138 RTCTestStats stats_with_all_values = empty_stats;
139 stats_with_all_values.m_bool = true;
140 stats_with_all_values.m_int32 = 123;
141 stats_with_all_values.m_uint32 = 123;
142 stats_with_all_values.m_int64 = 123;
143 stats_with_all_values.m_uint64 = 123;
144 stats_with_all_values.m_double = 123.0;
145 stats_with_all_values.m_string = "123";
146 stats_with_all_values.m_sequence_bool = std::vector<bool>();
147 stats_with_all_values.m_sequence_int32 = std::vector<int32_t>();
148 stats_with_all_values.m_sequence_uint32 = std::vector<uint32_t>();
149 stats_with_all_values.m_sequence_int64 = std::vector<int64_t>();
150 stats_with_all_values.m_sequence_uint64 = std::vector<uint64_t>();
151 stats_with_all_values.m_sequence_double = std::vector<double>();
152 stats_with_all_values.m_sequence_string = std::vector<std::string>();
153 EXPECT_NE(stats_with_all_values, empty_stats);
154 EXPECT_EQ(stats_with_all_values, stats_with_all_values);
155 EXPECT_NE(stats_with_all_values.m_int32, stats_with_all_values.m_uint32);
156
157 RTCTestStats one_member_different[] = {
Yves Gerey665174f2018-06-19 15:03:05 +0200158 stats_with_all_values, stats_with_all_values, stats_with_all_values,
159 stats_with_all_values, stats_with_all_values, stats_with_all_values,
160 stats_with_all_values, stats_with_all_values, stats_with_all_values,
161 stats_with_all_values, stats_with_all_values, stats_with_all_values,
162 stats_with_all_values, stats_with_all_values,
hbos67c8bc42016-10-25 04:31:23 -0700163 };
164 for (size_t i = 0; i < 14; ++i) {
165 EXPECT_EQ(stats_with_all_values, one_member_different[i]);
166 }
167 one_member_different[0].m_bool = false;
168 one_member_different[1].m_int32 = 321;
169 one_member_different[2].m_uint32 = 321;
170 one_member_different[3].m_int64 = 321;
171 one_member_different[4].m_uint64 = 321;
172 one_member_different[5].m_double = 321.0;
173 one_member_different[6].m_string = "321";
174 one_member_different[7].m_sequence_bool->push_back(false);
175 one_member_different[8].m_sequence_int32->push_back(321);
176 one_member_different[9].m_sequence_uint32->push_back(321);
177 one_member_different[10].m_sequence_int64->push_back(321);
178 one_member_different[11].m_sequence_uint64->push_back(321);
179 one_member_different[12].m_sequence_double->push_back(321.0);
180 one_member_different[13].m_sequence_string->push_back("321");
181 for (size_t i = 0; i < 14; ++i) {
182 EXPECT_NE(stats_with_all_values, one_member_different[i]);
183 }
184
185 RTCTestStats empty_stats_different_id("testId2", 123);
186 EXPECT_NE(empty_stats, empty_stats_different_id);
187 RTCTestStats empty_stats_different_timestamp("testId", 321);
hbos0583b282016-11-30 01:50:14 -0800188 EXPECT_EQ(empty_stats, empty_stats_different_timestamp);
hbos67c8bc42016-10-25 04:31:23 -0700189
190 RTCChildStats child("childId", 42);
191 RTCGrandChildStats grandchild("grandchildId", 42);
192 EXPECT_NE(child, grandchild);
hbos28747962016-11-21 09:17:41 -0800193
194 RTCChildStats stats_with_defined_member("leId", 0);
195 stats_with_defined_member.child_int = 0;
196 RTCChildStats stats_with_undefined_member("leId", 0);
197 EXPECT_NE(stats_with_defined_member, stats_with_undefined_member);
198 EXPECT_NE(stats_with_undefined_member, stats_with_defined_member);
hbos67c8bc42016-10-25 04:31:23 -0700199}
200
hbos615d3012016-08-24 01:33:13 -0700201TEST(RTCStatsTest, RTCStatsGrandChild) {
202 RTCGrandChildStats stats("grandchild", 0.0);
203 stats.child_int = 1;
204 stats.grandchild_int = 2;
205 int32_t sum = 0;
206 for (const RTCStatsMemberInterface* member : stats.Members()) {
207 sum += *member->cast_to<const RTCStatsMember<int32_t>>();
208 }
209 EXPECT_EQ(sum, static_cast<int32_t>(3));
210
211 std::unique_ptr<RTCStats> copy_ptr = stats.copy();
212 const RTCGrandChildStats& copy = copy_ptr->cast_to<RTCGrandChildStats>();
213 EXPECT_EQ(*copy.child_int, *stats.child_int);
214 EXPECT_EQ(*copy.grandchild_int, *stats.grandchild_int);
215}
216
ehmaldonado35a872c2017-07-28 07:29:12 -0700217TEST(RTCStatsTest, RTCStatsPrintsValidJson) {
218 std::string id = "statsId";
219 int timestamp = 42;
220 bool m_bool = true;
221 int m_int32 = 123;
222 int64_t m_int64 = 1234567890123456499L;
223 double m_double = 123.4567890123456499;
224 std::string m_string = "123";
225
226 std::vector<bool> sequence_bool;
227 std::vector<int32_t> sequence_int32;
228 sequence_int32.push_back(static_cast<int32_t>(1));
229 std::vector<int64_t> sequence_int64;
230 sequence_int64.push_back(static_cast<int64_t>(-1234567890123456499L));
231 sequence_int64.push_back(static_cast<int64_t>(1));
232 sequence_int64.push_back(static_cast<int64_t>(1234567890123456499L));
233 std::vector<double> sequence_double;
234 sequence_double.push_back(123.4567890123456499);
235 sequence_double.push_back(1234567890123.456499);
236 std::vector<std::string> sequence_string;
237 sequence_string.push_back(std::string("four"));
238
239 RTCTestStats stats(id, timestamp);
240 stats.m_bool = m_bool;
241 stats.m_int32 = m_int32;
242 stats.m_int64 = m_int64;
243 stats.m_double = m_double;
244 stats.m_string = m_string;
245 stats.m_sequence_bool = sequence_bool;
246 stats.m_sequence_int32 = sequence_int32;
247 stats.m_sequence_int64 = sequence_int64;
248 stats.m_sequence_double = sequence_double;
249 stats.m_sequence_string = sequence_string;
250
251 Json::Value json_output;
252 EXPECT_TRUE(Json::Reader().parse(stats.ToJson(), json_output));
253
254 EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "id", &id));
255 EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "timestamp", &timestamp));
256 EXPECT_TRUE(rtc::GetBoolFromJsonObject(json_output, "mBool", &m_bool));
257 EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "mInt32", &m_int32));
258 EXPECT_TRUE(rtc::GetDoubleFromJsonObject(json_output, "mDouble", &m_double));
259 EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "mString", &m_string));
260
261 Json::Value json_array;
262
263 EXPECT_TRUE(
264 rtc::GetValueFromJsonObject(json_output, "mSequenceBool", &json_array));
265 EXPECT_TRUE(rtc::JsonArrayToBoolVector(json_array, &sequence_bool));
266
267 EXPECT_TRUE(
268 rtc::GetValueFromJsonObject(json_output, "mSequenceInt32", &json_array));
269 EXPECT_TRUE(rtc::JsonArrayToIntVector(json_array, &sequence_int32));
270
271 EXPECT_TRUE(
272 rtc::GetValueFromJsonObject(json_output, "mSequenceDouble", &json_array));
273 EXPECT_TRUE(rtc::JsonArrayToDoubleVector(json_array, &sequence_double));
274
275 EXPECT_TRUE(
276 rtc::GetValueFromJsonObject(json_output, "mSequenceString", &json_array));
277 EXPECT_TRUE(rtc::JsonArrayToStringVector(json_array, &sequence_string));
278
279 EXPECT_EQ(id, stats.id());
280 EXPECT_EQ(timestamp, stats.timestamp_us());
281 EXPECT_EQ(m_bool, *stats.m_bool);
282 EXPECT_EQ(m_int32, *stats.m_int32);
283 EXPECT_EQ(m_string, *stats.m_string);
284 EXPECT_EQ(sequence_bool, *stats.m_sequence_bool);
285 EXPECT_EQ(sequence_int32, *stats.m_sequence_int32);
286 EXPECT_EQ(sequence_string, *stats.m_sequence_string);
287
288 EXPECT_NEAR(m_double, *stats.m_double, GetExpectedError(*stats.m_double));
289
290 EXPECT_EQ(sequence_double.size(), stats.m_sequence_double->size());
291 for (size_t i = 0; i < stats.m_sequence_double->size(); ++i) {
292 EXPECT_NEAR(sequence_double[i], stats.m_sequence_double->at(i),
293 GetExpectedError(stats.m_sequence_double->at(i)));
294 }
295
296 // We read mInt64 as double since JSON stores all numbers as doubles, so there
297 // is not enough precision to represent large numbers.
298 double m_int64_as_double;
299 std::vector<double> sequence_int64_as_double;
300
301 EXPECT_TRUE(
302 rtc::GetDoubleFromJsonObject(json_output, "mInt64", &m_int64_as_double));
303
304 EXPECT_TRUE(
305 rtc::GetValueFromJsonObject(json_output, "mSequenceInt64", &json_array));
306 EXPECT_TRUE(
307 rtc::JsonArrayToDoubleVector(json_array, &sequence_int64_as_double));
308
309 double stats_m_int64_as_double = static_cast<double>(*stats.m_int64);
310 EXPECT_NEAR(m_int64_as_double, stats_m_int64_as_double,
311 GetExpectedError(stats_m_int64_as_double));
312
313 EXPECT_EQ(sequence_int64_as_double.size(), stats.m_sequence_int64->size());
314 for (size_t i = 0; i < stats.m_sequence_int64->size(); ++i) {
315 const double stats_value_as_double =
316 static_cast<double>((*stats.m_sequence_int64)[i]);
317 EXPECT_NEAR(sequence_int64_as_double[i], stats_value_as_double,
318 GetExpectedError(stats_value_as_double));
319 }
320
321 // Neither stats.m_uint32 nor stats.m_uint64 are defined, so "mUint64" and
322 // "mUint32" should not be part of the generated JSON object.
323 int m_uint32;
324 int m_uint64;
325 EXPECT_FALSE(stats.m_uint32.is_defined());
326 EXPECT_FALSE(stats.m_uint64.is_defined());
327 EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint32", &m_uint32));
328 EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint64", &m_uint64));
329
330 std::cout << stats.ToJson() << std::endl;
331}
332
Taylor Brandstettere2751742018-06-25 13:42:44 -0700333TEST(RTCStatsTest, IsStandardized) {
334 RTCStatsMember<int32_t> standardized("standardized");
335 RTCNonStandardStatsMember<int32_t> unstandardized("unstandardized");
336 EXPECT_TRUE(standardized.is_standardized());
337 EXPECT_FALSE(unstandardized.is_standardized());
338}
339
hbos615d3012016-08-24 01:33:13 -0700340// Death tests.
341// Disabled on Android because death tests misbehave on Android, see
342// base/test/gtest_util.h.
343#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
344
345TEST(RTCStatsDeathTest, ValueOfUndefinedMember) {
346 RTCTestStats stats("testId", 0.0);
347 EXPECT_FALSE(stats.m_int32.is_defined());
348 EXPECT_DEATH(*stats.m_int32, "");
349}
350
351TEST(RTCStatsDeathTest, InvalidCasting) {
352 RTCGrandChildStats stats("grandchild", 0.0);
353 EXPECT_DEATH(stats.cast_to<RTCChildStats>(), "");
354}
355
356#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
357
358} // namespace webrtc