xref: /aosp_15_r20/external/webrtc/stats/rtc_stats_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "api/stats/rtc_stats.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <cmath>
14*d9f75844SAndroid Build Coastguard Worker #include <cstdint>
15*d9f75844SAndroid Build Coastguard Worker #include <cstring>
16*d9f75844SAndroid Build Coastguard Worker #include <iostream>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/json.h"
20*d9f75844SAndroid Build Coastguard Worker #include "stats/test/rtc_test_stats.h"
21*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
22*d9f75844SAndroid Build Coastguard Worker 
23*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
24*d9f75844SAndroid Build Coastguard Worker 
25*d9f75844SAndroid Build Coastguard Worker namespace {
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker // JSON stores numbers as floating point numbers with 53 significant bits, which
28*d9f75844SAndroid Build Coastguard Worker // amounts to about 15.95 decimal digits. Thus, when comparing large numbers
29*d9f75844SAndroid Build Coastguard Worker // processed by JSON, that's all the precision we should expect.
30*d9f75844SAndroid Build Coastguard Worker const double JSON_EPSILON = 1e-15;
31*d9f75844SAndroid Build Coastguard Worker 
32*d9f75844SAndroid Build Coastguard Worker // We do this since Google Test doesn't support relative error.
33*d9f75844SAndroid Build Coastguard Worker // This is computed as follows:
34*d9f75844SAndroid Build Coastguard Worker // If |a - b| / |a| < EPS, then |a - b| < |a| * EPS, so |a| * EPS is the
35*d9f75844SAndroid Build Coastguard Worker // maximum expected error.
GetExpectedError(const double expected_value)36*d9f75844SAndroid Build Coastguard Worker double GetExpectedError(const double expected_value) {
37*d9f75844SAndroid Build Coastguard Worker   return JSON_EPSILON * fabs(expected_value);
38*d9f75844SAndroid Build Coastguard Worker }
39*d9f75844SAndroid Build Coastguard Worker 
40*d9f75844SAndroid Build Coastguard Worker }  // namespace
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker class RTCChildStats : public RTCStats {
43*d9f75844SAndroid Build Coastguard Worker  public:
44*d9f75844SAndroid Build Coastguard Worker   WEBRTC_RTCSTATS_DECL();
45*d9f75844SAndroid Build Coastguard Worker 
RTCChildStats(const std::string & id,int64_t timestamp_us)46*d9f75844SAndroid Build Coastguard Worker   RTCChildStats(const std::string& id, int64_t timestamp_us)
47*d9f75844SAndroid Build Coastguard Worker       : RTCStats(id, timestamp_us), child_int("childInt") {}
48*d9f75844SAndroid Build Coastguard Worker 
49*d9f75844SAndroid Build Coastguard Worker   RTCStatsMember<int32_t> child_int;
50*d9f75844SAndroid Build Coastguard Worker };
51*d9f75844SAndroid Build Coastguard Worker 
52*d9f75844SAndroid Build Coastguard Worker WEBRTC_RTCSTATS_IMPL(RTCChildStats, RTCStats, "child-stats", &child_int)
53*d9f75844SAndroid Build Coastguard Worker 
54*d9f75844SAndroid Build Coastguard Worker class RTCGrandChildStats : public RTCChildStats {
55*d9f75844SAndroid Build Coastguard Worker  public:
56*d9f75844SAndroid Build Coastguard Worker   WEBRTC_RTCSTATS_DECL();
57*d9f75844SAndroid Build Coastguard Worker 
RTCGrandChildStats(const std::string & id,int64_t timestamp_us)58*d9f75844SAndroid Build Coastguard Worker   RTCGrandChildStats(const std::string& id, int64_t timestamp_us)
59*d9f75844SAndroid Build Coastguard Worker       : RTCChildStats(id, timestamp_us), grandchild_int("grandchildInt") {}
60*d9f75844SAndroid Build Coastguard Worker 
61*d9f75844SAndroid Build Coastguard Worker   RTCStatsMember<int32_t> grandchild_int;
62*d9f75844SAndroid Build Coastguard Worker };
63*d9f75844SAndroid Build Coastguard Worker 
64*d9f75844SAndroid Build Coastguard Worker WEBRTC_RTCSTATS_IMPL(RTCGrandChildStats,
65*d9f75844SAndroid Build Coastguard Worker                      RTCChildStats,
66*d9f75844SAndroid Build Coastguard Worker                      "grandchild-stats",
67*d9f75844SAndroid Build Coastguard Worker                      &grandchild_int)
68*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,RTCStatsAndMembers)69*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, RTCStatsAndMembers) {
70*d9f75844SAndroid Build Coastguard Worker   RTCTestStats stats("testId", 42);
71*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(stats.id(), "testId");
72*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(stats.timestamp_us(), static_cast<int64_t>(42));
73*d9f75844SAndroid Build Coastguard Worker   std::vector<const RTCStatsMemberInterface*> members = stats.Members();
74*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(members.size(), static_cast<size_t>(16));
75*d9f75844SAndroid Build Coastguard Worker   for (const RTCStatsMemberInterface* member : members) {
76*d9f75844SAndroid Build Coastguard Worker     EXPECT_FALSE(member->is_defined());
77*d9f75844SAndroid Build Coastguard Worker   }
78*d9f75844SAndroid Build Coastguard Worker   stats.m_bool = true;
79*d9f75844SAndroid Build Coastguard Worker   stats.m_int32 = 123;
80*d9f75844SAndroid Build Coastguard Worker   stats.m_uint32 = 123;
81*d9f75844SAndroid Build Coastguard Worker   stats.m_int64 = 123;
82*d9f75844SAndroid Build Coastguard Worker   stats.m_uint64 = 123;
83*d9f75844SAndroid Build Coastguard Worker   stats.m_double = 123.0;
84*d9f75844SAndroid Build Coastguard Worker   stats.m_string = std::string("123");
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker   std::vector<bool> sequence_bool;
87*d9f75844SAndroid Build Coastguard Worker   sequence_bool.push_back(true);
88*d9f75844SAndroid Build Coastguard Worker   std::vector<int32_t> sequence_int32;
89*d9f75844SAndroid Build Coastguard Worker   sequence_int32.push_back(static_cast<int32_t>(1));
90*d9f75844SAndroid Build Coastguard Worker   std::vector<uint32_t> sequence_uint32;
91*d9f75844SAndroid Build Coastguard Worker   sequence_uint32.push_back(static_cast<uint32_t>(2));
92*d9f75844SAndroid Build Coastguard Worker   std::vector<int64_t> sequence_int64;
93*d9f75844SAndroid Build Coastguard Worker   sequence_int64.push_back(static_cast<int64_t>(3));
94*d9f75844SAndroid Build Coastguard Worker   std::vector<uint64_t> sequence_uint64;
95*d9f75844SAndroid Build Coastguard Worker   sequence_uint64.push_back(static_cast<uint64_t>(4));
96*d9f75844SAndroid Build Coastguard Worker   std::vector<double> sequence_double;
97*d9f75844SAndroid Build Coastguard Worker   sequence_double.push_back(5.0);
98*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> sequence_string;
99*d9f75844SAndroid Build Coastguard Worker   sequence_string.push_back(std::string("six"));
100*d9f75844SAndroid Build Coastguard Worker 
101*d9f75844SAndroid Build Coastguard Worker   std::map<std::string, uint64_t> map_string_uint64{{"seven", 8}};
102*d9f75844SAndroid Build Coastguard Worker   std::map<std::string, double> map_string_double{{"nine", 10.0}};
103*d9f75844SAndroid Build Coastguard Worker 
104*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_bool = sequence_bool;
105*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_int32 = sequence_int32;
106*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_uint32 = sequence_uint32;
107*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_sequence_int64.is_defined());
108*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_int64 = sequence_int64;
109*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_uint64 = sequence_uint64;
110*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_double = sequence_double;
111*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_string = sequence_string;
112*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_uint64 = map_string_uint64;
113*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_double = map_string_double;
114*d9f75844SAndroid Build Coastguard Worker   for (const RTCStatsMemberInterface* member : members) {
115*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(member->is_defined());
116*d9f75844SAndroid Build Coastguard Worker   }
117*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_bool, true);
118*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_int32, static_cast<int32_t>(123));
119*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_uint32, static_cast<uint32_t>(123));
120*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_int64, static_cast<int64_t>(123));
121*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_uint64, static_cast<uint64_t>(123));
122*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_double, 123.0);
123*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_string, std::string("123"));
124*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_sequence_bool, sequence_bool);
125*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_sequence_int32, sequence_int32);
126*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_sequence_uint32, sequence_uint32);
127*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_sequence_int64, sequence_int64);
128*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_sequence_uint64, sequence_uint64);
129*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_sequence_double, sequence_double);
130*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_sequence_string, sequence_string);
131*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_map_string_uint64, map_string_uint64);
132*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_map_string_double, map_string_double);
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker   int32_t numbers[] = {4, 8, 15, 16, 23, 42};
135*d9f75844SAndroid Build Coastguard Worker   std::vector<int32_t> numbers_sequence(&numbers[0], &numbers[6]);
136*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_int32->clear();
137*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_int32->insert(stats.m_sequence_int32->end(),
138*d9f75844SAndroid Build Coastguard Worker                                  numbers_sequence.begin(),
139*d9f75844SAndroid Build Coastguard Worker                                  numbers_sequence.end());
140*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*stats.m_sequence_int32, numbers_sequence);
141*d9f75844SAndroid Build Coastguard Worker }
142*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,EqualityOperator)143*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, EqualityOperator) {
144*d9f75844SAndroid Build Coastguard Worker   RTCTestStats empty_stats("testId", 123);
145*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(empty_stats, empty_stats);
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker   RTCTestStats stats_with_all_values = empty_stats;
148*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_bool = true;
149*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_int32 = 123;
150*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_uint32 = 123;
151*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_int64 = 123;
152*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_uint64 = 123;
153*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_double = 123.0;
154*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_string = "123";
155*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_sequence_bool = std::vector<bool>();
156*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_sequence_int32 = std::vector<int32_t>();
157*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_sequence_uint32 = std::vector<uint32_t>();
158*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_sequence_int64 = std::vector<int64_t>();
159*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_sequence_uint64 = std::vector<uint64_t>();
160*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_sequence_double = std::vector<double>();
161*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_sequence_string = std::vector<std::string>();
162*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_map_string_uint64 = std::map<std::string, uint64_t>();
163*d9f75844SAndroid Build Coastguard Worker   stats_with_all_values.m_map_string_double = std::map<std::string, double>();
164*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(stats_with_all_values, empty_stats);
165*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(stats_with_all_values, stats_with_all_values);
166*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(stats_with_all_values.m_int32, stats_with_all_values.m_uint32);
167*d9f75844SAndroid Build Coastguard Worker 
168*d9f75844SAndroid Build Coastguard Worker   RTCTestStats one_member_different[] = {
169*d9f75844SAndroid Build Coastguard Worker       stats_with_all_values, stats_with_all_values, stats_with_all_values,
170*d9f75844SAndroid Build Coastguard Worker       stats_with_all_values, stats_with_all_values, stats_with_all_values,
171*d9f75844SAndroid Build Coastguard Worker       stats_with_all_values, stats_with_all_values, stats_with_all_values,
172*d9f75844SAndroid Build Coastguard Worker       stats_with_all_values, stats_with_all_values, stats_with_all_values,
173*d9f75844SAndroid Build Coastguard Worker       stats_with_all_values, stats_with_all_values,
174*d9f75844SAndroid Build Coastguard Worker   };
175*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < 14; ++i) {
176*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(stats_with_all_values, one_member_different[i]);
177*d9f75844SAndroid Build Coastguard Worker   }
178*d9f75844SAndroid Build Coastguard Worker   one_member_different[0].m_bool = false;
179*d9f75844SAndroid Build Coastguard Worker   one_member_different[1].m_int32 = 321;
180*d9f75844SAndroid Build Coastguard Worker   one_member_different[2].m_uint32 = 321;
181*d9f75844SAndroid Build Coastguard Worker   one_member_different[3].m_int64 = 321;
182*d9f75844SAndroid Build Coastguard Worker   one_member_different[4].m_uint64 = 321;
183*d9f75844SAndroid Build Coastguard Worker   one_member_different[5].m_double = 321.0;
184*d9f75844SAndroid Build Coastguard Worker   one_member_different[6].m_string = "321";
185*d9f75844SAndroid Build Coastguard Worker   one_member_different[7].m_sequence_bool->push_back(false);
186*d9f75844SAndroid Build Coastguard Worker   one_member_different[8].m_sequence_int32->push_back(321);
187*d9f75844SAndroid Build Coastguard Worker   one_member_different[9].m_sequence_uint32->push_back(321);
188*d9f75844SAndroid Build Coastguard Worker   one_member_different[10].m_sequence_int64->push_back(321);
189*d9f75844SAndroid Build Coastguard Worker   one_member_different[11].m_sequence_uint64->push_back(321);
190*d9f75844SAndroid Build Coastguard Worker   one_member_different[12].m_sequence_double->push_back(321.0);
191*d9f75844SAndroid Build Coastguard Worker   one_member_different[13].m_sequence_string->push_back("321");
192*d9f75844SAndroid Build Coastguard Worker   (*one_member_different[13].m_map_string_uint64)["321"] = 321;
193*d9f75844SAndroid Build Coastguard Worker   (*one_member_different[13].m_map_string_double)["321"] = 321.0;
194*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < 14; ++i) {
195*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(stats_with_all_values, one_member_different[i]);
196*d9f75844SAndroid Build Coastguard Worker   }
197*d9f75844SAndroid Build Coastguard Worker 
198*d9f75844SAndroid Build Coastguard Worker   RTCTestStats empty_stats_different_id("testId2", 123);
199*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(empty_stats, empty_stats_different_id);
200*d9f75844SAndroid Build Coastguard Worker   RTCTestStats empty_stats_different_timestamp("testId", 321);
201*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(empty_stats, empty_stats_different_timestamp);
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker   RTCChildStats child("childId", 42);
204*d9f75844SAndroid Build Coastguard Worker   RTCGrandChildStats grandchild("grandchildId", 42);
205*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(child, grandchild);
206*d9f75844SAndroid Build Coastguard Worker 
207*d9f75844SAndroid Build Coastguard Worker   RTCChildStats stats_with_defined_member("leId", 0);
208*d9f75844SAndroid Build Coastguard Worker   stats_with_defined_member.child_int = 0;
209*d9f75844SAndroid Build Coastguard Worker   RTCChildStats stats_with_undefined_member("leId", 0);
210*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(stats_with_defined_member, stats_with_undefined_member);
211*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(stats_with_undefined_member, stats_with_defined_member);
212*d9f75844SAndroid Build Coastguard Worker }
213*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,RTCStatsGrandChild)214*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, RTCStatsGrandChild) {
215*d9f75844SAndroid Build Coastguard Worker   RTCGrandChildStats stats("grandchild", 0.0);
216*d9f75844SAndroid Build Coastguard Worker   stats.child_int = 1;
217*d9f75844SAndroid Build Coastguard Worker   stats.grandchild_int = 2;
218*d9f75844SAndroid Build Coastguard Worker   int32_t sum = 0;
219*d9f75844SAndroid Build Coastguard Worker   for (const RTCStatsMemberInterface* member : stats.Members()) {
220*d9f75844SAndroid Build Coastguard Worker     sum += *member->cast_to<const RTCStatsMember<int32_t>>();
221*d9f75844SAndroid Build Coastguard Worker   }
222*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sum, static_cast<int32_t>(3));
223*d9f75844SAndroid Build Coastguard Worker 
224*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<RTCStats> copy_ptr = stats.copy();
225*d9f75844SAndroid Build Coastguard Worker   const RTCGrandChildStats& copy = copy_ptr->cast_to<RTCGrandChildStats>();
226*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*copy.child_int, *stats.child_int);
227*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(*copy.grandchild_int, *stats.grandchild_int);
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,RTCStatsPrintsValidJson)230*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, RTCStatsPrintsValidJson) {
231*d9f75844SAndroid Build Coastguard Worker   std::string id = "statsId";
232*d9f75844SAndroid Build Coastguard Worker   int timestamp = 42;
233*d9f75844SAndroid Build Coastguard Worker   bool m_bool = true;
234*d9f75844SAndroid Build Coastguard Worker   int m_int32 = 123;
235*d9f75844SAndroid Build Coastguard Worker   int64_t m_int64 = 1234567890123456499L;
236*d9f75844SAndroid Build Coastguard Worker   double m_double = 123.4567890123456499;
237*d9f75844SAndroid Build Coastguard Worker   std::string m_string = "123";
238*d9f75844SAndroid Build Coastguard Worker 
239*d9f75844SAndroid Build Coastguard Worker   std::vector<bool> sequence_bool;
240*d9f75844SAndroid Build Coastguard Worker   std::vector<int32_t> sequence_int32;
241*d9f75844SAndroid Build Coastguard Worker   sequence_int32.push_back(static_cast<int32_t>(1));
242*d9f75844SAndroid Build Coastguard Worker   std::vector<int64_t> sequence_int64;
243*d9f75844SAndroid Build Coastguard Worker   sequence_int64.push_back(static_cast<int64_t>(-1234567890123456499L));
244*d9f75844SAndroid Build Coastguard Worker   sequence_int64.push_back(static_cast<int64_t>(1));
245*d9f75844SAndroid Build Coastguard Worker   sequence_int64.push_back(static_cast<int64_t>(1234567890123456499L));
246*d9f75844SAndroid Build Coastguard Worker   std::vector<double> sequence_double;
247*d9f75844SAndroid Build Coastguard Worker   sequence_double.push_back(123.4567890123456499);
248*d9f75844SAndroid Build Coastguard Worker   sequence_double.push_back(1234567890123.456499);
249*d9f75844SAndroid Build Coastguard Worker   std::vector<std::string> sequence_string;
250*d9f75844SAndroid Build Coastguard Worker   sequence_string.push_back(std::string("four"));
251*d9f75844SAndroid Build Coastguard Worker 
252*d9f75844SAndroid Build Coastguard Worker   std::map<std::string, uint64_t> map_string_uint64{
253*d9f75844SAndroid Build Coastguard Worker       {"long", static_cast<uint64_t>(1234567890123456499L)}};
254*d9f75844SAndroid Build Coastguard Worker   std::map<std::string, double> map_string_double{
255*d9f75844SAndroid Build Coastguard Worker       {"three", 123.4567890123456499}, {"thirteen", 123.4567890123456499}};
256*d9f75844SAndroid Build Coastguard Worker 
257*d9f75844SAndroid Build Coastguard Worker   RTCTestStats stats(id, timestamp);
258*d9f75844SAndroid Build Coastguard Worker   stats.m_bool = m_bool;
259*d9f75844SAndroid Build Coastguard Worker   stats.m_int32 = m_int32;
260*d9f75844SAndroid Build Coastguard Worker   stats.m_int64 = m_int64;
261*d9f75844SAndroid Build Coastguard Worker   stats.m_double = m_double;
262*d9f75844SAndroid Build Coastguard Worker   stats.m_string = m_string;
263*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_bool = sequence_bool;
264*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_int32 = sequence_int32;
265*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_int64 = sequence_int64;
266*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_double = sequence_double;
267*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_string = sequence_string;
268*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_uint64 = map_string_uint64;
269*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_double = map_string_double;
270*d9f75844SAndroid Build Coastguard Worker   std::string json_stats = stats.ToJson();
271*d9f75844SAndroid Build Coastguard Worker 
272*d9f75844SAndroid Build Coastguard Worker   Json::CharReaderBuilder builder;
273*d9f75844SAndroid Build Coastguard Worker   Json::Value json_output;
274*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Json::CharReader> json_reader(builder.newCharReader());
275*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(json_reader->parse(json_stats.c_str(),
276*d9f75844SAndroid Build Coastguard Worker                                  json_stats.c_str() + json_stats.size(),
277*d9f75844SAndroid Build Coastguard Worker                                  &json_output, nullptr));
278*d9f75844SAndroid Build Coastguard Worker 
279*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "id", &id));
280*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "timestamp", &timestamp));
281*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::GetBoolFromJsonObject(json_output, "mBool", &m_bool));
282*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "mInt32", &m_int32));
283*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::GetDoubleFromJsonObject(json_output, "mDouble", &m_double));
284*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "mString", &m_string));
285*d9f75844SAndroid Build Coastguard Worker 
286*d9f75844SAndroid Build Coastguard Worker   Json::Value json_array;
287*d9f75844SAndroid Build Coastguard Worker 
288*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
289*d9f75844SAndroid Build Coastguard Worker       rtc::GetValueFromJsonObject(json_output, "mSequenceBool", &json_array));
290*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::JsonArrayToBoolVector(json_array, &sequence_bool));
291*d9f75844SAndroid Build Coastguard Worker 
292*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
293*d9f75844SAndroid Build Coastguard Worker       rtc::GetValueFromJsonObject(json_output, "mSequenceInt32", &json_array));
294*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::JsonArrayToIntVector(json_array, &sequence_int32));
295*d9f75844SAndroid Build Coastguard Worker 
296*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
297*d9f75844SAndroid Build Coastguard Worker       rtc::GetValueFromJsonObject(json_output, "mSequenceDouble", &json_array));
298*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::JsonArrayToDoubleVector(json_array, &sequence_double));
299*d9f75844SAndroid Build Coastguard Worker 
300*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
301*d9f75844SAndroid Build Coastguard Worker       rtc::GetValueFromJsonObject(json_output, "mSequenceString", &json_array));
302*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(rtc::JsonArrayToStringVector(json_array, &sequence_string));
303*d9f75844SAndroid Build Coastguard Worker 
304*d9f75844SAndroid Build Coastguard Worker   Json::Value json_map;
305*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
306*d9f75844SAndroid Build Coastguard Worker       rtc::GetValueFromJsonObject(json_output, "mMapStringDouble", &json_map));
307*d9f75844SAndroid Build Coastguard Worker   for (const auto& entry : map_string_double) {
308*d9f75844SAndroid Build Coastguard Worker     double double_output = 0.0;
309*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(
310*d9f75844SAndroid Build Coastguard Worker         rtc::GetDoubleFromJsonObject(json_map, entry.first, &double_output));
311*d9f75844SAndroid Build Coastguard Worker     EXPECT_NEAR(double_output, entry.second, GetExpectedError(entry.second));
312*d9f75844SAndroid Build Coastguard Worker   }
313*d9f75844SAndroid Build Coastguard Worker 
314*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(id, stats.id());
315*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(timestamp, stats.timestamp_us());
316*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(m_bool, *stats.m_bool);
317*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(m_int32, *stats.m_int32);
318*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(m_string, *stats.m_string);
319*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sequence_bool, *stats.m_sequence_bool);
320*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sequence_int32, *stats.m_sequence_int32);
321*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sequence_string, *stats.m_sequence_string);
322*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(map_string_double, *stats.m_map_string_double);
323*d9f75844SAndroid Build Coastguard Worker 
324*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(m_double, *stats.m_double, GetExpectedError(*stats.m_double));
325*d9f75844SAndroid Build Coastguard Worker 
326*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sequence_double.size(), stats.m_sequence_double->size());
327*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < stats.m_sequence_double->size(); ++i) {
328*d9f75844SAndroid Build Coastguard Worker     EXPECT_NEAR(sequence_double[i], stats.m_sequence_double->at(i),
329*d9f75844SAndroid Build Coastguard Worker                 GetExpectedError(stats.m_sequence_double->at(i)));
330*d9f75844SAndroid Build Coastguard Worker   }
331*d9f75844SAndroid Build Coastguard Worker 
332*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(map_string_double.size(), stats.m_map_string_double->size());
333*d9f75844SAndroid Build Coastguard Worker   for (const auto& entry : map_string_double) {
334*d9f75844SAndroid Build Coastguard Worker     auto it = stats.m_map_string_double->find(entry.first);
335*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(it, stats.m_map_string_double->end());
336*d9f75844SAndroid Build Coastguard Worker     EXPECT_NEAR(entry.second, it->second, GetExpectedError(it->second));
337*d9f75844SAndroid Build Coastguard Worker   }
338*d9f75844SAndroid Build Coastguard Worker 
339*d9f75844SAndroid Build Coastguard Worker   // We read mInt64 as double since JSON stores all numbers as doubles, so there
340*d9f75844SAndroid Build Coastguard Worker   // is not enough precision to represent large numbers.
341*d9f75844SAndroid Build Coastguard Worker   double m_int64_as_double;
342*d9f75844SAndroid Build Coastguard Worker   std::vector<double> sequence_int64_as_double;
343*d9f75844SAndroid Build Coastguard Worker 
344*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
345*d9f75844SAndroid Build Coastguard Worker       rtc::GetDoubleFromJsonObject(json_output, "mInt64", &m_int64_as_double));
346*d9f75844SAndroid Build Coastguard Worker 
347*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
348*d9f75844SAndroid Build Coastguard Worker       rtc::GetValueFromJsonObject(json_output, "mSequenceInt64", &json_array));
349*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
350*d9f75844SAndroid Build Coastguard Worker       rtc::JsonArrayToDoubleVector(json_array, &sequence_int64_as_double));
351*d9f75844SAndroid Build Coastguard Worker 
352*d9f75844SAndroid Build Coastguard Worker   double stats_m_int64_as_double = static_cast<double>(*stats.m_int64);
353*d9f75844SAndroid Build Coastguard Worker   EXPECT_NEAR(m_int64_as_double, stats_m_int64_as_double,
354*d9f75844SAndroid Build Coastguard Worker               GetExpectedError(stats_m_int64_as_double));
355*d9f75844SAndroid Build Coastguard Worker 
356*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(sequence_int64_as_double.size(), stats.m_sequence_int64->size());
357*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < stats.m_sequence_int64->size(); ++i) {
358*d9f75844SAndroid Build Coastguard Worker     const double stats_value_as_double =
359*d9f75844SAndroid Build Coastguard Worker         static_cast<double>((*stats.m_sequence_int64)[i]);
360*d9f75844SAndroid Build Coastguard Worker     EXPECT_NEAR(sequence_int64_as_double[i], stats_value_as_double,
361*d9f75844SAndroid Build Coastguard Worker                 GetExpectedError(stats_value_as_double));
362*d9f75844SAndroid Build Coastguard Worker   }
363*d9f75844SAndroid Build Coastguard Worker 
364*d9f75844SAndroid Build Coastguard Worker   // Similarly, read Uint64 as double
365*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(
366*d9f75844SAndroid Build Coastguard Worker       rtc::GetValueFromJsonObject(json_output, "mMapStringUint64", &json_map));
367*d9f75844SAndroid Build Coastguard Worker   for (const auto& entry : map_string_uint64) {
368*d9f75844SAndroid Build Coastguard Worker     const double stats_value_as_double =
369*d9f75844SAndroid Build Coastguard Worker         static_cast<double>((*stats.m_map_string_uint64)[entry.first]);
370*d9f75844SAndroid Build Coastguard Worker     double double_output = 0.0;
371*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(
372*d9f75844SAndroid Build Coastguard Worker         rtc::GetDoubleFromJsonObject(json_map, entry.first, &double_output));
373*d9f75844SAndroid Build Coastguard Worker     EXPECT_NEAR(double_output, stats_value_as_double,
374*d9f75844SAndroid Build Coastguard Worker                 GetExpectedError(stats_value_as_double));
375*d9f75844SAndroid Build Coastguard Worker   }
376*d9f75844SAndroid Build Coastguard Worker 
377*d9f75844SAndroid Build Coastguard Worker   // Neither stats.m_uint32 nor stats.m_uint64 are defined, so "mUint64" and
378*d9f75844SAndroid Build Coastguard Worker   // "mUint32" should not be part of the generated JSON object.
379*d9f75844SAndroid Build Coastguard Worker   int m_uint32;
380*d9f75844SAndroid Build Coastguard Worker   int m_uint64;
381*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_uint32.is_defined());
382*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_uint64.is_defined());
383*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint32", &m_uint32));
384*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint64", &m_uint64));
385*d9f75844SAndroid Build Coastguard Worker 
386*d9f75844SAndroid Build Coastguard Worker   std::cout << stats.ToJson() << std::endl;
387*d9f75844SAndroid Build Coastguard Worker }
388*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,IsStandardized)389*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, IsStandardized) {
390*d9f75844SAndroid Build Coastguard Worker   RTCStatsMember<int32_t> standardized("standardized");
391*d9f75844SAndroid Build Coastguard Worker   RTCNonStandardStatsMember<int32_t> unstandardized("unstandardized");
392*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(standardized.is_standardized());
393*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(unstandardized.is_standardized());
394*d9f75844SAndroid Build Coastguard Worker }
395*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,IsSequence)396*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, IsSequence) {
397*d9f75844SAndroid Build Coastguard Worker   RTCTestStats stats("statsId", 42);
398*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_bool.is_sequence());
399*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_int32.is_sequence());
400*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_uint32.is_sequence());
401*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_int64.is_sequence());
402*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_uint64.is_sequence());
403*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_double.is_sequence());
404*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_string.is_sequence());
405*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(stats.m_sequence_bool.is_sequence());
406*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(stats.m_sequence_int32.is_sequence());
407*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(stats.m_sequence_uint32.is_sequence());
408*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(stats.m_sequence_int64.is_sequence());
409*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(stats.m_sequence_uint64.is_sequence());
410*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(stats.m_sequence_double.is_sequence());
411*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(stats.m_sequence_string.is_sequence());
412*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_map_string_uint64.is_sequence());
413*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_map_string_double.is_sequence());
414*d9f75844SAndroid Build Coastguard Worker }
415*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,Type)416*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, Type) {
417*d9f75844SAndroid Build Coastguard Worker   RTCTestStats stats("statsId", 42);
418*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kBool, stats.m_bool.type());
419*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kInt32, stats.m_int32.type());
420*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kUint32, stats.m_uint32.type());
421*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kInt64, stats.m_int64.type());
422*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kUint64, stats.m_uint64.type());
423*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kDouble, stats.m_double.type());
424*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kString, stats.m_string.type());
425*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kSequenceBool,
426*d9f75844SAndroid Build Coastguard Worker             stats.m_sequence_bool.type());
427*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kSequenceInt32,
428*d9f75844SAndroid Build Coastguard Worker             stats.m_sequence_int32.type());
429*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kSequenceUint32,
430*d9f75844SAndroid Build Coastguard Worker             stats.m_sequence_uint32.type());
431*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kSequenceInt64,
432*d9f75844SAndroid Build Coastguard Worker             stats.m_sequence_int64.type());
433*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kSequenceUint64,
434*d9f75844SAndroid Build Coastguard Worker             stats.m_sequence_uint64.type());
435*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kSequenceDouble,
436*d9f75844SAndroid Build Coastguard Worker             stats.m_sequence_double.type());
437*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kSequenceString,
438*d9f75844SAndroid Build Coastguard Worker             stats.m_sequence_string.type());
439*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kMapStringUint64,
440*d9f75844SAndroid Build Coastguard Worker             stats.m_map_string_uint64.type());
441*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(RTCStatsMemberInterface::kMapStringDouble,
442*d9f75844SAndroid Build Coastguard Worker             stats.m_map_string_double.type());
443*d9f75844SAndroid Build Coastguard Worker }
444*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,IsString)445*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, IsString) {
446*d9f75844SAndroid Build Coastguard Worker   RTCTestStats stats("statsId", 42);
447*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(stats.m_string.is_string());
448*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_bool.is_string());
449*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_int32.is_string());
450*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_uint32.is_string());
451*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_int64.is_string());
452*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_uint64.is_string());
453*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_double.is_string());
454*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_sequence_bool.is_string());
455*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_sequence_int32.is_string());
456*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_sequence_uint32.is_string());
457*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_sequence_int64.is_string());
458*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_sequence_uint64.is_string());
459*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_sequence_double.is_string());
460*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_sequence_string.is_string());
461*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_map_string_uint64.is_string());
462*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_map_string_double.is_string());
463*d9f75844SAndroid Build Coastguard Worker }
464*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,ValueToString)465*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, ValueToString) {
466*d9f75844SAndroid Build Coastguard Worker   RTCTestStats stats("statsId", 42);
467*d9f75844SAndroid Build Coastguard Worker   stats.m_bool = true;
468*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("true", stats.m_bool.ValueToString());
469*d9f75844SAndroid Build Coastguard Worker 
470*d9f75844SAndroid Build Coastguard Worker   stats.m_string = "foo";
471*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("foo", stats.m_string.ValueToString());
472*d9f75844SAndroid Build Coastguard Worker   stats.m_int32 = -32;
473*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("-32", stats.m_int32.ValueToString());
474*d9f75844SAndroid Build Coastguard Worker   stats.m_uint32 = 32;
475*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("32", stats.m_uint32.ValueToString());
476*d9f75844SAndroid Build Coastguard Worker   stats.m_int64 = -64;
477*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("-64", stats.m_int64.ValueToString());
478*d9f75844SAndroid Build Coastguard Worker   stats.m_uint64 = 64;
479*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("64", stats.m_uint64.ValueToString());
480*d9f75844SAndroid Build Coastguard Worker   stats.m_double = 0.5;
481*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("0.5", stats.m_double.ValueToString());
482*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_bool = {true, false};
483*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("[true,false]", stats.m_sequence_bool.ValueToString());
484*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_int32 = {-32, 32};
485*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("[-32,32]", stats.m_sequence_int32.ValueToString());
486*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_uint32 = {64, 32};
487*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("[64,32]", stats.m_sequence_uint32.ValueToString());
488*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_int64 = {-64, 32};
489*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("[-64,32]", stats.m_sequence_int64.ValueToString());
490*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_uint64 = {16, 32};
491*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("[16,32]", stats.m_sequence_uint64.ValueToString());
492*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_double = {0.5, 0.25};
493*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("[0.5,0.25]", stats.m_sequence_double.ValueToString());
494*d9f75844SAndroid Build Coastguard Worker   stats.m_sequence_string = {"foo", "bar"};
495*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("[\"foo\",\"bar\"]", stats.m_sequence_string.ValueToString());
496*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_uint64 = std::map<std::string, uint64_t>();
497*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_uint64->emplace("foo", 32);
498*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_uint64->emplace("bar", 64);
499*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("{bar:64,foo:32}", stats.m_map_string_uint64.ValueToString());
500*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_double = std::map<std::string, double>();
501*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_double->emplace("foo", 0.5);
502*d9f75844SAndroid Build Coastguard Worker   stats.m_map_string_double->emplace("bar", 0.25);
503*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ("{bar:0.25,foo:0.5}", stats.m_map_string_double.ValueToString());
504*d9f75844SAndroid Build Coastguard Worker }
505*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,RestrictedStatsTest)506*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, RestrictedStatsTest) {
507*d9f75844SAndroid Build Coastguard Worker   RTCStatsMember<bool> unrestricted("unrestricted");
508*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(unrestricted.exposure_criteria(), StatExposureCriteria::kAlways);
509*d9f75844SAndroid Build Coastguard Worker   RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>
510*d9f75844SAndroid Build Coastguard Worker       restricted("restricted");
511*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(restricted.exposure_criteria(),
512*d9f75844SAndroid Build Coastguard Worker             StatExposureCriteria::kHardwareCapability);
513*d9f75844SAndroid Build Coastguard Worker 
514*d9f75844SAndroid Build Coastguard Worker   unrestricted = true;
515*d9f75844SAndroid Build Coastguard Worker   restricted = true;
516*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(unrestricted, restricted)
517*d9f75844SAndroid Build Coastguard Worker       << "These can not be equal as they have different exposure criteria.";
518*d9f75844SAndroid Build Coastguard Worker }
519*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsTest,NonStandardGroupId)520*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsTest, NonStandardGroupId) {
521*d9f75844SAndroid Build Coastguard Worker   auto group_id = NonStandardGroupId::kGroupIdForTesting;
522*d9f75844SAndroid Build Coastguard Worker   RTCNonStandardStatsMember<int32_t> with_group_id("stat", {group_id});
523*d9f75844SAndroid Build Coastguard Worker   std::vector<NonStandardGroupId> expected_ids({group_id});
524*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(expected_ids, with_group_id.group_ids());
525*d9f75844SAndroid Build Coastguard Worker 
526*d9f75844SAndroid Build Coastguard Worker   RTCNonStandardStatsMember<int32_t> without_group_id("stat");
527*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(without_group_id.group_ids().empty());
528*d9f75844SAndroid Build Coastguard Worker }
529*d9f75844SAndroid Build Coastguard Worker 
530*d9f75844SAndroid Build Coastguard Worker // Death tests.
531*d9f75844SAndroid Build Coastguard Worker // Disabled on Android because death tests misbehave on Android, see
532*d9f75844SAndroid Build Coastguard Worker // base/test/gtest_util.h.
533*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
534*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsDeathTest,ValueOfUndefinedMember)535*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsDeathTest, ValueOfUndefinedMember) {
536*d9f75844SAndroid Build Coastguard Worker   RTCTestStats stats("testId", 0.0);
537*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(stats.m_int32.is_defined());
538*d9f75844SAndroid Build Coastguard Worker   EXPECT_DEATH(*stats.m_int32, "");
539*d9f75844SAndroid Build Coastguard Worker }
540*d9f75844SAndroid Build Coastguard Worker 
TEST(RTCStatsDeathTest,InvalidCasting)541*d9f75844SAndroid Build Coastguard Worker TEST(RTCStatsDeathTest, InvalidCasting) {
542*d9f75844SAndroid Build Coastguard Worker   RTCGrandChildStats stats("grandchild", 0.0);
543*d9f75844SAndroid Build Coastguard Worker   EXPECT_DEATH(stats.cast_to<RTCChildStats>(), "");
544*d9f75844SAndroid Build Coastguard Worker }
545*d9f75844SAndroid Build Coastguard Worker 
546*d9f75844SAndroid Build Coastguard Worker #endif  // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
547*d9f75844SAndroid Build Coastguard Worker 
548*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
549