~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/libjingle/talk/app/webrtc/webrtcsession_unittest.cc

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * libjingle
 
3
 * Copyright 2011, 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 "talk/app/webrtc/webrtcsession.h"
 
29
#include "talk/app/webrtc/jsepicecandidate.h"
 
30
#include "talk/app/webrtc/jsepsessiondescription.h"
 
31
#include "talk/app/webrtc/mediastreamsignaling.h"
 
32
#include "talk/base/logging.h"
 
33
#include "talk/base/fakenetwork.h"
 
34
#include "talk/base/firewallsocketserver.h"
 
35
#include "talk/base/gunit.h"
 
36
#include "talk/base/network.h"
 
37
#include "talk/base/physicalsocketserver.h"
 
38
#include "talk/base/thread.h"
 
39
#include "talk/base/virtualsocketserver.h"
 
40
#include "talk/p2p/base/stunserver.h"
 
41
#include "talk/p2p/base/teststunserver.h"
 
42
#include "talk/p2p/client/basicportallocator.h"
 
43
#include "talk/session/phone/channelmanager.h"
 
44
#include "talk/session/phone/fakedevicemanager.h"
 
45
#include "talk/session/phone/fakemediaengine.h"
 
46
#include "talk/session/phone/mediasession.h"
 
47
 
 
48
using talk_base::scoped_ptr;
 
49
using talk_base::SocketAddress;
 
50
using webrtc::IceCandidateColletion;
 
51
using webrtc::JsepInterface;
 
52
using webrtc::JsepSessionDescription;
 
53
using webrtc::JsepIceCandidate;
 
54
using webrtc::SessionDescriptionInterface;
 
55
 
 
56
using webrtc::MediaHints;
 
57
 
 
58
static const SocketAddress kClientAddr1("11.11.11.11", 0);
 
59
static const SocketAddress kClientAddr2("22.22.22.22", 0);
 
60
static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
 
61
 
 
62
static const char kStream1[] = "stream1";
 
63
static const char kVideoTrack1[] = "video1";
 
64
static const char kAudioTrack1[] = "audio1";
 
65
 
 
66
static const char kStream2[] = "stream2";
 
67
static const char kVideoTrack2[] = "video2";
 
68
static const char kAudioTrack2[] = "audio2";
 
69
 
 
70
// Label of candidates belonging to the first media content.
 
71
static const char kMediaContentLabel0[] = "0";
 
72
static const int kMediaContentIndex0 = 0;
 
73
 
 
74
// Label of candidates belonging to the second media content.
 
75
static const char kMediaContentLabel1[] = "1";
 
76
static const int kMediaContentIndex1 = 1;
 
77
 
 
78
static const int kIceCandidatesTimeout = 3000;
 
79
 
 
80
 
 
81
class MockCandidateObserver : public webrtc::IceCandidateObserver {
 
82
 public:
 
83
  MockCandidateObserver()
 
84
      : oncandidatesready_(false) {
 
85
  }
 
86
 
 
87
  // Found a new candidate.
 
88
  virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
 
89
    if (candidate->label() == kMediaContentLabel0) {
 
90
      mline_0_candidates_.push_back(candidate->candidate());
 
91
    } else if (candidate->label() == kMediaContentLabel1) {
 
92
      mline_1_candidates_.push_back(candidate->candidate());
 
93
    }
 
94
  }
 
95
 
 
96
  virtual void OnIceComplete() {
 
97
    EXPECT_FALSE(oncandidatesready_);
 
98
    oncandidatesready_ = true;
 
99
  }
 
100
 
 
101
  bool oncandidatesready_;
 
102
  std::vector<cricket::Candidate> mline_0_candidates_;
 
103
  std::vector<cricket::Candidate> mline_1_candidates_;
 
104
};
 
