OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/api/stats/rtcstats.h" | 11 #include "webrtc/api/stats/rtcstats.h" |
12 | 12 |
| 13 #include <cmath> |
13 #include <cstring> | 14 #include <cstring> |
14 | 15 |
15 #include "webrtc/rtc_base/checks.h" | 16 #include "webrtc/rtc_base/checks.h" |
16 #include "webrtc/rtc_base/gunit.h" | 17 #include "webrtc/rtc_base/gunit.h" |
| 18 #include "webrtc/rtc_base/json.h" |
17 #include "webrtc/stats/test/rtcteststats.h" | 19 #include "webrtc/stats/test/rtcteststats.h" |
18 | 20 |
19 namespace webrtc { | 21 namespace webrtc { |
20 | 22 |
| 23 namespace { |
| 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. |
| 28 const 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. |
| 34 double GetExpectedError(const double expected_value) { |
| 35 return JSON_EPSILON * fabs(expected_value); |
| 36 } |
| 37 |
| 38 } // namespace |
| 39 |
21 class RTCChildStats : public RTCStats { | 40 class RTCChildStats : public RTCStats { |
22 public: | 41 public: |
23 WEBRTC_RTCSTATS_DECL(); | 42 WEBRTC_RTCSTATS_DECL(); |
24 | 43 |
25 RTCChildStats(const std::string& id, int64_t timestamp_us) | 44 RTCChildStats(const std::string& id, int64_t timestamp_us) |
26 : RTCStats(id, timestamp_us), | 45 : RTCStats(id, timestamp_us), |
27 child_int("childInt") {} | 46 child_int("childInt") {} |
28 | 47 |
29 RTCStatsMember<int32_t> child_int; | 48 RTCStatsMember<int32_t> child_int; |
30 }; | 49 }; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 sum += *member->cast_to<const RTCStatsMember<int32_t>>(); | 208 sum += *member->cast_to<const RTCStatsMember<int32_t>>(); |
190 } | 209 } |
191 EXPECT_EQ(sum, static_cast<int32_t>(3)); | 210 EXPECT_EQ(sum, static_cast<int32_t>(3)); |
192 | 211 |
193 std::unique_ptr<RTCStats> copy_ptr = stats.copy(); | 212 std::unique_ptr<RTCStats> copy_ptr = stats.copy(); |
194 const RTCGrandChildStats& copy = copy_ptr->cast_to<RTCGrandChildStats>(); | 213 const RTCGrandChildStats& copy = copy_ptr->cast_to<RTCGrandChildStats>(); |
195 EXPECT_EQ(*copy.child_int, *stats.child_int); | 214 EXPECT_EQ(*copy.child_int, *stats.child_int); |
196 EXPECT_EQ(*copy.grandchild_int, *stats.grandchild_int); | 215 EXPECT_EQ(*copy.grandchild_int, *stats.grandchild_int); |
197 } | 216 } |
198 | 217 |
| 218 TEST(RTCStatsTest, RTCStatsPrintsValidJson) { |
| 219 std::string id = "statsId"; |
| 220 int timestamp = 42; |
| 221 bool m_bool = true; |
| 222 int m_int32 = 123; |
| 223 int64_t m_int64 = 1234567890123456499L; |
| 224 double m_double = 123.4567890123456499; |
| 225 std::string m_string = "123"; |
| 226 |
| 227 std::vector<bool> sequence_bool; |
| 228 std::vector<int32_t> sequence_int32; |
| 229 sequence_int32.push_back(static_cast<int32_t>(1)); |
| 230 std::vector<int64_t> sequence_int64; |
| 231 sequence_int64.push_back(static_cast<int64_t>(-1234567890123456499L)); |
| 232 sequence_int64.push_back(static_cast<int64_t>(1)); |
| 233 sequence_int64.push_back(static_cast<int64_t>(1234567890123456499L)); |
| 234 std::vector<double> sequence_double; |
| 235 sequence_double.push_back(123.4567890123456499); |
| 236 sequence_double.push_back(1234567890123.456499); |
| 237 std::vector<std::string> sequence_string; |
| 238 sequence_string.push_back(std::string("four")); |
| 239 |
| 240 RTCTestStats stats(id, timestamp); |
| 241 stats.m_bool = m_bool; |
| 242 stats.m_int32 = m_int32; |
| 243 stats.m_int64 = m_int64; |
| 244 stats.m_double = m_double; |
| 245 stats.m_string = m_string; |
| 246 stats.m_sequence_bool = sequence_bool; |
| 247 stats.m_sequence_int32 = sequence_int32; |
| 248 stats.m_sequence_int64 = sequence_int64; |
| 249 stats.m_sequence_double = sequence_double; |
| 250 stats.m_sequence_string = sequence_string; |
| 251 |
| 252 Json::Value json_output; |
| 253 EXPECT_TRUE(Json::Reader().parse(stats.ToJson(), json_output)); |
| 254 |
| 255 EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "id", &id)); |
| 256 EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "timestamp", ×tamp)); |
| 257 EXPECT_TRUE(rtc::GetBoolFromJsonObject(json_output, "mBool", &m_bool)); |
| 258 EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "mInt32", &m_int32)); |
| 259 EXPECT_TRUE(rtc::GetDoubleFromJsonObject(json_output, "mDouble", &m_double)); |
| 260 EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "mString", &m_string)); |
| 261 |
| 262 Json::Value json_array; |
| 263 |
| 264 EXPECT_TRUE( |
| 265 rtc::GetValueFromJsonObject(json_output, "mSequenceBool", &json_array)); |
| 266 EXPECT_TRUE(rtc::JsonArrayToBoolVector(json_array, &sequence_bool)); |
| 267 |
| 268 EXPECT_TRUE( |
| 269 rtc::GetValueFromJsonObject(json_output, "mSequenceInt32", &json_array)); |
| 270 EXPECT_TRUE(rtc::JsonArrayToIntVector(json_array, &sequence_int32)); |
| 271 |
| 272 EXPECT_TRUE( |
| 273 rtc::GetValueFromJsonObject(json_output, "mSequenceDouble", &json_array)); |
| 274 EXPECT_TRUE(rtc::JsonArrayToDoubleVector(json_array, &sequence_double)); |
| 275 |
| 276 EXPECT_TRUE( |
| 277 rtc::GetValueFromJsonObject(json_output, "mSequenceString", &json_array)); |
| 278 EXPECT_TRUE(rtc::JsonArrayToStringVector(json_array, &sequence_string)); |
| 279 |
| 280 EXPECT_EQ(id, stats.id()); |
| 281 EXPECT_EQ(timestamp, stats.timestamp_us()); |
| 282 EXPECT_EQ(m_bool, *stats.m_bool); |
| 283 EXPECT_EQ(m_int32, *stats.m_int32); |
| 284 EXPECT_EQ(m_string, *stats.m_string); |
| 285 EXPECT_EQ(sequence_bool, *stats.m_sequence_bool); |
| 286 EXPECT_EQ(sequence_int32, *stats.m_sequence_int32); |
| 287 EXPECT_EQ(sequence_string, *stats.m_sequence_string); |
| 288 |
| 289 EXPECT_NEAR(m_double, *stats.m_double, GetExpectedError(*stats.m_double)); |
| 290 |
| 291 EXPECT_EQ(sequence_double.size(), stats.m_sequence_double->size()); |
| 292 for (size_t i = 0; i < stats.m_sequence_double->size(); ++i) { |
| 293 EXPECT_NEAR(sequence_double[i], stats.m_sequence_double->at(i), |
| 294 GetExpectedError(stats.m_sequence_double->at(i))); |
| 295 } |
| 296 |
| 297 // We read mInt64 as double since JSON stores all numbers as doubles, so there |
| 298 // is not enough precision to represent large numbers. |
| 299 double m_int64_as_double; |
| 300 std::vector<double> sequence_int64_as_double; |
| 301 |
| 302 EXPECT_TRUE( |
| 303 rtc::GetDoubleFromJsonObject(json_output, "mInt64", &m_int64_as_double)); |
| 304 |
| 305 EXPECT_TRUE( |
| 306 rtc::GetValueFromJsonObject(json_output, "mSequenceInt64", &json_array)); |
| 307 EXPECT_TRUE( |
| 308 rtc::JsonArrayToDoubleVector(json_array, &sequence_int64_as_double)); |
| 309 |
| 310 double stats_m_int64_as_double = static_cast<double>(*stats.m_int64); |
| 311 EXPECT_NEAR(m_int64_as_double, stats_m_int64_as_double, |
| 312 GetExpectedError(stats_m_int64_as_double)); |
| 313 |
| 314 EXPECT_EQ(sequence_int64_as_double.size(), stats.m_sequence_int64->size()); |
| 315 for (size_t i = 0; i < stats.m_sequence_int64->size(); ++i) { |
| 316 const double stats_value_as_double = |
| 317 static_cast<double>((*stats.m_sequence_int64)[i]); |
| 318 EXPECT_NEAR(sequence_int64_as_double[i], stats_value_as_double, |
| 319 GetExpectedError(stats_value_as_double)); |
| 320 } |
| 321 |
| 322 // Neither stats.m_uint32 nor stats.m_uint64 are defined, so "mUint64" and |
| 323 // "mUint32" should not be part of the generated JSON object. |
| 324 int m_uint32; |
| 325 int m_uint64; |
| 326 EXPECT_FALSE(stats.m_uint32.is_defined()); |
| 327 EXPECT_FALSE(stats.m_uint64.is_defined()); |
| 328 EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint32", &m_uint32)); |
| 329 EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint64", &m_uint64)); |
| 330 |
| 331 std::cout << stats.ToJson() << std::endl; |
| 332 } |
| 333 |
199 // Death tests. | 334 // Death tests. |
200 // Disabled on Android because death tests misbehave on Android, see | 335 // Disabled on Android because death tests misbehave on Android, see |
201 // base/test/gtest_util.h. | 336 // base/test/gtest_util.h. |
202 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 337 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
203 | 338 |
204 TEST(RTCStatsDeathTest, ValueOfUndefinedMember) { | 339 TEST(RTCStatsDeathTest, ValueOfUndefinedMember) { |
205 RTCTestStats stats("testId", 0.0); | 340 RTCTestStats stats("testId", 0.0); |
206 EXPECT_FALSE(stats.m_int32.is_defined()); | 341 EXPECT_FALSE(stats.m_int32.is_defined()); |
207 EXPECT_DEATH(*stats.m_int32, ""); | 342 EXPECT_DEATH(*stats.m_int32, ""); |
208 } | 343 } |
209 | 344 |
210 TEST(RTCStatsDeathTest, InvalidCasting) { | 345 TEST(RTCStatsDeathTest, InvalidCasting) { |
211 RTCGrandChildStats stats("grandchild", 0.0); | 346 RTCGrandChildStats stats("grandchild", 0.0); |
212 EXPECT_DEATH(stats.cast_to<RTCChildStats>(), ""); | 347 EXPECT_DEATH(stats.cast_to<RTCChildStats>(), ""); |
213 } | 348 } |
214 | 349 |
215 #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 350 #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
216 | 351 |
217 } // namespace webrtc | 352 } // namespace webrtc |
OLD | NEW |