blob: f57f806b647f01339fbb0252cc1071ea3a242d4a [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"
Mirko Bonadei2ff3f492018-11-22 09:00:13 +010018#include "api/create_peerconnection_factory.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070019#include "api/peerconnectionproxy.h"
Anders Carlsson67537952018-05-03 11:28:29 +020020#include "api/video_codecs/builtin_video_decoder_factory.h"
21#include "api/video_codecs/builtin_video_encoder_factory.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070022#include "pc/peerconnection.h"
23#include "pc/peerconnectionwrapper.h"
24#include "pc/sdputils.h"
25#ifdef WEBRTC_ANDROID
26#include "pc/test/androidtestinitializer.h"
27#endif
Karl Wiberg918f50c2018-07-05 11:40:33 +020028#include "absl/memory/memory.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070029#include "pc/test/fakeaudiocapturemodule.h"
30#include "pc/test/fakertccertificategenerator.h"
31#include "rtc_base/gunit.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070032#include "rtc_base/stringutils.h"
33#include "rtc_base/virtualsocketserver.h"
34#include "test/gmock.h"
35
36namespace webrtc {
37
38using SignalingState = PeerConnectionInterface::SignalingState;
39using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
40using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
41using ::testing::Bool;
42using ::testing::Combine;
43using ::testing::Values;
44
45class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
46 public:
47 using PeerConnectionWrapper::PeerConnectionWrapper;
48
49 bool initial_offerer() {
50 return GetInternalPeerConnection()->initial_offerer();
51 }
52
53 PeerConnection* GetInternalPeerConnection() {
Mirko Bonadeie97de912017-12-13 11:29:34 +010054 auto* pci =
55 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
56 pc());
57 return static_cast<PeerConnection*>(pci->internal());
Steve Anton8d3444d2017-10-20 15:30:51 -070058 }
59};
60
Steve Anton8acdd1a2018-02-07 17:27:36 -080061class PeerConnectionSignalingBaseTest : public ::testing::Test {
Steve Anton8d3444d2017-10-20 15:30:51 -070062 protected:
63 typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;
64
Steve Anton8acdd1a2018-02-07 17:27:36 -080065 explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
66 : vss_(new rtc::VirtualSocketServer()),
67 main_(vss_.get()),
68 sdp_semantics_(sdp_semantics) {
Steve Anton8d3444d2017-10-20 15:30:51 -070069#ifdef WEBRTC_ANDROID
70 InitializeAndroidObjects();
71#endif
72 pc_factory_ = CreatePeerConnectionFactory(
73 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
Anders Carlsson67537952018-05-03 11:28:29 +020074 rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
75 CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
76 CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
77 nullptr /* audio_mixer */, nullptr /* audio_processing */);
Steve Anton8d3444d2017-10-20 15:30:51 -070078 }
79
80 WrapperPtr CreatePeerConnection() {
81 return CreatePeerConnection(RTCConfiguration());
82 }
83
84 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
Karl Wiberg918f50c2018-07-05 11:40:33 +020085 auto observer = absl::make_unique<MockPeerConnectionObserver>();
Steve Anton8acdd1a2018-02-07 17:27:36 -080086 RTCConfiguration modified_config = config;
87 modified_config.sdp_semantics = sdp_semantics_;
88 auto pc = pc_factory_->CreatePeerConnection(modified_config, nullptr,
89 nullptr, observer.get());
Steve Anton8d3444d2017-10-20 15:30:51 -070090 if (!pc) {
91 return nullptr;
92 }
93
Yves Gerey4e933292018-10-31 15:36:05 +010094 observer->SetPeerConnectionInterface(pc.get());
Karl Wiberg918f50c2018-07-05 11:40:33 +020095 return absl::make_unique<PeerConnectionWrapperForSignalingTest>(
Steve Anton8d3444d2017-10-20 15:30:51 -070096 pc_factory_, pc, std::move(observer));
97 }
98
99 // Accepts the same arguments as CreatePeerConnection and adds default audio
100 // and video tracks.
101 template <typename... Args>
102 WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
103 auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
104 if (!wrapper) {
105 return nullptr;
106 }
107 wrapper->AddAudioTrack("a");
108 wrapper->AddVideoTrack("v");
109 return wrapper;
110 }
111
112 std::unique_ptr<rtc::VirtualSocketServer> vss_;
113 rtc::AutoSocketServerThread main_;
114 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
Steve Anton8acdd1a2018-02-07 17:27:36 -0800115 const SdpSemantics sdp_semantics_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700116};
117
Steve Anton8acdd1a2018-02-07 17:27:36 -0800118class PeerConnectionSignalingTest
119 : public PeerConnectionSignalingBaseTest,
120 public ::testing::WithParamInterface<SdpSemantics> {
121 protected:
122 PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
123};
124
125TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700126 auto caller = CreatePeerConnection();
127
128 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
129 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
130}
131
Steve Anton8acdd1a2018-02-07 17:27:36 -0800132TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700133 auto caller = CreatePeerConnection();
134 auto callee = CreatePeerConnection();
135
136 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
137 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
138}
139
Steve Anton8acdd1a2018-02-07 17:27:36 -0800140TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700141 auto caller = CreatePeerConnection();
142 std::string error;
143 ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
144 EXPECT_EQ("SessionDescription is NULL.", error);
145}
146
Steve Anton8acdd1a2018-02-07 17:27:36 -0800147TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700148 auto caller = CreatePeerConnection();
149 std::string error;
150 ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
151 EXPECT_EQ("SessionDescription is NULL.", error);
152}
153
154// The following parameterized test verifies that calls to various signaling
155// methods on PeerConnection will succeed/fail depending on what is the
156// PeerConnection's signaling state. Note that the test tries many different
157// forms of SignalingState::kClosed by arriving at a valid state then calling
158// |Close()|. This is intended to catch cases where the PeerConnection signaling
159// method ignores the closed flag but may work/not work because of the single
160// state the PeerConnection was created in before it was closed.
161
162class PeerConnectionSignalingStateTest
Steve Anton8acdd1a2018-02-07 17:27:36 -0800163 : public PeerConnectionSignalingBaseTest,
164 public ::testing::WithParamInterface<
165 std::tuple<SdpSemantics, SignalingState, bool>> {
Steve Anton8d3444d2017-10-20 15:30:51 -0700166 protected:
Steve Anton8acdd1a2018-02-07 17:27:36 -0800167 PeerConnectionSignalingStateTest()
168 : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
169 state_under_test_(std::make_tuple(std::get<1>(GetParam()),
170 std::get<2>(GetParam()))) {}
171
Steve Anton8d3444d2017-10-20 15:30:51 -0700172 RTCConfiguration GetConfig() {
173 RTCConfiguration config;
174 config.certificates.push_back(
175 FakeRTCCertificateGenerator::GenerateCertificate());
176 return config;
177 }
178
Steve Anton8acdd1a2018-02-07 17:27:36 -0800179 WrapperPtr CreatePeerConnectionUnderTest() {
180 return CreatePeerConnectionInState(state_under_test_);
181 }
182
Steve Anton8d3444d2017-10-20 15:30:51 -0700183 WrapperPtr CreatePeerConnectionInState(SignalingState state) {
184 return CreatePeerConnectionInState(std::make_tuple(state, false));
185 }
186
187 WrapperPtr CreatePeerConnectionInState(
188 std::tuple<SignalingState, bool> state_tuple) {
189 SignalingState state = std::get<0>(state_tuple);
190 bool closed = std::get<1>(state_tuple);
191
192 auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
193 switch (state) {
194 case SignalingState::kStable: {
195 break;
196 }
197 case SignalingState::kHaveLocalOffer: {
198 wrapper->SetLocalDescription(wrapper->CreateOffer());
199 break;
200 }
201 case SignalingState::kHaveLocalPrAnswer: {
202 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
203 wrapper->SetRemoteDescription(caller->CreateOffer());
204 auto answer = wrapper->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800205 wrapper->SetLocalDescription(
206 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700207 break;
208 }
209 case SignalingState::kHaveRemoteOffer: {
210 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
211 wrapper->SetRemoteDescription(caller->CreateOffer());
212 break;
213 }
214 case SignalingState::kHaveRemotePrAnswer: {
215 auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
216 callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
217 auto answer = callee->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800218 wrapper->SetRemoteDescription(
219 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700220 break;
221 }
222 case SignalingState::kClosed: {
223 RTC_NOTREACHED() << "Set the second member of the tuple to true to "
224 "achieve a closed state from an existing, valid "
225 "state.";
226 }
227 }
228
229 RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());
230
231 if (closed) {
232 wrapper->pc()->Close();
233 RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
234 }
235
236 return wrapper;
237 }
Steve Anton8acdd1a2018-02-07 17:27:36 -0800238
239 std::tuple<SignalingState, bool> state_under_test_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700240};
241
Steve Anton8d3444d2017-10-20 15:30:51 -0700242TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800243 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700244 if (wrapper->signaling_state() != SignalingState::kClosed) {
245 EXPECT_TRUE(wrapper->CreateOffer());
246 } else {
247 std::string error;
248 ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
249 EXPECT_PRED_FORMAT2(AssertStartsWith, error,
250 "CreateOffer called when PeerConnection is closed.");
251 }
252}
253
254TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800255 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700256 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
257 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
258 EXPECT_TRUE(wrapper->CreateAnswer());
259 } else {
260 std::string error;
261 ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
Steve Antondffead82018-02-06 10:31:29 -0800262 EXPECT_EQ(error,
263 "PeerConnection cannot create an answer in a state other than "
264 "have-remote-offer or have-local-pranswer.");
Steve Anton8d3444d2017-10-20 15:30:51 -0700265 }
266}
267
268TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800269 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700270 if (wrapper->signaling_state() == SignalingState::kStable ||
271 wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
272 // Need to call CreateOffer on the PeerConnection under test, otherwise when
273 // setting the local offer it will want to verify the DTLS fingerprint
274 // against the locally generated certificate, but without a call to
275 // CreateOffer the certificate will never be generated.
276 EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
277 } else {
278 auto wrapper_for_offer =
279 CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
280 auto offer =
281 CloneSessionDescription(wrapper_for_offer->pc()->local_description());
282
283 std::string error;
284 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
285 EXPECT_PRED_FORMAT2(
286 AssertStartsWith, error,
287 "Failed to set local offer sdp: Called in wrong state:");
288 }
289}
290
291TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
292 auto wrapper_for_pranswer =
293 CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
294 auto pranswer =
295 CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
296
Steve Anton8acdd1a2018-02-07 17:27:36 -0800297 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700298 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
299 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
300 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
301 } else {
302 std::string error;
303 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
304 EXPECT_PRED_FORMAT2(
305 AssertStartsWith, error,
306 "Failed to set local pranswer sdp: Called in wrong state:");
307 }
308}
309
310TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
311 auto wrapper_for_answer =
312 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
313 auto answer = wrapper_for_answer->CreateAnswer();
314
Steve Anton8acdd1a2018-02-07 17:27:36 -0800315 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700316 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
317 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
318 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
319 } else {
320 std::string error;
321 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
322 EXPECT_PRED_FORMAT2(
323 AssertStartsWith, error,
324 "Failed to set local answer sdp: Called in wrong state:");
325 }
326}
327
328TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
329 auto wrapper_for_offer =
330 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
331 auto offer =
332 CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
333
Steve Anton8acdd1a2018-02-07 17:27:36 -0800334 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700335 if (wrapper->signaling_state() == SignalingState::kStable ||
336 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
337 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
338 } else {
339 std::string error;
340 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
341 EXPECT_PRED_FORMAT2(
342 AssertStartsWith, error,
343 "Failed to set remote offer sdp: Called in wrong state:");
344 }
345}
346
347TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
348 auto wrapper_for_pranswer =
349 CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
350 auto pranswer =
351 CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
352
Steve Anton8acdd1a2018-02-07 17:27:36 -0800353 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700354 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
355 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
356 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
357 } else {
358 std::string error;
359 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
360 EXPECT_PRED_FORMAT2(
361 AssertStartsWith, error,
362 "Failed to set remote pranswer sdp: Called in wrong state:");
363 }
364}
365
366TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
367 auto wrapper_for_answer =
368 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
369 auto answer = wrapper_for_answer->CreateAnswer();
370
Steve Anton8acdd1a2018-02-07 17:27:36 -0800371 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700372 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
373 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
374 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
375 } else {
376 std::string error;
377 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
378 EXPECT_PRED_FORMAT2(
379 AssertStartsWith, error,
380 "Failed to set remote answer sdp: Called in wrong state:");
381 }
382}
383
384INSTANTIATE_TEST_CASE_P(PeerConnectionSignalingTest,
385 PeerConnectionSignalingStateTest,
Steve Anton8acdd1a2018-02-07 17:27:36 -0800386 Combine(Values(SdpSemantics::kPlanB,
387 SdpSemantics::kUnifiedPlan),
388 Values(SignalingState::kStable,
Steve Anton8d3444d2017-10-20 15:30:51 -0700389 SignalingState::kHaveLocalOffer,
390 SignalingState::kHaveLocalPrAnswer,
391 SignalingState::kHaveRemoteOffer,
392 SignalingState::kHaveRemotePrAnswer),
393 Bool()));
394
Steve Antondffead82018-02-06 10:31:29 -0800395// Test that CreateAnswer fails if a round of offer/answer has been done and
396// the PeerConnection is in the stable state.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800397TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700398 auto caller = CreatePeerConnection();
399 auto callee = CreatePeerConnection();
400
Steve Antondffead82018-02-06 10:31:29 -0800401 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Oleh Prypinc22d6a82018-02-02 08:42:18 +0000402
403 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
Steve Antondffead82018-02-06 10:31:29 -0800404 EXPECT_FALSE(caller->CreateAnswer());
405
406 ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
407 EXPECT_FALSE(callee->CreateAnswer());
Steve Anton8d3444d2017-10-20 15:30:51 -0700408}
409
410// According to https://tools.ietf.org/html/rfc3264#section-8, the session id
411// stays the same but the version must be incremented if a later, different
412// session description is generated. These two tests verify that is the case for
413// both offers and answers.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800414TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700415 SessionVersionIncrementedInSubsequentDifferentOffer) {
416 auto caller = CreatePeerConnection();
417 auto callee = CreatePeerConnection();
418
419 auto original_offer = caller->CreateOfferAndSetAsLocal();
420 const std::string original_id = original_offer->session_id();
421 const std::string original_version = original_offer->session_version();
422
423 ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
424 ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
425
426 // Add track to get a different offer.
427 caller->AddAudioTrack("a");
428
429 auto later_offer = caller->CreateOffer();
430
431 EXPECT_EQ(original_id, later_offer->session_id());
432 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
433 rtc::FromString<uint64_t>(later_offer->session_version()));
434}
Steve Anton8acdd1a2018-02-07 17:27:36 -0800435TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700436 SessionVersionIncrementedInSubsequentDifferentAnswer) {
437 auto caller = CreatePeerConnection();
438 auto callee = CreatePeerConnection();
439
440 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
441
Steve Antondffead82018-02-06 10:31:29 -0800442 auto original_answer = callee->CreateAnswer();
Steve Anton8d3444d2017-10-20 15:30:51 -0700443 const std::string original_id = original_answer->session_id();
444 const std::string original_version = original_answer->session_version();
445
446 // Add track to get a different answer.
447 callee->AddAudioTrack("a");
448
449 auto later_answer = callee->CreateAnswer();
450
451 EXPECT_EQ(original_id, later_answer->session_id());
452 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
453 rtc::FromString<uint64_t>(later_answer->session_version()));
454}
455
Steve Anton8acdd1a2018-02-07 17:27:36 -0800456TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700457 auto caller = CreatePeerConnectionWithAudioVideo();
458 auto callee = CreatePeerConnectionWithAudioVideo();
459
460 EXPECT_FALSE(caller->initial_offerer());
461 EXPECT_FALSE(callee->initial_offerer());
462
463 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
464
465 EXPECT_TRUE(caller->initial_offerer());
466 EXPECT_FALSE(callee->initial_offerer());
467
468 ASSERT_TRUE(
469 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
470
471 EXPECT_TRUE(caller->initial_offerer());
472 EXPECT_FALSE(callee->initial_offerer());
473}
474
475// Test creating a PeerConnection, request multiple offers, destroy the
476// PeerConnection and make sure we get success/failure callbacks for all of the
477// requests.
478// Background: crbug.com/507307
Steve Anton8acdd1a2018-02-07 17:27:36 -0800479TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700480 auto caller = CreatePeerConnection();
481
482 RTCOfferAnswerOptions options;
483 options.offer_to_receive_audio =
484 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
485
486 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
487 for (auto& observer : observers) {
488 observer =
489 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
490 caller->pc()->CreateOffer(observer, options);
491 }
492
493 // Destroy the PeerConnection.
494 caller.reset(nullptr);
495
496 for (auto& observer : observers) {
497 // We expect to have received a notification now even if the PeerConnection
498 // was terminated. The offer creation may or may not have succeeded, but we
499 // must have received a notification.
500 EXPECT_TRUE(observer->called());
501 }
502}
503
Steve Anton8acdd1a2018-02-07 17:27:36 -0800504INSTANTIATE_TEST_CASE_P(PeerConnectionSignalingTest,
505 PeerConnectionSignalingTest,
506 Values(SdpSemantics::kPlanB,
507 SdpSemantics::kUnifiedPlan));
508
Steve Anton8d3444d2017-10-20 15:30:51 -0700509} // namespace webrtc