105
 
 
106
class WebRtcSessionForTest : public webrtc::WebRtcSession {
 
107
 public:
 
108
  WebRtcSessionForTest(cricket::ChannelManager* cmgr,
 
109
                       talk_base::Thread* signaling_thread,
 
110
                       talk_base::Thread* worker_thread,
 
111
                       cricket::PortAllocator* port_allocator,
 
112
                       webrtc::IceCandidateObserver* ice_observer,
 
113
                       webrtc::MediaStreamSignaling* mediastream_signaling)
 
114
    : WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator,
 
115
                    mediastream_signaling) {
 
116
    RegisterObserver(ice_observer);
 
117
  }
 
118
  virtual ~WebRtcSessionForTest() {}
 
119
 
 
120
  using webrtc::WebRtcSession::CreateOffer;
 
121
  using webrtc::WebRtcSession::CreateAnswer;
 
122
  using webrtc::WebRtcSession::SetLocalDescription;
 
123
  using webrtc::WebRtcSession::SetRemoteDescription;
 
124
  using webrtc::WebRtcSession::ProcessIceMessage;
 
125
};
 
126
 
 
127
class FakeMediaStreamSignaling : public webrtc::MediaStreamSignaling,
 
128
                                 public webrtc::RemoteMediaStreamObserver {
 
129
 public:
 
130
  FakeMediaStreamSignaling() :
 
131
    webrtc::MediaStreamSignaling(talk_base::Thread::Current(), this) {
 
132
  }
 
133
 
 
134
  // Overrides GetMediaSessionOptions in MediaStreamSignaling.
 
135
  // Instead of depending on MediaStreams this version of GetMediaSessionOptions
 
136
  // returns the options decided by MediaSessionOptions set in one of the below
 
137
  // UseOptions functions.
 
138
  virtual cricket::MediaSessionOptions GetMediaSessionOptions(
 
139
        const MediaHints& hints) const {
 
140
    return options_;
 
141
  }
 
142
 
 
143
  void UseOptionsWithStream1() {
 
144
    cricket::MediaSessionOptions options;
 
145
    options.AddStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack1, kStream1);
 
146
    options.AddStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack1, kStream1);
 
147
    options_ = options;
 
148
  }
 
149
 
 
150
  void UseOptionsWithStream2() {
 
151
    cricket::MediaSessionOptions options;
 
152
    options.AddStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack2, kStream2);
 
153
    options.AddStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack2, kStream2);
 
154
    options_ = options;
 
155
  }
 
156
 
 
157
  void UseOptionsWithStream1And2() {
 
158
    cricket::MediaSessionOptions options;
 
159
    options.AddStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack1, kStream1);
 
160
    options.AddStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack1, kStream1);
 
161
    options.AddStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack2, kStream2);
 
162
    options.AddStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack2, kStream2);
 
163
    options_ = options;
 
164
  }
 
165
 
 
166
  void UseOptionsReceiveOnly() {
 
167
    cricket::MediaSessionOptions options;
 
168
    options.has_video = true;
 
169
    options_ = options;
 
170
  }
 
171
 
 
172
  // Implements RemoteMediaStreamObserver.
 
173
  virtual void OnAddStream(webrtc::MediaStreamInterface* stream) {
 
174
  }
 
175
  virtual void OnRemoveStream(webrtc::MediaStreamInterface* stream) {
 
176
  }
 
177
 
 
178
 private:
 
179
  cricket::MediaSessionOptions options_;
 
180
};
 
