blob: 9a89fceab255f31c1cb4b0ae95a2c64d8794123e [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öm831ae4e2020-07-29 12:04:00 +0200568TEST_P(PeerConnectionSignalingTest,
569 ImplicitCreateOfferAndShutdownWithOldObserver) {
Henrik Boströmd4089ca2020-07-28 10:39:36 +0200570 auto caller = CreatePeerConnection();
Henrik Boström4c9c75a2020-07-29 09:46:40 +0000571 auto observer = MockSetSessionDescriptionObserver::Create();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200572 caller->pc()->SetLocalDescription(observer.get());
573 caller.reset(nullptr);
574 // The old observer does not get invoked because posted messages are lost.
575 EXPECT_FALSE(observer->called());
576}
577
578TEST_P(PeerConnectionSignalingTest, ImplicitCreateOfferAndShutdown) {
579 auto caller = CreatePeerConnection();
580 rtc::scoped_refptr<FakeSetLocalDescriptionObserver> observer(
581 new FakeSetLocalDescriptionObserver());
Henrik Boström4e196702019-10-30 10:35:50 +0100582 caller->pc()->SetLocalDescription(observer);
583 caller.reset(nullptr);
Henrik Boström831ae4e2020-07-29 12:04:00 +0200584 // The new observer gets invoked because it is called immediately.
585 EXPECT_TRUE(observer->called());
586 EXPECT_FALSE(observer->error().ok());
587}
588
589TEST_P(PeerConnectionSignalingTest,
590 CloseBeforeImplicitCreateOfferAndShutdownWithOldObserver) {
591 auto caller = CreatePeerConnection();
592 auto observer = MockSetSessionDescriptionObserver::Create();
593 caller->pc()->Close();
594 caller->pc()->SetLocalDescription(observer.get());
595 caller.reset(nullptr);
596 // The old observer does not get invoked because posted messages are lost.
Henrik Boström4e196702019-10-30 10:35:50 +0100597 EXPECT_FALSE(observer->called());
598}
599
600TEST_P(PeerConnectionSignalingTest, CloseBeforeImplicitCreateOfferAndShutdown) {
601 auto caller = CreatePeerConnection();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200602 rtc::scoped_refptr<FakeSetLocalDescriptionObserver> observer(
603 new FakeSetLocalDescriptionObserver());
Henrik Boström4e196702019-10-30 10:35:50 +0100604 caller->pc()->Close();
605 caller->pc()->SetLocalDescription(observer);
606 caller.reset(nullptr);
Henrik Boström831ae4e2020-07-29 12:04:00 +0200607 // The new observer gets invoked because it is called immediately.
608 EXPECT_TRUE(observer->called());
609 EXPECT_FALSE(observer->error().ok());
610}
611
612TEST_P(PeerConnectionSignalingTest,
613 CloseAfterImplicitCreateOfferAndShutdownWithOldObserver) {
614 auto caller = CreatePeerConnection();
615 auto observer = MockSetSessionDescriptionObserver::Create();
616 caller->pc()->SetLocalDescription(observer.get());
617 caller->pc()->Close();
618 caller.reset(nullptr);
619 // The old observer does not get invoked because posted messages are lost.
Henrik Boström4e196702019-10-30 10:35:50 +0100620 EXPECT_FALSE(observer->called());
621}
622
623TEST_P(PeerConnectionSignalingTest, CloseAfterImplicitCreateOfferAndShutdown) {
624 auto caller = CreatePeerConnection();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200625 rtc::scoped_refptr<FakeSetLocalDescriptionObserver> observer(
626 new FakeSetLocalDescriptionObserver());
Henrik Boström4e196702019-10-30 10:35:50 +0100627 caller->pc()->SetLocalDescription(observer);
628 caller->pc()->Close();
629 caller.reset(nullptr);
Henrik Boström831ae4e2020-07-29 12:04:00 +0200630 // The new observer gets invoked because it is called immediately.
631 EXPECT_TRUE(observer->called());
632 EXPECT_FALSE(observer->error().ok());
633}
634
635TEST_P(PeerConnectionSignalingTest,
636 SetLocalDescriptionNewObserverIsInvokedImmediately) {
637 auto caller = CreatePeerConnection();
638 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
639
640 rtc::scoped_refptr<FakeSetLocalDescriptionObserver> observer(
641 new FakeSetLocalDescriptionObserver());
642 caller->pc()->SetLocalDescription(std::move(offer), observer);
643 // The new observer is invoked immediately.
644 EXPECT_TRUE(observer->called());
645 EXPECT_TRUE(observer->error().ok());
646}
647
648TEST_P(PeerConnectionSignalingTest,
649 SetLocalDescriptionOldObserverIsInvokedInAPostedMessage) {
650 auto caller = CreatePeerConnection();
651 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
652
653 auto observer = MockSetSessionDescriptionObserver::Create();
654 caller->pc()->SetLocalDescription(observer, offer.release());
655 // The old observer is not invoked immediately.
Henrik Boström4e196702019-10-30 10:35:50 +0100656 EXPECT_FALSE(observer->called());
Henrik Boström831ae4e2020-07-29 12:04:00 +0200657 // Process all currently pending messages by waiting for a posted task to run.
658 bool checkpoint_reached = false;
659 rtc::Thread::Current()->PostTask(
660 RTC_FROM_HERE, [&checkpoint_reached] { checkpoint_reached = true; });
661 EXPECT_TRUE_WAIT(checkpoint_reached, kWaitTimeout);
662 // If resolving the observer was pending, it must now have been called.
663 EXPECT_TRUE(observer->called());
Henrik Boström4e196702019-10-30 10:35:50 +0100664}
665
Henrik Boströma3728d32019-10-28 12:09:49 +0100666TEST_P(PeerConnectionSignalingTest, SetRemoteDescriptionExecutesImmediately) {
667 auto caller = CreatePeerConnectionWithAudioVideo();
668 auto callee = CreatePeerConnection();
669
670 // This offer will cause receivers to be created.
671 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
672
673 // By not waiting for the observer's callback we can verify that the operation
674 // executed immediately.
675 callee->pc()->SetRemoteDescription(std::move(offer),
Henrik Boström831ae4e2020-07-29 12:04:00 +0200676 new FakeSetRemoteDescriptionObserver());
Henrik Boströma3728d32019-10-28 12:09:49 +0100677 EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
678}
679
680TEST_P(PeerConnectionSignalingTest, CreateOfferBlocksSetRemoteDescription) {
681 auto caller = CreatePeerConnectionWithAudioVideo();
682 auto callee = CreatePeerConnection();
683
684 // This offer will cause receivers to be created.
685 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
686
687 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
688 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> offer_observer(
689 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
690 // Synchronously invoke CreateOffer() and SetRemoteDescription(). The
691 // SetRemoteDescription() operation should be chained to be executed
692 // asynchronously, when CreateOffer() completes.
693 callee->pc()->CreateOffer(offer_observer, RTCOfferAnswerOptions());
694 callee->pc()->SetRemoteDescription(std::move(offer),
Henrik Boström831ae4e2020-07-29 12:04:00 +0200695 new FakeSetRemoteDescriptionObserver());
Henrik Boströma3728d32019-10-28 12:09:49 +0100696 // CreateOffer() is asynchronous; without message processing this operation
697 // should not have completed.
698 EXPECT_FALSE(offer_observer->called());
699 // Due to chaining, the receivers should not have been created by the offer
700 // yet.
701 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
702 // EXPECT_TRUE_WAIT causes messages to be processed...
703 EXPECT_TRUE_WAIT(offer_observer->called(), kWaitTimeout);
704 // Now that the offer has been completed, SetRemoteDescription() will have
705 // been executed next in the chain.
706 EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
707}
708
Henrik Boström4e196702019-10-30 10:35:50 +0100709TEST_P(PeerConnectionSignalingTest,
710 ParameterlessSetLocalDescriptionCreatesOffer) {
711 auto caller = CreatePeerConnectionWithAudioVideo();
712
713 auto observer = MockSetSessionDescriptionObserver::Create();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200714 caller->pc()->SetLocalDescription(observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100715
716 // The offer is created asynchronously; message processing is needed for it to
717 // complete.
718 EXPECT_FALSE(observer->called());
719 EXPECT_FALSE(caller->pc()->pending_local_description());
720 EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
721
722 // Wait for messages to be processed.
723 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
724 EXPECT_TRUE(observer->result());
725 EXPECT_TRUE(caller->pc()->pending_local_description());
726 EXPECT_EQ(SdpType::kOffer,
727 caller->pc()->pending_local_description()->GetType());
728 EXPECT_EQ(PeerConnection::kHaveLocalOffer, caller->signaling_state());
729}
730
731TEST_P(PeerConnectionSignalingTest,
732 ParameterlessSetLocalDescriptionCreatesAnswer) {
733 auto caller = CreatePeerConnectionWithAudioVideo();
734 auto callee = CreatePeerConnectionWithAudioVideo();
735
736 callee->SetRemoteDescription(caller->CreateOffer());
737 EXPECT_EQ(PeerConnection::kHaveRemoteOffer, callee->signaling_state());
738
739 auto observer = MockSetSessionDescriptionObserver::Create();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200740 callee->pc()->SetLocalDescription(observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100741
742 // The answer is created asynchronously; message processing is needed for it
743 // to complete.
744 EXPECT_FALSE(observer->called());
745 EXPECT_FALSE(callee->pc()->current_local_description());
746
747 // Wait for messages to be processed.
748 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
749 EXPECT_TRUE(observer->result());
750 EXPECT_TRUE(callee->pc()->current_local_description());
751 EXPECT_EQ(SdpType::kAnswer,
752 callee->pc()->current_local_description()->GetType());
753 EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
754}
755
756TEST_P(PeerConnectionSignalingTest,
757 ParameterlessSetLocalDescriptionFullExchange) {
758 auto caller = CreatePeerConnectionWithAudioVideo();
759 auto callee = CreatePeerConnectionWithAudioVideo();
760
761 // SetLocalDescription(), implicitly creating an offer.
Henrik Boström831ae4e2020-07-29 12:04:00 +0200762 auto caller_set_local_description_observer =
763 MockSetSessionDescriptionObserver::Create();
764 caller->pc()->SetLocalDescription(
765 caller_set_local_description_observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100766 EXPECT_TRUE_WAIT(caller_set_local_description_observer->called(),
767 kWaitTimeout);
768 ASSERT_TRUE(caller->pc()->pending_local_description());
769
770 // SetRemoteDescription(offer)
Henrik Boström831ae4e2020-07-29 12:04:00 +0200771 auto callee_set_remote_description_observer =
772 MockSetSessionDescriptionObserver::Create();
Henrik Boström4e196702019-10-30 10:35:50 +0100773 callee->pc()->SetRemoteDescription(
Henrik Boström831ae4e2020-07-29 12:04:00 +0200774 callee_set_remote_description_observer,
Henrik Boström4e196702019-10-30 10:35:50 +0100775 CloneSessionDescription(caller->pc()->pending_local_description())
776 .release());
777
778 // SetLocalDescription(), implicitly creating an answer.
Henrik Boström831ae4e2020-07-29 12:04:00 +0200779 auto callee_set_local_description_observer =
780 MockSetSessionDescriptionObserver::Create();
781 callee->pc()->SetLocalDescription(
782 callee_set_local_description_observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100783 EXPECT_TRUE_WAIT(callee_set_local_description_observer->called(),
784 kWaitTimeout);
785 // Chaining guarantees SetRemoteDescription() happened before
786 // SetLocalDescription().
787 EXPECT_TRUE(callee_set_remote_description_observer->called());
788 EXPECT_TRUE(callee->pc()->current_local_description());
789
790 // SetRemoteDescription(answer)
Henrik Boström831ae4e2020-07-29 12:04:00 +0200791 auto caller_set_remote_description_observer =
792 MockSetSessionDescriptionObserver::Create();
Henrik Boström4e196702019-10-30 10:35:50 +0100793 caller->pc()->SetRemoteDescription(
794 caller_set_remote_description_observer,
795 CloneSessionDescription(callee->pc()->current_local_description())
796 .release());
797 EXPECT_TRUE_WAIT(caller_set_remote_description_observer->called(),
798 kWaitTimeout);
799
800 EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
801 EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
802}
803
804TEST_P(PeerConnectionSignalingTest,
805 ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer) {
806 auto caller = CreatePeerConnectionWithAudioVideo();
807
808 auto observer = MockSetSessionDescriptionObserver::Create();
809 caller->pc()->Close();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200810 caller->pc()->SetLocalDescription(observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100811
812 // The operation should fail asynchronously.
813 EXPECT_FALSE(observer->called());
814 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
815 EXPECT_FALSE(observer->result());
816 // This did not affect the signaling state.
817 EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
818 EXPECT_EQ(
819 "SetLocalDescription failed to create session description - "
820 "SetLocalDescription called when PeerConnection is closed.",
821 observer->error());
822}
823
824TEST_P(PeerConnectionSignalingTest,
825 ParameterlessSetLocalDescriptionCloseWhileCreatingOffer) {
826 auto caller = CreatePeerConnectionWithAudioVideo();
827
828 auto observer = MockSetSessionDescriptionObserver::Create();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200829 caller->pc()->SetLocalDescription(observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100830 caller->pc()->Close();
831
832 // The operation should fail asynchronously.
833 EXPECT_FALSE(observer->called());
834 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
835 EXPECT_FALSE(observer->result());
836 // This did not affect the signaling state.
837 EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
838 EXPECT_EQ(
839 "SetLocalDescription failed to create session description - "
840 "CreateOffer failed because the session was shut down",
841 observer->error());
842}
843
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100844INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
845 PeerConnectionSignalingTest,
846 Values(SdpSemantics::kPlanB,
847 SdpSemantics::kUnifiedPlan));
Steve Anton8acdd1a2018-02-07 17:27:36 -0800848
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100849class PeerConnectionSignalingUnifiedPlanTest
850 : public PeerConnectionSignalingBaseTest {
851 protected:
852 PeerConnectionSignalingUnifiedPlanTest()
853 : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
854};
855
Henrik Boströma3728d32019-10-28 12:09:49 +0100856// We verify that SetLocalDescription() executed immediately by verifying that
857// the transceiver mid values got assigned. SLD executing immeditately is not
858// unique to Unified Plan, but the transceivers used to verify this are only
859// available in Unified Plan.
860TEST_F(PeerConnectionSignalingUnifiedPlanTest,
Henrik Boström831ae4e2020-07-29 12:04:00 +0200861 SetLocalDescriptionExecutesImmediatelyUsingOldObserver) {
Henrik Boströma3728d32019-10-28 12:09:49 +0100862 auto caller = CreatePeerConnectionWithAudioVideo();
863
864 // This offer will cause transceiver mids to get assigned.
865 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
866
867 // By not waiting for the observer's callback we can verify that the operation
Henrik Boström831ae4e2020-07-29 12:04:00 +0200868 // executed immediately. The old observer is invoked in a posted message, so
869 // waiting for it would not ensure synchronicity.
Henrik Boströma3728d32019-10-28 12:09:49 +0100870 RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
871 caller->pc()->SetLocalDescription(
872 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>(),
873 offer.release());
874 EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
875}
876
877TEST_F(PeerConnectionSignalingUnifiedPlanTest,
Henrik Boström831ae4e2020-07-29 12:04:00 +0200878 SetLocalDescriptionExecutesImmediatelyUsingNewObserver) {
879 auto caller = CreatePeerConnectionWithAudioVideo();
880
881 // This offer will cause transceiver mids to get assigned.
882 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
883
884 // Verify that mids were assigned without waiting for the observer. (However,
885 // the new observer should also be invoked synchronously - as is ensured by
886 // other tests.)
887 RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
888 caller->pc()->SetLocalDescription(std::move(offer),
889 new FakeSetLocalDescriptionObserver());
890 EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
891}
892
893TEST_F(PeerConnectionSignalingUnifiedPlanTest,
Henrik Boströma3728d32019-10-28 12:09:49 +0100894 SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback) {
895 auto caller = CreatePeerConnectionWithAudioVideo();
896
897 // This offer will cause transceiver mids to get assigned.
898 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
899
900 rtc::scoped_refptr<ExecuteFunctionOnCreateSessionDescriptionObserver>
901 offer_observer(new rtc::RefCountedObject<
902 ExecuteFunctionOnCreateSessionDescriptionObserver>(
903 [pc = caller->pc()](SessionDescriptionInterface* desc) {
904 // By not waiting for the observer's callback we can verify that the
905 // operation executed immediately.
906 RTC_DCHECK(!pc->GetTransceivers()[0]->mid().has_value());
907 pc->SetLocalDescription(
908 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>(),
909 desc);
910 EXPECT_TRUE(pc->GetTransceivers()[0]->mid().has_value());
911 }));
912 caller->pc()->CreateOffer(offer_observer, RTCOfferAnswerOptions());
913 EXPECT_TRUE_WAIT(offer_observer->was_called(), kWaitTimeout);
914}
915
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100916// Test that transports are shown in the sender/receiver API after offer/answer.
917// This only works in Unified Plan.
918TEST_F(PeerConnectionSignalingUnifiedPlanTest,
919 DtlsTransportsInstantiateInOfferAnswer) {
920 auto caller = CreatePeerConnectionWithAudioVideo();
921 auto callee = CreatePeerConnection();
922
923 EXPECT_FALSE(HasDtlsTransport(caller));
924 EXPECT_FALSE(HasDtlsTransport(callee));
925 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
926 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
927 EXPECT_TRUE(HasDtlsTransport(caller));
928 callee->SetRemoteDescription(std::move(offer));
929 EXPECT_FALSE(HasDtlsTransport(callee));
930 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
931 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
932 EXPECT_TRUE(HasDtlsTransport(callee));
933 caller->SetRemoteDescription(std::move(answer));
934 EXPECT_TRUE(HasDtlsTransport(caller));
935
936 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
937}
938
939TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
940 auto caller = CreatePeerConnectionWithAudioVideo();
941 auto callee = CreatePeerConnection();
942
943 EXPECT_FALSE(HasDtlsTransport(caller));
944 EXPECT_FALSE(HasDtlsTransport(callee));
945 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
946 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
947 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
948 callee->SetRemoteDescription(std::move(offer));
949 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
950 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
951 caller->SetRemoteDescription(std::move(answer));
952 EXPECT_EQ(1, NumberOfDtlsTransports(caller));
953
954 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
955}
956
957TEST_F(PeerConnectionSignalingUnifiedPlanTest,
958 DtlsTransportsAreSeparateeWhenUnbundled) {
959 auto caller = CreatePeerConnectionWithAudioVideo();
960 auto callee = CreatePeerConnection();
961
962 EXPECT_FALSE(HasDtlsTransport(caller));
963 EXPECT_FALSE(HasDtlsTransport(callee));
964 RTCOfferAnswerOptions unbundle_options;
965 unbundle_options.use_rtp_mux = false;
966 auto offer = caller->CreateOffer(unbundle_options);
967 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
968 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
969 callee->SetRemoteDescription(std::move(offer));
970 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
971 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
972 EXPECT_EQ(2, NumberOfDtlsTransports(callee));
973 caller->SetRemoteDescription(std::move(answer));
974 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
975
976 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
977}
978
Henrik Boströme574a312020-08-25 10:20:11 +0200979TEST_F(PeerConnectionSignalingUnifiedPlanTest,
980 ShouldFireNegotiationNeededWhenNoChangesArePending) {
981 auto caller = CreatePeerConnection();
982 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
983 auto transceiver =
984 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
985 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
986 EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
987 caller->observer()->latest_negotiation_needed_event()));
988}
989
990TEST_F(PeerConnectionSignalingUnifiedPlanTest,
991 SuppressNegotiationNeededWhenOperationChainIsNotEmpty) {
992 auto caller = CreatePeerConnection();
993 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
994 auto transceiver =
995 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
996 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
997
998 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer =
999 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
1000 caller->pc()->CreateOffer(observer, RTCOfferAnswerOptions());
1001 // For this test to work, the operation has to be pending, i.e. the observer
1002 // has not yet been invoked.
1003 EXPECT_FALSE(observer->called());
1004 // Because the Operations Chain is not empty, the event is now suppressed.
1005 EXPECT_FALSE(caller->pc()->ShouldFireNegotiationNeededEvent(
1006 caller->observer()->latest_negotiation_needed_event()));
1007 caller->observer()->clear_latest_negotiation_needed_event();
1008
1009 // When the Operations Chain becomes empty again, a new negotiation needed
1010 // event will be generated that is not suppressed.
1011 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
1012 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1013 EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
1014 caller->observer()->latest_negotiation_needed_event()));
1015}
1016
1017TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1018 SuppressNegotiationNeededWhenSignalingStateIsNotStable) {
1019 auto caller = CreatePeerConnection();
1020 auto callee = CreatePeerConnection();
1021 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1022
1023 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1024 auto transceiver =
1025 callee->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1026 EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
1027
1028 // Change signaling state (to "have-remote-offer") by setting a remote offer.
1029 callee->SetRemoteDescription(std::move(offer));
1030 // Because the signaling state is not "stable", the event is now suppressed.
1031 EXPECT_FALSE(callee->pc()->ShouldFireNegotiationNeededEvent(
1032 callee->observer()->latest_negotiation_needed_event()));
1033 callee->observer()->clear_latest_negotiation_needed_event();
1034
1035 // Upon rolling back to "stable", a new negotiation needed event will be
1036 // generated that is not suppressed.
1037 callee->SetLocalDescription(CreateSessionDescription(SdpType::kRollback, ""));
1038 EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
1039 EXPECT_TRUE(callee->pc()->ShouldFireNegotiationNeededEvent(
1040 callee->observer()->latest_negotiation_needed_event()));
1041}
1042
Steve Anton8d3444d2017-10-20 15:30:51 -07001043} // namespace webrtc