OLD | NEW |
| (Empty) |
1 /* | |
2 * libjingle | |
3 * Copyright 2012 Google Inc. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions are met: | |
7 * | |
8 * 1. Redistributions of source code must retain the above copyright notice, | |
9 * this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
11 * this list of conditions and the following disclaimer in the documentation | |
12 * and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 #include <stdio.h> | |
29 | |
30 #include <algorithm> | |
31 #include <list> | |
32 #include <map> | |
33 #include <utility> | |
34 #include <vector> | |
35 | |
36 #include "talk/app/webrtc/dtmfsender.h" | |
37 #include "talk/app/webrtc/fakemetricsobserver.h" | |
38 #include "talk/app/webrtc/localaudiosource.h" | |
39 #include "talk/app/webrtc/mediastreaminterface.h" | |
40 #include "talk/app/webrtc/peerconnection.h" | |
41 #include "talk/app/webrtc/peerconnectionfactory.h" | |
42 #include "talk/app/webrtc/peerconnectioninterface.h" | |
43 #include "talk/app/webrtc/test/fakeaudiocapturemodule.h" | |
44 #include "talk/app/webrtc/test/fakeconstraints.h" | |
45 #include "talk/app/webrtc/test/fakedtlsidentitystore.h" | |
46 #include "talk/app/webrtc/test/fakeperiodicvideocapturer.h" | |
47 #include "talk/app/webrtc/test/fakevideotrackrenderer.h" | |
48 #include "talk/app/webrtc/test/mockpeerconnectionobservers.h" | |
49 #include "talk/app/webrtc/videosourceinterface.h" | |
50 #include "talk/media/webrtc/fakewebrtcvideoengine.h" | |
51 #include "talk/session/media/mediasession.h" | |
52 #include "webrtc/base/gunit.h" | |
53 #include "webrtc/base/physicalsocketserver.h" | |
54 #include "webrtc/base/scoped_ptr.h" | |
55 #include "webrtc/base/ssladapter.h" | |
56 #include "webrtc/base/sslstreamadapter.h" | |
57 #include "webrtc/base/thread.h" | |
58 #include "webrtc/base/virtualsocketserver.h" | |
59 #include "webrtc/p2p/base/constants.h" | |
60 #include "webrtc/p2p/base/sessiondescription.h" | |
61 #include "webrtc/p2p/client/fakeportallocator.h" | |
62 | |
63 #define MAYBE_SKIP_TEST(feature) \ | |
64 if (!(feature())) { \ | |
65 LOG(LS_INFO) << "Feature disabled... skipping"; \ | |
66 return; \ | |
67 } | |
68 | |
69 using cricket::ContentInfo; | |
70 using cricket::FakeWebRtcVideoDecoder; | |
71 using cricket::FakeWebRtcVideoDecoderFactory; | |
72 using cricket::FakeWebRtcVideoEncoder; | |
73 using cricket::FakeWebRtcVideoEncoderFactory; | |
74 using cricket::MediaContentDescription; | |
75 using webrtc::DataBuffer; | |
76 using webrtc::DataChannelInterface; | |
77 using webrtc::DtmfSender; | |
78 using webrtc::DtmfSenderInterface; | |
79 using webrtc::DtmfSenderObserverInterface; | |
80 using webrtc::FakeConstraints; | |
81 using webrtc::MediaConstraintsInterface; | |
82 using webrtc::MediaStreamInterface; | |
83 using webrtc::MediaStreamTrackInterface; | |
84 using webrtc::MockCreateSessionDescriptionObserver; | |
85 using webrtc::MockDataChannelObserver; | |
86 using webrtc::MockSetSessionDescriptionObserver; | |
87 using webrtc::MockStatsObserver; | |
88 using webrtc::ObserverInterface; | |
89 using webrtc::PeerConnectionInterface; | |
90 using webrtc::PeerConnectionFactory; | |
91 using webrtc::SessionDescriptionInterface; | |
92 using webrtc::StreamCollectionInterface; | |
93 | |
94 static const int kMaxWaitMs = 10000; | |
95 // Disable for TSan v2, see | |
96 // https://code.google.com/p/webrtc/issues/detail?id=1205 for details. | |
97 // This declaration is also #ifdef'd as it causes uninitialized-variable | |
98 // warnings. | |
99 #if !defined(THREAD_SANITIZER) | |
100 static const int kMaxWaitForStatsMs = 3000; | |
101 #endif | |
102 static const int kMaxWaitForActivationMs = 5000; | |
103 static const int kMaxWaitForFramesMs = 10000; | |
104 static const int kEndAudioFrameCount = 3; | |
105 static const int kEndVideoFrameCount = 3; | |
106 | |
107 static const char kStreamLabelBase[] = "stream_label"; | |
108 static const char kVideoTrackLabelBase[] = "video_track"; | |
109 static const char kAudioTrackLabelBase[] = "audio_track"; | |
110 static const char kDataChannelLabel[] = "data_channel"; | |
111 | |
112 // Disable for TSan v2, see | |
113 // https://code.google.com/p/webrtc/issues/detail?id=1205 for details. | |
114 // This declaration is also #ifdef'd as it causes unused-variable errors. | |
115 #if !defined(THREAD_SANITIZER) | |
116 // SRTP cipher name negotiated by the tests. This must be updated if the | |
117 // default changes. | |
118 static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_32; | |
119 #endif | |
120 | |
121 static void RemoveLinesFromSdp(const std::string& line_start, | |
122 std::string* sdp) { | |
123 const char kSdpLineEnd[] = "\r\n"; | |
124 size_t ssrc_pos = 0; | |
125 while ((ssrc_pos = sdp->find(line_start, ssrc_pos)) != | |
126 std::string::npos) { | |
127 size_t end_ssrc = sdp->find(kSdpLineEnd, ssrc_pos); | |
128 sdp->erase(ssrc_pos, end_ssrc - ssrc_pos + strlen(kSdpLineEnd)); | |
129 } | |
130 } | |
131 | |
132 class SignalingMessageReceiver { | |
133 public: | |
134 virtual void ReceiveSdpMessage(const std::string& type, | |
135 std::string& msg) = 0; | |
136 virtual void ReceiveIceMessage(const std::string& sdp_mid, | |
137 int sdp_mline_index, | |
138 const std::string& msg) = 0; | |
139 | |
140 protected: | |
141 SignalingMessageReceiver() {} | |
142 virtual ~SignalingMessageReceiver() {} | |
143 }; | |
144 | |
145 class PeerConnectionTestClient : public webrtc::PeerConnectionObserver, | |
146 public SignalingMessageReceiver, | |
147 public ObserverInterface { | |
148 public: | |
149 static PeerConnectionTestClient* CreateClientWithDtlsIdentityStore( | |
150 const std::string& id, | |
151 const MediaConstraintsInterface* constraints, | |
152 const PeerConnectionFactory::Options* options, | |
153 rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store) { | |
154 PeerConnectionTestClient* client(new PeerConnectionTestClient(id)); | |
155 if (!client->Init(constraints, options, std::move(dtls_identity_store))) { | |
156 delete client; | |
157 return nullptr; | |
158 } | |
159 return client; | |
160 } | |
161 | |
162 static PeerConnectionTestClient* CreateClient( | |
163 const std::string& id, | |
164 const MediaConstraintsInterface* constraints, | |
165 const PeerConnectionFactory::Options* options) { | |
166 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store( | |
167 rtc::SSLStreamAdapter::HaveDtlsSrtp() ? new FakeDtlsIdentityStore() | |
168 : nullptr); | |
169 | |
170 return CreateClientWithDtlsIdentityStore(id, constraints, options, | |
171 std::move(dtls_identity_store)); | |
172 } | |
173 | |
174 ~PeerConnectionTestClient() { | |
175 } | |
176 | |
177 void Negotiate() { Negotiate(true, true); } | |
178 | |
179 void Negotiate(bool audio, bool video) { | |
180 rtc::scoped_ptr<SessionDescriptionInterface> offer; | |
181 ASSERT_TRUE(DoCreateOffer(offer.use())); | |
182 | |
183 if (offer->description()->GetContentByName("audio")) { | |
184 offer->description()->GetContentByName("audio")->rejected = !audio; | |
185 } | |
186 if (offer->description()->GetContentByName("video")) { | |
187 offer->description()->GetContentByName("video")->rejected = !video; | |
188 } | |
189 | |
190 std::string sdp; | |
191 EXPECT_TRUE(offer->ToString(&sdp)); | |
192 EXPECT_TRUE(DoSetLocalDescription(offer.release())); | |
193 signaling_message_receiver_->ReceiveSdpMessage( | |
194 webrtc::SessionDescriptionInterface::kOffer, sdp); | |
195 } | |
196 | |
197 // SignalingMessageReceiver callback. | |
198 void ReceiveSdpMessage(const std::string& type, std::string& msg) override { | |
199 FilterIncomingSdpMessage(&msg); | |
200 if (type == webrtc::SessionDescriptionInterface::kOffer) { | |
201 HandleIncomingOffer(msg); | |
202 } else { | |
203 HandleIncomingAnswer(msg); | |
204 } | |
205 } | |
206 | |
207 // SignalingMessageReceiver callback. | |
208 void ReceiveIceMessage(const std::string& sdp_mid, | |
209 int sdp_mline_index, | |
210 const std::string& msg) override { | |
211 LOG(INFO) << id_ << "ReceiveIceMessage"; | |
212 rtc::scoped_ptr<webrtc::IceCandidateInterface> candidate( | |
213 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, nullptr)); | |
214 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get())); | |
215 } | |
216 | |
217 // PeerConnectionObserver callbacks. | |
218 void OnSignalingChange( | |
219 webrtc::PeerConnectionInterface::SignalingState new_state) override { | |
220 EXPECT_EQ(pc()->signaling_state(), new_state); | |
221 } | |
222 void OnAddStream(MediaStreamInterface* media_stream) override { | |
223 media_stream->RegisterObserver(this); | |
224 for (size_t i = 0; i < media_stream->GetVideoTracks().size(); ++i) { | |
225 const std::string id = media_stream->GetVideoTracks()[i]->id(); | |
226 ASSERT_TRUE(fake_video_renderers_.find(id) == | |
227 fake_video_renderers_.end()); | |
228 fake_video_renderers_[id].reset(new webrtc::FakeVideoTrackRenderer( | |
229 media_stream->GetVideoTracks()[i])); | |
230 } | |
231 } | |
232 void OnRemoveStream(MediaStreamInterface* media_stream) override {} | |
233 void OnRenegotiationNeeded() override {} | |
234 void OnIceConnectionChange( | |
235 webrtc::PeerConnectionInterface::IceConnectionState new_state) override { | |
236 EXPECT_EQ(pc()->ice_connection_state(), new_state); | |
237 } | |
238 void OnIceGatheringChange( | |
239 webrtc::PeerConnectionInterface::IceGatheringState new_state) override { | |
240 EXPECT_EQ(pc()->ice_gathering_state(), new_state); | |
241 } | |
242 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override { | |
243 LOG(INFO) << id_ << "OnIceCandidate"; | |
244 | |
245 std::string ice_sdp; | |
246 EXPECT_TRUE(candidate->ToString(&ice_sdp)); | |
247 if (signaling_message_receiver_ == nullptr) { | |
248 // Remote party may be deleted. | |
249 return; | |
250 } | |
251 signaling_message_receiver_->ReceiveIceMessage( | |
252 candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp); | |
253 } | |
254 | |
255 // MediaStreamInterface callback | |
256 void OnChanged() override { | |
257 // Track added or removed from MediaStream, so update our renderers. | |
258 rtc::scoped_refptr<StreamCollectionInterface> remote_streams = | |
259 pc()->remote_streams(); | |
260 // Remove renderers for tracks that were removed. | |
261 for (auto it = fake_video_renderers_.begin(); | |
262 it != fake_video_renderers_.end();) { | |
263 if (remote_streams->FindVideoTrack(it->first) == nullptr) { | |
264 auto to_remove = it++; | |
265 removed_fake_video_renderers_.push_back(std::move(to_remove->second)); | |
266 fake_video_renderers_.erase(to_remove); | |
267 } else { | |
268 ++it; | |
269 } | |
270 } | |
271 // Create renderers for new video tracks. | |
272 for (size_t stream_index = 0; stream_index < remote_streams->count(); | |
273 ++stream_index) { | |
274 MediaStreamInterface* remote_stream = remote_streams->at(stream_index); | |
275 for (size_t track_index = 0; | |
276 track_index < remote_stream->GetVideoTracks().size(); | |
277 ++track_index) { | |
278 const std::string id = | |
279 remote_stream->GetVideoTracks()[track_index]->id(); | |
280 if (fake_video_renderers_.find(id) != fake_video_renderers_.end()) { | |
281 continue; | |
282 } | |
283 fake_video_renderers_[id].reset(new webrtc::FakeVideoTrackRenderer( | |
284 remote_stream->GetVideoTracks()[track_index])); | |
285 } | |
286 } | |
287 } | |
288 | |
289 void SetVideoConstraints(const webrtc::FakeConstraints& video_constraint) { | |
290 video_constraints_ = video_constraint; | |
291 } | |
292 | |
293 void AddMediaStream(bool audio, bool video) { | |
294 std::string stream_label = | |
295 kStreamLabelBase + | |
296 rtc::ToString<int>(static_cast<int>(pc()->local_streams()->count())); | |
297 rtc::scoped_refptr<MediaStreamInterface> stream = | |
298 peer_connection_factory_->CreateLocalMediaStream(stream_label); | |
299 | |
300 if (audio && can_receive_audio()) { | |
301 stream->AddTrack(CreateLocalAudioTrack(stream_label)); | |
302 } | |
303 if (video && can_receive_video()) { | |
304 stream->AddTrack(CreateLocalVideoTrack(stream_label)); | |
305 } | |
306 | |
307 EXPECT_TRUE(pc()->AddStream(stream)); | |
308 } | |
309 | |
310 size_t NumberOfLocalMediaStreams() { return pc()->local_streams()->count(); } | |
311 | |
312 bool SessionActive() { | |
313 return pc()->signaling_state() == webrtc::PeerConnectionInterface::kStable; | |
314 } | |
315 | |
316 // Automatically add a stream when receiving an offer, if we don't have one. | |
317 // Defaults to true. | |
318 void set_auto_add_stream(bool auto_add_stream) { | |
319 auto_add_stream_ = auto_add_stream; | |
320 } | |
321 | |
322 void set_signaling_message_receiver( | |
323 SignalingMessageReceiver* signaling_message_receiver) { | |
324 signaling_message_receiver_ = signaling_message_receiver; | |
325 } | |
326 | |
327 void EnableVideoDecoderFactory() { | |
328 video_decoder_factory_enabled_ = true; | |
329 fake_video_decoder_factory_->AddSupportedVideoCodecType( | |
330 webrtc::kVideoCodecVP8); | |
331 } | |
332 | |
333 void IceRestart() { | |
334 session_description_constraints_.SetMandatoryIceRestart(true); | |
335 SetExpectIceRestart(true); | |
336 } | |
337 | |
338 void SetExpectIceRestart(bool expect_restart) { | |
339 expect_ice_restart_ = expect_restart; | |
340 } | |
341 | |
342 bool ExpectIceRestart() const { return expect_ice_restart_; } | |
343 | |
344 void SetReceiveAudioVideo(bool audio, bool video) { | |
345 SetReceiveAudio(audio); | |
346 SetReceiveVideo(video); | |
347 ASSERT_EQ(audio, can_receive_audio()); | |
348 ASSERT_EQ(video, can_receive_video()); | |
349 } | |
350 | |
351 void SetReceiveAudio(bool audio) { | |
352 if (audio && can_receive_audio()) | |
353 return; | |
354 session_description_constraints_.SetMandatoryReceiveAudio(audio); | |
355 } | |
356 | |
357 void SetReceiveVideo(bool video) { | |
358 if (video && can_receive_video()) | |
359 return; | |
360 session_description_constraints_.SetMandatoryReceiveVideo(video); | |
361 } | |
362 | |
363 void RemoveMsidFromReceivedSdp(bool remove) { remove_msid_ = remove; } | |
364 | |
365 void RemoveSdesCryptoFromReceivedSdp(bool remove) { remove_sdes_ = remove; } | |
366 | |
367 void RemoveBundleFromReceivedSdp(bool remove) { remove_bundle_ = remove; } | |
368 | |
369 bool can_receive_audio() { | |
370 bool value; | |
371 if (webrtc::FindConstraint(&session_description_constraints_, | |
372 MediaConstraintsInterface::kOfferToReceiveAudio, | |
373 &value, nullptr)) { | |
374 return value; | |
375 } | |
376 return true; | |
377 } | |
378 | |
379 bool can_receive_video() { | |
380 bool value; | |
381 if (webrtc::FindConstraint(&session_description_constraints_, | |
382 MediaConstraintsInterface::kOfferToReceiveVideo, | |
383 &value, nullptr)) { | |
384 return value; | |
385 } | |
386 return true; | |
387 } | |
388 | |
389 void OnIceComplete() override { LOG(INFO) << id_ << "OnIceComplete"; } | |
390 | |
391 void OnDataChannel(DataChannelInterface* data_channel) override { | |
392 LOG(INFO) << id_ << "OnDataChannel"; | |
393 data_channel_ = data_channel; | |
394 data_observer_.reset(new MockDataChannelObserver(data_channel)); | |
395 } | |
396 | |
397 void CreateDataChannel() { | |
398 data_channel_ = pc()->CreateDataChannel(kDataChannelLabel, nullptr); | |
399 ASSERT_TRUE(data_channel_.get() != nullptr); | |
400 data_observer_.reset(new MockDataChannelObserver(data_channel_)); | |
401 } | |
402 | |
403 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack( | |
404 const std::string& stream_label) { | |
405 FakeConstraints constraints; | |
406 // Disable highpass filter so that we can get all the test audio frames. | |
407 constraints.AddMandatory(MediaConstraintsInterface::kHighpassFilter, false); | |
408 rtc::scoped_refptr<webrtc::AudioSourceInterface> source = | |
409 peer_connection_factory_->CreateAudioSource(&constraints); | |
410 // TODO(perkj): Test audio source when it is implemented. Currently audio | |
411 // always use the default input. | |
412 std::string label = stream_label + kAudioTrackLabelBase; | |
413 return peer_connection_factory_->CreateAudioTrack(label, source); | |
414 } | |
415 | |
416 rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack( | |
417 const std::string& stream_label) { | |
418 // Set max frame rate to 10fps to reduce the risk of the tests to be flaky. | |
419 FakeConstraints source_constraints = video_constraints_; | |
420 source_constraints.SetMandatoryMaxFrameRate(10); | |
421 | |
422 cricket::FakeVideoCapturer* fake_capturer = | |
423 new webrtc::FakePeriodicVideoCapturer(); | |
424 video_capturers_.push_back(fake_capturer); | |
425 rtc::scoped_refptr<webrtc::VideoSourceInterface> source = | |
426 peer_connection_factory_->CreateVideoSource(fake_capturer, | |
427 &source_constraints); | |
428 std::string label = stream_label + kVideoTrackLabelBase; | |
429 return peer_connection_factory_->CreateVideoTrack(label, source); | |
430 } | |
431 | |
432 DataChannelInterface* data_channel() { return data_channel_; } | |
433 const MockDataChannelObserver* data_observer() const { | |
434 return data_observer_.get(); | |
435 } | |
436 | |
437 webrtc::PeerConnectionInterface* pc() { return peer_connection_.get(); } | |
438 | |
439 void StopVideoCapturers() { | |
440 for (std::vector<cricket::VideoCapturer*>::iterator it = | |
441 video_capturers_.begin(); | |
442 it != video_capturers_.end(); ++it) { | |
443 (*it)->Stop(); | |
444 } | |
445 } | |
446 | |
447 bool AudioFramesReceivedCheck(int number_of_frames) const { | |
448 return number_of_frames <= fake_audio_capture_module_->frames_received(); | |
449 } | |
450 | |
451 int audio_frames_received() const { | |
452 return fake_audio_capture_module_->frames_received(); | |
453 } | |
454 | |
455 bool VideoFramesReceivedCheck(int number_of_frames) { | |
456 if (video_decoder_factory_enabled_) { | |
457 const std::vector<FakeWebRtcVideoDecoder*>& decoders | |
458 = fake_video_decoder_factory_->decoders(); | |
459 if (decoders.empty()) { | |
460 return number_of_frames <= 0; | |
461 } | |
462 | |
463 for (FakeWebRtcVideoDecoder* decoder : decoders) { | |
464 if (number_of_frames > decoder->GetNumFramesReceived()) { | |
465 return false; | |
466 } | |
467 } | |
468 return true; | |
469 } else { | |
470 if (fake_video_renderers_.empty()) { | |
471 return number_of_frames <= 0; | |
472 } | |
473 | |
474 for (const auto& pair : fake_video_renderers_) { | |
475 if (number_of_frames > pair.second->num_rendered_frames()) { | |
476 return false; | |
477 } | |
478 } | |
479 return true; | |
480 } | |
481 } | |
482 | |
483 int video_frames_received() const { | |
484 int total = 0; | |
485 if (video_decoder_factory_enabled_) { | |
486 const std::vector<FakeWebRtcVideoDecoder*>& decoders = | |
487 fake_video_decoder_factory_->decoders(); | |
488 for (const FakeWebRtcVideoDecoder* decoder : decoders) { | |
489 total += decoder->GetNumFramesReceived(); | |
490 } | |
491 } else { | |
492 for (const auto& pair : fake_video_renderers_) { | |
493 total += pair.second->num_rendered_frames(); | |
494 } | |
495 for (const auto& renderer : removed_fake_video_renderers_) { | |
496 total += renderer->num_rendered_frames(); | |
497 } | |
498 } | |
499 return total; | |
500 } | |
501 | |
502 // Verify the CreateDtmfSender interface | |
503 void VerifyDtmf() { | |
504 rtc::scoped_ptr<DummyDtmfObserver> observer(new DummyDtmfObserver()); | |
505 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender; | |
506 | |
507 // We can't create a DTMF sender with an invalid audio track or a non local | |
508 // track. | |
509 EXPECT_TRUE(peer_connection_->CreateDtmfSender(nullptr) == nullptr); | |
510 rtc::scoped_refptr<webrtc::AudioTrackInterface> non_localtrack( | |
511 peer_connection_factory_->CreateAudioTrack("dummy_track", nullptr)); | |
512 EXPECT_TRUE(peer_connection_->CreateDtmfSender(non_localtrack) == nullptr); | |
513 | |
514 // We should be able to create a DTMF sender from a local track. | |
515 webrtc::AudioTrackInterface* localtrack = | |
516 peer_connection_->local_streams()->at(0)->GetAudioTracks()[0]; | |
517 dtmf_sender = peer_connection_->CreateDtmfSender(localtrack); | |
518 EXPECT_TRUE(dtmf_sender.get() != nullptr); | |
519 dtmf_sender->RegisterObserver(observer.get()); | |
520 | |
521 // Test the DtmfSender object just created. | |
522 EXPECT_TRUE(dtmf_sender->CanInsertDtmf()); | |
523 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50)); | |
524 | |
525 // We don't need to verify that the DTMF tones are actually sent out because | |
526 // that is already covered by the tests of the lower level components. | |
527 | |
528 EXPECT_TRUE_WAIT(observer->completed(), kMaxWaitMs); | |
529 std::vector<std::string> tones; | |
530 tones.push_back("1"); | |
531 tones.push_back("a"); | |
532 tones.push_back(""); | |
533 observer->Verify(tones); | |
534 | |
535 dtmf_sender->UnregisterObserver(); | |
536 } | |
537 | |
538 // Verifies that the SessionDescription have rejected the appropriate media | |
539 // content. | |
540 void VerifyRejectedMediaInSessionDescription() { | |
541 ASSERT_TRUE(peer_connection_->remote_description() != nullptr); | |
542 ASSERT_TRUE(peer_connection_->local_description() != nullptr); | |
543 const cricket::SessionDescription* remote_desc = | |
544 peer_connection_->remote_description()->description(); | |
545 const cricket::SessionDescription* local_desc = | |
546 peer_connection_->local_description()->description(); | |
547 | |
548 const ContentInfo* remote_audio_content = GetFirstAudioContent(remote_desc); | |
549 if (remote_audio_content) { | |
550 const ContentInfo* audio_content = | |
551 GetFirstAudioContent(local_desc); | |
552 EXPECT_EQ(can_receive_audio(), !audio_content->rejected); | |
553 } | |
554 | |
555 const ContentInfo* remote_video_content = GetFirstVideoContent(remote_desc); | |
556 if (remote_video_content) { | |
557 const ContentInfo* video_content = | |
558 GetFirstVideoContent(local_desc); | |
559 EXPECT_EQ(can_receive_video(), !video_content->rejected); | |
560 } | |
561 } | |
562 | |
563 void VerifyLocalIceUfragAndPassword() { | |
564 ASSERT_TRUE(peer_connection_->local_description() != nullptr); | |
565 const cricket::SessionDescription* desc = | |
566 peer_connection_->local_description()->description(); | |
567 const cricket::ContentInfos& contents = desc->contents(); | |
568 | |
569 for (size_t index = 0; index < contents.size(); ++index) { | |
570 if (contents[index].rejected) | |
571 continue; | |
572 const cricket::TransportDescription* transport_desc = | |
573 desc->GetTransportDescriptionByName(contents[index].name); | |
574 | |
575 std::map<int, IceUfragPwdPair>::const_iterator ufragpair_it = | |
576 ice_ufrag_pwd_.find(static_cast<int>(index)); | |
577 if (ufragpair_it == ice_ufrag_pwd_.end()) { | |
578 ASSERT_FALSE(ExpectIceRestart()); | |
579 ice_ufrag_pwd_[static_cast<int>(index)] = | |
580 IceUfragPwdPair(transport_desc->ice_ufrag, transport_desc->ice_pwd); | |
581 } else if (ExpectIceRestart()) { | |
582 const IceUfragPwdPair& ufrag_pwd = ufragpair_it->second; | |
583 EXPECT_NE(ufrag_pwd.first, transport_desc->ice_ufrag); | |
584 EXPECT_NE(ufrag_pwd.second, transport_desc->ice_pwd); | |
585 } else { | |
586 const IceUfragPwdPair& ufrag_pwd = ufragpair_it->second; | |
587 EXPECT_EQ(ufrag_pwd.first, transport_desc->ice_ufrag); | |
588 EXPECT_EQ(ufrag_pwd.second, transport_desc->ice_pwd); | |
589 } | |
590 } | |
591 } | |
592 | |
593 int GetAudioOutputLevelStats(webrtc::MediaStreamTrackInterface* track) { | |
594 rtc::scoped_refptr<MockStatsObserver> | |
595 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
596 EXPECT_TRUE(peer_connection_->GetStats( | |
597 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
598 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
599 EXPECT_NE(0, observer->timestamp()); | |
600 return observer->AudioOutputLevel(); | |
601 } | |
602 | |
603 int GetAudioInputLevelStats() { | |
604 rtc::scoped_refptr<MockStatsObserver> | |
605 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
606 EXPECT_TRUE(peer_connection_->GetStats( | |
607 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
608 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
609 EXPECT_NE(0, observer->timestamp()); | |
610 return observer->AudioInputLevel(); | |
611 } | |
612 | |
613 int GetBytesReceivedStats(webrtc::MediaStreamTrackInterface* track) { | |
614 rtc::scoped_refptr<MockStatsObserver> | |
615 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
616 EXPECT_TRUE(peer_connection_->GetStats( | |
617 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
618 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
619 EXPECT_NE(0, observer->timestamp()); | |
620 return observer->BytesReceived(); | |
621 } | |
622 | |
623 int GetBytesSentStats(webrtc::MediaStreamTrackInterface* track) { | |
624 rtc::scoped_refptr<MockStatsObserver> | |
625 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
626 EXPECT_TRUE(peer_connection_->GetStats( | |
627 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
628 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
629 EXPECT_NE(0, observer->timestamp()); | |
630 return observer->BytesSent(); | |
631 } | |
632 | |
633 int GetAvailableReceivedBandwidthStats() { | |
634 rtc::scoped_refptr<MockStatsObserver> | |
635 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
636 EXPECT_TRUE(peer_connection_->GetStats( | |
637 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
638 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
639 EXPECT_NE(0, observer->timestamp()); | |
640 int bw = observer->AvailableReceiveBandwidth(); | |
641 return bw; | |
642 } | |
643 | |
644 std::string GetDtlsCipherStats() { | |
645 rtc::scoped_refptr<MockStatsObserver> | |
646 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
647 EXPECT_TRUE(peer_connection_->GetStats( | |
648 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
649 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
650 EXPECT_NE(0, observer->timestamp()); | |
651 return observer->DtlsCipher(); | |
652 } | |
653 | |
654 std::string GetSrtpCipherStats() { | |
655 rtc::scoped_refptr<MockStatsObserver> | |
656 observer(new rtc::RefCountedObject<MockStatsObserver>()); | |
657 EXPECT_TRUE(peer_connection_->GetStats( | |
658 observer, nullptr, PeerConnectionInterface::kStatsOutputLevelStandard)); | |
659 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
660 EXPECT_NE(0, observer->timestamp()); | |
661 return observer->SrtpCipher(); | |
662 } | |
663 | |
664 int rendered_width() { | |
665 EXPECT_FALSE(fake_video_renderers_.empty()); | |
666 return fake_video_renderers_.empty() ? 1 : | |
667 fake_video_renderers_.begin()->second->width(); | |
668 } | |
669 | |
670 int rendered_height() { | |
671 EXPECT_FALSE(fake_video_renderers_.empty()); | |
672 return fake_video_renderers_.empty() ? 1 : | |
673 fake_video_renderers_.begin()->second->height(); | |
674 } | |
675 | |
676 size_t number_of_remote_streams() { | |
677 if (!pc()) | |
678 return 0; | |
679 return pc()->remote_streams()->count(); | |
680 } | |
681 | |
682 StreamCollectionInterface* remote_streams() { | |
683 if (!pc()) { | |
684 ADD_FAILURE(); | |
685 return nullptr; | |
686 } | |
687 return pc()->remote_streams(); | |
688 } | |
689 | |
690 StreamCollectionInterface* local_streams() { | |
691 if (!pc()) { | |
692 ADD_FAILURE(); | |
693 return nullptr; | |
694 } | |
695 return pc()->local_streams(); | |
696 } | |
697 | |
698 webrtc::PeerConnectionInterface::SignalingState signaling_state() { | |
699 return pc()->signaling_state(); | |
700 } | |
701 | |
702 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() { | |
703 return pc()->ice_connection_state(); | |
704 } | |
705 | |
706 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() { | |
707 return pc()->ice_gathering_state(); | |
708 } | |
709 | |
710 private: | |
711 class DummyDtmfObserver : public DtmfSenderObserverInterface { | |
712 public: | |
713 DummyDtmfObserver() : completed_(false) {} | |
714 | |
715 // Implements DtmfSenderObserverInterface. | |
716 void OnToneChange(const std::string& tone) override { | |
717 tones_.push_back(tone); | |
718 if (tone.empty()) { | |
719 completed_ = true; | |
720 } | |
721 } | |
722 | |
723 void Verify(const std::vector<std::string>& tones) const { | |
724 ASSERT_TRUE(tones_.size() == tones.size()); | |
725 EXPECT_TRUE(std::equal(tones.begin(), tones.end(), tones_.begin())); | |
726 } | |
727 | |
728 bool completed() const { return completed_; } | |
729 | |
730 private: | |
731 bool completed_; | |
732 std::vector<std::string> tones_; | |
733 }; | |
734 | |
735 explicit PeerConnectionTestClient(const std::string& id) : id_(id) {} | |
736 | |
737 bool Init( | |
738 const MediaConstraintsInterface* constraints, | |
739 const PeerConnectionFactory::Options* options, | |
740 rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store) { | |
741 EXPECT_TRUE(!peer_connection_); | |
742 EXPECT_TRUE(!peer_connection_factory_); | |
743 rtc::scoped_ptr<cricket::PortAllocator> port_allocator( | |
744 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr)); | |
745 fake_audio_capture_module_ = FakeAudioCaptureModule::Create(); | |
746 | |
747 if (fake_audio_capture_module_ == nullptr) { | |
748 return false; | |
749 } | |
750 fake_video_decoder_factory_ = new FakeWebRtcVideoDecoderFactory(); | |
751 fake_video_encoder_factory_ = new FakeWebRtcVideoEncoderFactory(); | |
752 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( | |
753 rtc::Thread::Current(), rtc::Thread::Current(), | |
754 fake_audio_capture_module_, fake_video_encoder_factory_, | |
755 fake_video_decoder_factory_); | |
756 if (!peer_connection_factory_) { | |
757 return false; | |
758 } | |
759 if (options) { | |
760 peer_connection_factory_->SetOptions(*options); | |
761 } | |
762 peer_connection_ = CreatePeerConnection( | |
763 std::move(port_allocator), constraints, std::move(dtls_identity_store)); | |
764 return peer_connection_.get() != nullptr; | |
765 } | |
766 | |
767 rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection( | |
768 rtc::scoped_ptr<cricket::PortAllocator> port_allocator, | |
769 const MediaConstraintsInterface* constraints, | |
770 rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store) { | |
771 // CreatePeerConnection with RTCConfiguration. | |
772 webrtc::PeerConnectionInterface::RTCConfiguration config; | |
773 webrtc::PeerConnectionInterface::IceServer ice_server; | |
774 ice_server.uri = "stun:stun.l.google.com:19302"; | |
775 config.servers.push_back(ice_server); | |
776 | |
777 return peer_connection_factory_->CreatePeerConnection( | |
778 config, constraints, std::move(port_allocator), | |
779 std::move(dtls_identity_store), this); | |
780 } | |
781 | |
782 void HandleIncomingOffer(const std::string& msg) { | |
783 LOG(INFO) << id_ << "HandleIncomingOffer "; | |
784 if (NumberOfLocalMediaStreams() == 0 && auto_add_stream_) { | |
785 // If we are not sending any streams ourselves it is time to add some. | |
786 AddMediaStream(true, true); | |
787 } | |
788 rtc::scoped_ptr<SessionDescriptionInterface> desc( | |
789 webrtc::CreateSessionDescription("offer", msg, nullptr)); | |
790 EXPECT_TRUE(DoSetRemoteDescription(desc.release())); | |
791 rtc::scoped_ptr<SessionDescriptionInterface> answer; | |
792 EXPECT_TRUE(DoCreateAnswer(answer.use())); | |
793 std::string sdp; | |
794 EXPECT_TRUE(answer->ToString(&sdp)); | |
795 EXPECT_TRUE(DoSetLocalDescription(answer.release())); | |
796 if (signaling_message_receiver_) { | |
797 signaling_message_receiver_->ReceiveSdpMessage( | |
798 webrtc::SessionDescriptionInterface::kAnswer, sdp); | |
799 } | |
800 } | |
801 | |
802 void HandleIncomingAnswer(const std::string& msg) { | |
803 LOG(INFO) << id_ << "HandleIncomingAnswer"; | |
804 rtc::scoped_ptr<SessionDescriptionInterface> desc( | |
805 webrtc::CreateSessionDescription("answer", msg, nullptr)); | |
806 EXPECT_TRUE(DoSetRemoteDescription(desc.release())); | |
807 } | |
808 | |
809 bool DoCreateOfferAnswer(SessionDescriptionInterface** desc, | |
810 bool offer) { | |
811 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> | |
812 observer(new rtc::RefCountedObject< | |
813 MockCreateSessionDescriptionObserver>()); | |
814 if (offer) { | |
815 pc()->CreateOffer(observer, &session_description_constraints_); | |
816 } else { | |
817 pc()->CreateAnswer(observer, &session_description_constraints_); | |
818 } | |
819 EXPECT_EQ_WAIT(true, observer->called(), kMaxWaitMs); | |
820 *desc = observer->release_desc(); | |
821 if (observer->result() && ExpectIceRestart()) { | |
822 EXPECT_EQ(0u, (*desc)->candidates(0)->count()); | |
823 } | |
824 return observer->result(); | |
825 } | |
826 | |
827 bool DoCreateOffer(SessionDescriptionInterface** desc) { | |
828 return DoCreateOfferAnswer(desc, true); | |
829 } | |
830 | |
831 bool DoCreateAnswer(SessionDescriptionInterface** desc) { | |
832 return DoCreateOfferAnswer(desc, false); | |
833 } | |
834 | |
835 bool DoSetLocalDescription(SessionDescriptionInterface* desc) { | |
836 rtc::scoped_refptr<MockSetSessionDescriptionObserver> | |
837 observer(new rtc::RefCountedObject< | |
838 MockSetSessionDescriptionObserver>()); | |
839 LOG(INFO) << id_ << "SetLocalDescription "; | |
840 pc()->SetLocalDescription(observer, desc); | |
841 // Ignore the observer result. If we wait for the result with | |
842 // EXPECT_TRUE_WAIT, local ice candidates might be sent to the remote peer | |
843 // before the offer which is an error. | |
844 // The reason is that EXPECT_TRUE_WAIT uses | |
845 // rtc::Thread::Current()->ProcessMessages(1); | |
846 // ProcessMessages waits at least 1ms but processes all messages before | |
847 // returning. Since this test is synchronous and send messages to the remote | |
848 // peer whenever a callback is invoked, this can lead to messages being | |
849 // sent to the remote peer in the wrong order. | |
850 // TODO(perkj): Find a way to check the result without risking that the | |
851 // order of sent messages are changed. Ex- by posting all messages that are | |
852 // sent to the remote peer. | |
853 return true; | |
854 } | |
855 | |
856 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) { | |
857 rtc::scoped_refptr<MockSetSessionDescriptionObserver> | |
858 observer(new rtc::RefCountedObject< | |
859 MockSetSessionDescriptionObserver>()); | |
860 LOG(INFO) << id_ << "SetRemoteDescription "; | |
861 pc()->SetRemoteDescription(observer, desc); | |
862 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs); | |
863 return observer->result(); | |
864 } | |
865 | |
866 // This modifies all received SDP messages before they are processed. | |
867 void FilterIncomingSdpMessage(std::string* sdp) { | |
868 if (remove_msid_) { | |
869 const char kSdpSsrcAttribute[] = "a=ssrc:"; | |
870 RemoveLinesFromSdp(kSdpSsrcAttribute, sdp); | |
871 const char kSdpMsidSupportedAttribute[] = "a=msid-semantic:"; | |
872 RemoveLinesFromSdp(kSdpMsidSupportedAttribute, sdp); | |
873 } | |
874 if (remove_bundle_) { | |
875 const char kSdpBundleAttribute[] = "a=group:BUNDLE"; | |
876 RemoveLinesFromSdp(kSdpBundleAttribute, sdp); | |
877 } | |
878 if (remove_sdes_) { | |
879 const char kSdpSdesCryptoAttribute[] = "a=crypto"; | |
880 RemoveLinesFromSdp(kSdpSdesCryptoAttribute, sdp); | |
881 } | |
882 } | |
883 | |
884 std::string id_; | |
885 | |
886 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; | |
887 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> | |
888 peer_connection_factory_; | |
889 | |
890 bool auto_add_stream_ = true; | |
891 | |
892 typedef std::pair<std::string, std::string> IceUfragPwdPair; | |
893 std::map<int, IceUfragPwdPair> ice_ufrag_pwd_; | |
894 bool expect_ice_restart_ = false; | |
895 | |
896 // Needed to keep track of number of frames sent. | |
897 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_; | |
898 // Needed to keep track of number of frames received. | |
899 std::map<std::string, rtc::scoped_ptr<webrtc::FakeVideoTrackRenderer>> | |
900 fake_video_renderers_; | |
901 // Needed to ensure frames aren't received for removed tracks. | |
902 std::vector<rtc::scoped_ptr<webrtc::FakeVideoTrackRenderer>> | |
903 removed_fake_video_renderers_; | |
904 // Needed to keep track of number of frames received when external decoder | |
905 // used. | |
906 FakeWebRtcVideoDecoderFactory* fake_video_decoder_factory_ = nullptr; | |
907 FakeWebRtcVideoEncoderFactory* fake_video_encoder_factory_ = nullptr; | |
908 bool video_decoder_factory_enabled_ = false; | |
909 webrtc::FakeConstraints video_constraints_; | |
910 | |
911 // For remote peer communication. | |
912 SignalingMessageReceiver* signaling_message_receiver_ = nullptr; | |
913 | |
914 // Store references to the video capturers we've created, so that we can stop | |
915 // them, if required. | |
916 std::vector<cricket::VideoCapturer*> video_capturers_; | |
917 | |
918 webrtc::FakeConstraints session_description_constraints_; | |
919 bool remove_msid_ = false; // True if MSID should be removed in received SDP. | |
920 bool remove_bundle_ = | |
921 false; // True if bundle should be removed in received SDP. | |
922 bool remove_sdes_ = | |
923 false; // True if a=crypto should be removed in received SDP. | |
924 | |
925 rtc::scoped_refptr<DataChannelInterface> data_channel_; | |
926 rtc::scoped_ptr<MockDataChannelObserver> data_observer_; | |
927 }; | |
928 | |
929 class P2PTestConductor : public testing::Test { | |
930 public: | |
931 P2PTestConductor() | |
932 : pss_(new rtc::PhysicalSocketServer), | |
933 ss_(new rtc::VirtualSocketServer(pss_.get())), | |
934 ss_scope_(ss_.get()) {} | |
935 | |
936 bool SessionActive() { | |
937 return initiating_client_->SessionActive() && | |
938 receiving_client_->SessionActive(); | |
939 } | |
940 | |
941 // Return true if the number of frames provided have been received or it is | |
942 // known that that will never occur (e.g. no frames will be sent or | |
943 // captured). | |
944 bool FramesNotPending(int audio_frames_to_receive, | |
945 int video_frames_to_receive) { | |
946 return VideoFramesReceivedCheck(video_frames_to_receive) && | |
947 AudioFramesReceivedCheck(audio_frames_to_receive); | |
948 } | |
949 bool AudioFramesReceivedCheck(int frames_received) { | |
950 return initiating_client_->AudioFramesReceivedCheck(frames_received) && | |
951 receiving_client_->AudioFramesReceivedCheck(frames_received); | |
952 } | |
953 bool VideoFramesReceivedCheck(int frames_received) { | |
954 return initiating_client_->VideoFramesReceivedCheck(frames_received) && | |
955 receiving_client_->VideoFramesReceivedCheck(frames_received); | |
956 } | |
957 void VerifyDtmf() { | |
958 initiating_client_->VerifyDtmf(); | |
959 receiving_client_->VerifyDtmf(); | |
960 } | |
961 | |
962 void TestUpdateOfferWithRejectedContent() { | |
963 // Renegotiate, rejecting the video m-line. | |
964 initiating_client_->Negotiate(true, false); | |
965 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs); | |
966 | |
967 int pc1_audio_received = initiating_client_->audio_frames_received(); | |
968 int pc1_video_received = initiating_client_->video_frames_received(); | |
969 int pc2_audio_received = receiving_client_->audio_frames_received(); | |
970 int pc2_video_received = receiving_client_->video_frames_received(); | |
971 | |
972 // Wait for some additional audio frames to be received. | |
973 EXPECT_TRUE_WAIT(initiating_client_->AudioFramesReceivedCheck( | |
974 pc1_audio_received + kEndAudioFrameCount) && | |
975 receiving_client_->AudioFramesReceivedCheck( | |
976 pc2_audio_received + kEndAudioFrameCount), | |
977 kMaxWaitForFramesMs); | |
978 | |
979 // During this time, we shouldn't have received any additional video frames | |
980 // for the rejected video tracks. | |
981 EXPECT_EQ(pc1_video_received, initiating_client_->video_frames_received()); | |
982 EXPECT_EQ(pc2_video_received, receiving_client_->video_frames_received()); | |
983 } | |
984 | |
985 void VerifyRenderedSize(int width, int height) { | |
986 EXPECT_EQ(width, receiving_client()->rendered_width()); | |
987 EXPECT_EQ(height, receiving_client()->rendered_height()); | |
988 EXPECT_EQ(width, initializing_client()->rendered_width()); | |
989 EXPECT_EQ(height, initializing_client()->rendered_height()); | |
990 } | |
991 | |
992 void VerifySessionDescriptions() { | |
993 initiating_client_->VerifyRejectedMediaInSessionDescription(); | |
994 receiving_client_->VerifyRejectedMediaInSessionDescription(); | |
995 initiating_client_->VerifyLocalIceUfragAndPassword(); | |
996 receiving_client_->VerifyLocalIceUfragAndPassword(); | |
997 } | |
998 | |
999 ~P2PTestConductor() { | |
1000 if (initiating_client_) { | |
1001 initiating_client_->set_signaling_message_receiver(nullptr); | |
1002 } | |
1003 if (receiving_client_) { | |
1004 receiving_client_->set_signaling_message_receiver(nullptr); | |
1005 } | |
1006 } | |
1007 | |
1008 bool CreateTestClients() { return CreateTestClients(nullptr, nullptr); } | |
1009 | |
1010 bool CreateTestClients(MediaConstraintsInterface* init_constraints, | |
1011 MediaConstraintsInterface* recv_constraints) { | |
1012 return CreateTestClients(init_constraints, nullptr, recv_constraints, | |
1013 nullptr); | |
1014 } | |
1015 | |
1016 void SetSignalingReceivers() { | |
1017 initiating_client_->set_signaling_message_receiver(receiving_client_.get()); | |
1018 receiving_client_->set_signaling_message_receiver(initiating_client_.get()); | |
1019 } | |
1020 | |
1021 bool CreateTestClients(MediaConstraintsInterface* init_constraints, | |
1022 PeerConnectionFactory::Options* init_options, | |
1023 MediaConstraintsInterface* recv_constraints, | |
1024 PeerConnectionFactory::Options* recv_options) { | |
1025 initiating_client_.reset(PeerConnectionTestClient::CreateClient( | |
1026 "Caller: ", init_constraints, init_options)); | |
1027 receiving_client_.reset(PeerConnectionTestClient::CreateClient( | |
1028 "Callee: ", recv_constraints, recv_options)); | |
1029 if (!initiating_client_ || !receiving_client_) { | |
1030 return false; | |
1031 } | |
1032 SetSignalingReceivers(); | |
1033 return true; | |
1034 } | |
1035 | |
1036 void SetVideoConstraints(const webrtc::FakeConstraints& init_constraints, | |
1037 const webrtc::FakeConstraints& recv_constraints) { | |
1038 initiating_client_->SetVideoConstraints(init_constraints); | |
1039 receiving_client_->SetVideoConstraints(recv_constraints); | |
1040 } | |
1041 | |
1042 void EnableVideoDecoderFactory() { | |
1043 initiating_client_->EnableVideoDecoderFactory(); | |
1044 receiving_client_->EnableVideoDecoderFactory(); | |
1045 } | |
1046 | |
1047 // This test sets up a call between two parties. Both parties send static | |
1048 // frames to each other. Once the test is finished the number of sent frames | |
1049 // is compared to the number of received frames. | |
1050 void LocalP2PTest() { | |
1051 if (initiating_client_->NumberOfLocalMediaStreams() == 0) { | |
1052 initiating_client_->AddMediaStream(true, true); | |
1053 } | |
1054 initiating_client_->Negotiate(); | |
1055 // Assert true is used here since next tests are guaranteed to fail and | |
1056 // would eat up 5 seconds. | |
1057 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs); | |
1058 VerifySessionDescriptions(); | |
1059 | |
1060 int audio_frame_count = kEndAudioFrameCount; | |
1061 // TODO(ronghuawu): Add test to cover the case of sendonly and recvonly. | |
1062 if (!initiating_client_->can_receive_audio() || | |
1063 !receiving_client_->can_receive_audio()) { | |
1064 audio_frame_count = -1; | |
1065 } | |
1066 int video_frame_count = kEndVideoFrameCount; | |
1067 if (!initiating_client_->can_receive_video() || | |
1068 !receiving_client_->can_receive_video()) { | |
1069 video_frame_count = -1; | |
1070 } | |
1071 | |
1072 if (audio_frame_count != -1 || video_frame_count != -1) { | |
1073 // Audio or video is expected to flow, so both clients should reach the | |
1074 // Connected state, and the offerer (ICE controller) should proceed to | |
1075 // Completed. | |
1076 // Note: These tests have been observed to fail under heavy load at | |
1077 // shorter timeouts, so they may be flaky. | |
1078 EXPECT_EQ_WAIT( | |
1079 webrtc::PeerConnectionInterface::kIceConnectionCompleted, | |
1080 initiating_client_->ice_connection_state(), | |
1081 kMaxWaitForFramesMs); | |
1082 EXPECT_EQ_WAIT( | |
1083 webrtc::PeerConnectionInterface::kIceConnectionConnected, | |
1084 receiving_client_->ice_connection_state(), | |
1085 kMaxWaitForFramesMs); | |
1086 } | |
1087 | |
1088 if (initiating_client_->can_receive_audio() || | |
1089 initiating_client_->can_receive_video()) { | |
1090 // The initiating client can receive media, so it must produce candidates | |
1091 // that will serve as destinations for that media. | |
1092 // TODO(bemasc): Understand why the state is not already Complete here, as | |
1093 // seems to be the case for the receiving client. This may indicate a bug | |
1094 // in the ICE gathering system. | |
1095 EXPECT_NE(webrtc::PeerConnectionInterface::kIceGatheringNew, | |
1096 initiating_client_->ice_gathering_state()); | |
1097 } | |
1098 if (receiving_client_->can_receive_audio() || | |
1099 receiving_client_->can_receive_video()) { | |
1100 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete, | |
1101 receiving_client_->ice_gathering_state(), | |
1102 kMaxWaitForFramesMs); | |
1103 } | |
1104 | |
1105 EXPECT_TRUE_WAIT(FramesNotPending(audio_frame_count, video_frame_count), | |
1106 kMaxWaitForFramesMs); | |
1107 } | |
1108 | |
1109 void SetupAndVerifyDtlsCall() { | |
1110 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
1111 FakeConstraints setup_constraints; | |
1112 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
1113 true); | |
1114 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
1115 LocalP2PTest(); | |
1116 VerifyRenderedSize(640, 480); | |
1117 } | |
1118 | |
1119 PeerConnectionTestClient* CreateDtlsClientWithAlternateKey() { | |
1120 FakeConstraints setup_constraints; | |
1121 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
1122 true); | |
1123 | |
1124 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store( | |
1125 rtc::SSLStreamAdapter::HaveDtlsSrtp() ? new FakeDtlsIdentityStore() | |
1126 : nullptr); | |
1127 dtls_identity_store->use_alternate_key(); | |
1128 | |
1129 // Make sure the new client is using a different certificate. | |
1130 return PeerConnectionTestClient::CreateClientWithDtlsIdentityStore( | |
1131 "New Peer: ", &setup_constraints, nullptr, | |
1132 std::move(dtls_identity_store)); | |
1133 } | |
1134 | |
1135 void SendRtpData(webrtc::DataChannelInterface* dc, const std::string& data) { | |
1136 // Messages may get lost on the unreliable DataChannel, so we send multiple | |
1137 // times to avoid test flakiness. | |
1138 static const size_t kSendAttempts = 5; | |
1139 | |
1140 for (size_t i = 0; i < kSendAttempts; ++i) { | |
1141 dc->Send(DataBuffer(data)); | |
1142 } | |
1143 } | |
1144 | |
1145 PeerConnectionTestClient* initializing_client() { | |
1146 return initiating_client_.get(); | |
1147 } | |
1148 | |
1149 // Set the |initiating_client_| to the |client| passed in and return the | |
1150 // original |initiating_client_|. | |
1151 PeerConnectionTestClient* set_initializing_client( | |
1152 PeerConnectionTestClient* client) { | |
1153 PeerConnectionTestClient* old = initiating_client_.release(); | |
1154 initiating_client_.reset(client); | |
1155 return old; | |
1156 } | |
1157 | |
1158 PeerConnectionTestClient* receiving_client() { | |
1159 return receiving_client_.get(); | |
1160 } | |
1161 | |
1162 // Set the |receiving_client_| to the |client| passed in and return the | |
1163 // original |receiving_client_|. | |
1164 PeerConnectionTestClient* set_receiving_client( | |
1165 PeerConnectionTestClient* client) { | |
1166 PeerConnectionTestClient* old = receiving_client_.release(); | |
1167 receiving_client_.reset(client); | |
1168 return old; | |
1169 } | |
1170 | |
1171 private: | |
1172 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_; | |
1173 rtc::scoped_ptr<rtc::VirtualSocketServer> ss_; | |
1174 rtc::SocketServerScope ss_scope_; | |
1175 rtc::scoped_ptr<PeerConnectionTestClient> initiating_client_; | |
1176 rtc::scoped_ptr<PeerConnectionTestClient> receiving_client_; | |
1177 }; | |
1178 | |
1179 // Disable for TSan v2, see | |
1180 // https://code.google.com/p/webrtc/issues/detail?id=1205 for details. | |
1181 #if !defined(THREAD_SANITIZER) | |
1182 | |
1183 // This test sets up a Jsep call between two parties and test Dtmf. | |
1184 // TODO(holmer): Disabled due to sometimes crashing on buildbots. | |
1185 // See issue webrtc/2378. | |
1186 TEST_F(P2PTestConductor, DISABLED_LocalP2PTestDtmf) { | |
1187 ASSERT_TRUE(CreateTestClients()); | |
1188 LocalP2PTest(); | |
1189 VerifyDtmf(); | |
1190 } | |
1191 | |
1192 // This test sets up a Jsep call between two parties and test that we can get a | |
1193 // video aspect ratio of 16:9. | |
1194 TEST_F(P2PTestConductor, LocalP2PTest16To9) { | |
1195 ASSERT_TRUE(CreateTestClients()); | |
1196 FakeConstraints constraint; | |
1197 double requested_ratio = 640.0/360; | |
1198 constraint.SetMandatoryMinAspectRatio(requested_ratio); | |
1199 SetVideoConstraints(constraint, constraint); | |
1200 LocalP2PTest(); | |
1201 | |
1202 ASSERT_LE(0, initializing_client()->rendered_height()); | |
1203 double initiating_video_ratio = | |
1204 static_cast<double>(initializing_client()->rendered_width()) / | |
1205 initializing_client()->rendered_height(); | |
1206 EXPECT_LE(requested_ratio, initiating_video_ratio); | |
1207 | |
1208 ASSERT_LE(0, receiving_client()->rendered_height()); | |
1209 double receiving_video_ratio = | |
1210 static_cast<double>(receiving_client()->rendered_width()) / | |
1211 receiving_client()->rendered_height(); | |
1212 EXPECT_LE(requested_ratio, receiving_video_ratio); | |
1213 } | |
1214 | |
1215 // This test sets up a Jsep call between two parties and test that the | |
1216 // received video has a resolution of 1280*720. | |
1217 // TODO(mallinath): Enable when | |
1218 // http://code.google.com/p/webrtc/issues/detail?id=981 is fixed. | |
1219 TEST_F(P2PTestConductor, DISABLED_LocalP2PTest1280By720) { | |
1220 ASSERT_TRUE(CreateTestClients()); | |
1221 FakeConstraints constraint; | |
1222 constraint.SetMandatoryMinWidth(1280); | |
1223 constraint.SetMandatoryMinHeight(720); | |
1224 SetVideoConstraints(constraint, constraint); | |
1225 LocalP2PTest(); | |
1226 VerifyRenderedSize(1280, 720); | |
1227 } | |
1228 | |
1229 // This test sets up a call between two endpoints that are configured to use | |
1230 // DTLS key agreement. As a result, DTLS is negotiated and used for transport. | |
1231 TEST_F(P2PTestConductor, LocalP2PTestDtls) { | |
1232 SetupAndVerifyDtlsCall(); | |
1233 } | |
1234 | |
1235 // This test sets up a audio call initially and then upgrades to audio/video, | |
1236 // using DTLS. | |
1237 TEST_F(P2PTestConductor, LocalP2PTestDtlsRenegotiate) { | |
1238 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
1239 FakeConstraints setup_constraints; | |
1240 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
1241 true); | |
1242 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
1243 receiving_client()->SetReceiveAudioVideo(true, false); | |
1244 LocalP2PTest(); | |
1245 receiving_client()->SetReceiveAudioVideo(true, true); | |
1246 receiving_client()->Negotiate(); | |
1247 } | |
1248 | |
1249 // This test sets up a call transfer to a new caller with a different DTLS | |
1250 // fingerprint. | |
1251 TEST_F(P2PTestConductor, LocalP2PTestDtlsTransferCallee) { | |
1252 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
1253 SetupAndVerifyDtlsCall(); | |
1254 | |
1255 // Keeping the original peer around which will still send packets to the | |
1256 // receiving client. These SRTP packets will be dropped. | |
1257 rtc::scoped_ptr<PeerConnectionTestClient> original_peer( | |
1258 set_initializing_client(CreateDtlsClientWithAlternateKey())); | |
1259 original_peer->pc()->Close(); | |
1260 | |
1261 SetSignalingReceivers(); | |
1262 receiving_client()->SetExpectIceRestart(true); | |
1263 LocalP2PTest(); | |
1264 VerifyRenderedSize(640, 480); | |
1265 } | |
1266 | |
1267 // This test sets up a non-bundle call and apply bundle during ICE restart. When | |
1268 // bundle is in effect in the restart, the channel can successfully reset its | |
1269 // DTLS-SRTP context. | |
1270 TEST_F(P2PTestConductor, LocalP2PTestDtlsBundleInIceRestart) { | |
1271 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
1272 FakeConstraints setup_constraints; | |
1273 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
1274 true); | |
1275 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
1276 receiving_client()->RemoveBundleFromReceivedSdp(true); | |
1277 LocalP2PTest(); | |
1278 VerifyRenderedSize(640, 480); | |
1279 | |
1280 initializing_client()->IceRestart(); | |
1281 receiving_client()->SetExpectIceRestart(true); | |
1282 receiving_client()->RemoveBundleFromReceivedSdp(false); | |
1283 LocalP2PTest(); | |
1284 VerifyRenderedSize(640, 480); | |
1285 } | |
1286 | |
1287 // This test sets up a call transfer to a new callee with a different DTLS | |
1288 // fingerprint. | |
1289 TEST_F(P2PTestConductor, LocalP2PTestDtlsTransferCaller) { | |
1290 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
1291 SetupAndVerifyDtlsCall(); | |
1292 | |
1293 // Keeping the original peer around which will still send packets to the | |
1294 // receiving client. These SRTP packets will be dropped. | |
1295 rtc::scoped_ptr<PeerConnectionTestClient> original_peer( | |
1296 set_receiving_client(CreateDtlsClientWithAlternateKey())); | |
1297 original_peer->pc()->Close(); | |
1298 | |
1299 SetSignalingReceivers(); | |
1300 initializing_client()->IceRestart(); | |
1301 LocalP2PTest(); | |
1302 VerifyRenderedSize(640, 480); | |
1303 } | |
1304 | |
1305 // This test sets up a call between two endpoints that are configured to use | |
1306 // DTLS key agreement. The offerer don't support SDES. As a result, DTLS is | |
1307 // negotiated and used for transport. | |
1308 TEST_F(P2PTestConductor, LocalP2PTestOfferDtlsButNotSdes) { | |
1309 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
1310 FakeConstraints setup_constraints; | |
1311 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | |
1312 true); | |
1313 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
1314 receiving_client()->RemoveSdesCryptoFromReceivedSdp(true); | |
1315 LocalP2PTest(); | |
1316 VerifyRenderedSize(640, 480); | |
1317 } | |
1318 | |
1319 // This test sets up a Jsep call between two parties, and the callee only | |
1320 // accept to receive video. | |
1321 TEST_F(P2PTestConductor, LocalP2PTestAnswerVideo) { | |
1322 ASSERT_TRUE(CreateTestClients()); | |
1323 receiving_client()->SetReceiveAudioVideo(false, true); | |
1324 LocalP2PTest(); | |
1325 } | |
1326 | |
1327 // This test sets up a Jsep call between two parties, and the callee only | |
1328 // accept to receive audio. | |
1329 TEST_F(P2PTestConductor, LocalP2PTestAnswerAudio) { | |
1330 ASSERT_TRUE(CreateTestClients()); | |
1331 receiving_client()->SetReceiveAudioVideo(true, false); | |
1332 LocalP2PTest(); | |
1333 } | |
1334 | |
1335 // This test sets up a Jsep call between two parties, and the callee reject both | |
1336 // audio and video. | |
1337 TEST_F(P2PTestConductor, LocalP2PTestAnswerNone) { | |
1338 ASSERT_TRUE(CreateTestClients()); | |
1339 receiving_client()->SetReceiveAudioVideo(false, false); | |
1340 LocalP2PTest(); | |
1341 } | |
1342 | |
1343 // This test sets up an audio and video call between two parties. After the call | |
1344 // runs for a while (10 frames), the caller sends an update offer with video | |
1345 // being rejected. Once the re-negotiation is done, the video flow should stop | |
1346 // and the audio flow should continue. | |
1347 TEST_F(P2PTestConductor, UpdateOfferWithRejectedContent) { | |
1348 ASSERT_TRUE(CreateTestClients()); | |
1349 LocalP2PTest(); | |
1350 TestUpdateOfferWithRejectedContent(); | |
1351 } | |
1352 | |
1353 // This test sets up a Jsep call between two parties. The MSID is removed from | |
1354 // the SDP strings from the caller. | |
1355 TEST_F(P2PTestConductor, LocalP2PTestWithoutMsid) { | |
1356 ASSERT_TRUE(CreateTestClients()); | |
1357 receiving_client()->RemoveMsidFromReceivedSdp(true); | |
1358 // TODO(perkj): Currently there is a bug that cause audio to stop playing if | |
1359 // audio and video is muxed when MSID is disabled. Remove | |
1360 // SetRemoveBundleFromSdp once | |
1361 // https://code.google.com/p/webrtc/issues/detail?id=1193 is fixed. | |
1362 receiving_client()->RemoveBundleFromReceivedSdp(true); | |
1363 LocalP2PTest(); | |
1364 } | |
1365 | |
1366 // This test sets up a Jsep call between two parties and the initiating peer | |
1367 // sends two steams. | |
1368 // TODO(perkj): Disabled due to | |
1369 // https://code.google.com/p/webrtc/issues/detail?id=1454 | |
1370 TEST_F(P2PTestConductor, DISABLED_LocalP2PTestTwoStreams) { | |
1371 ASSERT_TRUE(CreateTestClients()); | |
1372 // Set optional video constraint to max 320pixels to decrease CPU usage. | |
1373 FakeConstraints constraint; | |
1374 constraint.SetOptionalMaxWidth(320); | |
1375 SetVideoConstraints(constraint, constraint); | |
1376 initializing_client()->AddMediaStream(true, true); | |
1377 initializing_client()->AddMediaStream(false, true); | |
1378 ASSERT_EQ(2u, initializing_client()->NumberOfLocalMediaStreams()); | |
1379 LocalP2PTest(); | |
1380 EXPECT_EQ(2u, receiving_client()->number_of_remote_streams()); | |
1381 } | |
1382 | |
1383 // Test that we can receive the audio output level from a remote audio track. | |
1384 TEST_F(P2PTestConductor, GetAudioOutputLevelStats) { | |
1385 ASSERT_TRUE(CreateTestClients()); | |
1386 LocalP2PTest(); | |
1387 | |
1388 StreamCollectionInterface* remote_streams = | |
1389 initializing_client()->remote_streams(); | |
1390 ASSERT_GT(remote_streams->count(), 0u); | |
1391 ASSERT_GT(remote_streams->at(0)->GetAudioTracks().size(), 0u); | |
1392 MediaStreamTrackInterface* remote_audio_track = | |
1393 remote_streams->at(0)->GetAudioTracks()[0]; | |
1394 | |
1395 // Get the audio output level stats. Note that the level is not available | |
1396 // until a RTCP packet has been received. | |
1397 EXPECT_TRUE_WAIT( | |
1398 initializing_client()->GetAudioOutputLevelStats(remote_audio_track) > 0, | |
1399 kMaxWaitForStatsMs); | |
1400 } | |
1401 | |
1402 // Test that an audio input level is reported. | |
1403 TEST_F(P2PTestConductor, GetAudioInputLevelStats) { | |
1404 ASSERT_TRUE(CreateTestClients()); | |
1405 LocalP2PTest(); | |
1406 | |
1407 // Get the audio input level stats. The level should be available very | |
1408 // soon after the test starts. | |
1409 EXPECT_TRUE_WAIT(initializing_client()->GetAudioInputLevelStats() > 0, | |
1410 kMaxWaitForStatsMs); | |
1411 } | |
1412 | |
1413 // Test that we can get incoming byte counts from both audio and video tracks. | |
1414 TEST_F(P2PTestConductor, GetBytesReceivedStats) { | |
1415 ASSERT_TRUE(CreateTestClients()); | |
1416 LocalP2PTest(); | |
1417 | |
1418 StreamCollectionInterface* remote_streams = | |
1419 initializing_client()->remote_streams(); | |
1420 ASSERT_GT(remote_streams->count(), 0u); | |
1421 ASSERT_GT(remote_streams->at(0)->GetAudioTracks().size(), 0u); | |
1422 MediaStreamTrackInterface* remote_audio_track = | |
1423 remote_streams->at(0)->GetAudioTracks()[0]; | |
1424 EXPECT_TRUE_WAIT( | |
1425 initializing_client()->GetBytesReceivedStats(remote_audio_track) > 0, | |
1426 kMaxWaitForStatsMs); | |
1427 | |
1428 MediaStreamTrackInterface* remote_video_track = | |
1429 remote_streams->at(0)->GetVideoTracks()[0]; | |
1430 EXPECT_TRUE_WAIT( | |
1431 initializing_client()->GetBytesReceivedStats(remote_video_track) > 0, | |
1432 kMaxWaitForStatsMs); | |
1433 } | |
1434 | |
1435 // Test that we can get outgoing byte counts from both audio and video tracks. | |
1436 TEST_F(P2PTestConductor, GetBytesSentStats) { | |
1437 ASSERT_TRUE(CreateTestClients()); | |
1438 LocalP2PTest(); | |
1439 | |
1440 StreamCollectionInterface* local_streams = | |
1441 initializing_client()->local_streams(); | |
1442 ASSERT_GT(local_streams->count(), 0u); | |
1443 ASSERT_GT(local_streams->at(0)->GetAudioTracks().size(), 0u); | |
1444 MediaStreamTrackInterface* local_audio_track = | |
1445 local_streams->at(0)->GetAudioTracks()[0]; | |
1446 EXPECT_TRUE_WAIT( | |
1447 initializing_client()->GetBytesSentStats(local_audio_track) > 0, | |
1448 kMaxWaitForStatsMs); | |
1449 | |
1450 MediaStreamTrackInterface* local_video_track = | |
1451 local_streams->at(0)->GetVideoTracks()[0]; | |
1452 EXPECT_TRUE_WAIT( | |
1453 initializing_client()->GetBytesSentStats(local_video_track) > 0, | |
1454 kMaxWaitForStatsMs); | |
1455 } | |
1456 | |
1457 // Test that DTLS 1.0 is used if both sides only support DTLS 1.0. | |
1458 TEST_F(P2PTestConductor, GetDtls12None) { | |
1459 PeerConnectionFactory::Options init_options; | |
1460 init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; | |
1461 PeerConnectionFactory::Options recv_options; | |
1462 recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; | |
1463 ASSERT_TRUE( | |
1464 CreateTestClients(nullptr, &init_options, nullptr, &recv_options)); | |
1465 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
1466 init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
1467 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
1468 LocalP2PTest(); | |
1469 | |
1470 EXPECT_EQ_WAIT(rtc::SSLStreamAdapter::SslCipherSuiteToName( | |
1471 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest( | |
1472 rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)), | |
1473 initializing_client()->GetDtlsCipherStats(), | |
1474 kMaxWaitForStatsMs); | |
1475 EXPECT_EQ(1, init_observer->GetEnumCounter( | |
1476 webrtc::kEnumCounterAudioSslCipher, | |
1477 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest( | |
1478 rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT))); | |
1479 | |
1480 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), | |
1481 initializing_client()->GetSrtpCipherStats(), | |
1482 kMaxWaitForStatsMs); | |
1483 EXPECT_EQ(1, | |
1484 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
1485 kDefaultSrtpCryptoSuite)); | |
1486 } | |
1487 | |
1488 // Test that DTLS 1.2 is used if both ends support it. | |
1489 TEST_F(P2PTestConductor, GetDtls12Both) { | |
1490 PeerConnectionFactory::Options init_options; | |
1491 init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; | |
1492 PeerConnectionFactory::Options recv_options; | |
1493 recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; | |
1494 ASSERT_TRUE( | |
1495 CreateTestClients(nullptr, &init_options, nullptr, &recv_options)); | |
1496 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
1497 init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
1498 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
1499 LocalP2PTest(); | |
1500 | |
1501 EXPECT_EQ_WAIT(rtc::SSLStreamAdapter::SslCipherSuiteToName( | |
1502 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest( | |
1503 rtc::SSL_PROTOCOL_DTLS_12, rtc::KT_DEFAULT)), | |
1504 initializing_client()->GetDtlsCipherStats(), | |
1505 kMaxWaitForStatsMs); | |
1506 EXPECT_EQ(1, init_observer->GetEnumCounter( | |
1507 webrtc::kEnumCounterAudioSslCipher, | |
1508 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest( | |
1509 rtc::SSL_PROTOCOL_DTLS_12, rtc::KT_DEFAULT))); | |
1510 | |
1511 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), | |
1512 initializing_client()->GetSrtpCipherStats(), | |
1513 kMaxWaitForStatsMs); | |
1514 EXPECT_EQ(1, | |
1515 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
1516 kDefaultSrtpCryptoSuite)); | |
1517 } | |
1518 | |
1519 // Test that DTLS 1.0 is used if the initator supports DTLS 1.2 and the | |
1520 // received supports 1.0. | |
1521 TEST_F(P2PTestConductor, GetDtls12Init) { | |
1522 PeerConnectionFactory::Options init_options; | |
1523 init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; | |
1524 PeerConnectionFactory::Options recv_options; | |
1525 recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; | |
1526 ASSERT_TRUE( | |
1527 CreateTestClients(nullptr, &init_options, nullptr, &recv_options)); | |
1528 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
1529 init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
1530 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
1531 LocalP2PTest(); | |
1532 | |
1533 EXPECT_EQ_WAIT(rtc::SSLStreamAdapter::SslCipherSuiteToName( | |
1534 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest( | |
1535 rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)), | |
1536 initializing_client()->GetDtlsCipherStats(), | |
1537 kMaxWaitForStatsMs); | |
1538 EXPECT_EQ(1, init_observer->GetEnumCounter( | |
1539 webrtc::kEnumCounterAudioSslCipher, | |
1540 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest( | |
1541 rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT))); | |
1542 | |
1543 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), | |
1544 initializing_client()->GetSrtpCipherStats(), | |
1545 kMaxWaitForStatsMs); | |
1546 EXPECT_EQ(1, | |
1547 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
1548 kDefaultSrtpCryptoSuite)); | |
1549 } | |
1550 | |
1551 // Test that DTLS 1.0 is used if the initator supports DTLS 1.0 and the | |
1552 // received supports 1.2. | |
1553 TEST_F(P2PTestConductor, GetDtls12Recv) { | |
1554 PeerConnectionFactory::Options init_options; | |
1555 init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10; | |
1556 PeerConnectionFactory::Options recv_options; | |
1557 recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12; | |
1558 ASSERT_TRUE( | |
1559 CreateTestClients(nullptr, &init_options, nullptr, &recv_options)); | |
1560 rtc::scoped_refptr<webrtc::FakeMetricsObserver> | |
1561 init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>(); | |
1562 initializing_client()->pc()->RegisterUMAObserver(init_observer); | |
1563 LocalP2PTest(); | |
1564 | |
1565 EXPECT_EQ_WAIT(rtc::SSLStreamAdapter::SslCipherSuiteToName( | |
1566 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest( | |
1567 rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)), | |
1568 initializing_client()->GetDtlsCipherStats(), | |
1569 kMaxWaitForStatsMs); | |
1570 EXPECT_EQ(1, init_observer->GetEnumCounter( | |
1571 webrtc::kEnumCounterAudioSslCipher, | |
1572 rtc::SSLStreamAdapter::GetDefaultSslCipherForTest( | |
1573 rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT))); | |
1574 | |
1575 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite), | |
1576 initializing_client()->GetSrtpCipherStats(), | |
1577 kMaxWaitForStatsMs); | |
1578 EXPECT_EQ(1, | |
1579 init_observer->GetEnumCounter(webrtc::kEnumCounterAudioSrtpCipher, | |
1580 kDefaultSrtpCryptoSuite)); | |
1581 } | |
1582 | |
1583 // This test sets up a call between two parties with audio, video and an RTP | |
1584 // data channel. | |
1585 TEST_F(P2PTestConductor, LocalP2PTestRtpDataChannel) { | |
1586 FakeConstraints setup_constraints; | |
1587 setup_constraints.SetAllowRtpDataChannels(); | |
1588 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
1589 initializing_client()->CreateDataChannel(); | |
1590 LocalP2PTest(); | |
1591 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
1592 ASSERT_TRUE(receiving_client()->data_channel() != nullptr); | |
1593 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
1594 kMaxWaitMs); | |
1595 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), | |
1596 kMaxWaitMs); | |
1597 | |
1598 std::string data = "hello world"; | |
1599 | |
1600 SendRtpData(initializing_client()->data_channel(), data); | |
1601 EXPECT_EQ_WAIT(data, receiving_client()->data_observer()->last_message(), | |
1602 kMaxWaitMs); | |
1603 | |
1604 SendRtpData(receiving_client()->data_channel(), data); | |
1605 EXPECT_EQ_WAIT(data, initializing_client()->data_observer()->last_message(), | |
1606 kMaxWaitMs); | |
1607 | |
1608 receiving_client()->data_channel()->Close(); | |
1609 // Send new offer and answer. | |
1610 receiving_client()->Negotiate(); | |
1611 EXPECT_FALSE(initializing_client()->data_observer()->IsOpen()); | |
1612 EXPECT_FALSE(receiving_client()->data_observer()->IsOpen()); | |
1613 } | |
1614 | |
1615 // This test sets up a call between two parties with audio, video and an SCTP | |
1616 // data channel. | |
1617 TEST_F(P2PTestConductor, LocalP2PTestSctpDataChannel) { | |
1618 ASSERT_TRUE(CreateTestClients()); | |
1619 initializing_client()->CreateDataChannel(); | |
1620 LocalP2PTest(); | |
1621 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
1622 EXPECT_TRUE_WAIT(receiving_client()->data_channel() != nullptr, kMaxWaitMs); | |
1623 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
1624 kMaxWaitMs); | |
1625 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), kMaxWaitMs); | |
1626 | |
1627 std::string data = "hello world"; | |
1628 | |
1629 initializing_client()->data_channel()->Send(DataBuffer(data)); | |
1630 EXPECT_EQ_WAIT(data, receiving_client()->data_observer()->last_message(), | |
1631 kMaxWaitMs); | |
1632 | |
1633 receiving_client()->data_channel()->Send(DataBuffer(data)); | |
1634 EXPECT_EQ_WAIT(data, initializing_client()->data_observer()->last_message(), | |
1635 kMaxWaitMs); | |
1636 | |
1637 receiving_client()->data_channel()->Close(); | |
1638 EXPECT_TRUE_WAIT(!initializing_client()->data_observer()->IsOpen(), | |
1639 kMaxWaitMs); | |
1640 EXPECT_TRUE_WAIT(!receiving_client()->data_observer()->IsOpen(), kMaxWaitMs); | |
1641 } | |
1642 | |
1643 // This test sets up a call between two parties and creates a data channel. | |
1644 // The test tests that received data is buffered unless an observer has been | |
1645 // registered. | |
1646 // Rtp data channels can receive data before the underlying | |
1647 // transport has detected that a channel is writable and thus data can be | |
1648 // received before the data channel state changes to open. That is hard to test | |
1649 // but the same buffering is used in that case. | |
1650 TEST_F(P2PTestConductor, RegisterDataChannelObserver) { | |
1651 FakeConstraints setup_constraints; | |
1652 setup_constraints.SetAllowRtpDataChannels(); | |
1653 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
1654 initializing_client()->CreateDataChannel(); | |
1655 initializing_client()->Negotiate(); | |
1656 | |
1657 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
1658 ASSERT_TRUE(receiving_client()->data_channel() != nullptr); | |
1659 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
1660 kMaxWaitMs); | |
1661 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, | |
1662 receiving_client()->data_channel()->state(), kMaxWaitMs); | |
1663 | |
1664 // Unregister the existing observer. | |
1665 receiving_client()->data_channel()->UnregisterObserver(); | |
1666 | |
1667 std::string data = "hello world"; | |
1668 SendRtpData(initializing_client()->data_channel(), data); | |
1669 | |
1670 // Wait a while to allow the sent data to arrive before an observer is | |
1671 // registered.. | |
1672 rtc::Thread::Current()->ProcessMessages(100); | |
1673 | |
1674 MockDataChannelObserver new_observer(receiving_client()->data_channel()); | |
1675 EXPECT_EQ_WAIT(data, new_observer.last_message(), kMaxWaitMs); | |
1676 } | |
1677 | |
1678 // This test sets up a call between two parties with audio, video and but only | |
1679 // the initiating client support data. | |
1680 TEST_F(P2PTestConductor, LocalP2PTestReceiverDoesntSupportData) { | |
1681 FakeConstraints setup_constraints_1; | |
1682 setup_constraints_1.SetAllowRtpDataChannels(); | |
1683 // Must disable DTLS to make negotiation succeed. | |
1684 setup_constraints_1.SetMandatory( | |
1685 MediaConstraintsInterface::kEnableDtlsSrtp, false); | |
1686 FakeConstraints setup_constraints_2; | |
1687 setup_constraints_2.SetMandatory( | |
1688 MediaConstraintsInterface::kEnableDtlsSrtp, false); | |
1689 ASSERT_TRUE(CreateTestClients(&setup_constraints_1, &setup_constraints_2)); | |
1690 initializing_client()->CreateDataChannel(); | |
1691 LocalP2PTest(); | |
1692 EXPECT_TRUE(initializing_client()->data_channel() != nullptr); | |
1693 EXPECT_FALSE(receiving_client()->data_channel()); | |
1694 EXPECT_FALSE(initializing_client()->data_observer()->IsOpen()); | |
1695 } | |
1696 | |
1697 // This test sets up a call between two parties with audio, video. When audio | |
1698 // and video is setup and flowing and data channel is negotiated. | |
1699 TEST_F(P2PTestConductor, AddDataChannelAfterRenegotiation) { | |
1700 FakeConstraints setup_constraints; | |
1701 setup_constraints.SetAllowRtpDataChannels(); | |
1702 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | |
1703 LocalP2PTest(); | |
1704 initializing_client()->CreateDataChannel(); | |
1705 // Send new offer and answer. | |
1706 initializing_client()->Negotiate(); | |
1707 ASSERT_TRUE(initializing_client()->data_channel() != nullptr); | |
1708 ASSERT_TRUE(receiving_client()->data_channel() != nullptr); | |
1709 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(), | |
1710 kMaxWaitMs); | |
1711 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(), | |
1712 kMaxWaitMs); | |
1713 } | |
1714 | |
1715 // This test sets up a Jsep call with SCTP DataChannel and verifies the | |
1716 // negotiation is completed without error. | |
1717 #ifdef HAVE_SCTP | |
1718 TEST_F(P2PTestConductor, CreateOfferWithSctpDataChannel) { | |
1719 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | |
1720 FakeConstraints constraints; | |
1721 constraints.SetMandatory( | |
1722 MediaConstraintsInterface::kEnableDtlsSrtp, true); | |
1723 ASSERT_TRUE(CreateTestClients(&constraints, &constraints)); | |
1724 initializing_client()->CreateDataChannel(); | |
1725 initializing_client()->Negotiate(false, false); | |
1726 } | |
1727 #endif | |
1728 | |
1729 // This test sets up a call between two parties with audio, and video. | |
1730 // During the call, the initializing side restart ice and the test verifies that | |
1731 // new ice candidates are generated and audio and video still can flow. | |
1732 TEST_F(P2PTestConductor, IceRestart) { | |
1733 ASSERT_TRUE(CreateTestClients()); | |
1734 | |
1735 // Negotiate and wait for ice completion and make sure audio and video plays. | |
1736 LocalP2PTest(); | |
1737 | |
1738 // Create a SDP string of the first audio candidate for both clients. | |
1739 const webrtc::IceCandidateCollection* audio_candidates_initiator = | |
1740 initializing_client()->pc()->local_description()->candidates(0); | |
1741 const webrtc::IceCandidateCollection* audio_candidates_receiver = | |
1742 receiving_client()->pc()->local_description()->candidates(0); | |
1743 ASSERT_GT(audio_candidates_initiator->count(), 0u); | |
1744 ASSERT_GT(audio_candidates_receiver->count(), 0u); | |
1745 std::string initiator_candidate; | |
1746 EXPECT_TRUE( | |
1747 audio_candidates_initiator->at(0)->ToString(&initiator_candidate)); | |
1748 std::string receiver_candidate; | |
1749 EXPECT_TRUE(audio_candidates_receiver->at(0)->ToString(&receiver_candidate)); | |
1750 | |
1751 // Restart ice on the initializing client. | |
1752 receiving_client()->SetExpectIceRestart(true); | |
1753 initializing_client()->IceRestart(); | |
1754 | |
1755 // Negotiate and wait for ice completion again and make sure audio and video | |
1756 // plays. | |
1757 LocalP2PTest(); | |
1758 | |
1759 // Create a SDP string of the first audio candidate for both clients again. | |
1760 const webrtc::IceCandidateCollection* audio_candidates_initiator_restart = | |
1761 initializing_client()->pc()->local_description()->candidates(0); | |
1762 const webrtc::IceCandidateCollection* audio_candidates_reciever_restart = | |
1763 receiving_client()->pc()->local_description()->candidates(0); | |
1764 ASSERT_GT(audio_candidates_initiator_restart->count(), 0u); | |
1765 ASSERT_GT(audio_candidates_reciever_restart->count(), 0u); | |
1766 std::string initiator_candidate_restart; | |
1767 EXPECT_TRUE(audio_candidates_initiator_restart->at(0)->ToString( | |
1768 &initiator_candidate_restart)); | |
1769 std::string receiver_candidate_restart; | |
1770 EXPECT_TRUE(audio_candidates_reciever_restart->at(0)->ToString( | |
1771 &receiver_candidate_restart)); | |
1772 | |
1773 // Verify that the first candidates in the local session descriptions has | |
1774 // changed. | |
1775 EXPECT_NE(initiator_candidate, initiator_candidate_restart); | |
1776 EXPECT_NE(receiver_candidate, receiver_candidate_restart); | |
1777 } | |
1778 | |
1779 // This test sets up a call between two parties with audio, and video. | |
1780 // It then renegotiates setting the video m-line to "port 0", then later | |
1781 // renegotiates again, enabling video. | |
1782 TEST_F(P2PTestConductor, LocalP2PTestVideoDisableEnable) { | |
1783 ASSERT_TRUE(CreateTestClients()); | |
1784 | |
1785 // Do initial negotiation. Will result in video and audio sendonly m-lines. | |
1786 receiving_client()->set_auto_add_stream(false); | |
1787 initializing_client()->AddMediaStream(true, true); | |
1788 initializing_client()->Negotiate(); | |
1789 | |
1790 // Negotiate again, disabling the video m-line (receiving client will | |
1791 // set port to 0 due to mandatory "OfferToReceiveVideo: false" constraint). | |
1792 receiving_client()->SetReceiveVideo(false); | |
1793 initializing_client()->Negotiate(); | |
1794 | |
1795 // Enable video and do negotiation again, making sure video is received | |
1796 // end-to-end. | |
1797 receiving_client()->SetReceiveVideo(true); | |
1798 receiving_client()->AddMediaStream(true, true); | |
1799 LocalP2PTest(); | |
1800 } | |
1801 | |
1802 // This test sets up a Jsep call between two parties with external | |
1803 // VideoDecoderFactory. | |
1804 // TODO(holmer): Disabled due to sometimes crashing on buildbots. | |
1805 // See issue webrtc/2378. | |
1806 TEST_F(P2PTestConductor, DISABLED_LocalP2PTestWithVideoDecoderFactory) { | |
1807 ASSERT_TRUE(CreateTestClients()); | |
1808 EnableVideoDecoderFactory(); | |
1809 LocalP2PTest(); | |
1810 } | |
1811 | |
1812 // This tests that if we negotiate after calling CreateSender but before we | |
1813 // have a track, then set a track later, frames from the newly-set track are | |
1814 // received end-to-end. | |
1815 TEST_F(P2PTestConductor, EarlyWarmupTest) { | |
1816 ASSERT_TRUE(CreateTestClients()); | |
1817 auto audio_sender = | |
1818 initializing_client()->pc()->CreateSender("audio", "stream_id"); | |
1819 auto video_sender = | |
1820 initializing_client()->pc()->CreateSender("video", "stream_id"); | |
1821 initializing_client()->Negotiate(); | |
1822 // Wait for ICE connection to complete, without any tracks. | |
1823 // Note that the receiving client WILL (in HandleIncomingOffer) create | |
1824 // tracks, so it's only the initiator here that's doing early warmup. | |
1825 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs); | |
1826 VerifySessionDescriptions(); | |
1827 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted, | |
1828 initializing_client()->ice_connection_state(), | |
1829 kMaxWaitForFramesMs); | |
1830 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, | |
1831 receiving_client()->ice_connection_state(), | |
1832 kMaxWaitForFramesMs); | |
1833 // Now set the tracks, and expect frames to immediately start flowing. | |
1834 EXPECT_TRUE( | |
1835 audio_sender->SetTrack(initializing_client()->CreateLocalAudioTrack(""))); | |
1836 EXPECT_TRUE( | |
1837 video_sender->SetTrack(initializing_client()->CreateLocalVideoTrack(""))); | |
1838 EXPECT_TRUE_WAIT(FramesNotPending(kEndAudioFrameCount, kEndVideoFrameCount), | |
1839 kMaxWaitForFramesMs); | |
1840 } | |
1841 | |
1842 class IceServerParsingTest : public testing::Test { | |
1843 public: | |
1844 // Convenience for parsing a single URL. | |
1845 bool ParseUrl(const std::string& url) { | |
1846 return ParseUrl(url, std::string(), std::string()); | |
1847 } | |
1848 | |
1849 bool ParseUrl(const std::string& url, | |
1850 const std::string& username, | |
1851 const std::string& password) { | |
1852 PeerConnectionInterface::IceServers servers; | |
1853 PeerConnectionInterface::IceServer server; | |
1854 server.urls.push_back(url); | |
1855 server.username = username; | |
1856 server.password = password; | |
1857 servers.push_back(server); | |
1858 return webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_); | |
1859 } | |
1860 | |
1861 protected: | |
1862 cricket::ServerAddresses stun_servers_; | |
1863 std::vector<cricket::RelayServerConfig> turn_servers_; | |
1864 }; | |
1865 | |
1866 // Make sure all STUN/TURN prefixes are parsed correctly. | |
1867 TEST_F(IceServerParsingTest, ParseStunPrefixes) { | |
1868 EXPECT_TRUE(ParseUrl("stun:hostname")); | |
1869 EXPECT_EQ(1U, stun_servers_.size()); | |
1870 EXPECT_EQ(0U, turn_servers_.size()); | |
1871 stun_servers_.clear(); | |
1872 | |
1873 EXPECT_TRUE(ParseUrl("stuns:hostname")); | |
1874 EXPECT_EQ(1U, stun_servers_.size()); | |
1875 EXPECT_EQ(0U, turn_servers_.size()); | |
1876 stun_servers_.clear(); | |
1877 | |
1878 EXPECT_TRUE(ParseUrl("turn:hostname")); | |
1879 EXPECT_EQ(0U, stun_servers_.size()); | |
1880 EXPECT_EQ(1U, turn_servers_.size()); | |
1881 EXPECT_FALSE(turn_servers_[0].ports[0].secure); | |
1882 turn_servers_.clear(); | |
1883 | |
1884 EXPECT_TRUE(ParseUrl("turns:hostname")); | |
1885 EXPECT_EQ(0U, stun_servers_.size()); | |
1886 EXPECT_EQ(1U, turn_servers_.size()); | |
1887 EXPECT_TRUE(turn_servers_[0].ports[0].secure); | |
1888 turn_servers_.clear(); | |
1889 | |
1890 // invalid prefixes | |
1891 EXPECT_FALSE(ParseUrl("stunn:hostname")); | |
1892 EXPECT_FALSE(ParseUrl(":hostname")); | |
1893 EXPECT_FALSE(ParseUrl(":")); | |
1894 EXPECT_FALSE(ParseUrl("")); | |
1895 } | |
1896 | |
1897 TEST_F(IceServerParsingTest, VerifyDefaults) { | |
1898 // TURNS defaults | |
1899 EXPECT_TRUE(ParseUrl("turns:hostname")); | |
1900 EXPECT_EQ(1U, turn_servers_.size()); | |
1901 EXPECT_EQ(5349, turn_servers_[0].ports[0].address.port()); | |
1902 EXPECT_EQ(cricket::PROTO_TCP, turn_servers_[0].ports[0].proto); | |
1903 turn_servers_.clear(); | |
1904 | |
1905 // TURN defaults | |
1906 EXPECT_TRUE(ParseUrl("turn:hostname")); | |
1907 EXPECT_EQ(1U, turn_servers_.size()); | |
1908 EXPECT_EQ(3478, turn_servers_[0].ports[0].address.port()); | |
1909 EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto); | |
1910 turn_servers_.clear(); | |
1911 | |
1912 // STUN defaults | |
1913 EXPECT_TRUE(ParseUrl("stun:hostname")); | |
1914 EXPECT_EQ(1U, stun_servers_.size()); | |
1915 EXPECT_EQ(3478, stun_servers_.begin()->port()); | |
1916 stun_servers_.clear(); | |
1917 } | |
1918 | |
1919 // Check that the 6 combinations of IPv4/IPv6/hostname and with/without port | |
1920 // can be parsed correctly. | |
1921 TEST_F(IceServerParsingTest, ParseHostnameAndPort) { | |
1922 EXPECT_TRUE(ParseUrl("stun:1.2.3.4:1234")); | |
1923 EXPECT_EQ(1U, stun_servers_.size()); | |
1924 EXPECT_EQ("1.2.3.4", stun_servers_.begin()->hostname()); | |
1925 EXPECT_EQ(1234, stun_servers_.begin()->port()); | |
1926 stun_servers_.clear(); | |
1927 | |
1928 EXPECT_TRUE(ParseUrl("stun:[1:2:3:4:5:6:7:8]:4321")); | |
1929 EXPECT_EQ(1U, stun_servers_.size()); | |
1930 EXPECT_EQ("1:2:3:4:5:6:7:8", stun_servers_.begin()->hostname()); | |
1931 EXPECT_EQ(4321, stun_servers_.begin()->port()); | |
1932 stun_servers_.clear(); | |
1933 | |
1934 EXPECT_TRUE(ParseUrl("stun:hostname:9999")); | |
1935 EXPECT_EQ(1U, stun_servers_.size()); | |
1936 EXPECT_EQ("hostname", stun_servers_.begin()->hostname()); | |
1937 EXPECT_EQ(9999, stun_servers_.begin()->port()); | |
1938 stun_servers_.clear(); | |
1939 | |
1940 EXPECT_TRUE(ParseUrl("stun:1.2.3.4")); | |
1941 EXPECT_EQ(1U, stun_servers_.size()); | |
1942 EXPECT_EQ("1.2.3.4", stun_servers_.begin()->hostname()); | |
1943 EXPECT_EQ(3478, stun_servers_.begin()->port()); | |
1944 stun_servers_.clear(); | |
1945 | |
1946 EXPECT_TRUE(ParseUrl("stun:[1:2:3:4:5:6:7:8]")); | |
1947 EXPECT_EQ(1U, stun_servers_.size()); | |
1948 EXPECT_EQ("1:2:3:4:5:6:7:8", stun_servers_.begin()->hostname()); | |
1949 EXPECT_EQ(3478, stun_servers_.begin()->port()); | |
1950 stun_servers_.clear(); | |
1951 | |
1952 EXPECT_TRUE(ParseUrl("stun:hostname")); | |
1953 EXPECT_EQ(1U, stun_servers_.size()); | |
1954 EXPECT_EQ("hostname", stun_servers_.begin()->hostname()); | |
1955 EXPECT_EQ(3478, stun_servers_.begin()->port()); | |
1956 stun_servers_.clear(); | |
1957 | |
1958 // Try some invalid hostname:port strings. | |
1959 EXPECT_FALSE(ParseUrl("stun:hostname:99a99")); | |
1960 EXPECT_FALSE(ParseUrl("stun:hostname:-1")); | |
1961 EXPECT_FALSE(ParseUrl("stun:hostname:port:more")); | |
1962 EXPECT_FALSE(ParseUrl("stun:hostname:port more")); | |
1963 EXPECT_FALSE(ParseUrl("stun:hostname:")); | |
1964 EXPECT_FALSE(ParseUrl("stun:[1:2:3:4:5:6:7:8]junk:1000")); | |
1965 EXPECT_FALSE(ParseUrl("stun::5555")); | |
1966 EXPECT_FALSE(ParseUrl("stun:")); | |
1967 } | |
1968 | |
1969 // Test parsing the "?transport=xxx" part of the URL. | |
1970 TEST_F(IceServerParsingTest, ParseTransport) { | |
1971 EXPECT_TRUE(ParseUrl("turn:hostname:1234?transport=tcp")); | |
1972 EXPECT_EQ(1U, turn_servers_.size()); | |
1973 EXPECT_EQ(cricket::PROTO_TCP, turn_servers_[0].ports[0].proto); | |
1974 turn_servers_.clear(); | |
1975 | |
1976 EXPECT_TRUE(ParseUrl("turn:hostname?transport=udp")); | |
1977 EXPECT_EQ(1U, turn_servers_.size()); | |
1978 EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto); | |
1979 turn_servers_.clear(); | |
1980 | |
1981 EXPECT_FALSE(ParseUrl("turn:hostname?transport=invalid")); | |
1982 } | |
1983 | |
1984 // Test parsing ICE username contained in URL. | |
1985 TEST_F(IceServerParsingTest, ParseUsername) { | |
1986 EXPECT_TRUE(ParseUrl("turn:user@hostname")); | |
1987 EXPECT_EQ(1U, turn_servers_.size()); | |
1988 EXPECT_EQ("user", turn_servers_[0].credentials.username); | |
1989 turn_servers_.clear(); | |
1990 | |
1991 EXPECT_FALSE(ParseUrl("turn:@hostname")); | |
1992 EXPECT_FALSE(ParseUrl("turn:username@")); | |
1993 EXPECT_FALSE(ParseUrl("turn:@")); | |
1994 EXPECT_FALSE(ParseUrl("turn:user@name@hostname")); | |
1995 } | |
1996 | |
1997 // Test that username and password from IceServer is copied into the resulting | |
1998 // RelayServerConfig. | |
1999 TEST_F(IceServerParsingTest, CopyUsernameAndPasswordFromIceServer) { | |
2000 EXPECT_TRUE(ParseUrl("turn:hostname", "username", "password")); | |
2001 EXPECT_EQ(1U, turn_servers_.size()); | |
2002 EXPECT_EQ("username", turn_servers_[0].credentials.username); | |
2003 EXPECT_EQ("password", turn_servers_[0].credentials.password); | |
2004 } | |
2005 | |
2006 // Ensure that if a server has multiple URLs, each one is parsed. | |
2007 TEST_F(IceServerParsingTest, ParseMultipleUrls) { | |
2008 PeerConnectionInterface::IceServers servers; | |
2009 PeerConnectionInterface::IceServer server; | |
2010 server.urls.push_back("stun:hostname"); | |
2011 server.urls.push_back("turn:hostname"); | |
2012 servers.push_back(server); | |
2013 EXPECT_TRUE(webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_)); | |
2014 EXPECT_EQ(1U, stun_servers_.size()); | |
2015 EXPECT_EQ(1U, turn_servers_.size()); | |
2016 } | |
2017 | |
2018 // Ensure that TURN servers are given unique priorities, | |
2019 // so that their resulting candidates have unique priorities. | |
2020 TEST_F(IceServerParsingTest, TurnServerPrioritiesUnique) { | |
2021 PeerConnectionInterface::IceServers servers; | |
2022 PeerConnectionInterface::IceServer server; | |
2023 server.urls.push_back("turn:hostname"); | |
2024 server.urls.push_back("turn:hostname2"); | |
2025 servers.push_back(server); | |
2026 EXPECT_TRUE(webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_)); | |
2027 EXPECT_EQ(2U, turn_servers_.size()); | |
2028 EXPECT_NE(turn_servers_[0].priority, turn_servers_[1].priority); | |
2029 } | |
2030 | |
2031 #endif // if !defined(THREAD_SANITIZER) | |
OLD | NEW |