181
 
 
182
class WebRtcSessionTest : public testing::Test {
 
183
 protected:
 
184
  // TODO Investigate why ChannelManager crashes, if it's created
 
185
  // after stun_server.
 
186
  WebRtcSessionTest()
 
187
    : media_engine(new cricket::FakeMediaEngine()),
 
188
      device_manager(new cricket::FakeDeviceManager()),
 
189
     channel_manager_(new cricket::ChannelManager(
 
190
         media_engine, device_manager, talk_base::Thread::Current())),
 
191
      desc_factory_(new cricket::MediaSessionDescriptionFactory(
 
192
          channel_manager_.get())),
 
193
      pss_(new talk_base::PhysicalSocketServer),
 
194
      vss_(new talk_base::VirtualSocketServer(pss_.get())),
 
195
      fss_(new talk_base::FirewallSocketServer(vss_.get())),
 
196
      ss_scope_(fss_.get()),
 
197
      stun_server_(talk_base::Thread::Current(), kStunAddr),
 
198
      allocator_(&network_manager_, kStunAddr,
 
199
                 SocketAddress(), SocketAddress(), SocketAddress()) {
 
200
    EXPECT_TRUE(channel_manager_->Init());
 
201
    desc_factory_->set_add_legacy_streams(false);
 
202
  }
 
203
 
 
204
  void AddInterface(const SocketAddress& addr) {
 
205
    network_manager_.AddInterface(addr);
 
206
  }
 
207
 
 
208
  void Init() {
 
209
    ASSERT_TRUE(session_.get() == NULL);
 
210
    session_.reset(new WebRtcSessionForTest(
 
211
        channel_manager_.get(), talk_base::Thread::Current(),
 
212
        talk_base::Thread::Current(), &allocator_,
 
213
        &observer_,
 
214
        &mediastream_signaling_));
 
215
 
 
216
    EXPECT_TRUE(session_->Initialize());
 
217
    mediastream_signaling_.UseOptionsReceiveOnly();
 
218
 
 
219
    video_channel_ = media_engine->GetVideoChannel(0);
 
220
    voice_channel_ = media_engine->GetVoiceChannel(0);
 
221
  }
 
222
 
 
223
  // Creates a local offer and applies it. Starts ice.
 
224
  // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
 
225
  // to decide which streams to create.
 
226
  void InitiateCall() {
 
227
    SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
228
    EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
 
229
    EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
 
230
  }
 
231
 
 
232
  bool ChannelsExist() {
 
233
    return (session_->voice_channel() != NULL &&
 
234
            session_->video_channel() != NULL);
 
235
  }
 
236
 
 
237
  void CheckTransportChannels() {
 
238
    EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, "rtp") != NULL);
 
239
    EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, "rtcp") != NULL);
 
240
    EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, "video_rtp") != NULL);
 
241
    EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, "video_rtcp") != NULL);
 
242
  }
 
243
 
 
244
  void VerifyCryptoParams(const cricket::SessionDescription* sdp,
 
245
                          bool offer) {
 
246
    ASSERT_TRUE(session_.get() != NULL);
 
247
    const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
 
248
    ASSERT_TRUE(content != NULL);
 
249
    const cricket::AudioContentDescription* audio_content =
 
250
        static_cast<const cricket::AudioContentDescription*>(
 
251
            content->description);
 
252
    ASSERT_TRUE(audio_content != NULL);
 
253
    if (offer) {
 
254
      ASSERT_EQ(2U, audio_content->cryptos().size());
 
255
      // key(40) + inline string
 
256
      ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
 
257
      ASSERT_EQ("AES_CM_128_HMAC_SHA1_32",
 
258
                audio_content->cryptos()[0].cipher_suite);
 
259
      ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
 
260
                audio_content->cryptos()[1].cipher_suite);
 
261
      ASSERT_EQ(47U, audio_content->cryptos()[1].key_params.size());
 
262
    } else {
 
263
      ASSERT_EQ(1U, audio_content->cryptos().size());
 
264
      // key(40) + inline string
 
265
      ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
 
266
      ASSERT_EQ("AES_CM_128_HMAC_SHA1_32",
 
267
                audio_content->cryptos()[0].cipher_suite);
 
268
    }
 
269
 
 
270
    content = cricket::GetFirstVideoContent(sdp);
 
271
    ASSERT_TRUE(content != NULL);
 
272
    const cricket::VideoContentDescription* video_content =
 
273
        static_cast<const cricket::VideoContentDescription*>(
 
274
            content->description);
 
275
    ASSERT_TRUE(video_content != NULL);
 
276
    ASSERT_EQ(1U, video_content->cryptos().size());
 
277
    ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
 
278
              video_content->cryptos()[0].cipher_suite);
 
279
    ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
 
280
  }
 
