blob: fe712e8d04d898a3101450f1db8e74f9b2ea38a8 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2012 Google Inc.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004 *
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 <vector>
34
35#include "talk/app/webrtc/dtmfsender.h"
36#include "talk/app/webrtc/fakeportallocatorfactory.h"
37#include "talk/app/webrtc/localaudiosource.h"
38#include "talk/app/webrtc/mediastreaminterface.h"
39#include "talk/app/webrtc/peerconnectionfactory.h"
40#include "talk/app/webrtc/peerconnectioninterface.h"
41#include "talk/app/webrtc/test/fakeaudiocapturemodule.h"
42#include "talk/app/webrtc/test/fakeconstraints.h"
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +000043#include "talk/app/webrtc/test/fakedtlsidentityservice.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044#include "talk/app/webrtc/test/fakeperiodicvideocapturer.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000045#include "talk/app/webrtc/test/fakevideotrackrenderer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046#include "talk/app/webrtc/test/mockpeerconnectionobservers.h"
47#include "talk/app/webrtc/videosourceinterface.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000048#include "talk/media/webrtc/fakewebrtcvideoengine.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000049#include "talk/session/media/mediasession.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000050#include "webrtc/base/gunit.h"
pbos@webrtc.org9eacb8c2015-01-02 09:03:19 +000051#include "webrtc/base/physicalsocketserver.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000052#include "webrtc/base/scoped_ptr.h"
53#include "webrtc/base/ssladapter.h"
54#include "webrtc/base/sslstreamadapter.h"
55#include "webrtc/base/thread.h"
pbos@webrtc.org9eacb8c2015-01-02 09:03:19 +000056#include "webrtc/base/virtualsocketserver.h"
57#include "webrtc/p2p/base/constants.h"
58#include "webrtc/p2p/base/sessiondescription.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059
60#define MAYBE_SKIP_TEST(feature) \
61 if (!(feature())) { \
62 LOG(LS_INFO) << "Feature disabled... skipping"; \
63 return; \
64 }
65
66using cricket::ContentInfo;
67using cricket::FakeWebRtcVideoDecoder;
68using cricket::FakeWebRtcVideoDecoderFactory;
69using cricket::FakeWebRtcVideoEncoder;
70using cricket::FakeWebRtcVideoEncoderFactory;
71using cricket::MediaContentDescription;
72using webrtc::DataBuffer;
73using webrtc::DataChannelInterface;
74using webrtc::DtmfSender;
75using webrtc::DtmfSenderInterface;
76using webrtc::DtmfSenderObserverInterface;
77using webrtc::FakeConstraints;
78using webrtc::MediaConstraintsInterface;
79using webrtc::MediaStreamTrackInterface;
80using webrtc::MockCreateSessionDescriptionObserver;
81using webrtc::MockDataChannelObserver;
82using webrtc::MockSetSessionDescriptionObserver;
83using webrtc::MockStatsObserver;
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +000084using webrtc::PeerConnectionInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085using webrtc::SessionDescriptionInterface;
86using webrtc::StreamCollectionInterface;
87
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000088static const int kMaxWaitMs = 10000;
pbos@webrtc.org044bdac2014-06-03 09:40:01 +000089// Disable for TSan v2, see
90// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
91// This declaration is also #ifdef'd as it causes uninitialized-variable
92// warnings.
93#if !defined(THREAD_SANITIZER)
henrike@webrtc.org28e20752013-07-10 00:45:36 +000094static const int kMaxWaitForStatsMs = 3000;
pbos@webrtc.org044bdac2014-06-03 09:40:01 +000095#endif
buildbot@webrtc.org3e01e0b2014-05-13 17:54:10 +000096static const int kMaxWaitForFramesMs = 10000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000097static const int kEndAudioFrameCount = 3;
98static const int kEndVideoFrameCount = 3;
99
100static const char kStreamLabelBase[] = "stream_label";
101static const char kVideoTrackLabelBase[] = "video_track";
102static const char kAudioTrackLabelBase[] = "audio_track";
103static const char kDataChannelLabel[] = "data_channel";
104
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000105// Disable for TSan v2, see
106// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
107// This declaration is also #ifdef'd as it causes unused-variable errors.
108#if !defined(THREAD_SANITIZER)
109// SRTP cipher name negotiated by the tests. This must be updated if the
110// default changes.
111static const char kDefaultSrtpCipher[] = "AES_CM_128_HMAC_SHA1_32";
112#endif
113
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114static void RemoveLinesFromSdp(const std::string& line_start,
115 std::string* sdp) {
116 const char kSdpLineEnd[] = "\r\n";
117 size_t ssrc_pos = 0;
118 while ((ssrc_pos = sdp->find(line_start, ssrc_pos)) !=
119 std::string::npos) {
120 size_t end_ssrc = sdp->find(kSdpLineEnd, ssrc_pos);
121 sdp->erase(ssrc_pos, end_ssrc - ssrc_pos + strlen(kSdpLineEnd));
122 }
123}
124
125class SignalingMessageReceiver {
126 public:
127 protected:
128 SignalingMessageReceiver() {}
129 virtual ~SignalingMessageReceiver() {}
130};
131
132class JsepMessageReceiver : public 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 JsepMessageReceiver() {}
142 virtual ~JsepMessageReceiver() {}
143};
144
145template <typename MessageReceiver>
146class PeerConnectionTestClientBase
147 : public webrtc::PeerConnectionObserver,
148 public MessageReceiver {
149 public:
150 ~PeerConnectionTestClientBase() {
151 while (!fake_video_renderers_.empty()) {
152 RenderMap::iterator it = fake_video_renderers_.begin();
153 delete it->second;
154 fake_video_renderers_.erase(it);
155 }
156 }
157
158 virtual void Negotiate() = 0;
159
160 virtual void Negotiate(bool audio, bool video) = 0;
161
162 virtual void SetVideoConstraints(
163 const webrtc::FakeConstraints& video_constraint) {
164 video_constraints_ = video_constraint;
165 }
166
167 void AddMediaStream(bool audio, bool video) {
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000168 std::string stream_label = kStreamLabelBase +
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000169 rtc::ToString<int>(
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000170 static_cast<int>(peer_connection_->local_streams()->count()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000171 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream =
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000172 peer_connection_factory_->CreateLocalMediaStream(stream_label);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173
174 if (audio && can_receive_audio()) {
175 FakeConstraints constraints;
176 // Disable highpass filter so that we can get all the test audio frames.
177 constraints.AddMandatory(
178 MediaConstraintsInterface::kHighpassFilter, false);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000179 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
wu@webrtc.org97077a32013-10-25 21:18:33 +0000180 peer_connection_factory_->CreateAudioSource(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181 // TODO(perkj): Test audio source when it is implemented. Currently audio
182 // always use the default input.
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000183 std::string label = stream_label + kAudioTrackLabelBase;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000184 rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000185 peer_connection_factory_->CreateAudioTrack(label, source));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000186 stream->AddTrack(audio_track);
187 }
188 if (video && can_receive_video()) {
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000189 stream->AddTrack(CreateLocalVideoTrack(stream_label));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 }
191
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000192 EXPECT_TRUE(peer_connection_->AddStream(stream));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193 }
194
195 size_t NumberOfLocalMediaStreams() {
196 return peer_connection_->local_streams()->count();
197 }
198
199 bool SessionActive() {
200 return peer_connection_->signaling_state() ==
201 webrtc::PeerConnectionInterface::kStable;
202 }
203
204 void set_signaling_message_receiver(
205 MessageReceiver* signaling_message_receiver) {
206 signaling_message_receiver_ = signaling_message_receiver;
207 }
208
209 void EnableVideoDecoderFactory() {
210 video_decoder_factory_enabled_ = true;
211 fake_video_decoder_factory_->AddSupportedVideoCodecType(
212 webrtc::kVideoCodecVP8);
213 }
214
215 bool AudioFramesReceivedCheck(int number_of_frames) const {
216 return number_of_frames <= fake_audio_capture_module_->frames_received();
217 }
218
219 bool VideoFramesReceivedCheck(int number_of_frames) {
220 if (video_decoder_factory_enabled_) {
221 const std::vector<FakeWebRtcVideoDecoder*>& decoders
222 = fake_video_decoder_factory_->decoders();
223 if (decoders.empty()) {
224 return number_of_frames <= 0;
225 }
226
227 for (std::vector<FakeWebRtcVideoDecoder*>::const_iterator
228 it = decoders.begin(); it != decoders.end(); ++it) {
229 if (number_of_frames > (*it)->GetNumFramesReceived()) {
230 return false;
231 }
232 }
233 return true;
234 } else {
235 if (fake_video_renderers_.empty()) {
236 return number_of_frames <= 0;
237 }
238
239 for (RenderMap::const_iterator it = fake_video_renderers_.begin();
240 it != fake_video_renderers_.end(); ++it) {
241 if (number_of_frames > it->second->num_rendered_frames()) {
242 return false;
243 }
244 }
245 return true;
246 }
247 }
248 // Verify the CreateDtmfSender interface
249 void VerifyDtmf() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000250 rtc::scoped_ptr<DummyDtmfObserver> observer(new DummyDtmfObserver());
251 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252
253 // We can't create a DTMF sender with an invalid audio track or a non local
254 // track.
255 EXPECT_TRUE(peer_connection_->CreateDtmfSender(NULL) == NULL);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000256 rtc::scoped_refptr<webrtc::AudioTrackInterface> non_localtrack(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 peer_connection_factory_->CreateAudioTrack("dummy_track",
258 NULL));
259 EXPECT_TRUE(peer_connection_->CreateDtmfSender(non_localtrack) == NULL);
260
261 // We should be able to create a DTMF sender from a local track.
262 webrtc::AudioTrackInterface* localtrack =
263 peer_connection_->local_streams()->at(0)->GetAudioTracks()[0];
264 dtmf_sender = peer_connection_->CreateDtmfSender(localtrack);
265 EXPECT_TRUE(dtmf_sender.get() != NULL);
266 dtmf_sender->RegisterObserver(observer.get());
267
268 // Test the DtmfSender object just created.
269 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
270 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
271
272 // We don't need to verify that the DTMF tones are actually sent out because
273 // that is already covered by the tests of the lower level components.
274
275 EXPECT_TRUE_WAIT(observer->completed(), kMaxWaitMs);
276 std::vector<std::string> tones;
277 tones.push_back("1");
278 tones.push_back("a");
279 tones.push_back("");
280 observer->Verify(tones);
281
282 dtmf_sender->UnregisterObserver();
283 }
284
285 // Verifies that the SessionDescription have rejected the appropriate media
286 // content.
287 void VerifyRejectedMediaInSessionDescription() {
288 ASSERT_TRUE(peer_connection_->remote_description() != NULL);
289 ASSERT_TRUE(peer_connection_->local_description() != NULL);
290 const cricket::SessionDescription* remote_desc =
291 peer_connection_->remote_description()->description();
292 const cricket::SessionDescription* local_desc =
293 peer_connection_->local_description()->description();
294
295 const ContentInfo* remote_audio_content = GetFirstAudioContent(remote_desc);
296 if (remote_audio_content) {
297 const ContentInfo* audio_content =
298 GetFirstAudioContent(local_desc);
299 EXPECT_EQ(can_receive_audio(), !audio_content->rejected);
300 }
301
302 const ContentInfo* remote_video_content = GetFirstVideoContent(remote_desc);
303 if (remote_video_content) {
304 const ContentInfo* video_content =
305 GetFirstVideoContent(local_desc);
306 EXPECT_EQ(can_receive_video(), !video_content->rejected);
307 }
308 }
309
310 void SetExpectIceRestart(bool expect_restart) {
311 expect_ice_restart_ = expect_restart;
312 }
313
314 bool ExpectIceRestart() const { return expect_ice_restart_; }
315
316 void VerifyLocalIceUfragAndPassword() {
317 ASSERT_TRUE(peer_connection_->local_description() != NULL);
318 const cricket::SessionDescription* desc =
319 peer_connection_->local_description()->description();
320 const cricket::ContentInfos& contents = desc->contents();
321
322 for (size_t index = 0; index < contents.size(); ++index) {
323 if (contents[index].rejected)
324 continue;
325 const cricket::TransportDescription* transport_desc =
326 desc->GetTransportDescriptionByName(contents[index].name);
327
328 std::map<int, IceUfragPwdPair>::const_iterator ufragpair_it =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000329 ice_ufrag_pwd_.find(static_cast<int>(index));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 if (ufragpair_it == ice_ufrag_pwd_.end()) {
331 ASSERT_FALSE(ExpectIceRestart());
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000332 ice_ufrag_pwd_[static_cast<int>(index)] =
333 IceUfragPwdPair(transport_desc->ice_ufrag, transport_desc->ice_pwd);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000334 } else if (ExpectIceRestart()) {
335 const IceUfragPwdPair& ufrag_pwd = ufragpair_it->second;
336 EXPECT_NE(ufrag_pwd.first, transport_desc->ice_ufrag);
337 EXPECT_NE(ufrag_pwd.second, transport_desc->ice_pwd);
338 } else {
339 const IceUfragPwdPair& ufrag_pwd = ufragpair_it->second;
340 EXPECT_EQ(ufrag_pwd.first, transport_desc->ice_ufrag);
341 EXPECT_EQ(ufrag_pwd.second, transport_desc->ice_pwd);
342 }
343 }
344 }
345
346 int GetAudioOutputLevelStats(webrtc::MediaStreamTrackInterface* track) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000347 rtc::scoped_refptr<MockStatsObserver>
348 observer(new rtc::RefCountedObject<MockStatsObserver>());
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +0000349 EXPECT_TRUE(peer_connection_->GetStats(
350 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs);
352 return observer->AudioOutputLevel();
353 }
354
355 int GetAudioInputLevelStats() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000356 rtc::scoped_refptr<MockStatsObserver>
357 observer(new rtc::RefCountedObject<MockStatsObserver>());
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +0000358 EXPECT_TRUE(peer_connection_->GetStats(
359 observer, NULL, PeerConnectionInterface::kStatsOutputLevelStandard));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000360 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs);
361 return observer->AudioInputLevel();
362 }
363
364 int GetBytesReceivedStats(webrtc::MediaStreamTrackInterface* track) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000365 rtc::scoped_refptr<MockStatsObserver>
366 observer(new rtc::RefCountedObject<MockStatsObserver>());
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +0000367 EXPECT_TRUE(peer_connection_->GetStats(
368 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs);
370 return observer->BytesReceived();
371 }
372
373 int GetBytesSentStats(webrtc::MediaStreamTrackInterface* track) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000374 rtc::scoped_refptr<MockStatsObserver>
375 observer(new rtc::RefCountedObject<MockStatsObserver>());
jiayl@webrtc.orgdb41b4d2014-03-03 21:30:06 +0000376 EXPECT_TRUE(peer_connection_->GetStats(
377 observer, track, PeerConnectionInterface::kStatsOutputLevelStandard));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs);
379 return observer->BytesSent();
380 }
381
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000382 int GetAvailableReceivedBandwidthStats() {
383 rtc::scoped_refptr<MockStatsObserver>
384 observer(new rtc::RefCountedObject<MockStatsObserver>());
385 EXPECT_TRUE(peer_connection_->GetStats(
386 observer, NULL, PeerConnectionInterface::kStatsOutputLevelStandard));
387 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs);
388 int bw = observer->AvailableReceiveBandwidth();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000389 return bw;
390 }
391
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +0000392 std::string GetDtlsCipherStats() {
393 rtc::scoped_refptr<MockStatsObserver>
394 observer(new rtc::RefCountedObject<MockStatsObserver>());
395 EXPECT_TRUE(peer_connection_->GetStats(
396 observer, NULL, PeerConnectionInterface::kStatsOutputLevelStandard));
397 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs);
398 return observer->DtlsCipher();
399 }
400
401 std::string GetSrtpCipherStats() {
402 rtc::scoped_refptr<MockStatsObserver>
403 observer(new rtc::RefCountedObject<MockStatsObserver>());
404 EXPECT_TRUE(peer_connection_->GetStats(
405 observer, NULL, PeerConnectionInterface::kStatsOutputLevelStandard));
406 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs);
407 return observer->SrtpCipher();
408 }
409
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000410 int rendered_width() {
411 EXPECT_FALSE(fake_video_renderers_.empty());
412 return fake_video_renderers_.empty() ? 1 :
413 fake_video_renderers_.begin()->second->width();
414 }
415
416 int rendered_height() {
417 EXPECT_FALSE(fake_video_renderers_.empty());
418 return fake_video_renderers_.empty() ? 1 :
419 fake_video_renderers_.begin()->second->height();
420 }
421
422 size_t number_of_remote_streams() {
423 if (!pc())
424 return 0;
425 return pc()->remote_streams()->count();
426 }
427
428 StreamCollectionInterface* remote_streams() {
429 if (!pc()) {
430 ADD_FAILURE();
431 return NULL;
432 }
433 return pc()->remote_streams();
434 }
435
436 StreamCollectionInterface* local_streams() {
437 if (!pc()) {
438 ADD_FAILURE();
439 return NULL;
440 }
441 return pc()->local_streams();
442 }
443
444 webrtc::PeerConnectionInterface::SignalingState signaling_state() {
445 return pc()->signaling_state();
446 }
447
448 webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state() {
449 return pc()->ice_connection_state();
450 }
451
452 webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state() {
453 return pc()->ice_gathering_state();
454 }
455
456 // PeerConnectionObserver callbacks.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000457 virtual void OnMessage(const std::string&) {}
458 virtual void OnSignalingMessage(const std::string& /*msg*/) {}
459 virtual void OnSignalingChange(
460 webrtc::PeerConnectionInterface::SignalingState new_state) {
461 EXPECT_EQ(peer_connection_->signaling_state(), new_state);
462 }
463 virtual void OnAddStream(webrtc::MediaStreamInterface* media_stream) {
464 for (size_t i = 0; i < media_stream->GetVideoTracks().size(); ++i) {
465 const std::string id = media_stream->GetVideoTracks()[i]->id();
466 ASSERT_TRUE(fake_video_renderers_.find(id) ==
467 fake_video_renderers_.end());
468 fake_video_renderers_[id] = new webrtc::FakeVideoTrackRenderer(
469 media_stream->GetVideoTracks()[i]);
470 }
471 }
472 virtual void OnRemoveStream(webrtc::MediaStreamInterface* media_stream) {}
473 virtual void OnRenegotiationNeeded() {}
474 virtual void OnIceConnectionChange(
475 webrtc::PeerConnectionInterface::IceConnectionState new_state) {
476 EXPECT_EQ(peer_connection_->ice_connection_state(), new_state);
477 }
478 virtual void OnIceGatheringChange(
479 webrtc::PeerConnectionInterface::IceGatheringState new_state) {
480 EXPECT_EQ(peer_connection_->ice_gathering_state(), new_state);
481 }
482 virtual void OnIceCandidate(
483 const webrtc::IceCandidateInterface* /*candidate*/) {}
484
485 webrtc::PeerConnectionInterface* pc() {
486 return peer_connection_.get();
487 }
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000488 void StopVideoCapturers() {
489 for (std::vector<cricket::VideoCapturer*>::iterator it =
490 video_capturers_.begin(); it != video_capturers_.end(); ++it) {
491 (*it)->Stop();
492 }
493 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000494
495 protected:
496 explicit PeerConnectionTestClientBase(const std::string& id)
497 : id_(id),
498 expect_ice_restart_(false),
499 fake_video_decoder_factory_(NULL),
500 fake_video_encoder_factory_(NULL),
501 video_decoder_factory_enabled_(false),
502 signaling_message_receiver_(NULL) {
503 }
504 bool Init(const MediaConstraintsInterface* constraints) {
505 EXPECT_TRUE(!peer_connection_);
506 EXPECT_TRUE(!peer_connection_factory_);
507 allocator_factory_ = webrtc::FakePortAllocatorFactory::Create();
508 if (!allocator_factory_) {
509 return false;
510 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000511 fake_audio_capture_module_ = FakeAudioCaptureModule::Create(
jiayl@webrtc.org3987b6d2014-09-24 17:14:05 +0000512 rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000513
514 if (fake_audio_capture_module_ == NULL) {
515 return false;
516 }
517 fake_video_decoder_factory_ = new FakeWebRtcVideoDecoderFactory();
518 fake_video_encoder_factory_ = new FakeWebRtcVideoEncoderFactory();
519 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000520 rtc::Thread::Current(), rtc::Thread::Current(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000521 fake_audio_capture_module_, fake_video_encoder_factory_,
522 fake_video_decoder_factory_);
523 if (!peer_connection_factory_) {
524 return false;
525 }
526 peer_connection_ = CreatePeerConnection(allocator_factory_.get(),
527 constraints);
528 return peer_connection_.get() != NULL;
529 }
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000530 virtual rtc::scoped_refptr<webrtc::PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000531 CreatePeerConnection(webrtc::PortAllocatorFactoryInterface* factory,
532 const MediaConstraintsInterface* constraints) = 0;
533 MessageReceiver* signaling_message_receiver() {
534 return signaling_message_receiver_;
535 }
536 webrtc::PeerConnectionFactoryInterface* peer_connection_factory() {
537 return peer_connection_factory_.get();
538 }
539
540 virtual bool can_receive_audio() = 0;
541 virtual bool can_receive_video() = 0;
542 const std::string& id() const { return id_; }
543
544 private:
545 class DummyDtmfObserver : public DtmfSenderObserverInterface {
546 public:
547 DummyDtmfObserver() : completed_(false) {}
548
549 // Implements DtmfSenderObserverInterface.
550 void OnToneChange(const std::string& tone) {
551 tones_.push_back(tone);
552 if (tone.empty()) {
553 completed_ = true;
554 }
555 }
556
557 void Verify(const std::vector<std::string>& tones) const {
558 ASSERT_TRUE(tones_.size() == tones.size());
559 EXPECT_TRUE(std::equal(tones.begin(), tones.end(), tones_.begin()));
560 }
561
562 bool completed() const { return completed_; }
563
564 private:
565 bool completed_;
566 std::vector<std::string> tones_;
567 };
568
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000569 rtc::scoped_refptr<webrtc::VideoTrackInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000570 CreateLocalVideoTrack(const std::string stream_label) {
571 // Set max frame rate to 10fps to reduce the risk of the tests to be flaky.
572 FakeConstraints source_constraints = video_constraints_;
573 source_constraints.SetMandatoryMaxFrameRate(10);
574
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000575 cricket::FakeVideoCapturer* fake_capturer =
576 new webrtc::FakePeriodicVideoCapturer();
577 video_capturers_.push_back(fake_capturer);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000578 rtc::scoped_refptr<webrtc::VideoSourceInterface> source =
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579 peer_connection_factory_->CreateVideoSource(
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000580 fake_capturer, &source_constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000581 std::string label = stream_label + kVideoTrackLabelBase;
582 return peer_connection_factory_->CreateVideoTrack(label, source);
583 }
584
585 std::string id_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000586
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000587 rtc::scoped_refptr<webrtc::PortAllocatorFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000588 allocator_factory_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000589 rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
590 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000591 peer_connection_factory_;
592
593 typedef std::pair<std::string, std::string> IceUfragPwdPair;
594 std::map<int, IceUfragPwdPair> ice_ufrag_pwd_;
595 bool expect_ice_restart_;
596
597 // Needed to keep track of number of frames send.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000598 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599 // Needed to keep track of number of frames received.
600 typedef std::map<std::string, webrtc::FakeVideoTrackRenderer*> RenderMap;
601 RenderMap fake_video_renderers_;
602 // Needed to keep track of number of frames received when external decoder
603 // used.
604 FakeWebRtcVideoDecoderFactory* fake_video_decoder_factory_;
605 FakeWebRtcVideoEncoderFactory* fake_video_encoder_factory_;
606 bool video_decoder_factory_enabled_;
607 webrtc::FakeConstraints video_constraints_;
608
609 // For remote peer communication.
610 MessageReceiver* signaling_message_receiver_;
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +0000611
612 // Store references to the video capturers we've created, so that we can stop
613 // them, if required.
614 std::vector<cricket::VideoCapturer*> video_capturers_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000615};
616
617class JsepTestClient
618 : public PeerConnectionTestClientBase<JsepMessageReceiver> {
619 public:
620 static JsepTestClient* CreateClient(
621 const std::string& id,
622 const MediaConstraintsInterface* constraints) {
623 JsepTestClient* client(new JsepTestClient(id));
624 if (!client->Init(constraints)) {
625 delete client;
626 return NULL;
627 }
628 return client;
629 }
630 ~JsepTestClient() {}
631
632 virtual void Negotiate() {
633 Negotiate(true, true);
634 }
635 virtual void Negotiate(bool audio, bool video) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000636 rtc::scoped_ptr<SessionDescriptionInterface> offer;
pbos@webrtc.orgceb956b2014-09-04 15:27:49 +0000637 ASSERT_TRUE(DoCreateOffer(offer.use()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000638
639 if (offer->description()->GetContentByName("audio")) {
640 offer->description()->GetContentByName("audio")->rejected = !audio;
641 }
642 if (offer->description()->GetContentByName("video")) {
643 offer->description()->GetContentByName("video")->rejected = !video;
644 }
645
646 std::string sdp;
647 EXPECT_TRUE(offer->ToString(&sdp));
648 EXPECT_TRUE(DoSetLocalDescription(offer.release()));
649 signaling_message_receiver()->ReceiveSdpMessage(
650 webrtc::SessionDescriptionInterface::kOffer, sdp);
651 }
652 // JsepMessageReceiver callback.
653 virtual void ReceiveSdpMessage(const std::string& type,
654 std::string& msg) {
655 FilterIncomingSdpMessage(&msg);
656 if (type == webrtc::SessionDescriptionInterface::kOffer) {
657 HandleIncomingOffer(msg);
658 } else {
659 HandleIncomingAnswer(msg);
660 }
661 }
662 // JsepMessageReceiver callback.
663 virtual void ReceiveIceMessage(const std::string& sdp_mid,
664 int sdp_mline_index,
665 const std::string& msg) {
666 LOG(INFO) << id() << "ReceiveIceMessage";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000667 rtc::scoped_ptr<webrtc::IceCandidateInterface> candidate(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000668 webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, msg, NULL));
669 EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
670 }
671 // Implements PeerConnectionObserver functions needed by Jsep.
672 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
673 LOG(INFO) << id() << "OnIceCandidate";
674
675 std::string ice_sdp;
676 EXPECT_TRUE(candidate->ToString(&ice_sdp));
677 if (signaling_message_receiver() == NULL) {
678 // Remote party may be deleted.
679 return;
680 }
681 signaling_message_receiver()->ReceiveIceMessage(candidate->sdp_mid(),
682 candidate->sdp_mline_index(), ice_sdp);
683 }
684
685 void IceRestart() {
686 session_description_constraints_.SetMandatoryIceRestart(true);
687 SetExpectIceRestart(true);
688 }
689
690 void SetReceiveAudioVideo(bool audio, bool video) {
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000691 SetReceiveAudio(audio);
692 SetReceiveVideo(video);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000693 ASSERT_EQ(audio, can_receive_audio());
694 ASSERT_EQ(video, can_receive_video());
695 }
696
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000697 void SetReceiveAudio(bool audio) {
698 if (audio && can_receive_audio())
699 return;
700 session_description_constraints_.SetMandatoryReceiveAudio(audio);
701 }
702
703 void SetReceiveVideo(bool video) {
704 if (video && can_receive_video())
705 return;
706 session_description_constraints_.SetMandatoryReceiveVideo(video);
707 }
708
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000709 void RemoveMsidFromReceivedSdp(bool remove) {
710 remove_msid_ = remove;
711 }
712
713 void RemoveSdesCryptoFromReceivedSdp(bool remove) {
714 remove_sdes_ = remove;
715 }
716
717 void RemoveBundleFromReceivedSdp(bool remove) {
718 remove_bundle_ = remove;
719 }
720
721 virtual bool can_receive_audio() {
722 bool value;
723 if (webrtc::FindConstraint(&session_description_constraints_,
724 MediaConstraintsInterface::kOfferToReceiveAudio, &value, NULL)) {
725 return value;
726 }
727 return true;
728 }
729
730 virtual bool can_receive_video() {
731 bool value;
732 if (webrtc::FindConstraint(&session_description_constraints_,
733 MediaConstraintsInterface::kOfferToReceiveVideo, &value, NULL)) {
734 return value;
735 }
736 return true;
737 }
738
739 virtual void OnIceComplete() {
740 LOG(INFO) << id() << "OnIceComplete";
741 }
742
743 virtual void OnDataChannel(DataChannelInterface* data_channel) {
744 LOG(INFO) << id() << "OnDataChannel";
745 data_channel_ = data_channel;
746 data_observer_.reset(new MockDataChannelObserver(data_channel));
747 }
748
749 void CreateDataChannel() {
750 data_channel_ = pc()->CreateDataChannel(kDataChannelLabel,
751 NULL);
752 ASSERT_TRUE(data_channel_.get() != NULL);
753 data_observer_.reset(new MockDataChannelObserver(data_channel_));
754 }
755
756 DataChannelInterface* data_channel() { return data_channel_; }
757 const MockDataChannelObserver* data_observer() const {
758 return data_observer_.get();
759 }
760
761 protected:
762 explicit JsepTestClient(const std::string& id)
763 : PeerConnectionTestClientBase<JsepMessageReceiver>(id),
764 remove_msid_(false),
765 remove_bundle_(false),
766 remove_sdes_(false) {
767 }
768
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000769 virtual rtc::scoped_refptr<webrtc::PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770 CreatePeerConnection(webrtc::PortAllocatorFactoryInterface* factory,
771 const MediaConstraintsInterface* constraints) {
772 // CreatePeerConnection with IceServers.
773 webrtc::PeerConnectionInterface::IceServers ice_servers;
774 webrtc::PeerConnectionInterface::IceServer ice_server;
775 ice_server.uri = "stun:stun.l.google.com:19302";
776 ice_servers.push_back(ice_server);
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000777
buildbot@webrtc.org61c1b8e2014-04-09 06:06:38 +0000778 FakeIdentityService* dtls_service =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000779 rtc::SSLStreamAdapter::HaveDtlsSrtp() ?
buildbot@webrtc.org61c1b8e2014-04-09 06:06:38 +0000780 new FakeIdentityService() : NULL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781 return peer_connection_factory()->CreatePeerConnection(
jiayl@webrtc.orga576faf2014-01-29 17:45:53 +0000782 ice_servers, constraints, factory, dtls_service, this);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783 }
784
785 void HandleIncomingOffer(const std::string& msg) {
786 LOG(INFO) << id() << "HandleIncomingOffer ";
787 if (NumberOfLocalMediaStreams() == 0) {
788 // If we are not sending any streams ourselves it is time to add some.
789 AddMediaStream(true, true);
790 }
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000791 rtc::scoped_ptr<SessionDescriptionInterface> desc(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000792 webrtc::CreateSessionDescription("offer", msg, NULL));
793 EXPECT_TRUE(DoSetRemoteDescription(desc.release()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000794 rtc::scoped_ptr<SessionDescriptionInterface> answer;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795 EXPECT_TRUE(DoCreateAnswer(answer.use()));
796 std::string sdp;
797 EXPECT_TRUE(answer->ToString(&sdp));
798 EXPECT_TRUE(DoSetLocalDescription(answer.release()));
799 if (signaling_message_receiver()) {
800 signaling_message_receiver()->ReceiveSdpMessage(
801 webrtc::SessionDescriptionInterface::kAnswer, sdp);
802 }
803 }
804
805 void HandleIncomingAnswer(const std::string& msg) {
806 LOG(INFO) << id() << "HandleIncomingAnswer";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000807 rtc::scoped_ptr<SessionDescriptionInterface> desc(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808 webrtc::CreateSessionDescription("answer", msg, NULL));
809 EXPECT_TRUE(DoSetRemoteDescription(desc.release()));
810 }
811
812 bool DoCreateOfferAnswer(SessionDescriptionInterface** desc,
813 bool offer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000814 rtc::scoped_refptr<MockCreateSessionDescriptionObserver>
815 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816 MockCreateSessionDescriptionObserver>());
817 if (offer) {
818 pc()->CreateOffer(observer, &session_description_constraints_);
819 } else {
820 pc()->CreateAnswer(observer, &session_description_constraints_);
821 }
822 EXPECT_EQ_WAIT(true, observer->called(), kMaxWaitMs);
823 *desc = observer->release_desc();
824 if (observer->result() && ExpectIceRestart()) {
825 EXPECT_EQ(0u, (*desc)->candidates(0)->count());
826 }
827 return observer->result();
828 }
829
830 bool DoCreateOffer(SessionDescriptionInterface** desc) {
831 return DoCreateOfferAnswer(desc, true);
832 }
833
834 bool DoCreateAnswer(SessionDescriptionInterface** desc) {
835 return DoCreateOfferAnswer(desc, false);
836 }
837
838 bool DoSetLocalDescription(SessionDescriptionInterface* desc) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000839 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
840 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000841 MockSetSessionDescriptionObserver>());
842 LOG(INFO) << id() << "SetLocalDescription ";
843 pc()->SetLocalDescription(observer, desc);
844 // Ignore the observer result. If we wait for the result with
845 // EXPECT_TRUE_WAIT, local ice candidates might be sent to the remote peer
846 // before the offer which is an error.
847 // The reason is that EXPECT_TRUE_WAIT uses
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000848 // rtc::Thread::Current()->ProcessMessages(1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849 // ProcessMessages waits at least 1ms but processes all messages before
850 // returning. Since this test is synchronous and send messages to the remote
851 // peer whenever a callback is invoked, this can lead to messages being
852 // sent to the remote peer in the wrong order.
853 // TODO(perkj): Find a way to check the result without risking that the
854 // order of sent messages are changed. Ex- by posting all messages that are
855 // sent to the remote peer.
856 return true;
857 }
858
859 bool DoSetRemoteDescription(SessionDescriptionInterface* desc) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000860 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
861 observer(new rtc::RefCountedObject<
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000862 MockSetSessionDescriptionObserver>());
863 LOG(INFO) << id() << "SetRemoteDescription ";
864 pc()->SetRemoteDescription(observer, desc);
865 EXPECT_TRUE_WAIT(observer->called(), kMaxWaitMs);
866 return observer->result();
867 }
868
869 // This modifies all received SDP messages before they are processed.
870 void FilterIncomingSdpMessage(std::string* sdp) {
871 if (remove_msid_) {
872 const char kSdpSsrcAttribute[] = "a=ssrc:";
873 RemoveLinesFromSdp(kSdpSsrcAttribute, sdp);
874 const char kSdpMsidSupportedAttribute[] = "a=msid-semantic:";
875 RemoveLinesFromSdp(kSdpMsidSupportedAttribute, sdp);
876 }
877 if (remove_bundle_) {
878 const char kSdpBundleAttribute[] = "a=group:BUNDLE";
879 RemoveLinesFromSdp(kSdpBundleAttribute, sdp);
880 }
881 if (remove_sdes_) {
882 const char kSdpSdesCryptoAttribute[] = "a=crypto";
883 RemoveLinesFromSdp(kSdpSdesCryptoAttribute, sdp);
884 }
885 }
886
887 private:
888 webrtc::FakeConstraints session_description_constraints_;
889 bool remove_msid_; // True if MSID should be removed in received SDP.
890 bool remove_bundle_; // True if bundle should be removed in received SDP.
891 bool remove_sdes_; // True if a=crypto should be removed in received SDP.
892
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000893 rtc::scoped_refptr<DataChannelInterface> data_channel_;
894 rtc::scoped_ptr<MockDataChannelObserver> data_observer_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895};
896
897template <typename SignalingClass>
898class P2PTestConductor : public testing::Test {
899 public:
pbos@webrtc.org9eacb8c2015-01-02 09:03:19 +0000900 P2PTestConductor()
901 : pss_(new rtc::PhysicalSocketServer),
902 ss_(new rtc::VirtualSocketServer(pss_.get())),
903 ss_scope_(ss_.get()) {}
904
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 bool SessionActive() {
906 return initiating_client_->SessionActive() &&
pbos@webrtc.org9eacb8c2015-01-02 09:03:19 +0000907 receiving_client_->SessionActive();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000908 }
pbos@webrtc.org9eacb8c2015-01-02 09:03:19 +0000909
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000910 // Return true if the number of frames provided have been received or it is
911 // known that that will never occur (e.g. no frames will be sent or
912 // captured).
913 bool FramesNotPending(int audio_frames_to_receive,
914 int video_frames_to_receive) {
915 return VideoFramesReceivedCheck(video_frames_to_receive) &&
916 AudioFramesReceivedCheck(audio_frames_to_receive);
917 }
918 bool AudioFramesReceivedCheck(int frames_received) {
919 return initiating_client_->AudioFramesReceivedCheck(frames_received) &&
920 receiving_client_->AudioFramesReceivedCheck(frames_received);
921 }
922 bool VideoFramesReceivedCheck(int frames_received) {
923 return initiating_client_->VideoFramesReceivedCheck(frames_received) &&
924 receiving_client_->VideoFramesReceivedCheck(frames_received);
925 }
926 void VerifyDtmf() {
927 initiating_client_->VerifyDtmf();
928 receiving_client_->VerifyDtmf();
929 }
930
931 void TestUpdateOfferWithRejectedContent() {
932 initiating_client_->Negotiate(true, false);
933 EXPECT_TRUE_WAIT(
934 FramesNotPending(kEndAudioFrameCount * 2, kEndVideoFrameCount),
935 kMaxWaitForFramesMs);
936 // There shouldn't be any more video frame after the new offer is
937 // negotiated.
938 EXPECT_FALSE(VideoFramesReceivedCheck(kEndVideoFrameCount + 1));
939 }
940
941 void VerifyRenderedSize(int width, int height) {
942 EXPECT_EQ(width, receiving_client()->rendered_width());
943 EXPECT_EQ(height, receiving_client()->rendered_height());
944 EXPECT_EQ(width, initializing_client()->rendered_width());
945 EXPECT_EQ(height, initializing_client()->rendered_height());
946 }
947
948 void VerifySessionDescriptions() {
949 initiating_client_->VerifyRejectedMediaInSessionDescription();
950 receiving_client_->VerifyRejectedMediaInSessionDescription();
951 initiating_client_->VerifyLocalIceUfragAndPassword();
952 receiving_client_->VerifyLocalIceUfragAndPassword();
953 }
954
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955 ~P2PTestConductor() {
956 if (initiating_client_) {
957 initiating_client_->set_signaling_message_receiver(NULL);
958 }
959 if (receiving_client_) {
960 receiving_client_->set_signaling_message_receiver(NULL);
961 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000962 }
963
964 bool CreateTestClients() {
965 return CreateTestClients(NULL, NULL);
966 }
967
968 bool CreateTestClients(MediaConstraintsInterface* init_constraints,
969 MediaConstraintsInterface* recv_constraints) {
970 initiating_client_.reset(SignalingClass::CreateClient("Caller: ",
971 init_constraints));
972 receiving_client_.reset(SignalingClass::CreateClient("Callee: ",
973 recv_constraints));
974 if (!initiating_client_ || !receiving_client_) {
975 return false;
976 }
977 initiating_client_->set_signaling_message_receiver(receiving_client_.get());
978 receiving_client_->set_signaling_message_receiver(initiating_client_.get());
979 return true;
980 }
981
982 void SetVideoConstraints(const webrtc::FakeConstraints& init_constraints,
983 const webrtc::FakeConstraints& recv_constraints) {
984 initiating_client_->SetVideoConstraints(init_constraints);
985 receiving_client_->SetVideoConstraints(recv_constraints);
986 }
987
988 void EnableVideoDecoderFactory() {
989 initiating_client_->EnableVideoDecoderFactory();
990 receiving_client_->EnableVideoDecoderFactory();
991 }
992
993 // This test sets up a call between two parties. Both parties send static
994 // frames to each other. Once the test is finished the number of sent frames
995 // is compared to the number of received frames.
996 void LocalP2PTest() {
997 if (initiating_client_->NumberOfLocalMediaStreams() == 0) {
998 initiating_client_->AddMediaStream(true, true);
999 }
1000 initiating_client_->Negotiate();
1001 const int kMaxWaitForActivationMs = 5000;
1002 // Assert true is used here since next tests are guaranteed to fail and
1003 // would eat up 5 seconds.
1004 ASSERT_TRUE_WAIT(SessionActive(), kMaxWaitForActivationMs);
1005 VerifySessionDescriptions();
1006
1007
1008 int audio_frame_count = kEndAudioFrameCount;
1009 // TODO(ronghuawu): Add test to cover the case of sendonly and recvonly.
1010 if (!initiating_client_->can_receive_audio() ||
1011 !receiving_client_->can_receive_audio()) {
1012 audio_frame_count = -1;
1013 }
1014 int video_frame_count = kEndVideoFrameCount;
1015 if (!initiating_client_->can_receive_video() ||
1016 !receiving_client_->can_receive_video()) {
1017 video_frame_count = -1;
1018 }
1019
1020 if (audio_frame_count != -1 || video_frame_count != -1) {
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001021 // Audio or video is expected to flow, so both clients should reach the
1022 // Connected state, and the offerer (ICE controller) should proceed to
1023 // Completed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024 // Note: These tests have been observed to fail under heavy load at
1025 // shorter timeouts, so they may be flaky.
1026 EXPECT_EQ_WAIT(
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001027 webrtc::PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001028 initiating_client_->ice_connection_state(),
1029 kMaxWaitForFramesMs);
1030 EXPECT_EQ_WAIT(
1031 webrtc::PeerConnectionInterface::kIceConnectionConnected,
1032 receiving_client_->ice_connection_state(),
1033 kMaxWaitForFramesMs);
1034 }
1035
1036 if (initiating_client_->can_receive_audio() ||
1037 initiating_client_->can_receive_video()) {
1038 // The initiating client can receive media, so it must produce candidates
1039 // that will serve as destinations for that media.
1040 // TODO(bemasc): Understand why the state is not already Complete here, as
1041 // seems to be the case for the receiving client. This may indicate a bug
1042 // in the ICE gathering system.
1043 EXPECT_NE(webrtc::PeerConnectionInterface::kIceGatheringNew,
1044 initiating_client_->ice_gathering_state());
1045 }
1046 if (receiving_client_->can_receive_audio() ||
1047 receiving_client_->can_receive_video()) {
1048 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1049 receiving_client_->ice_gathering_state(),
1050 kMaxWaitForFramesMs);
1051 }
1052
1053 EXPECT_TRUE_WAIT(FramesNotPending(audio_frame_count, video_frame_count),
1054 kMaxWaitForFramesMs);
1055 }
1056
jiayl@webrtc.org6c6f33b2014-06-12 21:05:19 +00001057 void SendRtpData(webrtc::DataChannelInterface* dc, const std::string& data) {
1058 // Messages may get lost on the unreliable DataChannel, so we send multiple
1059 // times to avoid test flakiness.
1060 static const size_t kSendAttempts = 5;
1061
1062 for (size_t i = 0; i < kSendAttempts; ++i) {
1063 dc->Send(DataBuffer(data));
1064 }
1065 }
1066
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001067 SignalingClass* initializing_client() { return initiating_client_.get(); }
1068 SignalingClass* receiving_client() { return receiving_client_.get(); }
1069
1070 private:
pbos@webrtc.org9eacb8c2015-01-02 09:03:19 +00001071 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
1072 rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
1073 rtc::SocketServerScope ss_scope_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001074 rtc::scoped_ptr<SignalingClass> initiating_client_;
1075 rtc::scoped_ptr<SignalingClass> receiving_client_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001076};
1077typedef P2PTestConductor<JsepTestClient> JsepPeerConnectionP2PTestClient;
1078
kjellander@webrtc.orgd1cfa712013-10-16 16:51:52 +00001079// Disable for TSan v2, see
1080// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
1081#if !defined(THREAD_SANITIZER)
1082
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001083// This test sets up a Jsep call between two parties and test Dtmf.
stefan@webrtc.orgda790082013-09-17 13:11:38 +00001084// TODO(holmer): Disabled due to sometimes crashing on buildbots.
1085// See issue webrtc/2378.
1086TEST_F(JsepPeerConnectionP2PTestClient, DISABLED_LocalP2PTestDtmf) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001087 ASSERT_TRUE(CreateTestClients());
1088 LocalP2PTest();
1089 VerifyDtmf();
1090}
1091
1092// This test sets up a Jsep call between two parties and test that we can get a
1093// video aspect ratio of 16:9.
1094TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTest16To9) {
1095 ASSERT_TRUE(CreateTestClients());
1096 FakeConstraints constraint;
1097 double requested_ratio = 640.0/360;
1098 constraint.SetMandatoryMinAspectRatio(requested_ratio);
1099 SetVideoConstraints(constraint, constraint);
1100 LocalP2PTest();
1101
1102 ASSERT_LE(0, initializing_client()->rendered_height());
1103 double initiating_video_ratio =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001104 static_cast<double>(initializing_client()->rendered_width()) /
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001105 initializing_client()->rendered_height();
1106 EXPECT_LE(requested_ratio, initiating_video_ratio);
1107
1108 ASSERT_LE(0, receiving_client()->rendered_height());
1109 double receiving_video_ratio =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001110 static_cast<double>(receiving_client()->rendered_width()) /
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001111 receiving_client()->rendered_height();
1112 EXPECT_LE(requested_ratio, receiving_video_ratio);
1113}
1114
1115// This test sets up a Jsep call between two parties and test that the
1116// received video has a resolution of 1280*720.
1117// TODO(mallinath): Enable when
1118// http://code.google.com/p/webrtc/issues/detail?id=981 is fixed.
1119TEST_F(JsepPeerConnectionP2PTestClient, DISABLED_LocalP2PTest1280By720) {
1120 ASSERT_TRUE(CreateTestClients());
1121 FakeConstraints constraint;
1122 constraint.SetMandatoryMinWidth(1280);
1123 constraint.SetMandatoryMinHeight(720);
1124 SetVideoConstraints(constraint, constraint);
1125 LocalP2PTest();
1126 VerifyRenderedSize(1280, 720);
1127}
1128
1129// This test sets up a call between two endpoints that are configured to use
1130// DTLS key agreement. As a result, DTLS is negotiated and used for transport.
1131TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestDtls) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001132 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001133 FakeConstraints setup_constraints;
1134 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
1135 true);
1136 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints));
1137 LocalP2PTest();
1138 VerifyRenderedSize(640, 480);
1139}
1140
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001141// This test sets up a audio call initially and then upgrades to audio/video,
1142// using DTLS.
mallinath@webrtc.org50bc5532013-10-21 17:58:35 +00001143TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestDtlsRenegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001144 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001145 FakeConstraints setup_constraints;
1146 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
1147 true);
1148 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints));
1149 receiving_client()->SetReceiveAudioVideo(true, false);
1150 LocalP2PTest();
1151 receiving_client()->SetReceiveAudioVideo(true, true);
1152 receiving_client()->Negotiate();
1153}
1154
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001155// This test sets up a call between two endpoints that are configured to use
1156// DTLS key agreement. The offerer don't support SDES. As a result, DTLS is
1157// negotiated and used for transport.
1158TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestOfferDtlsButNotSdes) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001159 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001160 FakeConstraints setup_constraints;
1161 setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
1162 true);
1163 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints));
1164 receiving_client()->RemoveSdesCryptoFromReceivedSdp(true);
1165 LocalP2PTest();
1166 VerifyRenderedSize(640, 480);
1167}
1168
1169// This test sets up a Jsep call between two parties, and the callee only
1170// accept to receive video.
solenberg@webrtc.org503c3362015-02-12 13:12:50 +00001171TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestAnswerVideo) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001172 ASSERT_TRUE(CreateTestClients());
1173 receiving_client()->SetReceiveAudioVideo(false, true);
1174 LocalP2PTest();
1175}
1176
1177// This test sets up a Jsep call between two parties, and the callee only
1178// accept to receive audio.
solenberg@webrtc.org503c3362015-02-12 13:12:50 +00001179TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestAnswerAudio) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001180 ASSERT_TRUE(CreateTestClients());
1181 receiving_client()->SetReceiveAudioVideo(true, false);
1182 LocalP2PTest();
1183}
1184
1185// This test sets up a Jsep call between two parties, and the callee reject both
1186// audio and video.
1187TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestAnswerNone) {
1188 ASSERT_TRUE(CreateTestClients());
1189 receiving_client()->SetReceiveAudioVideo(false, false);
1190 LocalP2PTest();
1191}
1192
1193// This test sets up an audio and video call between two parties. After the call
1194// runs for a while (10 frames), the caller sends an update offer with video
1195// being rejected. Once the re-negotiation is done, the video flow should stop
1196// and the audio flow should continue.
buildbot@webrtc.org688ed692014-05-14 18:26:09 +00001197// Disabled due to b/14955157.
1198TEST_F(JsepPeerConnectionP2PTestClient,
1199 DISABLED_UpdateOfferWithRejectedContent) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001200 ASSERT_TRUE(CreateTestClients());
1201 LocalP2PTest();
1202 TestUpdateOfferWithRejectedContent();
1203}
1204
1205// This test sets up a Jsep call between two parties. The MSID is removed from
1206// the SDP strings from the caller.
buildbot@webrtc.org688ed692014-05-14 18:26:09 +00001207// Disabled due to b/14955157.
1208TEST_F(JsepPeerConnectionP2PTestClient, DISABLED_LocalP2PTestWithoutMsid) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001209 ASSERT_TRUE(CreateTestClients());
1210 receiving_client()->RemoveMsidFromReceivedSdp(true);
1211 // TODO(perkj): Currently there is a bug that cause audio to stop playing if
1212 // audio and video is muxed when MSID is disabled. Remove
1213 // SetRemoveBundleFromSdp once
1214 // https://code.google.com/p/webrtc/issues/detail?id=1193 is fixed.
1215 receiving_client()->RemoveBundleFromReceivedSdp(true);
1216 LocalP2PTest();
1217}
1218
1219// This test sets up a Jsep call between two parties and the initiating peer
1220// sends two steams.
1221// TODO(perkj): Disabled due to
1222// https://code.google.com/p/webrtc/issues/detail?id=1454
1223TEST_F(JsepPeerConnectionP2PTestClient, DISABLED_LocalP2PTestTwoStreams) {
1224 ASSERT_TRUE(CreateTestClients());
1225 // Set optional video constraint to max 320pixels to decrease CPU usage.
1226 FakeConstraints constraint;
1227 constraint.SetOptionalMaxWidth(320);
1228 SetVideoConstraints(constraint, constraint);
1229 initializing_client()->AddMediaStream(true, true);
1230 initializing_client()->AddMediaStream(false, true);
1231 ASSERT_EQ(2u, initializing_client()->NumberOfLocalMediaStreams());
1232 LocalP2PTest();
1233 EXPECT_EQ(2u, receiving_client()->number_of_remote_streams());
1234}
1235
1236// Test that we can receive the audio output level from a remote audio track.
1237TEST_F(JsepPeerConnectionP2PTestClient, GetAudioOutputLevelStats) {
1238 ASSERT_TRUE(CreateTestClients());
1239 LocalP2PTest();
1240
1241 StreamCollectionInterface* remote_streams =
1242 initializing_client()->remote_streams();
1243 ASSERT_GT(remote_streams->count(), 0u);
1244 ASSERT_GT(remote_streams->at(0)->GetAudioTracks().size(), 0u);
1245 MediaStreamTrackInterface* remote_audio_track =
1246 remote_streams->at(0)->GetAudioTracks()[0];
1247
1248 // Get the audio output level stats. Note that the level is not available
1249 // until a RTCP packet has been received.
1250 EXPECT_TRUE_WAIT(
1251 initializing_client()->GetAudioOutputLevelStats(remote_audio_track) > 0,
1252 kMaxWaitForStatsMs);
1253}
1254
1255// Test that an audio input level is reported.
1256TEST_F(JsepPeerConnectionP2PTestClient, GetAudioInputLevelStats) {
1257 ASSERT_TRUE(CreateTestClients());
1258 LocalP2PTest();
1259
1260 // Get the audio input level stats. The level should be available very
1261 // soon after the test starts.
1262 EXPECT_TRUE_WAIT(initializing_client()->GetAudioInputLevelStats() > 0,
1263 kMaxWaitForStatsMs);
1264}
1265
1266// Test that we can get incoming byte counts from both audio and video tracks.
1267TEST_F(JsepPeerConnectionP2PTestClient, GetBytesReceivedStats) {
1268 ASSERT_TRUE(CreateTestClients());
1269 LocalP2PTest();
1270
1271 StreamCollectionInterface* remote_streams =
1272 initializing_client()->remote_streams();
1273 ASSERT_GT(remote_streams->count(), 0u);
1274 ASSERT_GT(remote_streams->at(0)->GetAudioTracks().size(), 0u);
1275 MediaStreamTrackInterface* remote_audio_track =
1276 remote_streams->at(0)->GetAudioTracks()[0];
1277 EXPECT_TRUE_WAIT(
1278 initializing_client()->GetBytesReceivedStats(remote_audio_track) > 0,
1279 kMaxWaitForStatsMs);
1280
1281 MediaStreamTrackInterface* remote_video_track =
1282 remote_streams->at(0)->GetVideoTracks()[0];
1283 EXPECT_TRUE_WAIT(
1284 initializing_client()->GetBytesReceivedStats(remote_video_track) > 0,
1285 kMaxWaitForStatsMs);
1286}
1287
1288// Test that we can get outgoing byte counts from both audio and video tracks.
1289TEST_F(JsepPeerConnectionP2PTestClient, GetBytesSentStats) {
1290 ASSERT_TRUE(CreateTestClients());
1291 LocalP2PTest();
1292
1293 StreamCollectionInterface* local_streams =
1294 initializing_client()->local_streams();
1295 ASSERT_GT(local_streams->count(), 0u);
1296 ASSERT_GT(local_streams->at(0)->GetAudioTracks().size(), 0u);
1297 MediaStreamTrackInterface* local_audio_track =
1298 local_streams->at(0)->GetAudioTracks()[0];
1299 EXPECT_TRUE_WAIT(
1300 initializing_client()->GetBytesSentStats(local_audio_track) > 0,
1301 kMaxWaitForStatsMs);
1302
1303 MediaStreamTrackInterface* local_video_track =
1304 local_streams->at(0)->GetVideoTracks()[0];
1305 EXPECT_TRUE_WAIT(
1306 initializing_client()->GetBytesSentStats(local_video_track) > 0,
1307 kMaxWaitForStatsMs);
1308}
1309
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001310// Test that we can get negotiated ciphers.
1311TEST_F(JsepPeerConnectionP2PTestClient, GetNegotiatedCiphersStats) {
1312 ASSERT_TRUE(CreateTestClients());
1313 LocalP2PTest();
1314
Joachim Bauch831c5582015-05-20 12:48:41 +02001315 // TODO(jbauch): this should check for DTLS 1.0 / 1.2 when we have a way to
1316 // enable DTLS 1.2 on peer connections.
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001317 EXPECT_EQ_WAIT(
Joachim Bauch831c5582015-05-20 12:48:41 +02001318 rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_10),
pthatcher@webrtc.org7bea1ff2015-03-04 01:38:30 +00001319 initializing_client()->GetDtlsCipherStats(),
1320 kMaxWaitForStatsMs);
1321
1322 EXPECT_EQ_WAIT(
1323 kDefaultSrtpCipher,
1324 initializing_client()->GetSrtpCipherStats(),
1325 kMaxWaitForStatsMs);
1326}
1327
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001328// This test sets up a call between two parties with audio, video and data.
1329TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestDataChannel) {
1330 FakeConstraints setup_constraints;
1331 setup_constraints.SetAllowRtpDataChannels();
1332 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints));
1333 initializing_client()->CreateDataChannel();
1334 LocalP2PTest();
1335 ASSERT_TRUE(initializing_client()->data_channel() != NULL);
1336 ASSERT_TRUE(receiving_client()->data_channel() != NULL);
1337 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(),
1338 kMaxWaitMs);
1339 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(),
1340 kMaxWaitMs);
1341
1342 std::string data = "hello world";
jiayl@webrtc.org6c6f33b2014-06-12 21:05:19 +00001343
1344 SendRtpData(initializing_client()->data_channel(), data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001345 EXPECT_EQ_WAIT(data, receiving_client()->data_observer()->last_message(),
1346 kMaxWaitMs);
jiayl@webrtc.org6c6f33b2014-06-12 21:05:19 +00001347
1348 SendRtpData(receiving_client()->data_channel(), data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001349 EXPECT_EQ_WAIT(data, initializing_client()->data_observer()->last_message(),
1350 kMaxWaitMs);
1351
1352 receiving_client()->data_channel()->Close();
1353 // Send new offer and answer.
1354 receiving_client()->Negotiate();
1355 EXPECT_FALSE(initializing_client()->data_observer()->IsOpen());
1356 EXPECT_FALSE(receiving_client()->data_observer()->IsOpen());
1357}
1358
1359// This test sets up a call between two parties and creates a data channel.
1360// The test tests that received data is buffered unless an observer has been
1361// registered.
1362// Rtp data channels can receive data before the underlying
1363// transport has detected that a channel is writable and thus data can be
1364// received before the data channel state changes to open. That is hard to test
1365// but the same buffering is used in that case.
1366TEST_F(JsepPeerConnectionP2PTestClient, RegisterDataChannelObserver) {
1367 FakeConstraints setup_constraints;
1368 setup_constraints.SetAllowRtpDataChannels();
1369 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints));
1370 initializing_client()->CreateDataChannel();
1371 initializing_client()->Negotiate();
1372
1373 ASSERT_TRUE(initializing_client()->data_channel() != NULL);
1374 ASSERT_TRUE(receiving_client()->data_channel() != NULL);
1375 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(),
1376 kMaxWaitMs);
1377 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
1378 receiving_client()->data_channel()->state(), kMaxWaitMs);
1379
1380 // Unregister the existing observer.
1381 receiving_client()->data_channel()->UnregisterObserver();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00001382
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001383 std::string data = "hello world";
jiayl@webrtc.org6c6f33b2014-06-12 21:05:19 +00001384 SendRtpData(initializing_client()->data_channel(), data);
1385
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386 // Wait a while to allow the sent data to arrive before an observer is
1387 // registered..
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001388 rtc::Thread::Current()->ProcessMessages(100);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001389
1390 MockDataChannelObserver new_observer(receiving_client()->data_channel());
1391 EXPECT_EQ_WAIT(data, new_observer.last_message(), kMaxWaitMs);
1392}
1393
1394// This test sets up a call between two parties with audio, video and but only
1395// the initiating client support data.
1396TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestReceiverDoesntSupportData) {
buildbot@webrtc.org61c1b8e2014-04-09 06:06:38 +00001397 FakeConstraints setup_constraints_1;
1398 setup_constraints_1.SetAllowRtpDataChannels();
1399 // Must disable DTLS to make negotiation succeed.
1400 setup_constraints_1.SetMandatory(
1401 MediaConstraintsInterface::kEnableDtlsSrtp, false);
1402 FakeConstraints setup_constraints_2;
1403 setup_constraints_2.SetMandatory(
1404 MediaConstraintsInterface::kEnableDtlsSrtp, false);
1405 ASSERT_TRUE(CreateTestClients(&setup_constraints_1, &setup_constraints_2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001406 initializing_client()->CreateDataChannel();
1407 LocalP2PTest();
1408 EXPECT_TRUE(initializing_client()->data_channel() != NULL);
1409 EXPECT_FALSE(receiving_client()->data_channel());
1410 EXPECT_FALSE(initializing_client()->data_observer()->IsOpen());
1411}
1412
1413// This test sets up a call between two parties with audio, video. When audio
1414// and video is setup and flowing and data channel is negotiated.
1415TEST_F(JsepPeerConnectionP2PTestClient, AddDataChannelAfterRenegotiation) {
1416 FakeConstraints setup_constraints;
1417 setup_constraints.SetAllowRtpDataChannels();
1418 ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints));
1419 LocalP2PTest();
1420 initializing_client()->CreateDataChannel();
1421 // Send new offer and answer.
1422 initializing_client()->Negotiate();
1423 ASSERT_TRUE(initializing_client()->data_channel() != NULL);
1424 ASSERT_TRUE(receiving_client()->data_channel() != NULL);
1425 EXPECT_TRUE_WAIT(initializing_client()->data_observer()->IsOpen(),
1426 kMaxWaitMs);
1427 EXPECT_TRUE_WAIT(receiving_client()->data_observer()->IsOpen(),
1428 kMaxWaitMs);
1429}
1430
jiayl@webrtc.org9c16c392014-05-01 18:30:30 +00001431// This test sets up a Jsep call with SCTP DataChannel and verifies the
1432// negotiation is completed without error.
1433#ifdef HAVE_SCTP
1434TEST_F(JsepPeerConnectionP2PTestClient, CreateOfferWithSctpDataChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001435 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org9c16c392014-05-01 18:30:30 +00001436 FakeConstraints constraints;
1437 constraints.SetMandatory(
1438 MediaConstraintsInterface::kEnableDtlsSrtp, true);
1439 ASSERT_TRUE(CreateTestClients(&constraints, &constraints));
1440 initializing_client()->CreateDataChannel();
1441 initializing_client()->Negotiate(false, false);
1442}
1443#endif
1444
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445// This test sets up a call between two parties with audio, and video.
1446// During the call, the initializing side restart ice and the test verifies that
1447// new ice candidates are generated and audio and video still can flow.
1448TEST_F(JsepPeerConnectionP2PTestClient, IceRestart) {
1449 ASSERT_TRUE(CreateTestClients());
1450
1451 // Negotiate and wait for ice completion and make sure audio and video plays.
1452 LocalP2PTest();
1453
1454 // Create a SDP string of the first audio candidate for both clients.
1455 const webrtc::IceCandidateCollection* audio_candidates_initiator =
1456 initializing_client()->pc()->local_description()->candidates(0);
1457 const webrtc::IceCandidateCollection* audio_candidates_receiver =
1458 receiving_client()->pc()->local_description()->candidates(0);
1459 ASSERT_GT(audio_candidates_initiator->count(), 0u);
1460 ASSERT_GT(audio_candidates_receiver->count(), 0u);
1461 std::string initiator_candidate;
1462 EXPECT_TRUE(
1463 audio_candidates_initiator->at(0)->ToString(&initiator_candidate));
1464 std::string receiver_candidate;
1465 EXPECT_TRUE(audio_candidates_receiver->at(0)->ToString(&receiver_candidate));
1466
1467 // Restart ice on the initializing client.
1468 receiving_client()->SetExpectIceRestart(true);
1469 initializing_client()->IceRestart();
1470
1471 // Negotiate and wait for ice completion again and make sure audio and video
1472 // plays.
1473 LocalP2PTest();
1474
1475 // Create a SDP string of the first audio candidate for both clients again.
1476 const webrtc::IceCandidateCollection* audio_candidates_initiator_restart =
1477 initializing_client()->pc()->local_description()->candidates(0);
1478 const webrtc::IceCandidateCollection* audio_candidates_reciever_restart =
1479 receiving_client()->pc()->local_description()->candidates(0);
1480 ASSERT_GT(audio_candidates_initiator_restart->count(), 0u);
1481 ASSERT_GT(audio_candidates_reciever_restart->count(), 0u);
1482 std::string initiator_candidate_restart;
1483 EXPECT_TRUE(audio_candidates_initiator_restart->at(0)->ToString(
1484 &initiator_candidate_restart));
1485 std::string receiver_candidate_restart;
1486 EXPECT_TRUE(audio_candidates_reciever_restart->at(0)->ToString(
1487 &receiver_candidate_restart));
1488
1489 // Verify that the first candidates in the local session descriptions has
1490 // changed.
1491 EXPECT_NE(initiator_candidate, initiator_candidate_restart);
1492 EXPECT_NE(receiver_candidate, receiver_candidate_restart);
1493}
1494
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001495// This test sets up a Jsep call between two parties with external
1496// VideoDecoderFactory.
stefan@webrtc.orgda790082013-09-17 13:11:38 +00001497// TODO(holmer): Disabled due to sometimes crashing on buildbots.
1498// See issue webrtc/2378.
1499TEST_F(JsepPeerConnectionP2PTestClient,
1500 DISABLED_LocalP2PTestWithVideoDecoderFactory) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001501 ASSERT_TRUE(CreateTestClients());
1502 EnableVideoDecoderFactory();
1503 LocalP2PTest();
1504}
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00001505
kjellander@webrtc.orgd1cfa712013-10-16 16:51:52 +00001506#endif // if !defined(THREAD_SANITIZER)