blob: 30b11ceaa761dcb014c1f9dc1595eba37e235554 [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
Mirko Bonadei317a1f02019-09-17 17:06:18 +020014#include <memory>
Steve Anton8d3444d2017-10-20 15:30:51 -070015#include <tuple>
16
17#include "api/audio_codecs/builtin_audio_decoder_factory.h"
18#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei2ff3f492018-11-22 09:00:13 +010019#include "api/create_peerconnection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "api/peer_connection_proxy.h"
Anders Carlsson67537952018-05-03 11:28:29 +020021#include "api/video_codecs/builtin_video_decoder_factory.h"
22#include "api/video_codecs/builtin_video_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "pc/peer_connection.h"
24#include "pc/peer_connection_wrapper.h"
25#include "pc/sdp_utils.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070026#ifdef WEBRTC_ANDROID
Steve Anton10542f22019-01-11 09:11:00 -080027#include "pc/test/android_test_initializer.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070028#endif
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
Henrik Boströma3728d32019-10-28 12:09:49 +010044namespace {
45const int64_t kWaitTimeout = 10000;
46} // namespace
47
Steve Anton8d3444d2017-10-20 15:30:51 -070048class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
49 public:
50 using PeerConnectionWrapper::PeerConnectionWrapper;
51
52 bool initial_offerer() {
53 return GetInternalPeerConnection()->initial_offerer();
54 }
55
56 PeerConnection* GetInternalPeerConnection() {
Mirko Bonadeie97de912017-12-13 11:29:34 +010057 auto* pci =
58 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
59 pc());
60 return static_cast<PeerConnection*>(pci->internal());
Steve Anton8d3444d2017-10-20 15:30:51 -070061 }
62};
63
Henrik Boströma3728d32019-10-28 12:09:49 +010064class ExecuteFunctionOnCreateSessionDescriptionObserver
65 : public CreateSessionDescriptionObserver {
66 public:
67 ExecuteFunctionOnCreateSessionDescriptionObserver(
68 std::function<void(SessionDescriptionInterface*)> function)
69 : function_(std::move(function)) {}
70 ~ExecuteFunctionOnCreateSessionDescriptionObserver() override {
71 RTC_DCHECK(was_called_);
72 }
73
74 bool was_called() const { return was_called_; }
75
76 void OnSuccess(SessionDescriptionInterface* desc) override {
77 RTC_DCHECK(!was_called_);
78 was_called_ = true;
79 function_(desc);
80 }
81
82 void OnFailure(RTCError error) override { RTC_NOTREACHED(); }
83
84 private:
85 bool was_called_ = false;
86 std::function<void(SessionDescriptionInterface*)> function_;
87};
88
Steve Anton8acdd1a2018-02-07 17:27:36 -080089class PeerConnectionSignalingBaseTest : public ::testing::Test {
Steve Anton8d3444d2017-10-20 15:30:51 -070090 protected:
91 typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;
92
Steve Anton8acdd1a2018-02-07 17:27:36 -080093 explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
94 : vss_(new rtc::VirtualSocketServer()),
95 main_(vss_.get()),
96 sdp_semantics_(sdp_semantics) {
Steve Anton8d3444d2017-10-20 15:30:51 -070097#ifdef WEBRTC_ANDROID
98 InitializeAndroidObjects();
99#endif
100 pc_factory_ = CreatePeerConnectionFactory(
101 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
Anders Carlsson67537952018-05-03 11:28:29 +0200102 rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
103 CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
104 CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
105 nullptr /* audio_mixer */, nullptr /* audio_processing */);
Steve Anton8d3444d2017-10-20 15:30:51 -0700106 }
107
108 WrapperPtr CreatePeerConnection() {
109 return CreatePeerConnection(RTCConfiguration());
110 }
111
112 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200113 auto observer = std::make_unique<MockPeerConnectionObserver>();
Steve Anton8acdd1a2018-02-07 17:27:36 -0800114 RTCConfiguration modified_config = config;
115 modified_config.sdp_semantics = sdp_semantics_;
116 auto pc = pc_factory_->CreatePeerConnection(modified_config, nullptr,
117 nullptr, observer.get());
Steve Anton8d3444d2017-10-20 15:30:51 -0700118 if (!pc) {
119 return nullptr;
120 }
121
Yves Gerey4e933292018-10-31 15:36:05 +0100122 observer->SetPeerConnectionInterface(pc.get());
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200123 return std::make_unique<PeerConnectionWrapperForSignalingTest>(
Steve Anton8d3444d2017-10-20 15:30:51 -0700124 pc_factory_, pc, std::move(observer));
125 }
126
127 // Accepts the same arguments as CreatePeerConnection and adds default audio
128 // and video tracks.
129 template <typename... Args>
130 WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
131 auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
132 if (!wrapper) {
133 return nullptr;
134 }
135 wrapper->AddAudioTrack("a");
136 wrapper->AddVideoTrack("v");
137 return wrapper;
138 }
139
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100140 int NumberOfDtlsTransports(const WrapperPtr& pc_wrapper) {
141 std::set<DtlsTransportInterface*> transports;
142 auto transceivers = pc_wrapper->pc()->GetTransceivers();
143
144 for (auto& transceiver : transceivers) {
145 if (transceiver->sender()->dtls_transport()) {
146 EXPECT_TRUE(transceiver->receiver()->dtls_transport());
147 EXPECT_EQ(transceiver->sender()->dtls_transport().get(),
148 transceiver->receiver()->dtls_transport().get());
149 transports.insert(transceiver->sender()->dtls_transport().get());
150 } else {
151 // If one transceiver is missing, they all should be.
152 EXPECT_EQ(0UL, transports.size());
153 }
154 }
155 return transports.size();
156 }
157
158 bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
159 return NumberOfDtlsTransports(pc_wrapper) > 0;
160 }
161
Steve Anton8d3444d2017-10-20 15:30:51 -0700162 std::unique_ptr<rtc::VirtualSocketServer> vss_;
163 rtc::AutoSocketServerThread main_;
164 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
Steve Anton8acdd1a2018-02-07 17:27:36 -0800165 const SdpSemantics sdp_semantics_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700166};
167
Steve Anton8acdd1a2018-02-07 17:27:36 -0800168class PeerConnectionSignalingTest
169 : public PeerConnectionSignalingBaseTest,
170 public ::testing::WithParamInterface<SdpSemantics> {
171 protected:
172 PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
173};
174
175TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700176 auto caller = CreatePeerConnection();
177
178 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
179 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
180}
181
Steve Anton8acdd1a2018-02-07 17:27:36 -0800182TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700183 auto caller = CreatePeerConnection();
184 auto callee = CreatePeerConnection();
185
186 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
187 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
188}
189
Steve Anton8acdd1a2018-02-07 17:27:36 -0800190TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700191 auto caller = CreatePeerConnection();
192 std::string error;
193 ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
194 EXPECT_EQ("SessionDescription is NULL.", error);
195}
196
Steve Anton8acdd1a2018-02-07 17:27:36 -0800197TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700198 auto caller = CreatePeerConnection();
199 std::string error;
200 ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
201 EXPECT_EQ("SessionDescription is NULL.", error);
202}
203
204// The following parameterized test verifies that calls to various signaling
205// methods on PeerConnection will succeed/fail depending on what is the
206// PeerConnection's signaling state. Note that the test tries many different
207// forms of SignalingState::kClosed by arriving at a valid state then calling
208// |Close()|. This is intended to catch cases where the PeerConnection signaling
209// method ignores the closed flag but may work/not work because of the single
210// state the PeerConnection was created in before it was closed.
211
212class PeerConnectionSignalingStateTest
Steve Anton8acdd1a2018-02-07 17:27:36 -0800213 : public PeerConnectionSignalingBaseTest,
214 public ::testing::WithParamInterface<
215 std::tuple<SdpSemantics, SignalingState, bool>> {
Steve Anton8d3444d2017-10-20 15:30:51 -0700216 protected:
Steve Anton8acdd1a2018-02-07 17:27:36 -0800217 PeerConnectionSignalingStateTest()
218 : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
219 state_under_test_(std::make_tuple(std::get<1>(GetParam()),
220 std::get<2>(GetParam()))) {}
221
Steve Anton8d3444d2017-10-20 15:30:51 -0700222 RTCConfiguration GetConfig() {
223 RTCConfiguration config;
224 config.certificates.push_back(
225 FakeRTCCertificateGenerator::GenerateCertificate());
226 return config;
227 }
228
Steve Anton8acdd1a2018-02-07 17:27:36 -0800229 WrapperPtr CreatePeerConnectionUnderTest() {
230 return CreatePeerConnectionInState(state_under_test_);
231 }
232
Steve Anton8d3444d2017-10-20 15:30:51 -0700233 WrapperPtr CreatePeerConnectionInState(SignalingState state) {
234 return CreatePeerConnectionInState(std::make_tuple(state, false));
235 }
236
237 WrapperPtr CreatePeerConnectionInState(
238 std::tuple<SignalingState, bool> state_tuple) {
239 SignalingState state = std::get<0>(state_tuple);
240 bool closed = std::get<1>(state_tuple);
241
242 auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
243 switch (state) {
244 case SignalingState::kStable: {
245 break;
246 }
247 case SignalingState::kHaveLocalOffer: {
248 wrapper->SetLocalDescription(wrapper->CreateOffer());
249 break;
250 }
251 case SignalingState::kHaveLocalPrAnswer: {
252 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
253 wrapper->SetRemoteDescription(caller->CreateOffer());
254 auto answer = wrapper->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800255 wrapper->SetLocalDescription(
256 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700257 break;
258 }
259 case SignalingState::kHaveRemoteOffer: {
260 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
261 wrapper->SetRemoteDescription(caller->CreateOffer());
262 break;
263 }
264 case SignalingState::kHaveRemotePrAnswer: {
265 auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
266 callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
267 auto answer = callee->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800268 wrapper->SetRemoteDescription(
269 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700270 break;
271 }
272 case SignalingState::kClosed: {
273 RTC_NOTREACHED() << "Set the second member of the tuple to true to "
274 "achieve a closed state from an existing, valid "
275 "state.";
276 }
277 }
278
279 RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());
280
281 if (closed) {
282 wrapper->pc()->Close();
283 RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
284 }
285
286 return wrapper;
287 }
Steve Anton8acdd1a2018-02-07 17:27:36 -0800288
289 std::tuple<SignalingState, bool> state_under_test_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700290};
291
Steve Anton8d3444d2017-10-20 15:30:51 -0700292TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800293 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700294 if (wrapper->signaling_state() != SignalingState::kClosed) {
295 EXPECT_TRUE(wrapper->CreateOffer());
296 } else {
297 std::string error;
298 ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
299 EXPECT_PRED_FORMAT2(AssertStartsWith, error,
300 "CreateOffer called when PeerConnection is closed.");
301 }
302}
303
304TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800305 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700306 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
307 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
308 EXPECT_TRUE(wrapper->CreateAnswer());
309 } else {
310 std::string error;
311 ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
Steve Antondffead82018-02-06 10:31:29 -0800312 EXPECT_EQ(error,
313 "PeerConnection cannot create an answer in a state other than "
314 "have-remote-offer or have-local-pranswer.");
Steve Anton8d3444d2017-10-20 15:30:51 -0700315 }
316}
317
318TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800319 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700320 if (wrapper->signaling_state() == SignalingState::kStable ||
321 wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
322 // Need to call CreateOffer on the PeerConnection under test, otherwise when
323 // setting the local offer it will want to verify the DTLS fingerprint
324 // against the locally generated certificate, but without a call to
325 // CreateOffer the certificate will never be generated.
326 EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
327 } else {
328 auto wrapper_for_offer =
329 CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
330 auto offer =
331 CloneSessionDescription(wrapper_for_offer->pc()->local_description());
332
333 std::string error;
334 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
335 EXPECT_PRED_FORMAT2(
336 AssertStartsWith, error,
337 "Failed to set local offer sdp: Called in wrong state:");
338 }
339}
340
341TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
342 auto wrapper_for_pranswer =
343 CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
344 auto pranswer =
345 CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
346
Steve Anton8acdd1a2018-02-07 17:27:36 -0800347 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700348 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
349 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
350 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
351 } else {
352 std::string error;
353 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
354 EXPECT_PRED_FORMAT2(
355 AssertStartsWith, error,
356 "Failed to set local pranswer sdp: Called in wrong state:");
357 }
358}
359
360TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
361 auto wrapper_for_answer =
362 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
363 auto answer = wrapper_for_answer->CreateAnswer();
364
Steve Anton8acdd1a2018-02-07 17:27:36 -0800365 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700366 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
367 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
368 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
369 } else {
370 std::string error;
371 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
372 EXPECT_PRED_FORMAT2(
373 AssertStartsWith, error,
374 "Failed to set local answer sdp: Called in wrong state:");
375 }
376}
377
378TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
379 auto wrapper_for_offer =
380 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
381 auto offer =
382 CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
383
Steve Anton8acdd1a2018-02-07 17:27:36 -0800384 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700385 if (wrapper->signaling_state() == SignalingState::kStable ||
386 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
387 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
388 } else {
389 std::string error;
390 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
391 EXPECT_PRED_FORMAT2(
392 AssertStartsWith, error,
393 "Failed to set remote offer sdp: Called in wrong state:");
394 }
395}
396
397TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
398 auto wrapper_for_pranswer =
399 CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
400 auto pranswer =
401 CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
402
Steve Anton8acdd1a2018-02-07 17:27:36 -0800403 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700404 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
405 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
406 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
407 } else {
408 std::string error;
409 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
410 EXPECT_PRED_FORMAT2(
411 AssertStartsWith, error,
412 "Failed to set remote pranswer sdp: Called in wrong state:");
413 }
414}
415
416TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
417 auto wrapper_for_answer =
418 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
419 auto answer = wrapper_for_answer->CreateAnswer();
420
Steve Anton8acdd1a2018-02-07 17:27:36 -0800421 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700422 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
423 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
424 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
425 } else {
426 std::string error;
427 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
428 EXPECT_PRED_FORMAT2(
429 AssertStartsWith, error,
430 "Failed to set remote answer sdp: Called in wrong state:");
431 }
432}
433
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100434INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
435 PeerConnectionSignalingStateTest,
436 Combine(Values(SdpSemantics::kPlanB,
437 SdpSemantics::kUnifiedPlan),
438 Values(SignalingState::kStable,
439 SignalingState::kHaveLocalOffer,
440 SignalingState::kHaveLocalPrAnswer,
441 SignalingState::kHaveRemoteOffer,
442 SignalingState::kHaveRemotePrAnswer),
443 Bool()));
Steve Anton8d3444d2017-10-20 15:30:51 -0700444
Steve Antondffead82018-02-06 10:31:29 -0800445// Test that CreateAnswer fails if a round of offer/answer has been done and
446// the PeerConnection is in the stable state.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800447TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700448 auto caller = CreatePeerConnection();
449 auto callee = CreatePeerConnection();
450
Steve Antondffead82018-02-06 10:31:29 -0800451 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Oleh Prypinc22d6a82018-02-02 08:42:18 +0000452
453 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
Steve Antondffead82018-02-06 10:31:29 -0800454 EXPECT_FALSE(caller->CreateAnswer());
455
456 ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
457 EXPECT_FALSE(callee->CreateAnswer());
Steve Anton8d3444d2017-10-20 15:30:51 -0700458}
459
460// According to https://tools.ietf.org/html/rfc3264#section-8, the session id
461// stays the same but the version must be incremented if a later, different
462// session description is generated. These two tests verify that is the case for
463// both offers and answers.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800464TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700465 SessionVersionIncrementedInSubsequentDifferentOffer) {
466 auto caller = CreatePeerConnection();
467 auto callee = CreatePeerConnection();
468
469 auto original_offer = caller->CreateOfferAndSetAsLocal();
470 const std::string original_id = original_offer->session_id();
471 const std::string original_version = original_offer->session_version();
472
473 ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
474 ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
475
476 // Add track to get a different offer.
477 caller->AddAudioTrack("a");
478
479 auto later_offer = caller->CreateOffer();
480
481 EXPECT_EQ(original_id, later_offer->session_id());
482 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
483 rtc::FromString<uint64_t>(later_offer->session_version()));
484}
Steve Anton8acdd1a2018-02-07 17:27:36 -0800485TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700486 SessionVersionIncrementedInSubsequentDifferentAnswer) {
487 auto caller = CreatePeerConnection();
488 auto callee = CreatePeerConnection();
489
490 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
491
Steve Antondffead82018-02-06 10:31:29 -0800492 auto original_answer = callee->CreateAnswer();
Steve Anton8d3444d2017-10-20 15:30:51 -0700493 const std::string original_id = original_answer->session_id();
494 const std::string original_version = original_answer->session_version();
495
496 // Add track to get a different answer.
497 callee->AddAudioTrack("a");
498
499 auto later_answer = callee->CreateAnswer();
500
501 EXPECT_EQ(original_id, later_answer->session_id());
502 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
503 rtc::FromString<uint64_t>(later_answer->session_version()));
504}
505
Steve Anton8acdd1a2018-02-07 17:27:36 -0800506TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700507 auto caller = CreatePeerConnectionWithAudioVideo();
508 auto callee = CreatePeerConnectionWithAudioVideo();
509
510 EXPECT_FALSE(caller->initial_offerer());
511 EXPECT_FALSE(callee->initial_offerer());
512
513 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
514
515 EXPECT_TRUE(caller->initial_offerer());
516 EXPECT_FALSE(callee->initial_offerer());
517
518 ASSERT_TRUE(
519 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
520
521 EXPECT_TRUE(caller->initial_offerer());
522 EXPECT_FALSE(callee->initial_offerer());
523}
524
525// Test creating a PeerConnection, request multiple offers, destroy the
526// PeerConnection and make sure we get success/failure callbacks for all of the
527// requests.
528// Background: crbug.com/507307
Steve Anton8acdd1a2018-02-07 17:27:36 -0800529TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700530 auto caller = CreatePeerConnection();
531
532 RTCOfferAnswerOptions options;
533 options.offer_to_receive_audio =
534 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
535
536 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
537 for (auto& observer : observers) {
538 observer =
539 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
540 caller->pc()->CreateOffer(observer, options);
541 }
542
543 // Destroy the PeerConnection.
544 caller.reset(nullptr);
545
546 for (auto& observer : observers) {
547 // We expect to have received a notification now even if the PeerConnection
548 // was terminated. The offer creation may or may not have succeeded, but we
549 // must have received a notification.
550 EXPECT_TRUE(observer->called());
551 }
552}
553
Henrik Boströma3728d32019-10-28 12:09:49 +0100554// Similar to the above test, but by closing the PC first the CreateOffer() will
555// fail "early", which triggers a codepath where the PeerConnection is
556// reponsible for invoking the observer, instead of the normal codepath where
557// the WebRtcSessionDescriptionFactory is responsible for it.
558TEST_P(PeerConnectionSignalingTest, CloseCreateOfferAndShutdown) {
559 auto caller = CreatePeerConnection();
560 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer =
561 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
562 caller->pc()->Close();
563 caller->pc()->CreateOffer(observer, RTCOfferAnswerOptions());
564 caller.reset(nullptr);
565 EXPECT_TRUE(observer->called());
566}
567
Henrik Boström4e196702019-10-30 10:35:50 +0100568TEST_P(PeerConnectionSignalingTest, ImplicitCreateOfferAndShutdown) {
569 auto caller = CreatePeerConnection();
570 auto observer = MockSetSessionDescriptionObserver::Create();
571 caller->pc()->SetLocalDescription(observer);
572 caller.reset(nullptr);
573 EXPECT_FALSE(observer->called());
574}
575
576TEST_P(PeerConnectionSignalingTest, CloseBeforeImplicitCreateOfferAndShutdown) {
577 auto caller = CreatePeerConnection();
578 auto observer = MockSetSessionDescriptionObserver::Create();
579 caller->pc()->Close();
580 caller->pc()->SetLocalDescription(observer);
581 caller.reset(nullptr);
582 EXPECT_FALSE(observer->called());
583}
584
585TEST_P(PeerConnectionSignalingTest, CloseAfterImplicitCreateOfferAndShutdown) {
586 auto caller = CreatePeerConnection();
587 auto observer = MockSetSessionDescriptionObserver::Create();
588 caller->pc()->SetLocalDescription(observer);
589 caller->pc()->Close();
590 caller.reset(nullptr);
591 EXPECT_FALSE(observer->called());
592}
593
Henrik Boströma3728d32019-10-28 12:09:49 +0100594TEST_P(PeerConnectionSignalingTest, SetRemoteDescriptionExecutesImmediately) {
595 auto caller = CreatePeerConnectionWithAudioVideo();
596 auto callee = CreatePeerConnection();
597
598 // This offer will cause receivers to be created.
599 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
600
601 // By not waiting for the observer's callback we can verify that the operation
602 // executed immediately.
603 callee->pc()->SetRemoteDescription(std::move(offer),
604 new MockSetRemoteDescriptionObserver());
605 EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
606}
607
608TEST_P(PeerConnectionSignalingTest, CreateOfferBlocksSetRemoteDescription) {
609 auto caller = CreatePeerConnectionWithAudioVideo();
610 auto callee = CreatePeerConnection();
611
612 // This offer will cause receivers to be created.
613 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
614
615 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
616 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> offer_observer(
617 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
618 // Synchronously invoke CreateOffer() and SetRemoteDescription(). The
619 // SetRemoteDescription() operation should be chained to be executed
620 // asynchronously, when CreateOffer() completes.
621 callee->pc()->CreateOffer(offer_observer, RTCOfferAnswerOptions());
622 callee->pc()->SetRemoteDescription(std::move(offer),
623 new MockSetRemoteDescriptionObserver());
624 // CreateOffer() is asynchronous; without message processing this operation
625 // should not have completed.
626 EXPECT_FALSE(offer_observer->called());
627 // Due to chaining, the receivers should not have been created by the offer
628 // yet.
629 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
630 // EXPECT_TRUE_WAIT causes messages to be processed...
631 EXPECT_TRUE_WAIT(offer_observer->called(), kWaitTimeout);
632 // Now that the offer has been completed, SetRemoteDescription() will have
633 // been executed next in the chain.
634 EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
635}
636
Henrik Boström4e196702019-10-30 10:35:50 +0100637TEST_P(PeerConnectionSignalingTest,
638 ParameterlessSetLocalDescriptionCreatesOffer) {
639 auto caller = CreatePeerConnectionWithAudioVideo();
640
641 auto observer = MockSetSessionDescriptionObserver::Create();
642 caller->pc()->SetLocalDescription(observer);
643
644 // The offer is created asynchronously; message processing is needed for it to
645 // complete.
646 EXPECT_FALSE(observer->called());
647 EXPECT_FALSE(caller->pc()->pending_local_description());
648 EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
649
650 // Wait for messages to be processed.
651 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
652 EXPECT_TRUE(observer->result());
653 EXPECT_TRUE(caller->pc()->pending_local_description());
654 EXPECT_EQ(SdpType::kOffer,
655 caller->pc()->pending_local_description()->GetType());
656 EXPECT_EQ(PeerConnection::kHaveLocalOffer, caller->signaling_state());
657}
658
659TEST_P(PeerConnectionSignalingTest,
660 ParameterlessSetLocalDescriptionCreatesAnswer) {
661 auto caller = CreatePeerConnectionWithAudioVideo();
662 auto callee = CreatePeerConnectionWithAudioVideo();
663
664 callee->SetRemoteDescription(caller->CreateOffer());
665 EXPECT_EQ(PeerConnection::kHaveRemoteOffer, callee->signaling_state());
666
667 auto observer = MockSetSessionDescriptionObserver::Create();
668 callee->pc()->SetLocalDescription(observer);
669
670 // The answer is created asynchronously; message processing is needed for it
671 // to complete.
672 EXPECT_FALSE(observer->called());
673 EXPECT_FALSE(callee->pc()->current_local_description());
674
675 // Wait for messages to be processed.
676 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
677 EXPECT_TRUE(observer->result());
678 EXPECT_TRUE(callee->pc()->current_local_description());
679 EXPECT_EQ(SdpType::kAnswer,
680 callee->pc()->current_local_description()->GetType());
681 EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
682}
683
684TEST_P(PeerConnectionSignalingTest,
685 ParameterlessSetLocalDescriptionFullExchange) {
686 auto caller = CreatePeerConnectionWithAudioVideo();
687 auto callee = CreatePeerConnectionWithAudioVideo();
688
689 // SetLocalDescription(), implicitly creating an offer.
690 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
691 caller_set_local_description_observer(
692 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
693 caller->pc()->SetLocalDescription(caller_set_local_description_observer);
694 EXPECT_TRUE_WAIT(caller_set_local_description_observer->called(),
695 kWaitTimeout);
696 ASSERT_TRUE(caller->pc()->pending_local_description());
697
698 // SetRemoteDescription(offer)
699 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
700 callee_set_remote_description_observer(
701 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
702 callee->pc()->SetRemoteDescription(
703 callee_set_remote_description_observer.get(),
704 CloneSessionDescription(caller->pc()->pending_local_description())
705 .release());
706
707 // SetLocalDescription(), implicitly creating an answer.
708 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
709 callee_set_local_description_observer(
710 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
711 callee->pc()->SetLocalDescription(callee_set_local_description_observer);
712 EXPECT_TRUE_WAIT(callee_set_local_description_observer->called(),
713 kWaitTimeout);
714 // Chaining guarantees SetRemoteDescription() happened before
715 // SetLocalDescription().
716 EXPECT_TRUE(callee_set_remote_description_observer->called());
717 EXPECT_TRUE(callee->pc()->current_local_description());
718
719 // SetRemoteDescription(answer)
720 rtc::scoped_refptr<MockSetSessionDescriptionObserver>
721 caller_set_remote_description_observer(
722 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
723 caller->pc()->SetRemoteDescription(
724 caller_set_remote_description_observer,
725 CloneSessionDescription(callee->pc()->current_local_description())
726 .release());
727 EXPECT_TRUE_WAIT(caller_set_remote_description_observer->called(),
728 kWaitTimeout);
729
730 EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
731 EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
732}
733
734TEST_P(PeerConnectionSignalingTest,
735 ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer) {
736 auto caller = CreatePeerConnectionWithAudioVideo();
737
738 auto observer = MockSetSessionDescriptionObserver::Create();
739 caller->pc()->Close();
740 caller->pc()->SetLocalDescription(observer);
741
742 // The operation should fail asynchronously.
743 EXPECT_FALSE(observer->called());
744 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
745 EXPECT_FALSE(observer->result());
746 // This did not affect the signaling state.
747 EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
748 EXPECT_EQ(
749 "SetLocalDescription failed to create session description - "
750 "SetLocalDescription called when PeerConnection is closed.",
751 observer->error());
752}
753
754TEST_P(PeerConnectionSignalingTest,
755 ParameterlessSetLocalDescriptionCloseWhileCreatingOffer) {
756 auto caller = CreatePeerConnectionWithAudioVideo();
757
758 auto observer = MockSetSessionDescriptionObserver::Create();
759 caller->pc()->SetLocalDescription(observer);
760 caller->pc()->Close();
761
762 // The operation should fail asynchronously.
763 EXPECT_FALSE(observer->called());
764 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
765 EXPECT_FALSE(observer->result());
766 // This did not affect the signaling state.
767 EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
768 EXPECT_EQ(
769 "SetLocalDescription failed to create session description - "
770 "CreateOffer failed because the session was shut down",
771 observer->error());
772}
773
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100774INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
775 PeerConnectionSignalingTest,
776 Values(SdpSemantics::kPlanB,
777 SdpSemantics::kUnifiedPlan));
Steve Anton8acdd1a2018-02-07 17:27:36 -0800778
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100779class PeerConnectionSignalingUnifiedPlanTest
780 : public PeerConnectionSignalingBaseTest {
781 protected:
782 PeerConnectionSignalingUnifiedPlanTest()
783 : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
784};
785
Henrik Boströma3728d32019-10-28 12:09:49 +0100786// We verify that SetLocalDescription() executed immediately by verifying that
787// the transceiver mid values got assigned. SLD executing immeditately is not
788// unique to Unified Plan, but the transceivers used to verify this are only
789// available in Unified Plan.
790TEST_F(PeerConnectionSignalingUnifiedPlanTest,
791 SetLocalDescriptionExecutesImmediately) {
792 auto caller = CreatePeerConnectionWithAudioVideo();
793
794 // This offer will cause transceiver mids to get assigned.
795 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
796
797 // By not waiting for the observer's callback we can verify that the operation
798 // executed immediately.
799 RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
800 caller->pc()->SetLocalDescription(
801 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>(),
802 offer.release());
803 EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
804}
805
806TEST_F(PeerConnectionSignalingUnifiedPlanTest,
807 SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback) {
808 auto caller = CreatePeerConnectionWithAudioVideo();
809
810 // This offer will cause transceiver mids to get assigned.
811 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
812
813 rtc::scoped_refptr<ExecuteFunctionOnCreateSessionDescriptionObserver>
814 offer_observer(new rtc::RefCountedObject<
815 ExecuteFunctionOnCreateSessionDescriptionObserver>(
816 [pc = caller->pc()](SessionDescriptionInterface* desc) {
817 // By not waiting for the observer's callback we can verify that the
818 // operation executed immediately.
819 RTC_DCHECK(!pc->GetTransceivers()[0]->mid().has_value());
820 pc->SetLocalDescription(
821 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>(),
822 desc);
823 EXPECT_TRUE(pc->GetTransceivers()[0]->mid().has_value());
824 }));
825 caller->pc()->CreateOffer(offer_observer, RTCOfferAnswerOptions());
826 EXPECT_TRUE_WAIT(offer_observer->was_called(), kWaitTimeout);
827}
828
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100829// Test that transports are shown in the sender/receiver API after offer/answer.
830// This only works in Unified Plan.
831TEST_F(PeerConnectionSignalingUnifiedPlanTest,
832 DtlsTransportsInstantiateInOfferAnswer) {
833 auto caller = CreatePeerConnectionWithAudioVideo();
834 auto callee = CreatePeerConnection();
835
836 EXPECT_FALSE(HasDtlsTransport(caller));
837 EXPECT_FALSE(HasDtlsTransport(callee));
838 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
839 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
840 EXPECT_TRUE(HasDtlsTransport(caller));
841 callee->SetRemoteDescription(std::move(offer));
842 EXPECT_FALSE(HasDtlsTransport(callee));
843 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
844 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
845 EXPECT_TRUE(HasDtlsTransport(callee));
846 caller->SetRemoteDescription(std::move(answer));
847 EXPECT_TRUE(HasDtlsTransport(caller));
848
849 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
850}
851
852TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
853 auto caller = CreatePeerConnectionWithAudioVideo();
854 auto callee = CreatePeerConnection();
855
856 EXPECT_FALSE(HasDtlsTransport(caller));
857 EXPECT_FALSE(HasDtlsTransport(callee));
858 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
859 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
860 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
861 callee->SetRemoteDescription(std::move(offer));
862 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
863 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
864 caller->SetRemoteDescription(std::move(answer));
865 EXPECT_EQ(1, NumberOfDtlsTransports(caller));
866
867 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
868}
869
870TEST_F(PeerConnectionSignalingUnifiedPlanTest,
871 DtlsTransportsAreSeparateeWhenUnbundled) {
872 auto caller = CreatePeerConnectionWithAudioVideo();
873 auto callee = CreatePeerConnection();
874
875 EXPECT_FALSE(HasDtlsTransport(caller));
876 EXPECT_FALSE(HasDtlsTransport(callee));
877 RTCOfferAnswerOptions unbundle_options;
878 unbundle_options.use_rtp_mux = false;
879 auto offer = caller->CreateOffer(unbundle_options);
880 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
881 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
882 callee->SetRemoteDescription(std::move(offer));
883 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
884 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
885 EXPECT_EQ(2, NumberOfDtlsTransports(callee));
886 caller->SetRemoteDescription(std::move(answer));
887 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
888
889 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
890}
891
Steve Anton8d3444d2017-10-20 15:30:51 -0700892} // namespace webrtc