281
 
 
282
  void VerifyNoCryptoParams(const cricket::SessionDescription* sdp) {
 
283
    const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
 
284
    ASSERT_TRUE(content != NULL);
 
285
    const cricket::AudioContentDescription* audio_content =
 
286
        static_cast<const cricket::AudioContentDescription*>(
 
287
            content->description);
 
288
    ASSERT_TRUE(audio_content != NULL);
 
289
    ASSERT_EQ(0U, audio_content->cryptos().size());
 
290
 
 
291
    content = cricket::GetFirstVideoContent(sdp);
 
292
    ASSERT_TRUE(content != NULL);
 
293
    const cricket::VideoContentDescription* video_content =
 
294
        static_cast<const cricket::VideoContentDescription*>(
 
295
            content->description);
 
296
    ASSERT_TRUE(video_content != NULL);
 
297
    ASSERT_EQ(0U, video_content->cryptos().size());
 
298
  }
 
299
 
 
300
  void VerifyAnswerFromNonCryptoOffer() {
 
301
    // Create a SDP without Crypto.
 
302
    desc_factory_->set_secure(cricket::SEC_DISABLED);
 
303
    cricket::MediaSessionOptions options;
 
304
    options.has_video = true;
 
305
    scoped_ptr<JsepSessionDescription> offer(
 
306
        new JsepSessionDescription(desc_factory_->CreateOffer(options, NULL)));
 
307
    ASSERT_TRUE(offer.get() != NULL);
 
308
    VerifyNoCryptoParams(offer->description());
 
309
    const webrtc::SessionDescriptionInterface* answer =
 
310
        session_->CreateAnswer(MediaHints(), offer.get());
 
311
    // Answer should be NULL as no crypto params in offer.
 
312
    ASSERT_TRUE(answer->description() == NULL);
 
313
  }
 
314
 
 
315
  void VerifyAnswerFromCryptoOffer() {
 
316
    desc_factory_->set_secure(cricket::SEC_REQUIRED);
 
317
    cricket::MediaSessionOptions options;
 
318
    options.has_video = true;
 
319
    scoped_ptr<JsepSessionDescription> offer(
 
320
        new JsepSessionDescription(desc_factory_->CreateOffer(options, NULL)));
 
321
    ASSERT_TRUE(offer.get() != NULL);
 
322
    VerifyCryptoParams(offer->description(), true);
 
323
    scoped_ptr<SessionDescriptionInterface> answer(
 
324
        session_->CreateAnswer(MediaHints(), offer.get()));
 
325
    ASSERT_TRUE(answer.get() != NULL);
 
326
    VerifyCryptoParams(answer->description(), false);
 
327
  }
 
328
  // Creates and offer and an answer and applies it on the offer.
 
329
  // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
 
330
  // to decide which streams to create.
 
331
  void SetRemoteAndLocalSessionDescription() {
 
332
    SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
333
    SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
 
334
                                                                 offer);
 
335
    EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
336
    EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
 
337
  }
 
338
 
 
339
  cricket::FakeMediaEngine* media_engine;
 
340
  cricket::FakeDeviceManager* device_manager;
 
341
  talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
 
342
  talk_base::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
 
343
  talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
 
344
  talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
 
345
  talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
 
346
  talk_base::SocketServerScope ss_scope_;
 
347
  cricket::TestStunServer stun_server_;
 
348
  talk_base::FakeNetworkManager network_manager_;
 
349
  cricket::BasicPortAllocator allocator_;
 
350
  FakeMediaStreamSignaling mediastream_signaling_;
 
351
  talk_base::scoped_ptr<WebRtcSessionForTest> session_;
 
352
  MockCandidateObserver observer_;
 
353
  cricket::FakeVideoMediaChannel* video_channel_;
 
354
  cricket::FakeVoiceMediaChannel* voice_channel_;
 
355
};
 
356
 
 
357
TEST_F(WebRtcSessionTest, TestInitialize) {
 
358
  WebRtcSessionTest::Init();
 
359
  EXPECT_TRUE(ChannelsExist());
 
360
  CheckTransportChannels();
 
361
}
 
