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 // ammounts to about 15.95 decimal digits. Thus, when comparing large numbers | |
hbos
2017/07/27 16:27:41
nit: amounts
| |
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.0; | |
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(2.0); | |
236 sequence_double.push_back(3.0); | |
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_double, *stats.m_sequence_double); | |
288 EXPECT_EQ(sequence_string, *stats.m_sequence_string); | |
289 | |
290 // We read mInt64 as double since JSON stores all numbers as doubles, so there | |
291 // is not enough precision to represent large numbers. | |
292 double m_int64_as_double; | |
293 std::vector<double> sequence_int64_as_double; | |
294 | |
295 EXPECT_TRUE( | |
296 rtc::GetDoubleFromJsonObject(json_output, "mInt64", &m_int64_as_double)); | |
297 | |
298 EXPECT_TRUE( | |
299 rtc::GetValueFromJsonObject(json_output, "mSequenceInt64", &json_array)); | |
300 EXPECT_TRUE( | |
301 rtc::JsonArrayToDoubleVector(json_array, &sequence_int64_as_double)); | |
302 | |
303 double stats_m_int64_as_double = static_cast<double>(*stats.m_int64); | |
304 EXPECT_NEAR(m_int64_as_double, stats_m_int64_as_double, | |
305 GetExpectedError(stats_m_int64_as_double)); | |
306 | |
307 EXPECT_EQ(sequence_int64_as_double.size(), stats.m_sequence_int64->size()); | |
308 for (size_t i = 0; i < stats.m_sequence_int64->size(); ++i) { | |
309 const double stats_value_as_double = | |
310 static_cast<double>((*stats.m_sequence_int64)[i]); | |
311 EXPECT_NEAR(sequence_int64_as_double[i], stats_value_as_double, | |
312 GetExpectedError(stats_value_as_double)); | |
313 } | |
314 | |
315 // stats.m_uint64 is not defined, so "mUint64" is not part of the generated | |
316 // json object. | |
317 int m_uint64; | |
318 EXPECT_FALSE(stats.m_uint64.is_defined()); | |
319 EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint64", &m_uint64)); | |
hbos
2017/07/27 16:27:41
nit: The only other member not touched in this tes
| |
320 } | |
321 | |
199 // Death tests. | 322 // Death tests. |
200 // Disabled on Android because death tests misbehave on Android, see | 323 // Disabled on Android because death tests misbehave on Android, see |
201 // base/test/gtest_util.h. | 324 // base/test/gtest_util.h. |
202 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 325 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
203 | 326 |
204 TEST(RTCStatsDeathTest, ValueOfUndefinedMember) { | 327 TEST(RTCStatsDeathTest, ValueOfUndefinedMember) { |
205 RTCTestStats stats("testId", 0.0); | 328 RTCTestStats stats("testId", 0.0); |
206 EXPECT_FALSE(stats.m_int32.is_defined()); | 329 EXPECT_FALSE(stats.m_int32.is_defined()); |
207 EXPECT_DEATH(*stats.m_int32, ""); | 330 EXPECT_DEATH(*stats.m_int32, ""); |
208 } | 331 } |
209 | 332 |
210 TEST(RTCStatsDeathTest, InvalidCasting) { | 333 TEST(RTCStatsDeathTest, InvalidCasting) { |
211 RTCGrandChildStats stats("grandchild", 0.0); | 334 RTCGrandChildStats stats("grandchild", 0.0); |
212 EXPECT_DEATH(stats.cast_to<RTCChildStats>(), ""); | 335 EXPECT_DEATH(stats.cast_to<RTCChildStats>(), ""); |
213 } | 336 } |
214 | 337 |
215 #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 338 #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
216 | 339 |
217 } // namespace webrtc | 340 } // namespace webrtc |
OLD | NEW |