• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 // This file contains tests that check the PeerConnection's signaling state
12 // machine, as well as tests that check basic, media-agnostic aspects of SDP.
13 
14 #include <memory>
15 #include <tuple>
16 
17 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
18 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
19 #include "api/create_peerconnection_factory.h"
20 #include "api/peer_connection_proxy.h"
21 #include "api/video_codecs/builtin_video_decoder_factory.h"
22 #include "api/video_codecs/builtin_video_encoder_factory.h"
23 #include "pc/peer_connection.h"
24 #include "pc/peer_connection_wrapper.h"
25 #include "pc/sdp_utils.h"
26 #ifdef WEBRTC_ANDROID
27 #include "pc/test/android_test_initializer.h"
28 #endif
29 #include "pc/test/fake_audio_capture_module.h"
30 #include "pc/test/fake_rtc_certificate_generator.h"
31 #include "rtc_base/gunit.h"
32 #include "rtc_base/virtual_socket_server.h"
33 #include "test/gmock.h"
34 
35 namespace webrtc {
36 
37 using SignalingState = PeerConnectionInterface::SignalingState;
38 using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
39 using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
40 using ::testing::Bool;
41 using ::testing::Combine;
42 using ::testing::Values;
43 
44 namespace {
45 const int64_t kWaitTimeout = 10000;
46 }  // namespace
47 
48 class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
49  public:
50   using PeerConnectionWrapper::PeerConnectionWrapper;
51 
initial_offerer()52   bool initial_offerer() {
53     return GetInternalPeerConnection()->initial_offerer();
54   }
55 
GetInternalPeerConnection()56   PeerConnection* GetInternalPeerConnection() {
57     auto* pci =
58         static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
59             pc());
60     return static_cast<PeerConnection*>(pci->internal());
61   }
62 };
63 
64 class ExecuteFunctionOnCreateSessionDescriptionObserver
65     : public CreateSessionDescriptionObserver {
66  public:
ExecuteFunctionOnCreateSessionDescriptionObserver(std::function<void (SessionDescriptionInterface *)> function)67   ExecuteFunctionOnCreateSessionDescriptionObserver(
68       std::function<void(SessionDescriptionInterface*)> function)
69       : function_(std::move(function)) {}
~ExecuteFunctionOnCreateSessionDescriptionObserver()70   ~ExecuteFunctionOnCreateSessionDescriptionObserver() override {
71     RTC_DCHECK(was_called_);
72   }
73 
was_called() const74   bool was_called() const { return was_called_; }
75 
OnSuccess(SessionDescriptionInterface * desc)76   void OnSuccess(SessionDescriptionInterface* desc) override {
77     RTC_DCHECK(!was_called_);
78     was_called_ = true;
79     function_(desc);
80   }
81 
OnFailure(RTCError error)82   void OnFailure(RTCError error) override { RTC_NOTREACHED(); }
83 
84  private:
85   bool was_called_ = false;
86   std::function<void(SessionDescriptionInterface*)> function_;
87 };
88 
89 class PeerConnectionSignalingBaseTest : public ::testing::Test {
90  protected:
91   typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;
92 
PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)93   explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
94       : vss_(new rtc::VirtualSocketServer()),
95         main_(vss_.get()),
96         sdp_semantics_(sdp_semantics) {
97 #ifdef WEBRTC_ANDROID
98     InitializeAndroidObjects();
99 #endif
100     pc_factory_ = CreatePeerConnectionFactory(
101         rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
102         rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
103         CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
104         CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
105         nullptr /* audio_mixer */, nullptr /* audio_processing */);
106   }
107 
CreatePeerConnection()108   WrapperPtr CreatePeerConnection() {
109     return CreatePeerConnection(RTCConfiguration());
110   }
111 
CreatePeerConnection(const RTCConfiguration & config)112   WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
113     auto observer = std::make_unique<MockPeerConnectionObserver>();
114     RTCConfiguration modified_config = config;
115     modified_config.sdp_semantics = sdp_semantics_;
116     auto pc = pc_factory_->CreatePeerConnection(modified_config, nullptr,
117                                                 nullptr, observer.get());
118     if (!pc) {
119       return nullptr;
120     }
121 
122     observer->SetPeerConnectionInterface(pc.get());
123     return std::make_unique<PeerConnectionWrapperForSignalingTest>(
124         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>
CreatePeerConnectionWithAudioVideo(Args &&...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 
NumberOfDtlsTransports(const WrapperPtr & pc_wrapper)140   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 
HasDtlsTransport(const WrapperPtr & pc_wrapper)158   bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
159     return NumberOfDtlsTransports(pc_wrapper) > 0;
160   }
161 
162   std::unique_ptr<rtc::VirtualSocketServer> vss_;
163   rtc::AutoSocketServerThread main_;
164   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
165   const SdpSemantics sdp_semantics_;
166 };
167 
168 class PeerConnectionSignalingTest
169     : public PeerConnectionSignalingBaseTest,
170       public ::testing::WithParamInterface<SdpSemantics> {
171  protected:
PeerConnectionSignalingTest()172   PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
173 };
174 
TEST_P(PeerConnectionSignalingTest,SetLocalOfferTwiceWorks)175 TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
176   auto caller = CreatePeerConnection();
177 
178   EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
179   EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
180 }
181 
TEST_P(PeerConnectionSignalingTest,SetRemoteOfferTwiceWorks)182 TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
183   auto caller = CreatePeerConnection();
184   auto callee = CreatePeerConnection();
185 
186   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
187   EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
188 }
189 
TEST_P(PeerConnectionSignalingTest,FailToSetNullLocalDescription)190 TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
191   auto caller = CreatePeerConnection();
192   std::string error;
193   ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
194   EXPECT_EQ("SessionDescription is NULL.", error);
195 }
196 
TEST_P(PeerConnectionSignalingTest,FailToSetNullRemoteDescription)197 TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
198   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 
212 class PeerConnectionSignalingStateTest
213     : public PeerConnectionSignalingBaseTest,
214       public ::testing::WithParamInterface<
215           std::tuple<SdpSemantics, SignalingState, bool>> {
216  protected:
PeerConnectionSignalingStateTest()217   PeerConnectionSignalingStateTest()
218       : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
219         state_under_test_(std::make_tuple(std::get<1>(GetParam()),
220                                           std::get<2>(GetParam()))) {}
221 
GetConfig()222   RTCConfiguration GetConfig() {
223     RTCConfiguration config;
224     config.certificates.push_back(
225         FakeRTCCertificateGenerator::GenerateCertificate());
226     return config;
227   }
228 
CreatePeerConnectionUnderTest()229   WrapperPtr CreatePeerConnectionUnderTest() {
230     return CreatePeerConnectionInState(state_under_test_);
231   }
232 
CreatePeerConnectionInState(SignalingState state)233   WrapperPtr CreatePeerConnectionInState(SignalingState state) {
234     return CreatePeerConnectionInState(std::make_tuple(state, false));
235   }
236 
CreatePeerConnectionInState(std::tuple<SignalingState,bool> state_tuple)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();
255         wrapper->SetLocalDescription(
256             CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
257         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();
268         wrapper->SetRemoteDescription(
269             CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
270         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   }
288 
289   std::tuple<SignalingState, bool> state_under_test_;
290 };
291 
TEST_P(PeerConnectionSignalingStateTest,CreateOffer)292 TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
293   auto wrapper = CreatePeerConnectionUnderTest();
294   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 
TEST_P(PeerConnectionSignalingStateTest,CreateAnswer)304 TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
305   auto wrapper = CreatePeerConnectionUnderTest();
306   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));
312     EXPECT_EQ(error,
313               "PeerConnection cannot create an answer in a state other than "
314               "have-remote-offer or have-local-pranswer.");
315   }
316 }
317 
TEST_P(PeerConnectionSignalingStateTest,SetLocalOffer)318 TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
319   auto wrapper = CreatePeerConnectionUnderTest();
320   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 
TEST_P(PeerConnectionSignalingStateTest,SetLocalPrAnswer)341 TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
342   auto wrapper_for_pranswer =
343       CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
344   auto pranswer =
345       CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());
346 
347   auto wrapper = CreatePeerConnectionUnderTest();
348   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 
TEST_P(PeerConnectionSignalingStateTest,SetLocalAnswer)360 TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
361   auto wrapper_for_answer =
362       CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
363   auto answer = wrapper_for_answer->CreateAnswer();
364 
365   auto wrapper = CreatePeerConnectionUnderTest();
366   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 
TEST_P(PeerConnectionSignalingStateTest,SetRemoteOffer)378 TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
379   auto wrapper_for_offer =
380       CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
381   auto offer =
382       CloneSessionDescription(wrapper_for_offer->pc()->remote_description());
383 
384   auto wrapper = CreatePeerConnectionUnderTest();
385   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 
TEST_P(PeerConnectionSignalingStateTest,SetRemotePrAnswer)397 TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
398   auto wrapper_for_pranswer =
399       CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
400   auto pranswer =
401       CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());
402 
403   auto wrapper = CreatePeerConnectionUnderTest();
404   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 
TEST_P(PeerConnectionSignalingStateTest,SetRemoteAnswer)416 TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
417   auto wrapper_for_answer =
418       CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
419   auto answer = wrapper_for_answer->CreateAnswer();
420 
421   auto wrapper = CreatePeerConnectionUnderTest();
422   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 
434 INSTANTIATE_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()));
444 
445 // Test that CreateAnswer fails if a round of offer/answer has been done and
446 // the PeerConnection is in the stable state.
TEST_P(PeerConnectionSignalingTest,CreateAnswerFailsIfStable)447 TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
448   auto caller = CreatePeerConnection();
449   auto callee = CreatePeerConnection();
450 
451   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
452 
453   ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
454   EXPECT_FALSE(caller->CreateAnswer());
455 
456   ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
457   EXPECT_FALSE(callee->CreateAnswer());
458 }
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.
TEST_P(PeerConnectionSignalingTest,SessionVersionIncrementedInSubsequentDifferentOffer)464 TEST_P(PeerConnectionSignalingTest,
465        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 }
TEST_P(PeerConnectionSignalingTest,SessionVersionIncrementedInSubsequentDifferentAnswer)485 TEST_P(PeerConnectionSignalingTest,
486        SessionVersionIncrementedInSubsequentDifferentAnswer) {
487   auto caller = CreatePeerConnection();
488   auto callee = CreatePeerConnection();
489 
490   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
491 
492   auto original_answer = callee->CreateAnswer();
493   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 
TEST_P(PeerConnectionSignalingTest,InitiatorFlagSetOnCallerAndNotOnCallee)506 TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
507   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
TEST_P(PeerConnectionSignalingTest,CreateOffersAndShutdown)529 TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
530   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 
554 // 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.
TEST_P(PeerConnectionSignalingTest,CloseCreateOfferAndShutdown)558 TEST_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 
TEST_P(PeerConnectionSignalingTest,ImplicitCreateOfferAndShutdown)568 TEST_P(PeerConnectionSignalingTest, ImplicitCreateOfferAndShutdown) {
569   auto caller = CreatePeerConnection();
570   auto observer = MockSetSessionDescriptionObserver::Create();
571   caller->pc()->SetLocalDescription(observer);
572   caller.reset(nullptr);
573   EXPECT_FALSE(observer->called());
574 }
575 
TEST_P(PeerConnectionSignalingTest,CloseBeforeImplicitCreateOfferAndShutdown)576 TEST_P(PeerConnectionSignalingTest, CloseBeforeImplicitCreateOfferAndShutdown) {
577   auto caller = CreatePeerConnection();
578   auto observer = MockSetSessionDescriptionObserver::Create();
579   caller->pc()->Close();
580   caller->pc()->SetLocalDescription(observer);
581   caller.reset(nullptr);
582   EXPECT_FALSE(observer->called());
583 }
584 
TEST_P(PeerConnectionSignalingTest,CloseAfterImplicitCreateOfferAndShutdown)585 TEST_P(PeerConnectionSignalingTest, CloseAfterImplicitCreateOfferAndShutdown) {
586   auto caller = CreatePeerConnection();
587   auto observer = MockSetSessionDescriptionObserver::Create();
588   caller->pc()->SetLocalDescription(observer);
589   caller->pc()->Close();
590   caller.reset(nullptr);
591   EXPECT_FALSE(observer->called());
592 }
593 
TEST_P(PeerConnectionSignalingTest,SetRemoteDescriptionExecutesImmediately)594 TEST_P(PeerConnectionSignalingTest, SetRemoteDescriptionExecutesImmediately) {
595   auto caller = CreatePeerConnectionWithAudioVideo();
596   auto callee = CreatePeerConnection();
597 
598   // This offer will cause receivers to be created.
599   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
600 
601   // By not waiting for the observer's callback we can verify that the operation
602   // executed immediately.
603   callee->pc()->SetRemoteDescription(std::move(offer),
604                                      new MockSetRemoteDescriptionObserver());
605   EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
606 }
607 
TEST_P(PeerConnectionSignalingTest,CreateOfferBlocksSetRemoteDescription)608 TEST_P(PeerConnectionSignalingTest, CreateOfferBlocksSetRemoteDescription) {
609   auto caller = CreatePeerConnectionWithAudioVideo();
610   auto callee = CreatePeerConnection();
611 
612   // This offer will cause receivers to be created.
613   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
614 
615   EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
616   rtc::scoped_refptr<MockCreateSessionDescriptionObserver> offer_observer(
617       new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
618   // Synchronously invoke CreateOffer() and SetRemoteDescription(). The
619   // SetRemoteDescription() operation should be chained to be executed
620   // asynchronously, when CreateOffer() completes.
621   callee->pc()->CreateOffer(offer_observer, RTCOfferAnswerOptions());
622   callee->pc()->SetRemoteDescription(std::move(offer),
623                                      new MockSetRemoteDescriptionObserver());
624   // CreateOffer() is asynchronous; without message processing this operation
625   // should not have completed.
626   EXPECT_FALSE(offer_observer->called());
627   // Due to chaining, the receivers should not have been created by the offer
628   // yet.
629   EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
630   // EXPECT_TRUE_WAIT causes messages to be processed...
631   EXPECT_TRUE_WAIT(offer_observer->called(), kWaitTimeout);
632   // Now that the offer has been completed, SetRemoteDescription() will have
633   // been executed next in the chain.
634   EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
635 }
636 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCreatesOffer)637 TEST_P(PeerConnectionSignalingTest,
638        ParameterlessSetLocalDescriptionCreatesOffer) {
639   auto caller = CreatePeerConnectionWithAudioVideo();
640 
641   auto observer = MockSetSessionDescriptionObserver::Create();
642   caller->pc()->SetLocalDescription(observer);
643 
644   // The offer is created asynchronously; message processing is needed for it to
645   // complete.
646   EXPECT_FALSE(observer->called());
647   EXPECT_FALSE(caller->pc()->pending_local_description());
648   EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
649 
650   // Wait for messages to be processed.
651   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
652   EXPECT_TRUE(observer->result());
653   EXPECT_TRUE(caller->pc()->pending_local_description());
654   EXPECT_EQ(SdpType::kOffer,
655             caller->pc()->pending_local_description()->GetType());
656   EXPECT_EQ(PeerConnection::kHaveLocalOffer, caller->signaling_state());
657 }
658 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCreatesAnswer)659 TEST_P(PeerConnectionSignalingTest,
660        ParameterlessSetLocalDescriptionCreatesAnswer) {
661   auto caller = CreatePeerConnectionWithAudioVideo();
662   auto callee = CreatePeerConnectionWithAudioVideo();
663 
664   callee->SetRemoteDescription(caller->CreateOffer());
665   EXPECT_EQ(PeerConnection::kHaveRemoteOffer, callee->signaling_state());
666 
667   auto observer = MockSetSessionDescriptionObserver::Create();
668   callee->pc()->SetLocalDescription(observer);
669 
670   // The answer is created asynchronously; message processing is needed for it
671   // to complete.
672   EXPECT_FALSE(observer->called());
673   EXPECT_FALSE(callee->pc()->current_local_description());
674 
675   // Wait for messages to be processed.
676   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
677   EXPECT_TRUE(observer->result());
678   EXPECT_TRUE(callee->pc()->current_local_description());
679   EXPECT_EQ(SdpType::kAnswer,
680             callee->pc()->current_local_description()->GetType());
681   EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
682 }
683 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionFullExchange)684 TEST_P(PeerConnectionSignalingTest,
685        ParameterlessSetLocalDescriptionFullExchange) {
686   auto caller = CreatePeerConnectionWithAudioVideo();
687   auto callee = CreatePeerConnectionWithAudioVideo();
688 
689   // SetLocalDescription(), implicitly creating an offer.
690   rtc::scoped_refptr<MockSetSessionDescriptionObserver>
691       caller_set_local_description_observer(
692           new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
693   caller->pc()->SetLocalDescription(caller_set_local_description_observer);
694   EXPECT_TRUE_WAIT(caller_set_local_description_observer->called(),
695                    kWaitTimeout);
696   ASSERT_TRUE(caller->pc()->pending_local_description());
697 
698   // SetRemoteDescription(offer)
699   rtc::scoped_refptr<MockSetSessionDescriptionObserver>
700       callee_set_remote_description_observer(
701           new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
702   callee->pc()->SetRemoteDescription(
703       callee_set_remote_description_observer.get(),
704       CloneSessionDescription(caller->pc()->pending_local_description())
705           .release());
706 
707   // SetLocalDescription(), implicitly creating an answer.
708   rtc::scoped_refptr<MockSetSessionDescriptionObserver>
709       callee_set_local_description_observer(
710           new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
711   callee->pc()->SetLocalDescription(callee_set_local_description_observer);
712   EXPECT_TRUE_WAIT(callee_set_local_description_observer->called(),
713                    kWaitTimeout);
714   // Chaining guarantees SetRemoteDescription() happened before
715   // SetLocalDescription().
716   EXPECT_TRUE(callee_set_remote_description_observer->called());
717   EXPECT_TRUE(callee->pc()->current_local_description());
718 
719   // SetRemoteDescription(answer)
720   rtc::scoped_refptr<MockSetSessionDescriptionObserver>
721       caller_set_remote_description_observer(
722           new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
723   caller->pc()->SetRemoteDescription(
724       caller_set_remote_description_observer,
725       CloneSessionDescription(callee->pc()->current_local_description())
726           .release());
727   EXPECT_TRUE_WAIT(caller_set_remote_description_observer->called(),
728                    kWaitTimeout);
729 
730   EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
731   EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
732 }
733 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer)734 TEST_P(PeerConnectionSignalingTest,
735        ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer) {
736   auto caller = CreatePeerConnectionWithAudioVideo();
737 
738   auto observer = MockSetSessionDescriptionObserver::Create();
739   caller->pc()->Close();
740   caller->pc()->SetLocalDescription(observer);
741 
742   // The operation should fail asynchronously.
743   EXPECT_FALSE(observer->called());
744   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
745   EXPECT_FALSE(observer->result());
746   // This did not affect the signaling state.
747   EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
748   EXPECT_EQ(
749       "SetLocalDescription failed to create session description - "
750       "SetLocalDescription called when PeerConnection is closed.",
751       observer->error());
752 }
753 
TEST_P(PeerConnectionSignalingTest,ParameterlessSetLocalDescriptionCloseWhileCreatingOffer)754 TEST_P(PeerConnectionSignalingTest,
755        ParameterlessSetLocalDescriptionCloseWhileCreatingOffer) {
756   auto caller = CreatePeerConnectionWithAudioVideo();
757 
758   auto observer = MockSetSessionDescriptionObserver::Create();
759   caller->pc()->SetLocalDescription(observer);
760   caller->pc()->Close();
761 
762   // The operation should fail asynchronously.
763   EXPECT_FALSE(observer->called());
764   EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
765   EXPECT_FALSE(observer->result());
766   // This did not affect the signaling state.
767   EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
768   EXPECT_EQ(
769       "SetLocalDescription failed to create session description - "
770       "CreateOffer failed because the session was shut down",
771       observer->error());
772 }
773 
774 INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
775                          PeerConnectionSignalingTest,
776                          Values(SdpSemantics::kPlanB,
777                                 SdpSemantics::kUnifiedPlan));
778 
779 class PeerConnectionSignalingUnifiedPlanTest
780     : public PeerConnectionSignalingBaseTest {
781  protected:
PeerConnectionSignalingUnifiedPlanTest()782   PeerConnectionSignalingUnifiedPlanTest()
783       : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
784 };
785 
786 // We verify that SetLocalDescription() executed immediately by verifying that
787 // the transceiver mid values got assigned. SLD executing immeditately is not
788 // unique to Unified Plan, but the transceivers used to verify this are only
789 // available in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SetLocalDescriptionExecutesImmediately)790 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
791        SetLocalDescriptionExecutesImmediately) {
792   auto caller = CreatePeerConnectionWithAudioVideo();
793 
794   // This offer will cause transceiver mids to get assigned.
795   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
796 
797   // By not waiting for the observer's callback we can verify that the operation
798   // executed immediately.
799   RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
800   caller->pc()->SetLocalDescription(
801       new rtc::RefCountedObject<MockSetSessionDescriptionObserver>(),
802       offer.release());
803   EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
804 }
805 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback)806 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
807        SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback) {
808   auto caller = CreatePeerConnectionWithAudioVideo();
809 
810   // This offer will cause transceiver mids to get assigned.
811   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
812 
813   rtc::scoped_refptr<ExecuteFunctionOnCreateSessionDescriptionObserver>
814       offer_observer(new rtc::RefCountedObject<
815                      ExecuteFunctionOnCreateSessionDescriptionObserver>(
816           [pc = caller->pc()](SessionDescriptionInterface* desc) {
817             // By not waiting for the observer's callback we can verify that the
818             // operation executed immediately.
819             RTC_DCHECK(!pc->GetTransceivers()[0]->mid().has_value());
820             pc->SetLocalDescription(
821                 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>(),
822                 desc);
823             EXPECT_TRUE(pc->GetTransceivers()[0]->mid().has_value());
824           }));
825   caller->pc()->CreateOffer(offer_observer, RTCOfferAnswerOptions());
826   EXPECT_TRUE_WAIT(offer_observer->was_called(), kWaitTimeout);
827 }
828 
829 // Test that transports are shown in the sender/receiver API after offer/answer.
830 // This only works in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsInstantiateInOfferAnswer)831 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
832        DtlsTransportsInstantiateInOfferAnswer) {
833   auto caller = CreatePeerConnectionWithAudioVideo();
834   auto callee = CreatePeerConnection();
835 
836   EXPECT_FALSE(HasDtlsTransport(caller));
837   EXPECT_FALSE(HasDtlsTransport(callee));
838   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
839   caller->SetLocalDescription(CloneSessionDescription(offer.get()));
840   EXPECT_TRUE(HasDtlsTransport(caller));
841   callee->SetRemoteDescription(std::move(offer));
842   EXPECT_FALSE(HasDtlsTransport(callee));
843   auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
844   callee->SetLocalDescription(CloneSessionDescription(answer.get()));
845   EXPECT_TRUE(HasDtlsTransport(callee));
846   caller->SetRemoteDescription(std::move(answer));
847   EXPECT_TRUE(HasDtlsTransport(caller));
848 
849   ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
850 }
851 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsMergeWhenBundled)852 TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
853   auto caller = CreatePeerConnectionWithAudioVideo();
854   auto callee = CreatePeerConnection();
855 
856   EXPECT_FALSE(HasDtlsTransport(caller));
857   EXPECT_FALSE(HasDtlsTransport(callee));
858   auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
859   caller->SetLocalDescription(CloneSessionDescription(offer.get()));
860   EXPECT_EQ(2, NumberOfDtlsTransports(caller));
861   callee->SetRemoteDescription(std::move(offer));
862   auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
863   callee->SetLocalDescription(CloneSessionDescription(answer.get()));
864   caller->SetRemoteDescription(std::move(answer));
865   EXPECT_EQ(1, NumberOfDtlsTransports(caller));
866 
867   ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
868 }
869 
TEST_F(PeerConnectionSignalingUnifiedPlanTest,DtlsTransportsAreSeparateeWhenUnbundled)870 TEST_F(PeerConnectionSignalingUnifiedPlanTest,
871        DtlsTransportsAreSeparateeWhenUnbundled) {
872   auto caller = CreatePeerConnectionWithAudioVideo();
873   auto callee = CreatePeerConnection();
874 
875   EXPECT_FALSE(HasDtlsTransport(caller));
876   EXPECT_FALSE(HasDtlsTransport(callee));
877   RTCOfferAnswerOptions unbundle_options;
878   unbundle_options.use_rtp_mux = false;
879   auto offer = caller->CreateOffer(unbundle_options);
880   caller->SetLocalDescription(CloneSessionDescription(offer.get()));
881   EXPECT_EQ(2, NumberOfDtlsTransports(caller));
882   callee->SetRemoteDescription(std::move(offer));
883   auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
884   callee->SetLocalDescription(CloneSessionDescription(answer.get()));
885   EXPECT_EQ(2, NumberOfDtlsTransports(callee));
886   caller->SetRemoteDescription(std::move(answer));
887   EXPECT_EQ(2, NumberOfDtlsTransports(caller));
888 
889   ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
890 }
891 
892 }  // namespace webrtc
893