362
 
 
363
TEST_F(WebRtcSessionTest, TestSessionCandidates) {
 
364
  AddInterface(kClientAddr1);
 
365
  WebRtcSessionTest::Init();
 
366
  WebRtcSessionTest::InitiateCall();
 
367
  EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
 
368
  EXPECT_EQ(4u, observer_.mline_0_candidates_.size());
 
369
  EXPECT_EQ(4u, observer_.mline_1_candidates_.size());
 
370
}
 
371
 
 
372
TEST_F(WebRtcSessionTest, TestMultihomeCandidataes) {
 
373
  AddInterface(kClientAddr1);
 
374
  AddInterface(kClientAddr2);
 
375
  WebRtcSessionTest::Init();
 
376
  WebRtcSessionTest::InitiateCall();
 
377
  EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
 
378
  EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
 
379
  EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
 
380
}
 
381
 
 
382
TEST_F(WebRtcSessionTest, TestStunError) {
 
383
  AddInterface(kClientAddr1);
 
384
  AddInterface(kClientAddr2);
 
385
  fss_->AddRule(false, talk_base::FP_UDP, talk_base::FD_ANY, kClientAddr1);
 
386
  WebRtcSessionTest::Init();
 
387
  WebRtcSessionTest::InitiateCall();
 
388
  // Since kClientAddr1 is blocked, not expecting stun candidates for it.
 
389
  EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
 
390
  EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
 
391
  EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
 
392
}
 
393
 
 
394
// Test creating offers and receive answers and make sure the
 
395
// media engine creates the expected send and receive streams.
 
396
TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswer) {
 
397
  WebRtcSessionTest::Init();
 
398
  mediastream_signaling_.UseOptionsWithStream1();
 
399
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
400
 
 
401
  mediastream_signaling_.UseOptionsWithStream2();
 
402
  SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
 
403
                                                               offer);
 
404
  // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
 
405
  // and answer.
 
406
  EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
 
407
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kAnswer, answer));
 
408
 
 
409
  ASSERT_EQ(1u, video_channel_->recv_streams().size());
 
410
  EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].name);
 
411
 
 
412
  ASSERT_EQ(1u, voice_channel_->recv_streams().size());
 
413
  EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].name);
 
414
 
 
415
  ASSERT_EQ(1u, video_channel_->send_streams().size());
 
416
  EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].name);
 
417
  ASSERT_EQ(1u, voice_channel_->send_streams().size());
 
418
  EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].name);
 
419
 
 
420
  // Create new offer without send streams.
 
421
  mediastream_signaling_.UseOptionsReceiveOnly();
 
422
  offer = session_->CreateOffer(MediaHints());
 
423
 
 
424
  EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
 
425
 
 
426
  mediastream_signaling_.UseOptionsWithStream2();
 
427
  answer = session_->CreateAnswer(MediaHints(), offer);
 
428
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kAnswer, answer));
 
429
 
 
430
  EXPECT_EQ(0u, video_channel_->send_streams().size());
 
431
  EXPECT_EQ(0u, voice_channel_->send_streams().size());
 
432
 
 
433
  // Make sure the receive streams have not changed.
 
434
  ASSERT_EQ(1u, video_channel_->recv_streams().size());
 
435
  EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].name);
 
436
  ASSERT_EQ(1u, voice_channel_->recv_streams().size());
 
437
  EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].name);
 
438
}
 
439
 
 
440
// Test receiving offers and creating answers and make sure the
 
441
// media engine creates the expected send and receive streams.
 
442
TEST_F(WebRtcSessionTest, TestReceiveOfferCreateAnswer) {
 
443
  WebRtcSessionTest::Init();
 
444
  mediastream_signaling_.UseOptionsWithStream2();
 
445
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
446
 
 
447
  mediastream_signaling_.UseOptionsWithStream1();
 
448
  SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
 
449
                                                               offer);
 
450
 
 
451
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
452
  EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
 
453
 
 
454
  ASSERT_EQ(1u, video_channel_->recv_streams().size());
 
