blob: 340d472bc81a9e8763e6820c2b6c491bf6b6a19a [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
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100111 int NumberOfDtlsTransports(const WrapperPtr& pc_wrapper) {
112 std::set<DtlsTransportInterface*> transports;
113 auto transceivers = pc_wrapper->pc()->GetTransceivers();
114
115 for (auto& transceiver : transceivers) {
116 if (transceiver->sender()->dtls_transport()) {
117 EXPECT_TRUE(transceiver->receiver()->dtls_transport());
118 EXPECT_EQ(transceiver->sender()->dtls_transport().get(),
119 transceiver->receiver()->dtls_transport().get());
120 transports.insert(transceiver->sender()->dtls_transport().get());
121 } else {
122 // If one transceiver is missing, they all should be.
123 EXPECT_EQ(0UL, transports.size());
124 }
125 }
126 return transports.size();
127 }
128
129 bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
130 return NumberOfDtlsTransports(pc_wrapper) > 0;
131 }
132
Steve Anton8d3444d2017-10-20 15:30:51 -0700133 std::unique_ptr<rtc::VirtualSocketServer> vss_;
134 rtc::AutoSocketServerThread main_;
135 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
Steve Anton8acdd1a2018-02-07 17:27:36 -0800136 const SdpSemantics sdp_semantics_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700137};
138
Steve Anton8acdd1a2018-02-07 17:27:36 -0800139class PeerConnectionSignalingTest
140 : public PeerConnectionSignalingBaseTest,
141 public ::testing::WithParamInterface<SdpSemantics> {
142 protected:
143 PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
144};
145
146TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700147 auto caller = CreatePeerConnection();
148
149 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
150 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
151}
152
Steve Anton8acdd1a2018-02-07 17:27:36 -0800153TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700154 auto caller = CreatePeerConnection();
155 auto callee = CreatePeerConnection();
156
157 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
158 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
159}
160
Steve Anton8acdd1a2018-02-07 17:27:36 -0800161TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700162 auto caller = CreatePeerConnection();
163 std::string error;
164 ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
165 EXPECT_EQ("SessionDescription is NULL.", error);
166}
167
Steve Anton8acdd1a2018-02-07 17:27:36 -0800168TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700169 auto caller = CreatePeerConnection();
170 std::string error;
171 ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
172 EXPECT_EQ("SessionDescription is NULL.", error);
173}
174
175// The following parameterized test verifies that calls to various signaling
176// methods on PeerConnection will succeed/fail depending on what is the
177// PeerConnection's signaling state. Note that the test tries many different
178// forms of SignalingState::kClosed by arriving at a valid state then calling
179// |Close()|. This is intended to catch cases where the PeerConnection signaling
180// method ignores the closed flag but may work/not work because of the single
181// state the PeerConnection was created in before it was closed.
182
183class PeerConnectionSignalingStateTest
Steve Anton8acdd1a2018-02-07 17:27:36 -0800184 : public PeerConnectionSignalingBaseTest,
185 public ::testing::WithParamInterface<
186 std::tuple<SdpSemantics, SignalingState, bool>> {
Steve Anton8d3444d2017-10-20 15:30:51 -0700187 protected:
Steve Anton8acdd1a2018-02-07 17:27:36 -0800188 PeerConnectionSignalingStateTest()
189 : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
190 state_under_test_(std::make_tuple(std::get<1>(GetParam()),
191 std::get<2>(GetParam()))) {}
192
Steve Anton8d3444d2017-10-20 15:30:51 -0700193 RTCConfiguration GetConfig() {
194 RTCConfiguration config;
195 config.certificates.push_back(
196 FakeRTCCertificateGenerator::GenerateCertificate());
197 return config;
198 }
199
Steve Anton8acdd1a2018-02-07 17:27:36 -0800200 WrapperPtr CreatePeerConnectionUnderTest() {
201 return CreatePeerConnectionInState(state_under_test_);
202 }
203
Steve Anton8d3444d2017-10-20 15:30:51 -0700204 WrapperPtr CreatePeerConnectionInState(SignalingState state) {
205 return CreatePeerConnectionInState(std::make_tuple(state, false));
206 }
207
208 WrapperPtr CreatePeerConnectionInState(
209 std::tuple<SignalingState, bool> state_tuple) {
210 SignalingState state = std::get<0>(state_tuple);
211 bool closed = std::get<1>(state_tuple);
212
213 auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
214 switch (state) {
215 case SignalingState::kStable: {
216 break;
217 }
218 case SignalingState::kHaveLocalOffer: {
219 wrapper->SetLocalDescription(wrapper->CreateOffer());
220 break;
221 }
222 case SignalingState::kHaveLocalPrAnswer: {
223 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
224 wrapper->SetRemoteDescription(caller->CreateOffer());
225 auto answer = wrapper->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800226 wrapper->SetLocalDescription(
227 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700228 break;
229 }
230 case SignalingState::kHaveRemoteOffer: {
231 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
232 wrapper->SetRemoteDescription(caller->CreateOffer());
233 break;
234 }
235 case SignalingState::kHaveRemotePrAnswer: {
236 auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
237 callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
238 auto answer = callee->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800239 wrapper->SetRemoteDescription(
240 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700241 break;
242 }
243 case SignalingState::kClosed: {
244 RTC_NOTREACHED() << "Set the second member of the tuple to true to "
245 "achieve a closed state from an existing, valid "
246 "state.";
247 }
248 }
249
250 RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());
251
252 if (closed) {
253 wrapper->pc()->Close();
254 RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
255 }
256
257 return wrapper;
258 }
Steve Anton8acdd1a2018-02-07 17:27:36 -0800259
260 std::tuple<SignalingState, bool> state_under_test_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700261};
262
Steve Anton8d3444d2017-10-20 15:30:51 -0700263TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800264 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700265 if (wrapper->signaling_state() != SignalingState::kClosed) {
266 EXPECT_TRUE(wrapper->CreateOffer());
267 } else {
268 std::string error;
269 ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
270 EXPECT_PRED_FORMAT2(AssertStartsWith, error,
271 "CreateOffer called when PeerConnection is closed.");
272 }
273}
274
275TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800276 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700277 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
278 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
279 EXPECT_TRUE(wrapper->CreateAnswer());
280 } else {
281 std::string error;
282 ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
Steve Antondffead82018-02-06 10:31:29 -0800283 EXPECT_EQ(error,
284 "PeerConnection cannot create an answer in a state other than "
285 "have-remote-offer or have-local-pranswer.");
Steve Anton8d3444d2017-10-20 15:30:51 -0700286 }
287}
288
289TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800290 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700291 if (wrapper->signaling_state() == SignalingState::kStable ||
292 wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
293 // Need to call CreateOffer on the PeerConnection under test, otherwise when
294 // setting the local offer it will want to verify the DTLS fingerprint
295 // against the locally generated certificate, but without a call to
296 // CreateOffer the certificate will never be generated.
297 EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
298 } else {
299 auto wrapper_for_offer =
300 CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
301 auto offer =
302 CloneSessionDescription(wrapper_for_offer->pc()->local_description());
303
304 std::string error;
305 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
306 EXPECT_PRED_FORMAT2(
307 AssertStartsWith, error,
308 "Failed to set local offer sdp: Called in wrong state:");
309 }
310}
311
312TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
313 auto wrapper_for_pranswer =
314 CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
315 auto pranswer =
316 CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
317
Steve Anton8acdd1a2018-02-07 17:27:36 -0800318 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700319 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
320 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
321 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
322 } else {
323 std::string error;
324 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
325 EXPECT_PRED_FORMAT2(
326 AssertStartsWith, error,
327 "Failed to set local pranswer sdp: Called in wrong state:");
328 }
329}
330
331TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
332 auto wrapper_for_answer =
333 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
334 auto answer = wrapper_for_answer->CreateAnswer();
335
Steve Anton8acdd1a2018-02-07 17:27:36 -0800336 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700337 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
338 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
339 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
340 } else {
341 std::string error;
342 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
343 EXPECT_PRED_FORMAT2(
344 AssertStartsWith, error,
345 "Failed to set local answer sdp: Called in wrong state:");
346 }
347}
348
349TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
350 auto wrapper_for_offer =
351 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
352 auto offer =
353 CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
354
Steve Anton8acdd1a2018-02-07 17:27:36 -0800355 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700356 if (wrapper->signaling_state() == SignalingState::kStable ||
357 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
358 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
359 } else {
360 std::string error;
361 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
362 EXPECT_PRED_FORMAT2(
363 AssertStartsWith, error,
364 "Failed to set remote offer sdp: Called in wrong state:");
365 }
366}
367
368TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
369 auto wrapper_for_pranswer =
370 CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
371 auto pranswer =
372 CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
373
Steve Anton8acdd1a2018-02-07 17:27:36 -0800374 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700375 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
376 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
377 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
378 } else {
379 std::string error;
380 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
381 EXPECT_PRED_FORMAT2(
382 AssertStartsWith, error,
383 "Failed to set remote pranswer sdp: Called in wrong state:");
384 }
385}
386
387TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
388 auto wrapper_for_answer =
389 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
390 auto answer = wrapper_for_answer->CreateAnswer();
391
Steve Anton8acdd1a2018-02-07 17:27:36 -0800392 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700393 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
394 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
395 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
396 } else {
397 std::string error;
398 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
399 EXPECT_PRED_FORMAT2(
400 AssertStartsWith, error,
401 "Failed to set remote answer sdp: Called in wrong state:");
402 }
403}
404
405INSTANTIATE_TEST_CASE_P(PeerConnectionSignalingTest,
406 PeerConnectionSignalingStateTest,
Steve Anton8acdd1a2018-02-07 17:27:36 -0800407 Combine(Values(SdpSemantics::kPlanB,
408 SdpSemantics::kUnifiedPlan),
409 Values(SignalingState::kStable,
Steve Anton8d3444d2017-10-20 15:30:51 -0700410 SignalingState::kHaveLocalOffer,
411 SignalingState::kHaveLocalPrAnswer,
412 SignalingState::kHaveRemoteOffer,
413 SignalingState::kHaveRemotePrAnswer),
414 Bool()));
415
Steve Antondffead82018-02-06 10:31:29 -0800416// Test that CreateAnswer fails if a round of offer/answer has been done and
417// the PeerConnection is in the stable state.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800418TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700419 auto caller = CreatePeerConnection();
420 auto callee = CreatePeerConnection();
421
Steve Antondffead82018-02-06 10:31:29 -0800422 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Oleh Prypinc22d6a82018-02-02 08:42:18 +0000423
424 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
Steve Antondffead82018-02-06 10:31:29 -0800425 EXPECT_FALSE(caller->CreateAnswer());
426
427 ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
428 EXPECT_FALSE(callee->CreateAnswer());
Steve Anton8d3444d2017-10-20 15:30:51 -0700429}
430
431// According to https://tools.ietf.org/html/rfc3264#section-8, the session id
432// stays the same but the version must be incremented if a later, different
433// session description is generated. These two tests verify that is the case for
434// both offers and answers.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800435TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700436 SessionVersionIncrementedInSubsequentDifferentOffer) {
437 auto caller = CreatePeerConnection();
438 auto callee = CreatePeerConnection();
439
440 auto original_offer = caller->CreateOfferAndSetAsLocal();
441 const std::string original_id = original_offer->session_id();
442 const std::string original_version = original_offer->session_version();
443
444 ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
445 ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
446
447 // Add track to get a different offer.
448 caller->AddAudioTrack("a");
449
450 auto later_offer = caller->CreateOffer();
451
452 EXPECT_EQ(original_id, later_offer->session_id());
453 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
454 rtc::FromString<uint64_t>(later_offer->session_version()));
455}
Steve Anton8acdd1a2018-02-07 17:27:36 -0800456TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700457 SessionVersionIncrementedInSubsequentDifferentAnswer) {
458 auto caller = CreatePeerConnection();
459 auto callee = CreatePeerConnection();
460
461 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
462
Steve Antondffead82018-02-06 10:31:29 -0800463 auto original_answer = callee->CreateAnswer();
Steve Anton8d3444d2017-10-20 15:30:51 -0700464 const std::string original_id = original_answer->session_id();
465 const std::string original_version = original_answer->session_version();
466
467 // Add track to get a different answer.
468 callee->AddAudioTrack("a");
469
470 auto later_answer = callee->CreateAnswer();
471
472 EXPECT_EQ(original_id, later_answer->session_id());
473 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
474 rtc::FromString<uint64_t>(later_answer->session_version()));
475}
476
Steve Anton8acdd1a2018-02-07 17:27:36 -0800477TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700478 auto caller = CreatePeerConnectionWithAudioVideo();
479 auto callee = CreatePeerConnectionWithAudioVideo();
480
481 EXPECT_FALSE(caller->initial_offerer());
482 EXPECT_FALSE(callee->initial_offerer());
483
484 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
485
486 EXPECT_TRUE(caller->initial_offerer());
487 EXPECT_FALSE(callee->initial_offerer());
488
489 ASSERT_TRUE(
490 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
491
492 EXPECT_TRUE(caller->initial_offerer());
493 EXPECT_FALSE(callee->initial_offerer());
494}
495
496// Test creating a PeerConnection, request multiple offers, destroy the
497// PeerConnection and make sure we get success/failure callbacks for all of the
498// requests.
499// Background: crbug.com/507307
Steve Anton8acdd1a2018-02-07 17:27:36 -0800500TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700501 auto caller = CreatePeerConnection();
502
503 RTCOfferAnswerOptions options;
504 options.offer_to_receive_audio =
505 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
506
507 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
508 for (auto& observer : observers) {
509 observer =
510 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
511 caller->pc()->CreateOffer(observer, options);
512 }
513
514 // Destroy the PeerConnection.
515 caller.reset(nullptr);
516
517 for (auto& observer : observers) {
518 // We expect to have received a notification now even if the PeerConnection
519 // was terminated. The offer creation may or may not have succeeded, but we
520 // must have received a notification.
521 EXPECT_TRUE(observer->called());
522 }
523}
524
Steve Anton8acdd1a2018-02-07 17:27:36 -0800525INSTANTIATE_TEST_CASE_P(PeerConnectionSignalingTest,
526 PeerConnectionSignalingTest,
527 Values(SdpSemantics::kPlanB,
528 SdpSemantics::kUnifiedPlan));
529
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100530class PeerConnectionSignalingUnifiedPlanTest
531 : public PeerConnectionSignalingBaseTest {
532 protected:
533 PeerConnectionSignalingUnifiedPlanTest()
534 : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
535};
536
537// Test that transports are shown in the sender/receiver API after offer/answer.
538// This only works in Unified Plan.
539TEST_F(PeerConnectionSignalingUnifiedPlanTest,
540 DtlsTransportsInstantiateInOfferAnswer) {
541 auto caller = CreatePeerConnectionWithAudioVideo();
542 auto callee = CreatePeerConnection();
543
544 EXPECT_FALSE(HasDtlsTransport(caller));
545 EXPECT_FALSE(HasDtlsTransport(callee));
546 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
547 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
548 EXPECT_TRUE(HasDtlsTransport(caller));
549 callee->SetRemoteDescription(std::move(offer));
550 EXPECT_FALSE(HasDtlsTransport(callee));
551 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
552 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
553 EXPECT_TRUE(HasDtlsTransport(callee));
554 caller->SetRemoteDescription(std::move(answer));
555 EXPECT_TRUE(HasDtlsTransport(caller));
556
557 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
558}
559
560TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
561 auto caller = CreatePeerConnectionWithAudioVideo();
562 auto callee = CreatePeerConnection();
563
564 EXPECT_FALSE(HasDtlsTransport(caller));
565 EXPECT_FALSE(HasDtlsTransport(callee));
566 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
567 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
568 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
569 callee->SetRemoteDescription(std::move(offer));
570 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
571 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
572 caller->SetRemoteDescription(std::move(answer));
573 EXPECT_EQ(1, NumberOfDtlsTransports(caller));
574
575 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
576}
577
578TEST_F(PeerConnectionSignalingUnifiedPlanTest,
579 DtlsTransportsAreSeparateeWhenUnbundled) {
580 auto caller = CreatePeerConnectionWithAudioVideo();
581 auto callee = CreatePeerConnection();
582
583 EXPECT_FALSE(HasDtlsTransport(caller));
584 EXPECT_FALSE(HasDtlsTransport(callee));
585 RTCOfferAnswerOptions unbundle_options;
586 unbundle_options.use_rtp_mux = false;
587 auto offer = caller->CreateOffer(unbundle_options);
588 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
589 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
590 callee->SetRemoteDescription(std::move(offer));
591 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
592 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
593 EXPECT_EQ(2, NumberOfDtlsTransports(callee));
594 caller->SetRemoteDescription(std::move(answer));
595 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
596
597 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
598}
599
Steve Anton8d3444d2017-10-20 15:30:51 -0700600} // namespace webrtc