OLD | NEW |
---|---|
(Empty) | |
1 /* | |
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 | |
11 #include <set> | |
12 #include <sstream> | |
13 #include <vector> | |
14 | |
15 #include "webrtc/api/datachannelinterface.h" | |
16 #include "webrtc/api/peerconnectioninterface.h" | |
17 #include "webrtc/api/stats/rtcstats_objects.h" | |
18 #include "webrtc/api/stats/rtcstatsreport.h" | |
19 #include "webrtc/api/test/peerconnectiontestwrapper.h" | |
20 #include "webrtc/api/test/rtcstatsobtainer.h" | |
21 #include "webrtc/base/checks.h" | |
22 #include "webrtc/base/gunit.h" | |
23 #include "webrtc/base/physicalsocketserver.h" | |
24 #include "webrtc/base/refcountedobject.h" | |
25 #include "webrtc/base/scoped_ref_ptr.h" | |
26 #include "webrtc/base/virtualsocketserver.h" | |
27 #include "webrtc/p2p/base/stunserver.h" | |
28 #include "webrtc/p2p/base/teststunserver.h" | |
29 | |
30 namespace webrtc { | |
31 | |
32 namespace { | |
33 | |
34 const int64_t kGetStatsTimeoutMs = 10000; | |
35 | |
36 const char* kFakeStunServerAddress = "1.1.1.1"; | |
37 const int kFakeStunServerPort = 3478; | |
38 const char* kLocalAddress = "192.168.0.1"; | |
39 | |
40 class RTCStatsIntegrationTest : public testing::Test { | |
41 public: | |
42 RTCStatsIntegrationTest() | |
43 : physical_socket_server_(), | |
44 virtual_socket_server_(&physical_socket_server_), | |
45 network_thread_(&virtual_socket_server_), | |
46 worker_thread_() { | |
47 RTC_CHECK(network_thread_.Start()); | |
48 RTC_CHECK(worker_thread_.Start()); | |
49 | |
50 stun_server_.reset(cricket::TestStunServer::Create( | |
51 &network_thread_, | |
52 rtc::SocketAddress(kFakeStunServerAddress, kFakeStunServerPort))); | |
53 stun_server_->set_fake_stun_addr(rtc::SocketAddress(kLocalAddress, 0)); | |
54 | |
55 caller_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>( | |
56 "caller", &network_thread_, &worker_thread_); | |
57 callee_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>( | |
58 "callee", &network_thread_, &worker_thread_); | |
59 } | |
60 | |
61 void StartCall() { | |
62 // Create PeerConnections and "connect" sigslots | |
63 PeerConnectionInterface::RTCConfiguration config; | |
64 PeerConnectionInterface::IceServer ice_server; | |
65 std::ostringstream oss; | |
66 oss << "stun:" << kFakeStunServerAddress << ":" << kFakeStunServerPort; | |
67 ice_server.uri = oss.str(); | |
68 config.servers.push_back(ice_server); | |
69 EXPECT_TRUE(caller_->CreatePc(nullptr, config)); | |
70 EXPECT_TRUE(callee_->CreatePc(nullptr, config)); | |
71 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get()); | |
72 | |
73 // Get user media for audio and video | |
74 caller_->GetAndAddUserMedia(true, FakeConstraints(), | |
75 true, FakeConstraints()); | |
76 callee_->GetAndAddUserMedia(true, FakeConstraints(), | |
77 true, FakeConstraints()); | |
78 | |
79 // Create data channels | |
80 DataChannelInit init; | |
81 caller_->CreateDataChannel("data", init); | |
82 callee_->CreateDataChannel("data", init); | |
83 | |
84 // Negotiate and wait for call to establish | |
85 caller_->CreateOffer(nullptr); | |
86 caller_->WaitForCallEstablished(); | |
87 callee_->WaitForCallEstablished(); | |
88 } | |
89 | |
90 rtc::scoped_refptr<const RTCStatsReport> CallerGetStats() { | |
hta-webrtc
2016/11/23 07:52:11
Nit/preference: I would prefer to call these GetSt
hbos
2016/11/23 09:55:49
Done.
| |
91 return GetStats(caller_->pc()); | |
92 } | |
93 | |
94 rtc::scoped_refptr<const RTCStatsReport> CalleeGetStats() { | |
95 return GetStats(callee_->pc()); | |
96 } | |
97 | |
98 protected: | |
99 static rtc::scoped_refptr<const RTCStatsReport> GetStats( | |
100 PeerConnectionInterface* pc) { | |
101 rtc::scoped_refptr<RTCStatsObtainer> stats_obtainer = | |
102 RTCStatsObtainer::Create(); | |
103 pc->GetStats(stats_obtainer); | |
104 EXPECT_TRUE_WAIT(stats_obtainer->report(), kGetStatsTimeoutMs); | |
105 return stats_obtainer->report(); | |
106 } | |
107 | |
108 // These objects use each other and must be constructed/destroyed in this | |
109 // order. Relationship: | |
110 // |physical_socket_server_| <- |virtual_socket_server_| <- |network_thread_| | |
111 rtc::PhysicalSocketServer physical_socket_server_; | |
112 rtc::VirtualSocketServer virtual_socket_server_; | |
113 rtc::Thread network_thread_; | |
114 rtc::Thread worker_thread_; | |
115 std::unique_ptr<cricket::TestStunServer> stun_server_; | |
hta-webrtc
2016/11/23 07:52:11
Do you really need to have the stun server here? I
hbos
2016/11/23 09:55:49
Done, removed.
Oh... I thought it was working bec
| |
116 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_; | |
117 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_; | |
118 }; | |
119 | |
120 class RTCStatsVerifier { | |
121 public: | |
122 RTCStatsVerifier(const RTCStatsReport* report, const RTCStats* stats) | |
123 : report_(report), stats_(stats), all_tests_successful_(true) { | |
124 RTC_CHECK(report_); | |
125 RTC_CHECK(stats_); | |
126 for (const RTCStatsMemberInterface* member : stats_->Members()) { | |
127 untested_members_.insert(member); | |
128 } | |
129 } | |
130 | |
131 void MarkMemberTested( | |
132 const RTCStatsMemberInterface& member, bool test_successful) { | |
133 untested_members_.erase(&member); | |
134 all_tests_successful_ &= test_successful; | |
135 } | |
136 | |
137 void TestMemberIsDefined(const RTCStatsMemberInterface& member) { | |
138 EXPECT_TRUE(member.is_defined()) << | |
139 stats_->type() << "." << member.name() << "[" << stats_->id() << | |
140 "] was undefined."; | |
141 MarkMemberTested(member, member.is_defined()); | |
142 } | |
143 | |
144 void TestMemberIsUndefined(const RTCStatsMemberInterface& member) { | |
145 EXPECT_FALSE(member.is_defined()) << | |
146 stats_->type() << "." << member.name() << "[" << stats_->id() << | |
147 "] was defined (" << member.ValueToString() << ")."; | |
148 MarkMemberTested(member, !member.is_defined()); | |
149 } | |
150 | |
151 void TestMemberIsIDReference( | |
152 const RTCStatsMemberInterface& member, | |
153 const char* expected_type) { | |
154 TestMemberIsIDReference(member, expected_type, false); | |
155 } | |
156 | |
157 void TestMemberIsOptionalIDReference( | |
158 const RTCStatsMemberInterface& member, | |
159 const char* expected_type) { | |
160 TestMemberIsIDReference(member, expected_type, true); | |
161 } | |
162 | |
163 bool ExpectAllMembersSuccessfullyTested() { | |
164 if (untested_members_.empty()) | |
165 return all_tests_successful_; | |
166 for (const RTCStatsMemberInterface* member : untested_members_) { | |
167 EXPECT_TRUE(false) << | |
168 stats_->type() << "." << member->name() << "[" << stats_->id() << | |
169 "] was not tested."; | |
170 } | |
171 return false; | |
172 } | |
173 | |
174 private: | |
175 void TestMemberIsIDReference( | |
176 const RTCStatsMemberInterface& member, | |
177 const char* expected_type, | |
178 bool optional) { | |
179 if (optional && !member.is_defined()) { | |
180 MarkMemberTested(member, true); | |
181 return; | |
182 } | |
183 bool valid_reference = false; | |
184 if (member.is_defined()) { | |
185 if (member.type() == RTCStatsMemberInterface::kString) { | |
186 // A single ID. | |
187 const RTCStatsMember<std::string>& id = | |
188 member.cast_to<RTCStatsMember<std::string>>(); | |
189 const RTCStats* referenced_stats = report_->Get(*id); | |
190 valid_reference = | |
191 referenced_stats && referenced_stats->type() == expected_type; | |
192 } else if (member.type() == RTCStatsMemberInterface::kSequenceString) { | |
193 // A vector of IDs. | |
194 valid_reference = true; | |
195 const RTCStatsMember<std::vector<std::string>>& ids = | |
196 member.cast_to<RTCStatsMember<std::vector<std::string>>>(); | |
197 for (const std::string id : *ids) { | |
198 const RTCStats* referenced_stats = report_->Get(id); | |
199 if (!referenced_stats || referenced_stats->type() != expected_type) { | |
200 valid_reference = false; | |
201 break; | |
202 } | |
203 } | |
204 } | |
205 } | |
206 EXPECT_TRUE(valid_reference) << | |
207 stats_->type() << "." << member.name() << " is not a reference to an " << | |
208 "existing dictionary of type " << expected_type << " (" << | |
209 member.ValueToString() << ")."; | |
210 MarkMemberTested(member, valid_reference); | |
211 } | |
212 | |
213 rtc::scoped_refptr<const RTCStatsReport> report_; | |
214 const RTCStats* stats_; | |
215 std::set<const RTCStatsMemberInterface*> untested_members_; | |
216 bool all_tests_successful_; | |
217 }; | |
218 | |
219 class RTCStatsReportVerifier { | |
220 public: | |
221 static std::set<const char*> StatsTypes() { | |
222 std::set<const char*> stats_types; | |
223 stats_types.insert(RTCCertificateStats::kType); | |
224 stats_types.insert(RTCDataChannelStats::kType); | |
225 stats_types.insert(RTCIceCandidatePairStats::kType); | |
226 stats_types.insert(RTCLocalIceCandidateStats::kType); | |
227 stats_types.insert(RTCRemoteIceCandidateStats::kType); | |
228 stats_types.insert(RTCMediaStreamStats::kType); | |
229 stats_types.insert(RTCMediaStreamTrackStats::kType); | |
230 stats_types.insert(RTCPeerConnectionStats::kType); | |
231 stats_types.insert(RTCInboundRTPStreamStats::kType); | |
232 stats_types.insert(RTCOutboundRTPStreamStats::kType); | |
233 stats_types.insert(RTCTransportStats::kType); | |
234 return stats_types; | |
235 } | |
236 | |
237 explicit RTCStatsReportVerifier(const RTCStatsReport* report) | |
238 : report_(report) { | |
239 } | |
240 | |
241 void VerifyReport() { | |
242 std::set<const char*> missing_stats = StatsTypes(); | |
243 bool verify_successful = true; | |
244 for (const RTCStats& stats : *report_) { | |
245 missing_stats.erase(stats.type()); | |
246 if (stats.type() == RTCCertificateStats::kType) { | |
247 verify_successful &= VerifyRTCCertificateStats( | |
248 stats.cast_to<RTCCertificateStats>()); | |
249 } else if (stats.type() == RTCDataChannelStats::kType) { | |
250 verify_successful &= VerifyRTCDataChannelStats( | |
251 stats.cast_to<RTCDataChannelStats>()); | |
252 } else if (stats.type() == RTCIceCandidatePairStats::kType) { | |
253 verify_successful &= VerifyRTCIceCandidatePairStats( | |
254 stats.cast_to<RTCIceCandidatePairStats>()); | |
255 } else if (stats.type() == RTCLocalIceCandidateStats::kType) { | |
256 verify_successful &= VerifyRTCLocalIceCandidateStats( | |
257 stats.cast_to<RTCLocalIceCandidateStats>()); | |
258 } else if (stats.type() == RTCRemoteIceCandidateStats::kType) { | |
259 verify_successful &= VerifyRTCRemoteIceCandidateStats( | |
260 stats.cast_to<RTCRemoteIceCandidateStats>()); | |
261 } else if (stats.type() == RTCMediaStreamStats::kType) { | |
262 verify_successful &= VerifyRTCMediaStreamStats( | |
263 stats.cast_to<RTCMediaStreamStats>()); | |
264 } else if (stats.type() == RTCMediaStreamTrackStats::kType) { | |
265 verify_successful &= VerifyRTCMediaStreamTrackStats( | |
266 stats.cast_to<RTCMediaStreamTrackStats>()); | |
267 } else if (stats.type() == RTCPeerConnectionStats::kType) { | |
268 verify_successful &= VerifyRTCPeerConnectionStats( | |
269 stats.cast_to<RTCPeerConnectionStats>()); | |
270 } else if (stats.type() == RTCInboundRTPStreamStats::kType) { | |
271 verify_successful &= VerifyRTCInboundRTPStreamStats( | |
272 stats.cast_to<RTCInboundRTPStreamStats>()); | |
273 } else if (stats.type() == RTCOutboundRTPStreamStats::kType) { | |
274 verify_successful &= VerifyRTCOutboundRTPStreamStats( | |
275 stats.cast_to<RTCOutboundRTPStreamStats>()); | |
276 } else if (stats.type() == RTCTransportStats::kType) { | |
277 verify_successful &= VerifyRTCTransportStats( | |
278 stats.cast_to<RTCTransportStats>()); | |
279 } else { | |
280 EXPECT_TRUE(false) << "Unrecognized stats type: " << stats.type(); | |
281 verify_successful = false; | |
282 } | |
283 } | |
284 if (!missing_stats.empty()) { | |
285 verify_successful = false; | |
286 for (const char* missing : missing_stats) { | |
287 EXPECT_TRUE(false) << "Missing expected stats type: " << missing; | |
288 } | |
289 } | |
290 EXPECT_TRUE(verify_successful) << | |
291 "One or more problems with the stats. This is the report:\n" << | |
292 report_->ToString(); | |
293 } | |
294 | |
295 bool VerifyRTCCertificateStats( | |
296 const RTCCertificateStats& certificate) { | |
297 RTCStatsVerifier verifier(report_, &certificate); | |
298 verifier.TestMemberIsDefined(certificate.fingerprint); | |
299 verifier.TestMemberIsDefined(certificate.fingerprint_algorithm); | |
300 verifier.TestMemberIsDefined(certificate.base64_certificate); | |
301 verifier.TestMemberIsOptionalIDReference( | |
302 certificate.issuer_certificate_id, RTCCertificateStats::kType); | |
303 return verifier.ExpectAllMembersSuccessfullyTested(); | |
304 } | |
305 | |
306 bool VerifyRTCDataChannelStats( | |
307 const RTCDataChannelStats& data_channel) { | |
308 RTCStatsVerifier verifier(report_, &data_channel); | |
309 verifier.TestMemberIsDefined(data_channel.label); | |
310 verifier.TestMemberIsDefined(data_channel.protocol); | |
311 verifier.TestMemberIsDefined(data_channel.datachannelid); | |
312 verifier.TestMemberIsDefined(data_channel.state); | |
313 verifier.TestMemberIsDefined(data_channel.messages_sent); | |
314 verifier.TestMemberIsDefined(data_channel.bytes_sent); | |
315 verifier.TestMemberIsDefined(data_channel.messages_received); | |
316 verifier.TestMemberIsDefined(data_channel.bytes_received); | |
317 return verifier.ExpectAllMembersSuccessfullyTested(); | |
318 } | |
319 | |
320 bool VerifyRTCIceCandidatePairStats( | |
321 const RTCIceCandidatePairStats& candidate_pair) { | |
322 RTCStatsVerifier verifier(report_, &candidate_pair); | |
323 verifier.TestMemberIsUndefined(candidate_pair.transport_id); | |
324 verifier.TestMemberIsIDReference( | |
325 candidate_pair.local_candidate_id, RTCLocalIceCandidateStats::kType); | |
326 verifier.TestMemberIsIDReference( | |
327 candidate_pair.remote_candidate_id, RTCRemoteIceCandidateStats::kType); | |
328 verifier.TestMemberIsUndefined(candidate_pair.state); | |
329 verifier.TestMemberIsUndefined(candidate_pair.priority); | |
330 verifier.TestMemberIsUndefined(candidate_pair.nominated); | |
331 verifier.TestMemberIsDefined(candidate_pair.writable); | |
332 verifier.TestMemberIsUndefined(candidate_pair.readable); | |
333 verifier.TestMemberIsDefined(candidate_pair.bytes_sent); | |
334 verifier.TestMemberIsDefined(candidate_pair.bytes_received); | |
335 verifier.TestMemberIsUndefined(candidate_pair.total_rtt); | |
336 verifier.TestMemberIsDefined(candidate_pair.current_rtt); | |
337 verifier.TestMemberIsUndefined(candidate_pair.available_outgoing_bitrate); | |
338 verifier.TestMemberIsUndefined(candidate_pair.available_incoming_bitrate); | |
339 verifier.TestMemberIsUndefined(candidate_pair.requests_received); | |
340 verifier.TestMemberIsDefined(candidate_pair.requests_sent); | |
341 verifier.TestMemberIsDefined(candidate_pair.responses_received); | |
342 verifier.TestMemberIsDefined(candidate_pair.responses_sent); | |
343 verifier.TestMemberIsUndefined(candidate_pair.retransmissions_received); | |
344 verifier.TestMemberIsUndefined(candidate_pair.retransmissions_sent); | |
345 verifier.TestMemberIsUndefined(candidate_pair.consent_requests_received); | |
346 verifier.TestMemberIsUndefined(candidate_pair.consent_requests_sent); | |
347 verifier.TestMemberIsUndefined(candidate_pair.consent_responses_received); | |
348 verifier.TestMemberIsUndefined(candidate_pair.consent_responses_sent); | |
349 return verifier.ExpectAllMembersSuccessfullyTested(); | |
350 } | |
351 | |
352 bool VerifyRTCIceCandidateStats( | |
353 const RTCIceCandidateStats& candidate) { | |
354 RTCStatsVerifier verifier(report_, &candidate); | |
355 verifier.TestMemberIsDefined(candidate.ip); | |
356 verifier.TestMemberIsDefined(candidate.port); | |
357 verifier.TestMemberIsDefined(candidate.protocol); | |
358 verifier.TestMemberIsDefined(candidate.candidate_type); | |
359 verifier.TestMemberIsDefined(candidate.priority); | |
360 verifier.TestMemberIsUndefined(candidate.url); | |
361 return verifier.ExpectAllMembersSuccessfullyTested(); | |
362 } | |
363 | |
364 bool VerifyRTCLocalIceCandidateStats( | |
365 const RTCLocalIceCandidateStats& local_candidate) { | |
366 return VerifyRTCIceCandidateStats(local_candidate); | |
367 } | |
368 | |
369 bool VerifyRTCRemoteIceCandidateStats( | |
370 const RTCRemoteIceCandidateStats& remote_candidate) { | |
371 return VerifyRTCIceCandidateStats(remote_candidate); | |
372 } | |
373 | |
374 bool VerifyRTCMediaStreamStats( | |
375 const RTCMediaStreamStats& media_stream) { | |
376 RTCStatsVerifier verifier(report_, &media_stream); | |
377 verifier.TestMemberIsDefined(media_stream.stream_identifier); | |
378 verifier.TestMemberIsIDReference( | |
379 media_stream.track_ids, RTCMediaStreamTrackStats::kType); | |
380 return verifier.ExpectAllMembersSuccessfullyTested(); | |
381 } | |
382 | |
383 bool VerifyRTCMediaStreamTrackStats( | |
384 const RTCMediaStreamTrackStats& media_stream_track) { | |
385 RTCStatsVerifier verifier(report_, &media_stream_track); | |
386 verifier.TestMemberIsDefined(media_stream_track.track_identifier); | |
387 verifier.TestMemberIsDefined(media_stream_track.remote_source); | |
388 verifier.TestMemberIsDefined(media_stream_track.ended); | |
389 verifier.TestMemberIsDefined(media_stream_track.detached); | |
390 verifier.TestMemberIsUndefined(media_stream_track.ssrc_ids); | |
391 // Video or audio media stream track? | |
392 if (media_stream_track.frame_width.is_defined()) { | |
393 // Video-only members | |
394 verifier.TestMemberIsDefined(media_stream_track.frame_width); | |
395 verifier.TestMemberIsDefined(media_stream_track.frame_height); | |
396 verifier.TestMemberIsUndefined(media_stream_track.frames_per_second); | |
397 verifier.TestMemberIsUndefined(media_stream_track.frames_sent); | |
398 verifier.TestMemberIsUndefined(media_stream_track.frames_received); | |
399 verifier.TestMemberIsUndefined(media_stream_track.frames_decoded); | |
400 verifier.TestMemberIsUndefined(media_stream_track.frames_dropped); | |
401 verifier.TestMemberIsUndefined(media_stream_track.frames_corrupted); | |
402 verifier.TestMemberIsUndefined(media_stream_track.partial_frames_lost); | |
403 verifier.TestMemberIsUndefined(media_stream_track.full_frames_lost); | |
404 // Audio-only members should be undefined | |
405 verifier.TestMemberIsUndefined(media_stream_track.audio_level); | |
406 verifier.TestMemberIsUndefined(media_stream_track.echo_return_loss); | |
407 verifier.TestMemberIsUndefined( | |
408 media_stream_track.echo_return_loss_enhancement); | |
409 } else { | |
410 // Video-only members should be undefined | |
411 verifier.TestMemberIsUndefined(media_stream_track.frame_width); | |
412 verifier.TestMemberIsUndefined(media_stream_track.frame_height); | |
413 verifier.TestMemberIsUndefined(media_stream_track.frames_per_second); | |
414 verifier.TestMemberIsUndefined(media_stream_track.frames_sent); | |
415 verifier.TestMemberIsUndefined(media_stream_track.frames_received); | |
416 verifier.TestMemberIsUndefined(media_stream_track.frames_decoded); | |
417 verifier.TestMemberIsUndefined(media_stream_track.frames_dropped); | |
418 verifier.TestMemberIsUndefined(media_stream_track.frames_corrupted); | |
419 verifier.TestMemberIsUndefined(media_stream_track.partial_frames_lost); | |
420 verifier.TestMemberIsUndefined(media_stream_track.full_frames_lost); | |
421 // Audio-only members | |
422 // TODO(hbos): Why are the audio track missing |audio_level|, | |
423 // |echo_return_loss| and |echo_return_loss_enhancement|? Is this a real | |
424 // problem or does it have to do with testing and not using real devices? | |
425 // crbug.com/627816 | |
426 verifier.MarkMemberTested(media_stream_track.audio_level, true); | |
427 verifier.MarkMemberTested(media_stream_track.echo_return_loss, true); | |
428 verifier.MarkMemberTested( | |
429 media_stream_track.echo_return_loss_enhancement, true); | |
430 } | |
431 return verifier.ExpectAllMembersSuccessfullyTested(); | |
432 } | |
433 | |
434 bool VerifyRTCPeerConnectionStats( | |
435 const RTCPeerConnectionStats& peer_connection) { | |
436 RTCStatsVerifier verifier(report_, &peer_connection); | |
437 verifier.TestMemberIsDefined(peer_connection.data_channels_opened); | |
438 verifier.TestMemberIsDefined(peer_connection.data_channels_closed); | |
439 return verifier.ExpectAllMembersSuccessfullyTested(); | |
440 } | |
441 | |
442 void VerifyRTCRTPStreamStats( | |
443 const RTCRTPStreamStats& stream, RTCStatsVerifier* verifier) { | |
444 verifier->TestMemberIsDefined(stream.ssrc); | |
445 verifier->TestMemberIsUndefined(stream.associate_stats_id); | |
446 verifier->TestMemberIsDefined(stream.is_remote); | |
447 verifier->TestMemberIsDefined(stream.media_type); | |
448 verifier->TestMemberIsUndefined(stream.media_track_id); | |
449 verifier->TestMemberIsIDReference( | |
450 stream.transport_id, RTCTransportStats::kType); | |
451 verifier->TestMemberIsUndefined(stream.codec_id); | |
452 if (stream.media_type.is_defined() && *stream.media_type == "video") { | |
453 verifier->TestMemberIsDefined(stream.fir_count); | |
454 verifier->TestMemberIsDefined(stream.pli_count); | |
455 verifier->TestMemberIsDefined(stream.nack_count); | |
456 } else { | |
457 verifier->TestMemberIsUndefined(stream.fir_count); | |
458 verifier->TestMemberIsUndefined(stream.pli_count); | |
459 verifier->TestMemberIsUndefined(stream.nack_count); | |
460 } | |
461 verifier->TestMemberIsUndefined(stream.sli_count); | |
462 } | |
463 | |
464 bool VerifyRTCInboundRTPStreamStats( | |
465 const RTCInboundRTPStreamStats& inbound_stream) { | |
466 RTCStatsVerifier verifier(report_, &inbound_stream); | |
467 VerifyRTCRTPStreamStats(inbound_stream, &verifier); | |
468 verifier.TestMemberIsDefined(inbound_stream.packets_received); | |
469 verifier.TestMemberIsDefined(inbound_stream.bytes_received); | |
470 verifier.TestMemberIsUndefined(inbound_stream.packets_lost); | |
471 if (inbound_stream.media_type.is_defined() && | |
472 *inbound_stream.media_type == "video") { | |
473 verifier.TestMemberIsUndefined(inbound_stream.jitter); | |
474 } else { | |
475 verifier.TestMemberIsDefined(inbound_stream.jitter); | |
476 } | |
477 verifier.TestMemberIsDefined(inbound_stream.fraction_lost); | |
478 verifier.TestMemberIsUndefined(inbound_stream.packets_discarded); | |
479 verifier.TestMemberIsUndefined(inbound_stream.packets_repaired); | |
480 verifier.TestMemberIsUndefined(inbound_stream.burst_packets_lost); | |
481 verifier.TestMemberIsUndefined(inbound_stream.burst_packets_discarded); | |
482 verifier.TestMemberIsUndefined(inbound_stream.burst_loss_count); | |
483 verifier.TestMemberIsUndefined(inbound_stream.burst_discard_count); | |
484 verifier.TestMemberIsUndefined(inbound_stream.burst_loss_rate); | |
485 verifier.TestMemberIsUndefined(inbound_stream.burst_discard_rate); | |
486 verifier.TestMemberIsUndefined(inbound_stream.gap_loss_rate); | |
487 verifier.TestMemberIsUndefined(inbound_stream.gap_discard_rate); | |
488 return verifier.ExpectAllMembersSuccessfullyTested(); | |
489 } | |
490 | |
491 bool VerifyRTCOutboundRTPStreamStats( | |
492 const RTCOutboundRTPStreamStats& outbound_stream) { | |
493 RTCStatsVerifier verifier(report_, &outbound_stream); | |
494 VerifyRTCRTPStreamStats(outbound_stream, &verifier); | |
495 verifier.TestMemberIsDefined(outbound_stream.packets_sent); | |
496 verifier.TestMemberIsDefined(outbound_stream.bytes_sent); | |
497 verifier.TestMemberIsUndefined(outbound_stream.target_bitrate); | |
498 verifier.TestMemberIsDefined(outbound_stream.round_trip_time); | |
499 return verifier.ExpectAllMembersSuccessfullyTested(); | |
500 } | |
501 | |
502 bool VerifyRTCTransportStats( | |
503 const RTCTransportStats& transport) { | |
504 RTCStatsVerifier verifier(report_, &transport); | |
505 verifier.TestMemberIsDefined(transport.bytes_sent); | |
506 verifier.TestMemberIsDefined(transport.bytes_received); | |
507 verifier.TestMemberIsOptionalIDReference( | |
508 transport.rtcp_transport_stats_id, RTCTransportStats::kType); | |
509 verifier.TestMemberIsDefined(transport.active_connection); | |
510 verifier.TestMemberIsDefined(transport.selected_candidate_pair_id); | |
511 verifier.TestMemberIsDefined(transport.local_certificate_id); | |
512 verifier.TestMemberIsDefined(transport.remote_certificate_id); | |
513 return verifier.ExpectAllMembersSuccessfullyTested(); | |
514 } | |
515 | |
516 private: | |
517 rtc::scoped_refptr<const RTCStatsReport> report_; | |
518 }; | |
519 | |
520 TEST_F(RTCStatsIntegrationTest, CallerGetStats) { | |
521 StartCall(); | |
522 | |
523 rtc::scoped_refptr<const RTCStatsReport> report = CallerGetStats(); | |
524 RTCStatsReportVerifier(report.get()).VerifyReport(); | |
525 } | |
526 | |
527 TEST_F(RTCStatsIntegrationTest, CalleeGetStats) { | |
528 StartCall(); | |
529 | |
530 rtc::scoped_refptr<const RTCStatsReport> report = CalleeGetStats(); | |
531 RTCStatsReportVerifier(report.get()).VerifyReport(); | |
532 } | |
533 | |
534 } // namespace | |
535 | |
536 } // namespace webrtc | |
OLD | NEW |