455
  EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].name);
 
456
 
 
457
  ASSERT_EQ(1u, voice_channel_->recv_streams().size());
 
458
  EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].name);
 
459
 
 
460
  ASSERT_EQ(1u, video_channel_->send_streams().size());
 
461
  EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].name);
 
462
  ASSERT_EQ(1u, voice_channel_->send_streams().size());
 
463
  EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].name);
 
464
 
 
465
  mediastream_signaling_.UseOptionsWithStream1And2();
 
466
  offer = session_->CreateOffer(MediaHints());
 
467
 
 
468
  // Answer by turning off all send streams.
 
469
  mediastream_signaling_.UseOptionsReceiveOnly();
 
470
  answer = session_->CreateAnswer(MediaHints(), offer);
 
471
 
 
472
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
473
  EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
 
474
 
 
475
  ASSERT_EQ(2u, video_channel_->recv_streams().size());
 
476
  EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].name);
 
477
  EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].name);
 
478
  ASSERT_EQ(2u, voice_channel_->recv_streams().size());
 
479
  EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].name);
 
480
  EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].name);
 
481
 
 
482
  // Make sure we have no send streams.
 
483
  EXPECT_EQ(0u, video_channel_->send_streams().size());
 
484
  EXPECT_EQ(0u, voice_channel_->send_streams().size());
 
485
}
 
486
 
 
487
TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
 
488
  WebRtcSessionTest::Init();
 
489
  mediastream_signaling_.UseOptionsReceiveOnly();
 
490
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
491
 
 
492
  EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
 
493
  EXPECT_FALSE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
 
494
}
 
495
 
 
496
TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
 
497
  WebRtcSessionTest::Init();
 
498
  mediastream_signaling_.UseOptionsReceiveOnly();
 
499
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
500
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
501
  EXPECT_FALSE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
502
}
 
503
 
 
504
TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
 
505
  WebRtcSessionTest::Init();
 
506
  mediastream_signaling_.UseOptionsReceiveOnly();
 
507
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
508
  EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
 
509
  EXPECT_FALSE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
510
}
 
511
 
 
512
TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
 
513
  WebRtcSessionTest::Init();
 
514
  mediastream_signaling_.UseOptionsReceiveOnly();
 
515
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
516
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
517
  EXPECT_FALSE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
 
518
}
 
519
 
 
520
TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
 
521
  WebRtcSessionTest::Init();
 
522
  mediastream_signaling_.UseOptionsReceiveOnly();
 
523
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
524
  SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
 
525
                                                               offer);
 
526
  EXPECT_FALSE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
 
527
}
 
528
 
 
529
TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
 
530
  WebRtcSessionTest::Init();
 
531
  mediastream_signaling_.UseOptionsReceiveOnly();
 
532
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
533
  SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
 
534
                                                               offer);
 
535
  EXPECT_FALSE(session_->SetRemoteDescription(JsepInterface::kAnswer, answer));
 
536
}
 
537
 
 
538
TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
 
539
  WebRtcSessionTest::Init();
 
540
 
 
541
  cricket::Candidate candidate1;
 
542
  candidate1.set_name("fake_candidate1");
 
543
  JsepIceCandidate ice_candidate(talk_base::ToString(0), candidate1);
 
544
 
 
545
  // Fail since we have not set a remote description
 
546
  EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate));
 
547
 
 
548
  SetRemoteAndLocalSessionDescription();
 
549
 
 
550
  EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
 
551
 
 
552
  JsepIceCandidate bad_ice_candidate("bad content name", candidate1);
 
553
  EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
 
554
}
 
555
 
 
556
// Test that a remote candidate is added to the remote session description and
 
557
// that it is retained if the remote session description is changed.
 
558
TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
 
559
  WebRtcSessionTest::Init();
 
560
  cricket::Candidate candidate1;
 
561
  candidate1.set_name("fake_candidate1");
 
562
  JsepIceCandidate ice_candidate1(kMediaContentLabel0, candidate1);
 
