blob: 605a1338c65140c4962946a7005a1db7d43efc68 [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"
Philipp Hancke4e8c1152020-10-13 12:43:15 +020020#include "api/jsep_session_description.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "api/peer_connection_proxy.h"
Anders Carlsson67537952018-05-03 11:28:29 +020022#include "api/video_codecs/builtin_video_decoder_factory.h"
23#include "api/video_codecs/builtin_video_encoder_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "pc/peer_connection.h"
25#include "pc/peer_connection_wrapper.h"
26#include "pc/sdp_utils.h"
Philipp Hancke4e8c1152020-10-13 12:43:15 +020027#include "pc/webrtc_sdp.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070028#ifdef WEBRTC_ANDROID
Steve Anton10542f22019-01-11 09:11:00 -080029#include "pc/test/android_test_initializer.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070030#endif
Steve Anton10542f22019-01-11 09:11:00 -080031#include "pc/test/fake_audio_capture_module.h"
32#include "pc/test/fake_rtc_certificate_generator.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070033#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080034#include "rtc_base/virtual_socket_server.h"
Steve Anton8d3444d2017-10-20 15:30:51 -070035#include "test/gmock.h"
36
37namespace webrtc {
38
39using SignalingState = PeerConnectionInterface::SignalingState;
40using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
41using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
42using ::testing::Bool;
43using ::testing::Combine;
44using ::testing::Values;
45
Henrik Boströma3728d32019-10-28 12:09:49 +010046namespace {
47const int64_t kWaitTimeout = 10000;
48} // namespace
49
Steve Anton8d3444d2017-10-20 15:30:51 -070050class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
51 public:
52 using PeerConnectionWrapper::PeerConnectionWrapper;
53
54 bool initial_offerer() {
55 return GetInternalPeerConnection()->initial_offerer();
56 }
57
58 PeerConnection* GetInternalPeerConnection() {
Mirko Bonadeie97de912017-12-13 11:29:34 +010059 auto* pci =
60 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
61 pc());
62 return static_cast<PeerConnection*>(pci->internal());
Steve Anton8d3444d2017-10-20 15:30:51 -070063 }
64};
65
Henrik Boströma3728d32019-10-28 12:09:49 +010066class ExecuteFunctionOnCreateSessionDescriptionObserver
67 : public CreateSessionDescriptionObserver {
68 public:
69 ExecuteFunctionOnCreateSessionDescriptionObserver(
70 std::function<void(SessionDescriptionInterface*)> function)
71 : function_(std::move(function)) {}
72 ~ExecuteFunctionOnCreateSessionDescriptionObserver() override {
73 RTC_DCHECK(was_called_);
74 }
75
76 bool was_called() const { return was_called_; }
77
78 void OnSuccess(SessionDescriptionInterface* desc) override {
79 RTC_DCHECK(!was_called_);
80 was_called_ = true;
81 function_(desc);
82 }
83
84 void OnFailure(RTCError error) override { RTC_NOTREACHED(); }
85
86 private:
87 bool was_called_ = false;
88 std::function<void(SessionDescriptionInterface*)> function_;
89};
90
Steve Anton8acdd1a2018-02-07 17:27:36 -080091class PeerConnectionSignalingBaseTest : public ::testing::Test {
Steve Anton8d3444d2017-10-20 15:30:51 -070092 protected:
93 typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;
94
Steve Anton8acdd1a2018-02-07 17:27:36 -080095 explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
96 : vss_(new rtc::VirtualSocketServer()),
97 main_(vss_.get()),
98 sdp_semantics_(sdp_semantics) {
Steve Anton8d3444d2017-10-20 15:30:51 -070099#ifdef WEBRTC_ANDROID
100 InitializeAndroidObjects();
101#endif
102 pc_factory_ = CreatePeerConnectionFactory(
103 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
Anders Carlsson67537952018-05-03 11:28:29 +0200104 rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
105 CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
106 CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
107 nullptr /* audio_mixer */, nullptr /* audio_processing */);
Steve Anton8d3444d2017-10-20 15:30:51 -0700108 }
109
110 WrapperPtr CreatePeerConnection() {
111 return CreatePeerConnection(RTCConfiguration());
112 }
113
114 WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200115 auto observer = std::make_unique<MockPeerConnectionObserver>();
Steve Anton8acdd1a2018-02-07 17:27:36 -0800116 RTCConfiguration modified_config = config;
117 modified_config.sdp_semantics = sdp_semantics_;
118 auto pc = pc_factory_->CreatePeerConnection(modified_config, nullptr,
119 nullptr, observer.get());
Steve Anton8d3444d2017-10-20 15:30:51 -0700120 if (!pc) {
121 return nullptr;
122 }
123
Yves Gerey4e933292018-10-31 15:36:05 +0100124 observer->SetPeerConnectionInterface(pc.get());
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200125 return std::make_unique<PeerConnectionWrapperForSignalingTest>(
Steve Anton8d3444d2017-10-20 15:30:51 -0700126 pc_factory_, pc, std::move(observer));
127 }
128
129 // Accepts the same arguments as CreatePeerConnection and adds default audio
130 // and video tracks.
131 template <typename... Args>
132 WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
133 auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
134 if (!wrapper) {
135 return nullptr;
136 }
137 wrapper->AddAudioTrack("a");
138 wrapper->AddVideoTrack("v");
139 return wrapper;
140 }
141
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100142 int NumberOfDtlsTransports(const WrapperPtr& pc_wrapper) {
143 std::set<DtlsTransportInterface*> transports;
144 auto transceivers = pc_wrapper->pc()->GetTransceivers();
145
146 for (auto& transceiver : transceivers) {
147 if (transceiver->sender()->dtls_transport()) {
148 EXPECT_TRUE(transceiver->receiver()->dtls_transport());
149 EXPECT_EQ(transceiver->sender()->dtls_transport().get(),
150 transceiver->receiver()->dtls_transport().get());
151 transports.insert(transceiver->sender()->dtls_transport().get());
152 } else {
153 // If one transceiver is missing, they all should be.
154 EXPECT_EQ(0UL, transports.size());
155 }
156 }
157 return transports.size();
158 }
159
160 bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
161 return NumberOfDtlsTransports(pc_wrapper) > 0;
162 }
163
Steve Anton8d3444d2017-10-20 15:30:51 -0700164 std::unique_ptr<rtc::VirtualSocketServer> vss_;
165 rtc::AutoSocketServerThread main_;
166 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
Steve Anton8acdd1a2018-02-07 17:27:36 -0800167 const SdpSemantics sdp_semantics_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700168};
169
Steve Anton8acdd1a2018-02-07 17:27:36 -0800170class PeerConnectionSignalingTest
171 : public PeerConnectionSignalingBaseTest,
172 public ::testing::WithParamInterface<SdpSemantics> {
173 protected:
174 PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
175};
176
177TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700178 auto caller = CreatePeerConnection();
179
180 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
181 EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
182}
183
Steve Anton8acdd1a2018-02-07 17:27:36 -0800184TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700185 auto caller = CreatePeerConnection();
186 auto callee = CreatePeerConnection();
187
188 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
189 EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
190}
191
Steve Anton8acdd1a2018-02-07 17:27:36 -0800192TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700193 auto caller = CreatePeerConnection();
194 std::string error;
195 ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
196 EXPECT_EQ("SessionDescription is NULL.", error);
197}
198
Steve Anton8acdd1a2018-02-07 17:27:36 -0800199TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700200 auto caller = CreatePeerConnection();
201 std::string error;
202 ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
203 EXPECT_EQ("SessionDescription is NULL.", error);
204}
205
206// The following parameterized test verifies that calls to various signaling
207// methods on PeerConnection will succeed/fail depending on what is the
208// PeerConnection's signaling state. Note that the test tries many different
209// forms of SignalingState::kClosed by arriving at a valid state then calling
210// |Close()|. This is intended to catch cases where the PeerConnection signaling
211// method ignores the closed flag but may work/not work because of the single
212// state the PeerConnection was created in before it was closed.
213
214class PeerConnectionSignalingStateTest
Steve Anton8acdd1a2018-02-07 17:27:36 -0800215 : public PeerConnectionSignalingBaseTest,
216 public ::testing::WithParamInterface<
217 std::tuple<SdpSemantics, SignalingState, bool>> {
Steve Anton8d3444d2017-10-20 15:30:51 -0700218 protected:
Steve Anton8acdd1a2018-02-07 17:27:36 -0800219 PeerConnectionSignalingStateTest()
220 : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
221 state_under_test_(std::make_tuple(std::get<1>(GetParam()),
222 std::get<2>(GetParam()))) {}
223
Steve Anton8d3444d2017-10-20 15:30:51 -0700224 RTCConfiguration GetConfig() {
225 RTCConfiguration config;
226 config.certificates.push_back(
227 FakeRTCCertificateGenerator::GenerateCertificate());
228 return config;
229 }
230
Steve Anton8acdd1a2018-02-07 17:27:36 -0800231 WrapperPtr CreatePeerConnectionUnderTest() {
232 return CreatePeerConnectionInState(state_under_test_);
233 }
234
Steve Anton8d3444d2017-10-20 15:30:51 -0700235 WrapperPtr CreatePeerConnectionInState(SignalingState state) {
236 return CreatePeerConnectionInState(std::make_tuple(state, false));
237 }
238
239 WrapperPtr CreatePeerConnectionInState(
240 std::tuple<SignalingState, bool> state_tuple) {
241 SignalingState state = std::get<0>(state_tuple);
242 bool closed = std::get<1>(state_tuple);
243
244 auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
245 switch (state) {
246 case SignalingState::kStable: {
247 break;
248 }
249 case SignalingState::kHaveLocalOffer: {
250 wrapper->SetLocalDescription(wrapper->CreateOffer());
251 break;
252 }
253 case SignalingState::kHaveLocalPrAnswer: {
254 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
255 wrapper->SetRemoteDescription(caller->CreateOffer());
256 auto answer = wrapper->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800257 wrapper->SetLocalDescription(
258 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700259 break;
260 }
261 case SignalingState::kHaveRemoteOffer: {
262 auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
263 wrapper->SetRemoteDescription(caller->CreateOffer());
264 break;
265 }
266 case SignalingState::kHaveRemotePrAnswer: {
267 auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
268 callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
269 auto answer = callee->CreateAnswer();
Steve Antona3a92c22017-12-07 10:27:41 -0800270 wrapper->SetRemoteDescription(
271 CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
Steve Anton8d3444d2017-10-20 15:30:51 -0700272 break;
273 }
274 case SignalingState::kClosed: {
275 RTC_NOTREACHED() << "Set the second member of the tuple to true to "
276 "achieve a closed state from an existing, valid "
277 "state.";
278 }
279 }
280
281 RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());
282
283 if (closed) {
284 wrapper->pc()->Close();
285 RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
286 }
287
288 return wrapper;
289 }
Steve Anton8acdd1a2018-02-07 17:27:36 -0800290
291 std::tuple<SignalingState, bool> state_under_test_;
Steve Anton8d3444d2017-10-20 15:30:51 -0700292};
293
Steve Anton8d3444d2017-10-20 15:30:51 -0700294TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800295 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700296 if (wrapper->signaling_state() != SignalingState::kClosed) {
297 EXPECT_TRUE(wrapper->CreateOffer());
298 } else {
299 std::string error;
300 ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
301 EXPECT_PRED_FORMAT2(AssertStartsWith, error,
302 "CreateOffer called when PeerConnection is closed.");
303 }
304}
305
306TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800307 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700308 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
309 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
310 EXPECT_TRUE(wrapper->CreateAnswer());
311 } else {
312 std::string error;
313 ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
Steve Antondffead82018-02-06 10:31:29 -0800314 EXPECT_EQ(error,
315 "PeerConnection cannot create an answer in a state other than "
316 "have-remote-offer or have-local-pranswer.");
Steve Anton8d3444d2017-10-20 15:30:51 -0700317 }
318}
319
320TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
Steve Anton8acdd1a2018-02-07 17:27:36 -0800321 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700322 if (wrapper->signaling_state() == SignalingState::kStable ||
323 wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
324 // Need to call CreateOffer on the PeerConnection under test, otherwise when
325 // setting the local offer it will want to verify the DTLS fingerprint
326 // against the locally generated certificate, but without a call to
327 // CreateOffer the certificate will never be generated.
328 EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
329 } else {
330 auto wrapper_for_offer =
331 CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
332 auto offer =
333 CloneSessionDescription(wrapper_for_offer->pc()->local_description());
334
335 std::string error;
336 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
337 EXPECT_PRED_FORMAT2(
338 AssertStartsWith, error,
339 "Failed to set local offer sdp: Called in wrong state:");
340 }
341}
342
343TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
344 auto wrapper_for_pranswer =
345 CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
346 auto pranswer =
347 CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
348
Steve Anton8acdd1a2018-02-07 17:27:36 -0800349 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700350 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
351 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
352 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
353 } else {
354 std::string error;
355 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
356 EXPECT_PRED_FORMAT2(
357 AssertStartsWith, error,
358 "Failed to set local pranswer sdp: Called in wrong state:");
359 }
360}
361
362TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
363 auto wrapper_for_answer =
364 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
365 auto answer = wrapper_for_answer->CreateAnswer();
366
Steve Anton8acdd1a2018-02-07 17:27:36 -0800367 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700368 if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
369 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
370 EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
371 } else {
372 std::string error;
373 ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
374 EXPECT_PRED_FORMAT2(
375 AssertStartsWith, error,
376 "Failed to set local answer sdp: Called in wrong state:");
377 }
378}
379
380TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
381 auto wrapper_for_offer =
382 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
383 auto offer =
384 CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
385
Steve Anton8acdd1a2018-02-07 17:27:36 -0800386 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700387 if (wrapper->signaling_state() == SignalingState::kStable ||
388 wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
389 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
390 } else {
391 std::string error;
392 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
393 EXPECT_PRED_FORMAT2(
394 AssertStartsWith, error,
395 "Failed to set remote offer sdp: Called in wrong state:");
396 }
397}
398
399TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
400 auto wrapper_for_pranswer =
401 CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
402 auto pranswer =
403 CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
404
Steve Anton8acdd1a2018-02-07 17:27:36 -0800405 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700406 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
407 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
408 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
409 } else {
410 std::string error;
411 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
412 EXPECT_PRED_FORMAT2(
413 AssertStartsWith, error,
414 "Failed to set remote pranswer sdp: Called in wrong state:");
415 }
416}
417
418TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
419 auto wrapper_for_answer =
420 CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
421 auto answer = wrapper_for_answer->CreateAnswer();
422
Steve Anton8acdd1a2018-02-07 17:27:36 -0800423 auto wrapper = CreatePeerConnectionUnderTest();
Steve Anton8d3444d2017-10-20 15:30:51 -0700424 if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
425 wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
426 EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
427 } else {
428 std::string error;
429 ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
430 EXPECT_PRED_FORMAT2(
431 AssertStartsWith, error,
432 "Failed to set remote answer sdp: Called in wrong state:");
433 }
434}
435
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100436INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
437 PeerConnectionSignalingStateTest,
438 Combine(Values(SdpSemantics::kPlanB,
439 SdpSemantics::kUnifiedPlan),
440 Values(SignalingState::kStable,
441 SignalingState::kHaveLocalOffer,
442 SignalingState::kHaveLocalPrAnswer,
443 SignalingState::kHaveRemoteOffer,
444 SignalingState::kHaveRemotePrAnswer),
445 Bool()));
Steve Anton8d3444d2017-10-20 15:30:51 -0700446
Steve Antondffead82018-02-06 10:31:29 -0800447// Test that CreateAnswer fails if a round of offer/answer has been done and
448// the PeerConnection is in the stable state.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800449TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700450 auto caller = CreatePeerConnection();
451 auto callee = CreatePeerConnection();
452
Steve Antondffead82018-02-06 10:31:29 -0800453 ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
Oleh Prypinc22d6a82018-02-02 08:42:18 +0000454
455 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
Steve Antondffead82018-02-06 10:31:29 -0800456 EXPECT_FALSE(caller->CreateAnswer());
457
458 ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
459 EXPECT_FALSE(callee->CreateAnswer());
Steve Anton8d3444d2017-10-20 15:30:51 -0700460}
461
462// According to https://tools.ietf.org/html/rfc3264#section-8, the session id
463// stays the same but the version must be incremented if a later, different
464// session description is generated. These two tests verify that is the case for
465// both offers and answers.
Steve Anton8acdd1a2018-02-07 17:27:36 -0800466TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700467 SessionVersionIncrementedInSubsequentDifferentOffer) {
468 auto caller = CreatePeerConnection();
469 auto callee = CreatePeerConnection();
470
471 auto original_offer = caller->CreateOfferAndSetAsLocal();
472 const std::string original_id = original_offer->session_id();
473 const std::string original_version = original_offer->session_version();
474
475 ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
476 ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));
477
478 // Add track to get a different offer.
479 caller->AddAudioTrack("a");
480
481 auto later_offer = caller->CreateOffer();
482
483 EXPECT_EQ(original_id, later_offer->session_id());
484 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
485 rtc::FromString<uint64_t>(later_offer->session_version()));
486}
Steve Anton8acdd1a2018-02-07 17:27:36 -0800487TEST_P(PeerConnectionSignalingTest,
Steve Anton8d3444d2017-10-20 15:30:51 -0700488 SessionVersionIncrementedInSubsequentDifferentAnswer) {
489 auto caller = CreatePeerConnection();
490 auto callee = CreatePeerConnection();
491
492 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
493
Steve Antondffead82018-02-06 10:31:29 -0800494 auto original_answer = callee->CreateAnswer();
Steve Anton8d3444d2017-10-20 15:30:51 -0700495 const std::string original_id = original_answer->session_id();
496 const std::string original_version = original_answer->session_version();
497
498 // Add track to get a different answer.
499 callee->AddAudioTrack("a");
500
501 auto later_answer = callee->CreateAnswer();
502
503 EXPECT_EQ(original_id, later_answer->session_id());
504 EXPECT_LT(rtc::FromString<uint64_t>(original_version),
505 rtc::FromString<uint64_t>(later_answer->session_version()));
506}
507
Steve Anton8acdd1a2018-02-07 17:27:36 -0800508TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700509 auto caller = CreatePeerConnectionWithAudioVideo();
510 auto callee = CreatePeerConnectionWithAudioVideo();
511
512 EXPECT_FALSE(caller->initial_offerer());
513 EXPECT_FALSE(callee->initial_offerer());
514
515 ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
516
517 EXPECT_TRUE(caller->initial_offerer());
518 EXPECT_FALSE(callee->initial_offerer());
519
520 ASSERT_TRUE(
521 caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
522
523 EXPECT_TRUE(caller->initial_offerer());
524 EXPECT_FALSE(callee->initial_offerer());
525}
526
527// Test creating a PeerConnection, request multiple offers, destroy the
528// PeerConnection and make sure we get success/failure callbacks for all of the
529// requests.
530// Background: crbug.com/507307
Steve Anton8acdd1a2018-02-07 17:27:36 -0800531TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
Steve Anton8d3444d2017-10-20 15:30:51 -0700532 auto caller = CreatePeerConnection();
533
534 RTCOfferAnswerOptions options;
535 options.offer_to_receive_audio =
536 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
537
538 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
539 for (auto& observer : observers) {
540 observer =
541 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
542 caller->pc()->CreateOffer(observer, options);
543 }
544
545 // Destroy the PeerConnection.
546 caller.reset(nullptr);
547
548 for (auto& observer : observers) {
549 // We expect to have received a notification now even if the PeerConnection
550 // was terminated. The offer creation may or may not have succeeded, but we
551 // must have received a notification.
552 EXPECT_TRUE(observer->called());
553 }
554}
555
Henrik Boströma3728d32019-10-28 12:09:49 +0100556// Similar to the above test, but by closing the PC first the CreateOffer() will
557// fail "early", which triggers a codepath where the PeerConnection is
558// reponsible for invoking the observer, instead of the normal codepath where
559// the WebRtcSessionDescriptionFactory is responsible for it.
560TEST_P(PeerConnectionSignalingTest, CloseCreateOfferAndShutdown) {
561 auto caller = CreatePeerConnection();
562 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer =
563 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
564 caller->pc()->Close();
565 caller->pc()->CreateOffer(observer, RTCOfferAnswerOptions());
566 caller.reset(nullptr);
567 EXPECT_TRUE(observer->called());
568}
569
Henrik Boström831ae4e2020-07-29 12:04:00 +0200570TEST_P(PeerConnectionSignalingTest,
571 ImplicitCreateOfferAndShutdownWithOldObserver) {
Henrik Boströmd4089ca2020-07-28 10:39:36 +0200572 auto caller = CreatePeerConnection();
Henrik Boström4c9c75a2020-07-29 09:46:40 +0000573 auto observer = MockSetSessionDescriptionObserver::Create();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200574 caller->pc()->SetLocalDescription(observer.get());
575 caller.reset(nullptr);
576 // The old observer does not get invoked because posted messages are lost.
577 EXPECT_FALSE(observer->called());
578}
579
580TEST_P(PeerConnectionSignalingTest, ImplicitCreateOfferAndShutdown) {
581 auto caller = CreatePeerConnection();
582 rtc::scoped_refptr<FakeSetLocalDescriptionObserver> observer(
583 new FakeSetLocalDescriptionObserver());
Henrik Boström4e196702019-10-30 10:35:50 +0100584 caller->pc()->SetLocalDescription(observer);
585 caller.reset(nullptr);
Henrik Boström831ae4e2020-07-29 12:04:00 +0200586 // The new observer gets invoked because it is called immediately.
587 EXPECT_TRUE(observer->called());
588 EXPECT_FALSE(observer->error().ok());
589}
590
591TEST_P(PeerConnectionSignalingTest,
592 CloseBeforeImplicitCreateOfferAndShutdownWithOldObserver) {
593 auto caller = CreatePeerConnection();
594 auto observer = MockSetSessionDescriptionObserver::Create();
595 caller->pc()->Close();
596 caller->pc()->SetLocalDescription(observer.get());
597 caller.reset(nullptr);
598 // The old observer does not get invoked because posted messages are lost.
Henrik Boström4e196702019-10-30 10:35:50 +0100599 EXPECT_FALSE(observer->called());
600}
601
602TEST_P(PeerConnectionSignalingTest, CloseBeforeImplicitCreateOfferAndShutdown) {
603 auto caller = CreatePeerConnection();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200604 rtc::scoped_refptr<FakeSetLocalDescriptionObserver> observer(
605 new FakeSetLocalDescriptionObserver());
Henrik Boström4e196702019-10-30 10:35:50 +0100606 caller->pc()->Close();
607 caller->pc()->SetLocalDescription(observer);
608 caller.reset(nullptr);
Henrik Boström831ae4e2020-07-29 12:04:00 +0200609 // The new observer gets invoked because it is called immediately.
610 EXPECT_TRUE(observer->called());
611 EXPECT_FALSE(observer->error().ok());
612}
613
614TEST_P(PeerConnectionSignalingTest,
615 CloseAfterImplicitCreateOfferAndShutdownWithOldObserver) {
616 auto caller = CreatePeerConnection();
617 auto observer = MockSetSessionDescriptionObserver::Create();
618 caller->pc()->SetLocalDescription(observer.get());
619 caller->pc()->Close();
620 caller.reset(nullptr);
621 // The old observer does not get invoked because posted messages are lost.
Henrik Boström4e196702019-10-30 10:35:50 +0100622 EXPECT_FALSE(observer->called());
623}
624
625TEST_P(PeerConnectionSignalingTest, CloseAfterImplicitCreateOfferAndShutdown) {
626 auto caller = CreatePeerConnection();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200627 rtc::scoped_refptr<FakeSetLocalDescriptionObserver> observer(
628 new FakeSetLocalDescriptionObserver());
Henrik Boström4e196702019-10-30 10:35:50 +0100629 caller->pc()->SetLocalDescription(observer);
630 caller->pc()->Close();
631 caller.reset(nullptr);
Henrik Boström831ae4e2020-07-29 12:04:00 +0200632 // The new observer gets invoked because it is called immediately.
633 EXPECT_TRUE(observer->called());
634 EXPECT_FALSE(observer->error().ok());
635}
636
637TEST_P(PeerConnectionSignalingTest,
638 SetLocalDescriptionNewObserverIsInvokedImmediately) {
639 auto caller = CreatePeerConnection();
640 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
641
642 rtc::scoped_refptr<FakeSetLocalDescriptionObserver> observer(
643 new FakeSetLocalDescriptionObserver());
644 caller->pc()->SetLocalDescription(std::move(offer), observer);
645 // The new observer is invoked immediately.
646 EXPECT_TRUE(observer->called());
647 EXPECT_TRUE(observer->error().ok());
648}
649
650TEST_P(PeerConnectionSignalingTest,
651 SetLocalDescriptionOldObserverIsInvokedInAPostedMessage) {
652 auto caller = CreatePeerConnection();
653 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
654
655 auto observer = MockSetSessionDescriptionObserver::Create();
656 caller->pc()->SetLocalDescription(observer, offer.release());
657 // The old observer is not invoked immediately.
Henrik Boström4e196702019-10-30 10:35:50 +0100658 EXPECT_FALSE(observer->called());
Henrik Boström831ae4e2020-07-29 12:04:00 +0200659 // Process all currently pending messages by waiting for a posted task to run.
660 bool checkpoint_reached = false;
661 rtc::Thread::Current()->PostTask(
662 RTC_FROM_HERE, [&checkpoint_reached] { checkpoint_reached = true; });
663 EXPECT_TRUE_WAIT(checkpoint_reached, kWaitTimeout);
664 // If resolving the observer was pending, it must now have been called.
665 EXPECT_TRUE(observer->called());
Henrik Boström4e196702019-10-30 10:35:50 +0100666}
667
Henrik Boströma3728d32019-10-28 12:09:49 +0100668TEST_P(PeerConnectionSignalingTest, SetRemoteDescriptionExecutesImmediately) {
669 auto caller = CreatePeerConnectionWithAudioVideo();
670 auto callee = CreatePeerConnection();
671
672 // This offer will cause receivers to be created.
673 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
674
675 // By not waiting for the observer's callback we can verify that the operation
676 // executed immediately.
677 callee->pc()->SetRemoteDescription(std::move(offer),
Henrik Boström831ae4e2020-07-29 12:04:00 +0200678 new FakeSetRemoteDescriptionObserver());
Henrik Boströma3728d32019-10-28 12:09:49 +0100679 EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
680}
681
682TEST_P(PeerConnectionSignalingTest, CreateOfferBlocksSetRemoteDescription) {
683 auto caller = CreatePeerConnectionWithAudioVideo();
684 auto callee = CreatePeerConnection();
685
686 // This offer will cause receivers to be created.
687 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
688
689 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
690 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> offer_observer(
691 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
692 // Synchronously invoke CreateOffer() and SetRemoteDescription(). The
693 // SetRemoteDescription() operation should be chained to be executed
694 // asynchronously, when CreateOffer() completes.
695 callee->pc()->CreateOffer(offer_observer, RTCOfferAnswerOptions());
696 callee->pc()->SetRemoteDescription(std::move(offer),
Henrik Boström831ae4e2020-07-29 12:04:00 +0200697 new FakeSetRemoteDescriptionObserver());
Henrik Boströma3728d32019-10-28 12:09:49 +0100698 // CreateOffer() is asynchronous; without message processing this operation
699 // should not have completed.
700 EXPECT_FALSE(offer_observer->called());
701 // Due to chaining, the receivers should not have been created by the offer
702 // yet.
703 EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
704 // EXPECT_TRUE_WAIT causes messages to be processed...
705 EXPECT_TRUE_WAIT(offer_observer->called(), kWaitTimeout);
706 // Now that the offer has been completed, SetRemoteDescription() will have
707 // been executed next in the chain.
708 EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
709}
710
Henrik Boström4e196702019-10-30 10:35:50 +0100711TEST_P(PeerConnectionSignalingTest,
712 ParameterlessSetLocalDescriptionCreatesOffer) {
713 auto caller = CreatePeerConnectionWithAudioVideo();
714
715 auto observer = MockSetSessionDescriptionObserver::Create();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200716 caller->pc()->SetLocalDescription(observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100717
718 // The offer is created asynchronously; message processing is needed for it to
719 // complete.
720 EXPECT_FALSE(observer->called());
721 EXPECT_FALSE(caller->pc()->pending_local_description());
722 EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
723
724 // Wait for messages to be processed.
725 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
726 EXPECT_TRUE(observer->result());
727 EXPECT_TRUE(caller->pc()->pending_local_description());
728 EXPECT_EQ(SdpType::kOffer,
729 caller->pc()->pending_local_description()->GetType());
730 EXPECT_EQ(PeerConnection::kHaveLocalOffer, caller->signaling_state());
731}
732
733TEST_P(PeerConnectionSignalingTest,
734 ParameterlessSetLocalDescriptionCreatesAnswer) {
735 auto caller = CreatePeerConnectionWithAudioVideo();
736 auto callee = CreatePeerConnectionWithAudioVideo();
737
738 callee->SetRemoteDescription(caller->CreateOffer());
739 EXPECT_EQ(PeerConnection::kHaveRemoteOffer, callee->signaling_state());
740
741 auto observer = MockSetSessionDescriptionObserver::Create();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200742 callee->pc()->SetLocalDescription(observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100743
744 // The answer is created asynchronously; message processing is needed for it
745 // to complete.
746 EXPECT_FALSE(observer->called());
747 EXPECT_FALSE(callee->pc()->current_local_description());
748
749 // Wait for messages to be processed.
750 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
751 EXPECT_TRUE(observer->result());
752 EXPECT_TRUE(callee->pc()->current_local_description());
753 EXPECT_EQ(SdpType::kAnswer,
754 callee->pc()->current_local_description()->GetType());
755 EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
756}
757
758TEST_P(PeerConnectionSignalingTest,
759 ParameterlessSetLocalDescriptionFullExchange) {
760 auto caller = CreatePeerConnectionWithAudioVideo();
761 auto callee = CreatePeerConnectionWithAudioVideo();
762
763 // SetLocalDescription(), implicitly creating an offer.
Henrik Boström831ae4e2020-07-29 12:04:00 +0200764 auto caller_set_local_description_observer =
765 MockSetSessionDescriptionObserver::Create();
766 caller->pc()->SetLocalDescription(
767 caller_set_local_description_observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100768 EXPECT_TRUE_WAIT(caller_set_local_description_observer->called(),
769 kWaitTimeout);
770 ASSERT_TRUE(caller->pc()->pending_local_description());
771
772 // SetRemoteDescription(offer)
Henrik Boström831ae4e2020-07-29 12:04:00 +0200773 auto callee_set_remote_description_observer =
774 MockSetSessionDescriptionObserver::Create();
Henrik Boström4e196702019-10-30 10:35:50 +0100775 callee->pc()->SetRemoteDescription(
Henrik Boström831ae4e2020-07-29 12:04:00 +0200776 callee_set_remote_description_observer,
Henrik Boström4e196702019-10-30 10:35:50 +0100777 CloneSessionDescription(caller->pc()->pending_local_description())
778 .release());
779
780 // SetLocalDescription(), implicitly creating an answer.
Henrik Boström831ae4e2020-07-29 12:04:00 +0200781 auto callee_set_local_description_observer =
782 MockSetSessionDescriptionObserver::Create();
783 callee->pc()->SetLocalDescription(
784 callee_set_local_description_observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100785 EXPECT_TRUE_WAIT(callee_set_local_description_observer->called(),
786 kWaitTimeout);
787 // Chaining guarantees SetRemoteDescription() happened before
788 // SetLocalDescription().
789 EXPECT_TRUE(callee_set_remote_description_observer->called());
790 EXPECT_TRUE(callee->pc()->current_local_description());
791
792 // SetRemoteDescription(answer)
Henrik Boström831ae4e2020-07-29 12:04:00 +0200793 auto caller_set_remote_description_observer =
794 MockSetSessionDescriptionObserver::Create();
Henrik Boström4e196702019-10-30 10:35:50 +0100795 caller->pc()->SetRemoteDescription(
796 caller_set_remote_description_observer,
797 CloneSessionDescription(callee->pc()->current_local_description())
798 .release());
799 EXPECT_TRUE_WAIT(caller_set_remote_description_observer->called(),
800 kWaitTimeout);
801
802 EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
803 EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
804}
805
806TEST_P(PeerConnectionSignalingTest,
807 ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer) {
808 auto caller = CreatePeerConnectionWithAudioVideo();
809
810 auto observer = MockSetSessionDescriptionObserver::Create();
811 caller->pc()->Close();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200812 caller->pc()->SetLocalDescription(observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100813
814 // The operation should fail asynchronously.
815 EXPECT_FALSE(observer->called());
816 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
817 EXPECT_FALSE(observer->result());
818 // This did not affect the signaling state.
819 EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
820 EXPECT_EQ(
821 "SetLocalDescription failed to create session description - "
822 "SetLocalDescription called when PeerConnection is closed.",
823 observer->error());
824}
825
826TEST_P(PeerConnectionSignalingTest,
827 ParameterlessSetLocalDescriptionCloseWhileCreatingOffer) {
828 auto caller = CreatePeerConnectionWithAudioVideo();
829
830 auto observer = MockSetSessionDescriptionObserver::Create();
Henrik Boström831ae4e2020-07-29 12:04:00 +0200831 caller->pc()->SetLocalDescription(observer.get());
Henrik Boström4e196702019-10-30 10:35:50 +0100832 caller->pc()->Close();
833
834 // The operation should fail asynchronously.
835 EXPECT_FALSE(observer->called());
836 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
837 EXPECT_FALSE(observer->result());
838 // This did not affect the signaling state.
839 EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
840 EXPECT_EQ(
841 "SetLocalDescription failed to create session description - "
842 "CreateOffer failed because the session was shut down",
843 observer->error());
844}
845
Philipp Hancke4e8c1152020-10-13 12:43:15 +0200846TEST_P(PeerConnectionSignalingTest, UnsupportedContentType) {
847 auto caller = CreatePeerConnection();
848
849 // Call setRemoteDescription with a m= line we don't understand.
850 std::string sdp =
851 "v=0\r\n"
852 "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
853 "s=-\r\n"
854 "t=0 0\r\n"
855 "m=bogus 9 FOO 0 8\r\n"
856 "c=IN IP4 0.0.0.0\r\n"
857 "a=mid:bogusmid\r\n";
858 std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
859 webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);
860
861 EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));
862
863 // Assert we respond back with something meaningful.
864 auto answer = caller->CreateAnswer();
865 ASSERT_EQ(answer->description()->contents().size(), 1u);
866 EXPECT_NE(answer->description()
867 ->contents()[0]
868 .media_description()
869 ->as_unsupported(),
870 nullptr);
871 EXPECT_EQ(answer->description()
872 ->contents()[0]
873 .media_description()
874 ->as_unsupported()
875 ->media_type(),
876 "bogus");
877 EXPECT_TRUE(answer->description()->contents()[0].rejected);
878 EXPECT_EQ(answer->description()->contents()[0].mid(), "bogusmid");
879 EXPECT_EQ(
880 answer->description()->contents()[0].media_description()->protocol(),
881 "FOO");
882 EXPECT_FALSE(
883 answer->description()->contents()[0].media_description()->has_codecs());
884
885 EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
886
887 // Assert we keep this in susequent offers.
888 auto offer = caller->CreateOffer();
889 EXPECT_EQ(offer->description()
890 ->contents()[0]
891 .media_description()
892 ->as_unsupported()
893 ->media_type(),
894 "bogus");
895 EXPECT_TRUE(offer->description()->contents()[0].rejected);
896 EXPECT_EQ(offer->description()->contents()[0].media_description()->protocol(),
897 "FOO");
898 EXPECT_EQ(offer->description()->contents()[0].mid(), "bogusmid");
899 EXPECT_FALSE(
900 offer->description()->contents()[0].media_description()->has_codecs());
901 EXPECT_TRUE(caller->SetLocalDescription(std::move(offer)));
902}
903
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100904INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
905 PeerConnectionSignalingTest,
906 Values(SdpSemantics::kPlanB,
907 SdpSemantics::kUnifiedPlan));
Steve Anton8acdd1a2018-02-07 17:27:36 -0800908
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100909class PeerConnectionSignalingUnifiedPlanTest
910 : public PeerConnectionSignalingBaseTest {
911 protected:
912 PeerConnectionSignalingUnifiedPlanTest()
913 : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
914};
915
Henrik Boströma3728d32019-10-28 12:09:49 +0100916// We verify that SetLocalDescription() executed immediately by verifying that
917// the transceiver mid values got assigned. SLD executing immeditately is not
918// unique to Unified Plan, but the transceivers used to verify this are only
919// available in Unified Plan.
920TEST_F(PeerConnectionSignalingUnifiedPlanTest,
Henrik Boström831ae4e2020-07-29 12:04:00 +0200921 SetLocalDescriptionExecutesImmediatelyUsingOldObserver) {
Henrik Boströma3728d32019-10-28 12:09:49 +0100922 auto caller = CreatePeerConnectionWithAudioVideo();
923
924 // This offer will cause transceiver mids to get assigned.
925 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
926
927 // By not waiting for the observer's callback we can verify that the operation
Henrik Boström831ae4e2020-07-29 12:04:00 +0200928 // executed immediately. The old observer is invoked in a posted message, so
929 // waiting for it would not ensure synchronicity.
Henrik Boströma3728d32019-10-28 12:09:49 +0100930 RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
931 caller->pc()->SetLocalDescription(
932 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>(),
933 offer.release());
934 EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
935}
936
937TEST_F(PeerConnectionSignalingUnifiedPlanTest,
Henrik Boström831ae4e2020-07-29 12:04:00 +0200938 SetLocalDescriptionExecutesImmediatelyUsingNewObserver) {
939 auto caller = CreatePeerConnectionWithAudioVideo();
940
941 // This offer will cause transceiver mids to get assigned.
942 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
943
944 // Verify that mids were assigned without waiting for the observer. (However,
945 // the new observer should also be invoked synchronously - as is ensured by
946 // other tests.)
947 RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
948 caller->pc()->SetLocalDescription(std::move(offer),
949 new FakeSetLocalDescriptionObserver());
950 EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
951}
952
953TEST_F(PeerConnectionSignalingUnifiedPlanTest,
Henrik Boströma3728d32019-10-28 12:09:49 +0100954 SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback) {
955 auto caller = CreatePeerConnectionWithAudioVideo();
956
957 // This offer will cause transceiver mids to get assigned.
958 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
959
960 rtc::scoped_refptr<ExecuteFunctionOnCreateSessionDescriptionObserver>
961 offer_observer(new rtc::RefCountedObject<
962 ExecuteFunctionOnCreateSessionDescriptionObserver>(
963 [pc = caller->pc()](SessionDescriptionInterface* desc) {
964 // By not waiting for the observer's callback we can verify that the
965 // operation executed immediately.
966 RTC_DCHECK(!pc->GetTransceivers()[0]->mid().has_value());
967 pc->SetLocalDescription(
968 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>(),
969 desc);
970 EXPECT_TRUE(pc->GetTransceivers()[0]->mid().has_value());
971 }));
972 caller->pc()->CreateOffer(offer_observer, RTCOfferAnswerOptions());
973 EXPECT_TRUE_WAIT(offer_observer->was_called(), kWaitTimeout);
974}
975
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +0100976// Test that transports are shown in the sender/receiver API after offer/answer.
977// This only works in Unified Plan.
978TEST_F(PeerConnectionSignalingUnifiedPlanTest,
979 DtlsTransportsInstantiateInOfferAnswer) {
980 auto caller = CreatePeerConnectionWithAudioVideo();
981 auto callee = CreatePeerConnection();
982
983 EXPECT_FALSE(HasDtlsTransport(caller));
984 EXPECT_FALSE(HasDtlsTransport(callee));
985 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
986 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
987 EXPECT_TRUE(HasDtlsTransport(caller));
988 callee->SetRemoteDescription(std::move(offer));
989 EXPECT_FALSE(HasDtlsTransport(callee));
990 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
991 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
992 EXPECT_TRUE(HasDtlsTransport(callee));
993 caller->SetRemoteDescription(std::move(answer));
994 EXPECT_TRUE(HasDtlsTransport(caller));
995
996 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
997}
998
999TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
1000 auto caller = CreatePeerConnectionWithAudioVideo();
1001 auto callee = CreatePeerConnection();
1002
1003 EXPECT_FALSE(HasDtlsTransport(caller));
1004 EXPECT_FALSE(HasDtlsTransport(callee));
1005 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1006 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
1007 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1008 callee->SetRemoteDescription(std::move(offer));
1009 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1010 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
1011 caller->SetRemoteDescription(std::move(answer));
1012 EXPECT_EQ(1, NumberOfDtlsTransports(caller));
1013
1014 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
1015}
1016
1017TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1018 DtlsTransportsAreSeparateeWhenUnbundled) {
1019 auto caller = CreatePeerConnectionWithAudioVideo();
1020 auto callee = CreatePeerConnection();
1021
1022 EXPECT_FALSE(HasDtlsTransport(caller));
1023 EXPECT_FALSE(HasDtlsTransport(callee));
1024 RTCOfferAnswerOptions unbundle_options;
1025 unbundle_options.use_rtp_mux = false;
1026 auto offer = caller->CreateOffer(unbundle_options);
1027 caller->SetLocalDescription(CloneSessionDescription(offer.get()));
1028 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1029 callee->SetRemoteDescription(std::move(offer));
1030 auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
1031 callee->SetLocalDescription(CloneSessionDescription(answer.get()));
1032 EXPECT_EQ(2, NumberOfDtlsTransports(callee));
1033 caller->SetRemoteDescription(std::move(answer));
1034 EXPECT_EQ(2, NumberOfDtlsTransports(caller));
1035
1036 ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
1037}
1038
Henrik Boströme574a312020-08-25 10:20:11 +02001039TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1040 ShouldFireNegotiationNeededWhenNoChangesArePending) {
1041 auto caller = CreatePeerConnection();
1042 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1043 auto transceiver =
1044 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1045 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1046 EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
1047 caller->observer()->latest_negotiation_needed_event()));
1048}
1049
1050TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1051 SuppressNegotiationNeededWhenOperationChainIsNotEmpty) {
1052 auto caller = CreatePeerConnection();
1053 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1054 auto transceiver =
1055 caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1056 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1057
1058 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer =
1059 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>();
1060 caller->pc()->CreateOffer(observer, RTCOfferAnswerOptions());
1061 // For this test to work, the operation has to be pending, i.e. the observer
1062 // has not yet been invoked.
1063 EXPECT_FALSE(observer->called());
1064 // Because the Operations Chain is not empty, the event is now suppressed.
1065 EXPECT_FALSE(caller->pc()->ShouldFireNegotiationNeededEvent(
1066 caller->observer()->latest_negotiation_needed_event()));
1067 caller->observer()->clear_latest_negotiation_needed_event();
1068
1069 // When the Operations Chain becomes empty again, a new negotiation needed
1070 // event will be generated that is not suppressed.
1071 EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
1072 EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1073 EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
1074 caller->observer()->latest_negotiation_needed_event()));
1075}
1076
1077TEST_F(PeerConnectionSignalingUnifiedPlanTest,
1078 SuppressNegotiationNeededWhenSignalingStateIsNotStable) {
1079 auto caller = CreatePeerConnection();
1080 auto callee = CreatePeerConnection();
1081 auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
1082
1083 EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1084 auto transceiver =
1085 callee->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
1086 EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
1087
1088 // Change signaling state (to "have-remote-offer") by setting a remote offer.
1089 callee->SetRemoteDescription(std::move(offer));
1090 // Because the signaling state is not "stable", the event is now suppressed.
1091 EXPECT_FALSE(callee->pc()->ShouldFireNegotiationNeededEvent(
1092 callee->observer()->latest_negotiation_needed_event()));
1093 callee->observer()->clear_latest_negotiation_needed_event();
1094
1095 // Upon rolling back to "stable", a new negotiation needed event will be
1096 // generated that is not suppressed.
1097 callee->SetLocalDescription(CreateSessionDescription(SdpType::kRollback, ""));
1098 EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
1099 EXPECT_TRUE(callee->pc()->ShouldFireNegotiationNeededEvent(
1100 callee->observer()->latest_negotiation_needed_event()));
1101}
1102
Steve Anton8d3444d2017-10-20 15:30:51 -07001103} // namespace webrtc