blob: 73a659b134a28f8dcceb73cb3d9eeec16c7396f2 [file] [log] [blame]
Steve Anton8d3444d2017-10-20 15:30:51 -07001/*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// This file contains tests that check the PeerConnection's signaling state
12// machine, as well as tests that check basic, media-agnostic aspects of SDP.
13
14#include <tuple>
15
16#include "api/audio_codecs/builtin_audio_decoder_factory.h"
17#include "api/audio_codecs/builtin_audio_encoder_factory.h"
18#include "api/peerconnectionproxy.h"
Anders Carlsson67537952018-05-03 11:28:29 +020019#include "api/video_codecs/builtin_video_decoder_factory.h"
20#include "api/video_codecs/builtin_video_encoder_factory.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070021#include "pc/peerconnection.h"
22#include "pc/peerconnectionwrapper.h"
23#include "pc/sdputils.h"
24#ifdef WEBRTC_ANDROID
25#include "pc/test/androidtestinitializer.h"
26#endif
27#include "pc/test/fakeaudiocapturemodule.h"
28#include "pc/test/fakertccertificategenerator.h"
29#include "rtc_base/gunit.h"
30#include "rtc_base/ptr_util.h"
31#include "rtc_base/stringutils.h"
32#include "rtc_base/virtualsocketserver.h"
33#include "test/gmock.h"
34
35namespace webrtc {
36
37using SignalingState = PeerConnectionInterface::SignalingState;
38using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
39using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
40using ::testing::Bool;
41using ::testing::Combine;
42using ::testing::Values;
43
44class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
45 public:
46 using PeerConnectionWrapper::PeerConnectionWrapper;
47
48 bool initial_offerer() {
49 return GetInternalPeerConnection()->initial_offerer();
50 }
51
52 PeerConnection* GetInternalPeerConnection() {
Mirko Bonadeie97de912017-12-13 11:29:34 +010053 auto* pci =
54 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
55 pc());
56 return static_cast<PeerConnection*>(pci->internal());
Steve Anton8d3444d2017-10-20 15:30:51 -070057 }
58};
59
Steve Anton8acdd1a2018-02-07 17:27:36 -080060class PeerConnectionSignalingBaseTest : public ::testing::Test {
Steve Anton8d3444d2017-10-20 15:30:51 -070061 protected:
62 typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;
63
Steve Anton8acdd1a2018-02-07 17:27:36 -080064 explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
65 : vss_(new rtc::VirtualSocketServer()),
66 main_(vss_.get()),
67 sdp_semantics_(sdp_semantics) {
Steve Anton8d3444d2017-10-20 15:30:51 -070068#ifdef WEBRTC_ANDROID
69 InitializeAndroidObjects();
70#endif
71 pc_factory_ = CreatePeerConnectionFactory(
72 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
Anders Carlsson67537952018-05-03 11:28:29 +020073 rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
74 CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
75 CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
76 nullptr /* audio_mixer */, nullptr /* audio_processing */);
Steve Anton8d3444d2017-10-20 15:30:51 -070077 }
78
79 WrapperPtr CreatePeerConnection() {
80 return CreatePeerConnection(RTCConfiguration());
81 }
82
83 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
84 auto observer = rtc::MakeUnique<MockPeerConnectionObserver>();
Steve Anton8acdd1a2018-02-07 17:27:36 -080085 RTCConfiguration modified_config = config;
86 modified_config.sdp_semantics = sdp_semantics_;
87 auto pc = pc_factory_->CreatePeerConnection(modified_config, nullptr,
88 nullptr, observer.get());
Steve Anton8d3444d2017-10-20 15:30:51 -070089 if (!pc) {
90 return nullptr;
91 }
92
93 return rtc::MakeUnique<PeerConnectionWrapperForSignalingTest>(
94 pc_factory_, pc, std::move(observer));
95 }
96
97 // Accepts the same arguments as CreatePeerConnection and adds default audio
98 // and video tracks.
99 template <typename... Args>
100 WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
101 auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
102 if (!wrapper) {
103 return nullptr;
104 }
105 wrapper->AddAudioTrack("a");
106 wrapper->AddVideoTrack("v");
107 return wrapper;
108 }
109
110 std::unique_ptr<rtc::VirtualSocketServer> vss_;
111 rtc::AutoSocketServerThread main_;
112 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
Steve Anton8acdd1a2018-02-07 17:27:36 -0800113 const SdpSemantics sdp_semantics_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700114};
115
Steve Anton8acdd1a2018-02-07 17:27:36 -0800116class PeerConnectionSignalingTest
117 : public PeerConnectionSignalingBaseTest,
118 public ::testing::WithParamInterface<SdpSemantics> {
119 protected:
120 PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
121};
122
123TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700124 auto caller = CreatePeerConnection();
125
126 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
127 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
128}
129
Steve Anton8acdd1a2018-02-07 17:27:36 -0800130TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700131 auto caller = CreatePeerConnection();
132 auto callee = CreatePeerConnection();
133
134 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
135 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
136}
137
Steve Anton8acdd1a2018-02-07 17:27:36 -0800138TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700139 auto caller = CreatePeerConnection();
140 std::string error;
141 ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
142 EXPECT_EQ("SessionDescription is NULL.", error);
143}
144
Steve Anton8acdd1a2018-02-07 17:27:36 -0800145TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700146 auto caller = CreatePeerConnection();
147 std::string error;
148 ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
149 EXPECT_EQ("SessionDescription is NULL.", error);
150}
151
152// The following parameterized test verifies that calls to various signaling
153// methods on PeerConnection will succeed/fail depending on what is the
154// PeerConnection's signaling state. Note that the test tries many different
155// forms of SignalingState::kClosed by arriving at a valid state then calling
156// |Close()|. This is intended to catch cases where the PeerConnection signaling
157// method ignores the closed flag but may work/not work because of the single
158// state the PeerConnection was created in before it was closed.
159
160class PeerConnectionSignalingStateTest
Steve Anton8acdd1a2018-02-07 17:27:36 -0800161 : public PeerConnectionSignalingBaseTest,
162 public ::testing::WithParamInterface<
163 std::tuple<SdpSemantics, SignalingState, bool>> {
Steve Anton8d3444d2017-10-20 15:30:51 -0700164 protected:
Steve Anton8acdd1a2018-02-07 17:27:36 -0800165 PeerConnectionSignalingStateTest()
166 : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
167 state_under_test_(std::make_tuple(std::get<1>(GetParam()),
168 std::get<2>(GetParam()))) {}
169
Steve Anton8d3444d2017-10-20 15:30:51 -0700170 RTCConfiguration GetConfig() {
171 RTCConfiguration config;
172 config.certificates.push_back(
173 FakeRTCCertificateGenerator::GenerateCertificate());
174 return config;
175 }
176
Steve Anton8acdd1a2018-02-07 17:27:36 -0800177 WrapperPtr CreatePeerConnectionUnderTest() {
178 return CreatePeerConnectionInState(state_under_test_);
179 }
180
Steve Anton8d3444d2017-10-20 15:30:51 -0700181 WrapperPtr CreatePeerConnectionInState(SignalingState state) {
182 return CreatePeerConnectionInState(std::make_tuple(state, false));
183 }
184
185 WrapperPtr CreatePeerConnectionInState(
186 std::tuple<SignalingState, bool> state_tuple) {
187 SignalingState state = std::get<0>(state_tuple);
188 bool closed = std::get<1>(state_tuple);
189
190 auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
191 switch (state) {
192 case SignalingState::kStable: {
193 break;
194 }
195 case SignalingState::kHaveLocalOffer: {
196 wrapper->SetLocalDescription(wrapper->CreateOffer());
197 break;
198 }
199 case SignalingState::kHaveLocalPrAnswer: {
200 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
201 wrapper->SetRemoteDescription(caller->CreateOffer());
202 auto answer = wrapper->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800203 wrapper->SetLocalDescription(
204 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700205 break;
206 }
207 case SignalingState::kHaveRemoteOffer: {
208 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
209 wrapper->SetRemoteDescription(caller->CreateOffer());
210 break;
211 }
212 case SignalingState::kHaveRemotePrAnswer: {
213 auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
214 callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
215 auto answer = callee->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800216 wrapper->SetRemoteDescription(
217 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700218 break;
219 }
220 case SignalingState::kClosed: {
221 RTC_NOTREACHED() << "Set the second member of the tuple to true to "
222 "achieve a closed state from an existing, valid "
223 "state.";
224 }
225 }
226
227 RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());
228
229 if (closed) {
230 wrapper->pc()->Close();
231 RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
232 }
233
234 return wrapper;
235 }
Steve Anton8acdd1a2018-02-07 17:27:36 -0800236
237 std::tuple<SignalingState, bool> state_under_test_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700238};
239
Steve Anton8d3444d2017-10-20 15:30:51 -0700240TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800241 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700242 if (wrapper->signaling_state() != SignalingState::kClosed) {
243 EXPECT_TRUE(wrapper->CreateOffer());
244 } else {
245 std::string error;
246 ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
247 EXPECT_PRED_FORMAT2(AssertStartsWith, error,
248 "CreateOffer called when PeerConnection is closed.");
249 }
250}
251
252TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800253 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700254 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
255 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
256 EXPECT_TRUE(wrapper->CreateAnswer());
257 } else {
258 std::string error;
259 ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
Steve Antondffead82018-02-06 10:31:29 -0800260 EXPECT_EQ(error,
261 "PeerConnection cannot create an answer in a state other than "
262 "have-remote-offer or have-local-pranswer.");
Steve Anton8d3444d2017-10-20 15:30:51 -0700263 }
264}
265
266TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800267 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700268 if (wrapper->signaling_state() == SignalingState::kStable ||
269 wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
270 // Need to call CreateOffer on the PeerConnection under test, otherwise when
271 // setting the local offer it will want to verify the DTLS fingerprint
272 // against the locally generated certificate, but without a call to
273 // CreateOffer the certificate will never be generated.
274 EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
275 } else {
276 auto wrapper_for_offer =
277 CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
278 auto offer =
279 CloneSessionDescription(wrapper_for_offer->pc()->local_description());
280
281 std::string error;
282 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
283 EXPECT_PRED_FORMAT2(
284 AssertStartsWith, error,
285 "Failed to set local offer sdp: Called in wrong state:");
286 }
287}
288
289TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
290 auto wrapper_for_pranswer =
291 CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
292 auto pranswer =
293 CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
294
Steve Anton8acdd1a2018-02-07 17:27:36 -0800295 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700296 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
297 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
298 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
299 } else {
300 std::string error;
301 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
302 EXPECT_PRED_FORMAT2(
303 AssertStartsWith, error,
304 "Failed to set local pranswer sdp: Called in wrong state:");
305 }
306}
307
308TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
309 auto wrapper_for_answer =
310 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
311 auto answer = wrapper_for_answer->CreateAnswer();
312
Steve Anton8acdd1a2018-02-07 17:27:36 -0800313 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700314 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
315 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
316 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
317 } else {
318 std::string error;
319 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
320 EXPECT_PRED_FORMAT2(
321 AssertStartsWith, error,
322 "Failed to set local answer sdp: Called in wrong state:");
323 }
324}
325
326TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
327 auto wrapper_for_offer =
328 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
329 auto offer =
330 CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
331
Steve Anton8acdd1a2018-02-07 17:27:36 -0800332 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700333 if (wrapper->signaling_state() == SignalingState::kStable ||
334 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
335 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
336 } else {
337 std::string error;
338 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
339 EXPECT_PRED_FORMAT2(
340 AssertStartsWith, error,
341 "Failed to set remote offer sdp: Called in wrong state:");
342 }
343}
344
345TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
346 auto wrapper_for_pranswer =
347 CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
348 auto pranswer =
349 CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
350
Steve Anton8acdd1a2018-02-07 17:27:36 -0800351 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700352 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
353 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
354 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
355 } else {
356 std::string error;
357 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
358 EXPECT_PRED_FORMAT2(
359 AssertStartsWith, error,
360 "Failed to set remote pranswer sdp: Called in wrong state:");
361 }
362}
363
364TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
365 auto wrapper_for_answer =
366 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
367 auto answer = wrapper_for_answer->CreateAnswer();
368
Steve Anton8acdd1a2018-02-07 17:27:36 -0800369 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700370 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
371 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
372 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
373 } else {
374 std::string error;
375 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
376 EXPECT_PRED_FORMAT2(
377 AssertStartsWith, error,
378 "Failed to set remote answer sdp: Called in wrong state:");
379 }
380}
381
382INSTANTIATE_TEST_CASE_P(PeerConnectionSignalingTest,
383 PeerConnectionSignalingStateTest,
Steve Anton8acdd1a2018-02-07 17:27:36 -0800384 Combine(Values(SdpSemantics::kPlanB,
385 SdpSemantics::kUnifiedPlan),
386 Values(SignalingState::kStable,
Steve Anton8d3444d2017-10-20 15:30:51 -0700387 SignalingState::kHaveLocalOffer,
388 SignalingState::kHaveLocalPrAnswer,
389 SignalingState::kHaveRemoteOffer,
390 SignalingState::kHaveRemotePrAnswer),
391 Bool()));
392
Steve Antondffead82018-02-06 10:31:29 -0800393// Test that CreateAnswer fails if a round of offer/answer has been done and
394// the PeerConnection is in the stable state.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800395TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700396 auto caller = CreatePeerConnection();
397 auto callee = CreatePeerConnection();
398
Steve Antondffead82018-02-06 10:31:29 -0800399 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Oleh Prypinc22d6a82018-02-02 08:42:18 +0000400
401 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
Steve Antondffead82018-02-06 10:31:29 -0800402 EXPECT_FALSE(caller->CreateAnswer());
403
404 ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
405 EXPECT_FALSE(callee->CreateAnswer());
Steve Anton8d3444d2017-10-20 15:30:51 -0700406}
407
408// According to https://tools.ietf.org/html/rfc3264#section-8, the session id
409// stays the same but the version must be incremented if a later, different
410// session description is generated. These two tests verify that is the case for
411// both offers and answers.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800412TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700413 SessionVersionIncrementedInSubsequentDifferentOffer) {
414 auto caller = CreatePeerConnection();
415 auto callee = CreatePeerConnection();
416
417 auto original_offer = caller->CreateOfferAndSetAsLocal();
418 const std::string original_id = original_offer->session_id();
419 const std::string original_version = original_offer->session_version();
420
421 ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
422 ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
423
424 // Add track to get a different offer.
425 caller->AddAudioTrack("a");
426
427 auto later_offer = caller->CreateOffer();
428
429 EXPECT_EQ(original_id, later_offer->session_id());
430 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
431 rtc::FromString<uint64_t>(later_offer->session_version()));
432}
Steve Anton8acdd1a2018-02-07 17:27:36 -0800433TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700434 SessionVersionIncrementedInSubsequentDifferentAnswer) {
435 auto caller = CreatePeerConnection();
436 auto callee = CreatePeerConnection();
437
438 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
439
Steve Antondffead82018-02-06 10:31:29 -0800440 auto original_answer = callee->CreateAnswer();
Steve Anton8d3444d2017-10-20 15:30:51 -0700441 const std::string original_id = original_answer->session_id();
442 const std::string original_version = original_answer->session_version();
443
444 // Add track to get a different answer.
445 callee->AddAudioTrack("a");
446
447 auto later_answer = callee->CreateAnswer();
448
449 EXPECT_EQ(original_id, later_answer->session_id());
450 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
451 rtc::FromString<uint64_t>(later_answer->session_version()));
452}
453
Steve Anton8acdd1a2018-02-07 17:27:36 -0800454TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700455 auto caller = CreatePeerConnectionWithAudioVideo();
456 auto callee = CreatePeerConnectionWithAudioVideo();
457
458 EXPECT_FALSE(caller->initial_offerer());
459 EXPECT_FALSE(callee->initial_offerer());
460
461 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
462
463 EXPECT_TRUE(caller->initial_offerer());
464 EXPECT_FALSE(callee->initial_offerer());
465
466 ASSERT_TRUE(
467 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
468
469 EXPECT_TRUE(caller->initial_offerer());
470 EXPECT_FALSE(callee->initial_offerer());
471}
472
473// Test creating a PeerConnection, request multiple offers, destroy the
474// PeerConnection and make sure we get success/failure callbacks for all of the
475// requests.
476// Background: crbug.com/507307
Steve Anton8acdd1a2018-02-07 17:27:36 -0800477TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700478 auto caller = CreatePeerConnection();
479
480 RTCOfferAnswerOptions options;
481 options.offer_to_receive_audio =
482 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
483
484 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
485 for (auto& observer : observers) {
486 observer =
487 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
488 caller->pc()->CreateOffer(observer, options);
489 }
490
491 // Destroy the PeerConnection.
492 caller.reset(nullptr);
493
494 for (auto& observer : observers) {
495 // We expect to have received a notification now even if the PeerConnection
496 // was terminated. The offer creation may or may not have succeeded, but we
497 // must have received a notification.
498 EXPECT_TRUE(observer->called());
499 }
500}
501
Steve Anton8acdd1a2018-02-07 17:27:36 -0800502INSTANTIATE_TEST_CASE_P(PeerConnectionSignalingTest,
503 PeerConnectionSignalingTest,
504 Values(SdpSemantics::kPlanB,
505 SdpSemantics::kUnifiedPlan));
506
Steve Anton8d3444d2017-10-20 15:30:51 -0700507} // namespace webrtc