563
 
 
564
  SetRemoteAndLocalSessionDescription();
 
565
  EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
 
566
 
 
567
  EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
 
568
  const SessionDescriptionInterface* remote_desc =
 
569
      session_->remote_description();
 
570
  ASSERT_TRUE(remote_desc != NULL);
 
571
  ASSERT_EQ(2u, remote_desc->number_of_mediasections());
 
572
  const IceCandidateColletion* candidates =
 
573
      remote_desc->candidates(kMediaContentIndex0);
 
574
  ASSERT_EQ(1u, candidates->count());
 
575
  EXPECT_EQ(kMediaContentLabel0, candidates->at(0)->label());
 
576
 
 
577
  // Update the RemoteSessionDescription with a new session description and
 
578
  // a candidate and check that the new remote session description contains both
 
579
  // candidates.
 
580
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
581
  cricket::Candidate candidate2;
 
582
  candidate2.set_name("fake_candidate2");
 
583
  JsepIceCandidate ice_candidate2(kMediaContentLabel0, candidate2);
 
584
  EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
 
585
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
586
 
 
587
  remote_desc = session_->remote_description();
 
588
  ASSERT_TRUE(remote_desc != NULL);
 
589
  ASSERT_EQ(2u, remote_desc->number_of_mediasections());
 
590
  candidates = remote_desc->candidates(kMediaContentIndex0);
 
591
  ASSERT_EQ(2u, candidates->count());
 
592
  EXPECT_EQ(kMediaContentLabel0, candidates->at(0)->label());
 
593
  EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
 
594
  EXPECT_EQ(kMediaContentLabel0, candidates->at(1)->label());
 
595
  EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
 
596
 
 
597
  // Test that the candidate is ignored if we can add the same candidate again.
 
598
  EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
 
599
}
 
600
 
 
601
// Test that local candidates are added to the local session description and
 
602
// that they are retained if the local session description is changed.
 
603
TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
 
604
  AddInterface(kClientAddr1);
 
605
  WebRtcSessionTest::Init();
 
606
  SetRemoteAndLocalSessionDescription();
 
607
 
 
608
  const SessionDescriptionInterface* local_desc = session_->local_description();
 
609
  const IceCandidateColletion* candidates =
 
610
      local_desc->candidates(kMediaContentIndex0);
 
611
  ASSERT_TRUE(candidates != NULL);
 
612
  EXPECT_EQ(0u, candidates->count());
 
613
 
 
614
  EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
 
615
  EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
 
616
 
 
617
  local_desc = session_->local_description();
 
618
  candidates = local_desc->candidates(kMediaContentIndex0);
 
619
  ASSERT_TRUE(candidates != NULL);
 
620
  EXPECT_LT(0u, candidates->count());
 
621
  candidates = local_desc->candidates(1);
 
622
  ASSERT_TRUE(candidates != NULL);
 
623
  EXPECT_LT(0u, candidates->count());
 
624
 
 
625
  // Update the session descriptions.
 
626
  mediastream_signaling_.UseOptionsWithStream1();
 
627
  SetRemoteAndLocalSessionDescription();
 
628
 
 
629
  local_desc = session_->local_description();
 
630
  candidates = local_desc->candidates(kMediaContentIndex0);
 
631
  ASSERT_TRUE(candidates != NULL);
 
632
  EXPECT_LT(0u, candidates->count());
 
633
  candidates = local_desc->candidates(1);
 
634
  ASSERT_TRUE(candidates != NULL);
 
635
  EXPECT_LT(0u, candidates->count());
 
636
}
 
637
 
 
638
// Test that we can set a remote session description with remote candidates.
 
639
TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
 
640
  WebRtcSessionTest::Init();
 
641
 
 
642
  cricket::Candidate candidate1;
 
643
  candidate1.set_name("fake_candidate1");
 
644
 
 
645
  JsepIceCandidate ice_candidate(kMediaContentLabel0, candidate1);
 
646
  mediastream_signaling_.UseOptionsReceiveOnly();
 
647
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
648
 
 
649
  EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
 
