blob: ed76753e9d31f26b5d31eedb3470aa543528e927 [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 Anton10542f22019-01-11 09:11:00 -080019#include "api/peer_connection_proxy.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 Anton10542f22019-01-11 09:11:00 -080022#include "pc/peer_connection.h"
23#include "pc/peer_connection_wrapper.h"
24#include "pc/sdp_utils.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070025#ifdef WEBRTC_ANDROID
Steve Anton10542f22019-01-11 09:11:00 -080026#include "pc/test/android_test_initializer.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070027#endif
Karl Wiberg918f50c2018-07-05 11:40:33 +020028#include "absl/memory/memory.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "pc/test/fake_audio_capture_module.h"
30#include "pc/test/fake_rtc_certificate_generator.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070031#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/virtual_socket_server.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070033#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) {
Karl Wiberg918f50c2018-07-05 11:40:33 +020084 auto observer = absl::make_unique<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
Yves Gerey4e933292018-10-31 15:36:05 +010093 observer->SetPeerConnectionInterface(pc.get());
Karl Wiberg918f50c2018-07-05 11:40:33 +020094 return absl::make_unique<PeerConnectionWrapperForSignalingTest>(
Steve Anton8d3444d2017-10-20 15:30:51 -070095 pc_factory_, pc, std::move(observer));
96 }
97
98 // Accepts the same arguments as CreatePeerConnection and adds default audio
99 // and video tracks.
100 template <typename... Args>
101 WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
102 auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
103 if (!wrapper) {
104 return nullptr;
105 }
106 wrapper->AddAudioTrack("a");
107 wrapper->AddVideoTrack("v");
108 return wrapper;
109 }
110
111 std::unique_ptr<rtc::VirtualSocketServer> vss_;
112 rtc::AutoSocketServerThread main_;
113 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
Steve Anton8acdd1a2018-02-07 17:27:36 -0800114 const SdpSemantics sdp_semantics_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700115};
116
Steve Anton8acdd1a2018-02-07 17:27:36 -0800117class PeerConnectionSignalingTest
118 : public PeerConnectionSignalingBaseTest,
119 public ::testing::WithParamInterface<SdpSemantics> {
120 protected:
121 PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
122};
123
124TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700125 auto caller = CreatePeerConnection();
126
127 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
128 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
129}
130
Steve Anton8acdd1a2018-02-07 17:27:36 -0800131TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700132 auto caller = CreatePeerConnection();
133 auto callee = CreatePeerConnection();
134
135 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
136 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
137}
138
Steve Anton8acdd1a2018-02-07 17:27:36 -0800139TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700140 auto caller = CreatePeerConnection();
141 std::string error;
142 ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
143 EXPECT_EQ("SessionDescription is NULL.", error);
144}
145
Steve Anton8acdd1a2018-02-07 17:27:36 -0800146TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700147 auto caller = CreatePeerConnection();
148 std::string error;
149 ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
150 EXPECT_EQ("SessionDescription is NULL.", error);
151}
152
153// The following parameterized test verifies that calls to various signaling
154// methods on PeerConnection will succeed/fail depending on what is the
155// PeerConnection's signaling state. Note that the test tries many different
156// forms of SignalingState::kClosed by arriving at a valid state then calling
157// |Close()|. This is intended to catch cases where the PeerConnection signaling
158// method ignores the closed flag but may work/not work because of the single
159// state the PeerConnection was created in before it was closed.
160
161class PeerConnectionSignalingStateTest
Steve Anton8acdd1a2018-02-07 17:27:36 -0800162 : public PeerConnectionSignalingBaseTest,
163 public ::testing::WithParamInterface<
164 std::tuple<SdpSemantics, SignalingState, bool>> {
Steve Anton8d3444d2017-10-20 15:30:51 -0700165 protected:
Steve Anton8acdd1a2018-02-07 17:27:36 -0800166 PeerConnectionSignalingStateTest()
167 : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
168 state_under_test_(std::make_tuple(std::get<1>(GetParam()),
169 std::get<2>(GetParam()))) {}
170
Steve Anton8d3444d2017-10-20 15:30:51 -0700171 RTCConfiguration GetConfig() {
172 RTCConfiguration config;
173 config.certificates.push_back(
174 FakeRTCCertificateGenerator::GenerateCertificate());
175 return config;
176 }
177
Steve Anton8acdd1a2018-02-07 17:27:36 -0800178 WrapperPtr CreatePeerConnectionUnderTest() {
179 return CreatePeerConnectionInState(state_under_test_);
180 }
181
Steve Anton8d3444d2017-10-20 15:30:51 -0700182 WrapperPtr CreatePeerConnectionInState(SignalingState state) {
183 return CreatePeerConnectionInState(std::make_tuple(state, false));
184 }
185
186 WrapperPtr CreatePeerConnectionInState(
187 std::tuple<SignalingState, bool> state_tuple) {
188 SignalingState state = std::get<0>(state_tuple);
189 bool closed = std::get<1>(state_tuple);
190
191 auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
192 switch (state) {
193 case SignalingState::kStable: {
194 break;
195 }
196 case SignalingState::kHaveLocalOffer: {
197 wrapper->SetLocalDescription(wrapper->CreateOffer());
198 break;
199 }
200 case SignalingState::kHaveLocalPrAnswer: {
201 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
202 wrapper->SetRemoteDescription(caller->CreateOffer());
203 auto answer = wrapper->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800204 wrapper->SetLocalDescription(
205 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700206 break;
207 }
208 case SignalingState::kHaveRemoteOffer: {
209 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
210 wrapper->SetRemoteDescription(caller->CreateOffer());
211 break;
212 }
213 case SignalingState::kHaveRemotePrAnswer: {
214 auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
215 callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
216 auto answer = callee->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800217 wrapper->SetRemoteDescription(
218 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700219 break;
220 }
221 case SignalingState::kClosed: {
222 RTC_NOTREACHED() << "Set the second member of the tuple to true to "
223 "achieve a closed state from an existing, valid "
224 "state.";
225 }
226 }
227
228 RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());
229
230 if (closed) {
231 wrapper->pc()->Close();
232 RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
233 }
234
235 return wrapper;
236 }
Steve Anton8acdd1a2018-02-07 17:27:36 -0800237
238 std::tuple<SignalingState, bool> state_under_test_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700239};
240
Steve Anton8d3444d2017-10-20 15:30:51 -0700241TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800242 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700243 if (wrapper->signaling_state() != SignalingState::kClosed) {
244 EXPECT_TRUE(wrapper->CreateOffer());
245 } else {
246 std::string error;
247 ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
248 EXPECT_PRED_FORMAT2(AssertStartsWith, error,
249 "CreateOffer called when PeerConnection is closed.");
250 }
251}
252
253TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800254 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700255 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
256 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
257 EXPECT_TRUE(wrapper->CreateAnswer());
258 } else {
259 std::string error;
260 ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
Steve Antondffead82018-02-06 10:31:29 -0800261 EXPECT_EQ(error,
262 "PeerConnection cannot create an answer in a state other than "
263 "have-remote-offer or have-local-pranswer.");
Steve Anton8d3444d2017-10-20 15:30:51 -0700264 }
265}
266
267TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800268 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700269 if (wrapper->signaling_state() == SignalingState::kStable ||
270 wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
271 // Need to call CreateOffer on the PeerConnection under test, otherwise when
272 // setting the local offer it will want to verify the DTLS fingerprint
273 // against the locally generated certificate, but without a call to
274 // CreateOffer the certificate will never be generated.
275 EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
276 } else {
277 auto wrapper_for_offer =
278 CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
279 auto offer =
280 CloneSessionDescription(wrapper_for_offer->pc()->local_description());
281
282 std::string error;
283 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
284 EXPECT_PRED_FORMAT2(
285 AssertStartsWith, error,
286 "Failed to set local offer sdp: Called in wrong state:");
287 }
288}
289
290TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
291 auto wrapper_for_pranswer =
292 CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
293 auto pranswer =
294 CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
295
Steve Anton8acdd1a2018-02-07 17:27:36 -0800296 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700297 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
298 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
299 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
300 } else {
301 std::string error;
302 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
303 EXPECT_PRED_FORMAT2(
304 AssertStartsWith, error,
305 "Failed to set local pranswer sdp: Called in wrong state:");
306 }
307}
308
309TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
310 auto wrapper_for_answer =
311 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
312 auto answer = wrapper_for_answer->CreateAnswer();
313
Steve Anton8acdd1a2018-02-07 17:27:36 -0800314 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700315 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
316 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
317 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
318 } else {
319 std::string error;
320 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
321 EXPECT_PRED_FORMAT2(
322 AssertStartsWith, error,
323 "Failed to set local answer sdp: Called in wrong state:");
324 }
325}
326
327TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
328 auto wrapper_for_offer =
329 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
330 auto offer =
331 CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
332
Steve Anton8acdd1a2018-02-07 17:27:36 -0800333 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700334 if (wrapper->signaling_state() == SignalingState::kStable ||
335 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
336 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
337 } else {
338 std::string error;
339 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
340 EXPECT_PRED_FORMAT2(
341 AssertStartsWith, error,
342 "Failed to set remote offer sdp: Called in wrong state:");
343 }
344}
345
346TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
347 auto wrapper_for_pranswer =
348 CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
349 auto pranswer =
350 CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
351
Steve Anton8acdd1a2018-02-07 17:27:36 -0800352 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700353 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
354 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
355 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
356 } else {
357 std::string error;
358 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
359 EXPECT_PRED_FORMAT2(
360 AssertStartsWith, error,
361 "Failed to set remote pranswer sdp: Called in wrong state:");
362 }
363}
364
365TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
366 auto wrapper_for_answer =
367 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
368 auto answer = wrapper_for_answer->CreateAnswer();
369
Steve Anton8acdd1a2018-02-07 17:27:36 -0800370 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700371 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
372 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
373 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
374 } else {
375 std::string error;
376 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
377 EXPECT_PRED_FORMAT2(
378 AssertStartsWith, error,
379 "Failed to set remote answer sdp: Called in wrong state:");
380 }
381}
382
383INSTANTIATE_TEST_CASE_P(PeerConnectionSignalingTest,
384 PeerConnectionSignalingStateTest,
Steve Anton8acdd1a2018-02-07 17:27:36 -0800385 Combine(Values(SdpSemantics::kPlanB,
386 SdpSemantics::kUnifiedPlan),
387 Values(SignalingState::kStable,
Steve Anton8d3444d2017-10-20 15:30:51 -0700388 SignalingState::kHaveLocalOffer,
389 SignalingState::kHaveLocalPrAnswer,
390 SignalingState::kHaveRemoteOffer,
391 SignalingState::kHaveRemotePrAnswer),
392 Bool()));
393
Steve Antondffead82018-02-06 10:31:29 -0800394// Test that CreateAnswer fails if a round of offer/answer has been done and
395// the PeerConnection is in the stable state.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800396TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700397 auto caller = CreatePeerConnection();
398 auto callee = CreatePeerConnection();
399
Steve Antondffead82018-02-06 10:31:29 -0800400 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Oleh Prypinc22d6a82018-02-02 08:42:18 +0000401
402 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
Steve Antondffead82018-02-06 10:31:29 -0800403 EXPECT_FALSE(caller->CreateAnswer());
404
405 ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
406 EXPECT_FALSE(callee->CreateAnswer());
Steve Anton8d3444d2017-10-20 15:30:51 -0700407}
408
409// According to https://tools.ietf.org/html/rfc3264#section-8, the session id
410// stays the same but the version must be incremented if a later, different
411// session description is generated. These two tests verify that is the case for
412// both offers and answers.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800413TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700414 SessionVersionIncrementedInSubsequentDifferentOffer) {
415 auto caller = CreatePeerConnection();
416 auto callee = CreatePeerConnection();
417
418 auto original_offer = caller->CreateOfferAndSetAsLocal();
419 const std::string original_id = original_offer->session_id();
420 const std::string original_version = original_offer->session_version();
421
422 ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
423 ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
424
425 // Add track to get a different offer.
426 caller->AddAudioTrack("a");
427
428 auto later_offer = caller->CreateOffer();
429
430 EXPECT_EQ(original_id, later_offer->session_id());
431 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
432 rtc::FromString<uint64_t>(later_offer->session_version()));
433}
Steve Anton8acdd1a2018-02-07 17:27:36 -0800434TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700435 SessionVersionIncrementedInSubsequentDifferentAnswer) {
436 auto caller = CreatePeerConnection();
437 auto callee = CreatePeerConnection();
438
439 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
440
Steve Antondffead82018-02-06 10:31:29 -0800441 auto original_answer = callee->CreateAnswer();
Steve Anton8d3444d2017-10-20 15:30:51 -0700442 const std::string original_id = original_answer->session_id();
443 const std::string original_version = original_answer->session_version();
444
445 // Add track to get a different answer.
446 callee->AddAudioTrack("a");
447
448 auto later_answer = callee->CreateAnswer();
449
450 EXPECT_EQ(original_id, later_answer->session_id());
451 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
452 rtc::FromString<uint64_t>(later_answer->session_version()));
453}
454
Steve Anton8acdd1a2018-02-07 17:27:36 -0800455TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700456 auto caller = CreatePeerConnectionWithAudioVideo();
457 auto callee = CreatePeerConnectionWithAudioVideo();
458
459 EXPECT_FALSE(caller->initial_offerer());
460 EXPECT_FALSE(callee->initial_offerer());
461
462 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
463
464 EXPECT_TRUE(caller->initial_offerer());
465 EXPECT_FALSE(callee->initial_offerer());
466
467 ASSERT_TRUE(
468 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
469
470 EXPECT_TRUE(caller->initial_offerer());
471 EXPECT_FALSE(callee->initial_offerer());
472}
473
474// Test creating a PeerConnection, request multiple offers, destroy the
475// PeerConnection and make sure we get success/failure callbacks for all of the
476// requests.
477// Background: crbug.com/507307
Steve Anton8acdd1a2018-02-07 17:27:36 -0800478TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700479 auto caller = CreatePeerConnection();
480
481 RTCOfferAnswerOptions options;
482 options.offer_to_receive_audio =
483 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
484
485 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
486 for (auto& observer : observers) {
487 observer =
488 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
489 caller->pc()->CreateOffer(observer, options);
490 }
491
492 // Destroy the PeerConnection.
493 caller.reset(nullptr);
494
495 for (auto& observer : observers) {
496 // We expect to have received a notification now even if the PeerConnection
497 // was terminated. The offer creation may or may not have succeeded, but we
498 // must have received a notification.
499 EXPECT_TRUE(observer->called());
500 }
501}
502
Steve Anton8acdd1a2018-02-07 17:27:36 -0800503INSTANTIATE_TEST_CASE_P(PeerConnectionSignalingTest,
504 PeerConnectionSignalingTest,
505 Values(SdpSemantics::kPlanB,
506 SdpSemantics::kUnifiedPlan));
507
Steve Anton8d3444d2017-10-20 15:30:51 -0700508} // namespace webrtc