650
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kOffer, offer));
 
651
 
 
652
  const SessionDescriptionInterface* remote_desc =
 
653
      session_->remote_description();
 
654
  ASSERT_TRUE(remote_desc != NULL);
 
655
  ASSERT_EQ(2u, remote_desc->number_of_mediasections());
 
656
  const IceCandidateColletion* candidates =
 
657
      remote_desc->candidates(kMediaContentIndex0);
 
658
  ASSERT_EQ(1u, candidates->count());
 
659
  EXPECT_EQ(kMediaContentLabel0, candidates->at(0)->label());
 
660
 
 
661
  SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
 
662
                                                              remote_desc);
 
663
  EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kAnswer, answer));
 
664
  EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
 
665
  // TODO: How do I check that the transport have got the
 
666
  // remote candidates?
 
667
}
 
668
 
 
669
// Test that offers and answers contains ice canidates when Ice candidates have
 
670
// been gathered.
 
671
TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
 
672
  AddInterface(kClientAddr1);
 
673
  WebRtcSessionTest::Init();
 
674
  mediastream_signaling_.UseOptionsReceiveOnly();
 
675
  SetRemoteAndLocalSessionDescription();
 
676
  EXPECT_TRUE(session_->StartIce(JsepInterface::kUseAll));
 
677
  // Wait until at least one local candidate has been collected.
 
678
  EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
 
679
                   kIceCandidatesTimeout);
 
680
  EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
 
681
                   kIceCandidatesTimeout);
 
682
 
 
683
  SessionDescriptionInterface* offer = session_->CreateOffer(MediaHints());
 
684
  ASSERT_TRUE(offer->candidates(kMediaContentIndex0) != NULL);
 
685
  EXPECT_LT(0u, offer->candidates(kMediaContentIndex0)->count());
 
686
  ASSERT_TRUE(offer->candidates(kMediaContentIndex1) != NULL);
 
687
  EXPECT_LT(0u, offer->candidates(kMediaContentIndex1)->count());
 
688
 
 
689
  SessionDescriptionInterface* answer = session_->CreateAnswer(MediaHints(),
 
690
                                                               offer);
 
691
  ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
 
692
  EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
 
693
  ASSERT_TRUE(answer->candidates(kMediaContentIndex1) != NULL);
 
694
  EXPECT_LT(0u, answer->candidates(kMediaContentIndex1)->count());
 
695
 
 
696
  EXPECT_TRUE(session_->SetLocalDescription(JsepInterface::kOffer, offer));
 
697
  EXPECT_TRUE(session_->SetRemoteDescription(JsepInterface::kAnswer, answer));
 
698
}
 
699
 
 
700
 
 
701
TEST_F(WebRtcSessionTest, TestDefaultSetSecurePolicy) {
 
702
  WebRtcSessionTest::Init();
 
703
  EXPECT_EQ(cricket::SEC_REQUIRED, session_->secure_policy());
 
704
}
 
705
 
 
706
TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
 
707
  WebRtcSessionTest::Init();
 
708
  mediastream_signaling_.UseOptionsWithStream1();
 
709
  scoped_ptr<SessionDescriptionInterface> offer(
 
710
      session_->CreateOffer(MediaHints()));
 
711
  VerifyCryptoParams(offer->description(), true);
 
712
}
 
713
 
 
714
TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
 
715
  WebRtcSessionTest::Init();
 
716
  session_->set_secure_policy(cricket::SEC_DISABLED);
 
717
  mediastream_signaling_.UseOptionsWithStream1();
 
718
  scoped_ptr<SessionDescriptionInterface> offer(
 
719
        session_->CreateOffer(MediaHints()));
 
720
  VerifyNoCryptoParams(offer->description());
 
721
}
 
722
 
 
723
TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
 
724
  WebRtcSessionTest::Init();
 
725
  VerifyAnswerFromNonCryptoOffer();
 
726
}
 
727
 
 
728
TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
 
729
  WebRtcSessionTest::Init();
 
730
  VerifyAnswerFromCryptoOffer();
 
731
}