• 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 #include <memory>
12 
13 #include "p2p/base/fake_port_allocator.h"
14 #include "p2p/base/test_stun_server.h"
15 #include "p2p/client/basic_port_allocator.h"
16 #include "pc/media_session.h"
17 #include "pc/peer_connection.h"
18 #include "pc/peer_connection_wrapper.h"
19 #include "pc/sdp_utils.h"
20 #ifdef WEBRTC_ANDROID
21 #include "pc/test/android_test_initializer.h"
22 #endif
23 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
24 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
25 #include "api/create_peerconnection_factory.h"
26 #include "api/peer_connection_proxy.h"
27 #include "api/uma_metrics.h"
28 #include "api/video_codecs/builtin_video_decoder_factory.h"
29 #include "api/video_codecs/builtin_video_encoder_factory.h"
30 #include "pc/test/fake_audio_capture_module.h"
31 #include "pc/test/mock_peer_connection_observers.h"
32 #include "rtc_base/fake_network.h"
33 #include "rtc_base/gunit.h"
34 #include "rtc_base/strings/string_builder.h"
35 #include "rtc_base/virtual_socket_server.h"
36 #include "system_wrappers/include/metrics.h"
37 #include "test/gmock.h"
38 
39 namespace webrtc {
40 
41 using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
42 using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
43 using rtc::SocketAddress;
44 using ::testing::Combine;
45 using ::testing::ElementsAre;
46 using ::testing::Pair;
47 using ::testing::Values;
48 
49 constexpr int kIceCandidatesTimeout = 10000;
50 constexpr int64_t kWaitTimeout = 10000;
51 
52 class PeerConnectionWrapperForIceTest : public PeerConnectionWrapper {
53  public:
54   using PeerConnectionWrapper::PeerConnectionWrapper;
55 
CreateJsepCandidateForFirstTransport(cricket::Candidate * candidate)56   std::unique_ptr<IceCandidateInterface> CreateJsepCandidateForFirstTransport(
57       cricket::Candidate* candidate) {
58     RTC_DCHECK(pc()->remote_description());
59     const auto* desc = pc()->remote_description()->description();
60     RTC_DCHECK(desc->contents().size() > 0);
61     const auto& first_content = desc->contents()[0];
62     candidate->set_transport_name(first_content.name);
63     return CreateIceCandidate(first_content.name, -1, *candidate);
64   }
65 
66   // Adds a new ICE candidate to the first transport.
AddIceCandidate(cricket::Candidate * candidate)67   bool AddIceCandidate(cricket::Candidate* candidate) {
68     return pc()->AddIceCandidate(
69         CreateJsepCandidateForFirstTransport(candidate).get());
70   }
71 
72   // Returns ICE candidates from the remote session description.
73   std::vector<const IceCandidateInterface*>
GetIceCandidatesFromRemoteDescription()74   GetIceCandidatesFromRemoteDescription() {
75     const SessionDescriptionInterface* sdesc = pc()->remote_description();
76     RTC_DCHECK(sdesc);
77     std::vector<const IceCandidateInterface*> candidates;
78     for (size_t mline_index = 0; mline_index < sdesc->number_of_mediasections();
79          mline_index++) {
80       const auto* candidate_collection = sdesc->candidates(mline_index);
81       for (size_t i = 0; i < candidate_collection->count(); i++) {
82         candidates.push_back(candidate_collection->at(i));
83       }
84     }
85     return candidates;
86   }
87 
network()88   rtc::FakeNetworkManager* network() { return network_; }
89 
set_network(rtc::FakeNetworkManager * network)90   void set_network(rtc::FakeNetworkManager* network) { network_ = network; }
91 
92   // The port allocator used by this PC.
93   cricket::PortAllocator* port_allocator_;
94 
95  private:
96   rtc::FakeNetworkManager* network_;
97 };
98 
99 class PeerConnectionIceBaseTest : public ::testing::Test {
100  protected:
101   typedef std::unique_ptr<PeerConnectionWrapperForIceTest> WrapperPtr;
102 
PeerConnectionIceBaseTest(SdpSemantics sdp_semantics)103   explicit PeerConnectionIceBaseTest(SdpSemantics sdp_semantics)
104       : vss_(new rtc::VirtualSocketServer()),
105         main_(vss_.get()),
106         sdp_semantics_(sdp_semantics) {
107 #ifdef WEBRTC_ANDROID
108     InitializeAndroidObjects();
109 #endif
110     pc_factory_ = CreatePeerConnectionFactory(
111         rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
112         rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
113         CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
114         CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
115         nullptr /* audio_mixer */, nullptr /* audio_processing */);
116   }
117 
CreatePeerConnection()118   WrapperPtr CreatePeerConnection() {
119     return CreatePeerConnection(RTCConfiguration());
120   }
121 
CreatePeerConnection(const RTCConfiguration & config)122   WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
123     auto* fake_network = NewFakeNetwork();
124     auto port_allocator =
125         std::make_unique<cricket::BasicPortAllocator>(fake_network);
126     port_allocator->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
127                               cricket::PORTALLOCATOR_DISABLE_RELAY);
128     port_allocator->set_step_delay(cricket::kMinimumStepDelay);
129     RTCConfiguration modified_config = config;
130     modified_config.sdp_semantics = sdp_semantics_;
131     auto observer = std::make_unique<MockPeerConnectionObserver>();
132     auto port_allocator_copy = port_allocator.get();
133     auto pc = pc_factory_->CreatePeerConnection(
134         modified_config, std::move(port_allocator), nullptr, observer.get());
135     if (!pc) {
136       return nullptr;
137     }
138 
139     observer->SetPeerConnectionInterface(pc.get());
140     auto wrapper = std::make_unique<PeerConnectionWrapperForIceTest>(
141         pc_factory_, pc, std::move(observer));
142     wrapper->set_network(fake_network);
143     wrapper->port_allocator_ = port_allocator_copy;
144     return wrapper;
145   }
146 
147   // Accepts the same arguments as CreatePeerConnection and adds default audio
148   // and video tracks.
149   template <typename... Args>
CreatePeerConnectionWithAudioVideo(Args &&...args)150   WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
151     auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
152     if (!wrapper) {
153       return nullptr;
154     }
155     wrapper->AddAudioTrack("a");
156     wrapper->AddVideoTrack("v");
157     return wrapper;
158   }
159 
CreateLocalUdpCandidate(const rtc::SocketAddress & address)160   cricket::Candidate CreateLocalUdpCandidate(
161       const rtc::SocketAddress& address) {
162     cricket::Candidate candidate;
163     candidate.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
164     candidate.set_protocol(cricket::UDP_PROTOCOL_NAME);
165     candidate.set_address(address);
166     candidate.set_type(cricket::LOCAL_PORT_TYPE);
167     return candidate;
168   }
169 
170   // Remove all ICE ufrag/pwd lines from the given session description.
RemoveIceUfragPwd(SessionDescriptionInterface * sdesc)171   void RemoveIceUfragPwd(SessionDescriptionInterface* sdesc) {
172     SetIceUfragPwd(sdesc, "", "");
173   }
174 
175   // Sets all ICE ufrag/pwds on the given session description.
SetIceUfragPwd(SessionDescriptionInterface * sdesc,const std::string & ufrag,const std::string & pwd)176   void SetIceUfragPwd(SessionDescriptionInterface* sdesc,
177                       const std::string& ufrag,
178                       const std::string& pwd) {
179     auto* desc = sdesc->description();
180     for (const auto& content : desc->contents()) {
181       auto* transport_info = desc->GetTransportInfoByName(content.name);
182       transport_info->description.ice_ufrag = ufrag;
183       transport_info->description.ice_pwd = pwd;
184     }
185   }
186 
187   // Set ICE mode on the given session description.
SetIceMode(SessionDescriptionInterface * sdesc,const cricket::IceMode ice_mode)188   void SetIceMode(SessionDescriptionInterface* sdesc,
189                   const cricket::IceMode ice_mode) {
190     auto* desc = sdesc->description();
191     for (const auto& content : desc->contents()) {
192       auto* transport_info = desc->GetTransportInfoByName(content.name);
193       transport_info->description.ice_mode = ice_mode;
194     }
195   }
196 
GetFirstTransportDescription(SessionDescriptionInterface * sdesc)197   cricket::TransportDescription* GetFirstTransportDescription(
198       SessionDescriptionInterface* sdesc) {
199     auto* desc = sdesc->description();
200     RTC_DCHECK(desc->contents().size() > 0);
201     auto* transport_info =
202         desc->GetTransportInfoByName(desc->contents()[0].name);
203     RTC_DCHECK(transport_info);
204     return &transport_info->description;
205   }
206 
GetFirstTransportDescription(const SessionDescriptionInterface * sdesc)207   const cricket::TransportDescription* GetFirstTransportDescription(
208       const SessionDescriptionInterface* sdesc) {
209     auto* desc = sdesc->description();
210     RTC_DCHECK(desc->contents().size() > 0);
211     auto* transport_info =
212         desc->GetTransportInfoByName(desc->contents()[0].name);
213     RTC_DCHECK(transport_info);
214     return &transport_info->description;
215   }
216 
217   // TODO(qingsi): Rewrite this method in terms of the standard IceTransport
218   // after it is implemented.
GetIceRole(const WrapperPtr & pc_wrapper_ptr)219   cricket::IceRole GetIceRole(const WrapperPtr& pc_wrapper_ptr) {
220     auto* pc_proxy =
221         static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
222             pc_wrapper_ptr->pc());
223     PeerConnection* pc = static_cast<PeerConnection*>(pc_proxy->internal());
224     for (const auto& transceiver : pc->GetTransceiversInternal()) {
225       if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
226         auto dtls_transport = pc->LookupDtlsTransportByMidInternal(
227             transceiver->internal()->channel()->content_name());
228         return dtls_transport->ice_transport()->internal()->GetIceRole();
229       }
230     }
231     RTC_NOTREACHED();
232     return cricket::ICEROLE_UNKNOWN;
233   }
234 
235   // Returns a list of (ufrag, pwd) pairs in the order that they appear in
236   // |description|, or the empty list if |description| is null.
GetIceCredentials(const SessionDescriptionInterface * description)237   std::vector<std::pair<std::string, std::string>> GetIceCredentials(
238       const SessionDescriptionInterface* description) {
239     std::vector<std::pair<std::string, std::string>> ice_credentials;
240     if (!description)
241       return ice_credentials;
242     const auto* desc = description->description();
243     for (const auto& content_info : desc->contents()) {
244       const auto* transport_info =
245           desc->GetTransportInfoByName(content_info.name);
246       if (transport_info) {
247         ice_credentials.push_back(
248             std::make_pair(transport_info->description.ice_ufrag,
249                            transport_info->description.ice_pwd));
250       }
251     }
252     return ice_credentials;
253   }
254 
AddCandidateToFirstTransport(cricket::Candidate * candidate,SessionDescriptionInterface * sdesc)255   bool AddCandidateToFirstTransport(cricket::Candidate* candidate,
256                                     SessionDescriptionInterface* sdesc) {
257     auto* desc = sdesc->description();
258     RTC_DCHECK(desc->contents().size() > 0);
259     const auto& first_content = desc->contents()[0];
260     candidate->set_transport_name(first_content.name);
261     std::unique_ptr<IceCandidateInterface> jsep_candidate =
262         CreateIceCandidate(first_content.name, 0, *candidate);
263     return sdesc->AddCandidate(jsep_candidate.get());
264   }
265 
NewFakeNetwork()266   rtc::FakeNetworkManager* NewFakeNetwork() {
267     // The PeerConnection's port allocator is tied to the PeerConnection's
268     // lifetime and expects the underlying NetworkManager to outlive it. That
269     // prevents us from having the PeerConnectionWrapper own the fake network.
270     // Therefore, the test fixture will own all the fake networks even though
271     // tests should access the fake network through the PeerConnectionWrapper.
272     auto* fake_network = new rtc::FakeNetworkManager();
273     fake_networks_.emplace_back(fake_network);
274     return fake_network;
275   }
276 
277   std::unique_ptr<rtc::VirtualSocketServer> vss_;
278   rtc::AutoSocketServerThread main_;
279   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
280   std::vector<std::unique_ptr<rtc::FakeNetworkManager>> fake_networks_;
281   const SdpSemantics sdp_semantics_;
282 };
283 
284 class PeerConnectionIceTest
285     : public PeerConnectionIceBaseTest,
286       public ::testing::WithParamInterface<SdpSemantics> {
287  protected:
PeerConnectionIceTest()288   PeerConnectionIceTest() : PeerConnectionIceBaseTest(GetParam()) {
289     webrtc::metrics::Reset();
290   }
291 };
292 
AssertCandidatesEqual(const char * a_expr,const char * b_expr,const cricket::Candidate & a,const cricket::Candidate & b)293 ::testing::AssertionResult AssertCandidatesEqual(const char* a_expr,
294                                                  const char* b_expr,
295                                                  const cricket::Candidate& a,
296                                                  const cricket::Candidate& b) {
297   rtc::StringBuilder failure_info;
298   if (a.component() != b.component()) {
299     failure_info << "\ncomponent: " << a.component() << " != " << b.component();
300   }
301   if (a.protocol() != b.protocol()) {
302     failure_info << "\nprotocol: " << a.protocol() << " != " << b.protocol();
303   }
304   if (a.address() != b.address()) {
305     failure_info << "\naddress: " << a.address().ToString()
306                  << " != " << b.address().ToString();
307   }
308   if (a.type() != b.type()) {
309     failure_info << "\ntype: " << a.type() << " != " << b.type();
310   }
311   std::string failure_info_str = failure_info.str();
312   if (failure_info_str.empty()) {
313     return ::testing::AssertionSuccess();
314   } else {
315     return ::testing::AssertionFailure()
316            << a_expr << " and " << b_expr << " are not equal"
317            << failure_info_str;
318   }
319 }
320 
TEST_P(PeerConnectionIceTest,OfferContainsGatheredCandidates)321 TEST_P(PeerConnectionIceTest, OfferContainsGatheredCandidates) {
322   const SocketAddress kLocalAddress("1.1.1.1", 0);
323 
324   auto caller = CreatePeerConnectionWithAudioVideo();
325   caller->network()->AddInterface(kLocalAddress);
326 
327   // Start ICE candidate gathering by setting the local offer.
328   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
329 
330   EXPECT_TRUE_WAIT(caller->IsIceGatheringDone(), kIceCandidatesTimeout);
331 
332   auto offer = caller->CreateOffer();
333   EXPECT_LT(0u, caller->observer()->GetCandidatesByMline(0).size());
334   EXPECT_EQ(caller->observer()->GetCandidatesByMline(0).size(),
335             offer->candidates(0)->count());
336   EXPECT_LT(0u, caller->observer()->GetCandidatesByMline(1).size());
337   EXPECT_EQ(caller->observer()->GetCandidatesByMline(1).size(),
338             offer->candidates(1)->count());
339 }
340 
TEST_P(PeerConnectionIceTest,AnswerContainsGatheredCandidates)341 TEST_P(PeerConnectionIceTest, AnswerContainsGatheredCandidates) {
342   const SocketAddress kCallerAddress("1.1.1.1", 0);
343 
344   auto caller = CreatePeerConnectionWithAudioVideo();
345   auto callee = CreatePeerConnectionWithAudioVideo();
346   caller->network()->AddInterface(kCallerAddress);
347 
348   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
349   ASSERT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
350 
351   EXPECT_TRUE_WAIT(callee->IsIceGatheringDone(), kIceCandidatesTimeout);
352 
353   auto* answer = callee->pc()->local_description();
354   EXPECT_LT(0u, caller->observer()->GetCandidatesByMline(0).size());
355   EXPECT_EQ(callee->observer()->GetCandidatesByMline(0).size(),
356             answer->candidates(0)->count());
357   EXPECT_LT(0u, caller->observer()->GetCandidatesByMline(1).size());
358   EXPECT_EQ(callee->observer()->GetCandidatesByMline(1).size(),
359             answer->candidates(1)->count());
360 }
361 
TEST_P(PeerConnectionIceTest,CanSetRemoteSessionDescriptionWithRemoteCandidates)362 TEST_P(PeerConnectionIceTest,
363        CanSetRemoteSessionDescriptionWithRemoteCandidates) {
364   const SocketAddress kCallerAddress("1.1.1.1", 1111);
365 
366   auto caller = CreatePeerConnectionWithAudioVideo();
367   auto callee = CreatePeerConnectionWithAudioVideo();
368 
369   auto offer = caller->CreateOfferAndSetAsLocal();
370   cricket::Candidate candidate = CreateLocalUdpCandidate(kCallerAddress);
371   AddCandidateToFirstTransport(&candidate, offer.get());
372 
373   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
374   auto remote_candidates = callee->GetIceCandidatesFromRemoteDescription();
375   ASSERT_EQ(1u, remote_candidates.size());
376   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate,
377                       remote_candidates[0]->candidate());
378 }
379 
TEST_P(PeerConnectionIceTest,SetLocalDescriptionFailsIfNoIceCredentials)380 TEST_P(PeerConnectionIceTest, SetLocalDescriptionFailsIfNoIceCredentials) {
381   auto caller = CreatePeerConnectionWithAudioVideo();
382 
383   auto offer = caller->CreateOffer();
384   RemoveIceUfragPwd(offer.get());
385 
386   EXPECT_FALSE(caller->SetLocalDescription(std::move(offer)));
387 }
388 
TEST_P(PeerConnectionIceTest,SetRemoteDescriptionFailsIfNoIceCredentials)389 TEST_P(PeerConnectionIceTest, SetRemoteDescriptionFailsIfNoIceCredentials) {
390   auto caller = CreatePeerConnectionWithAudioVideo();
391   auto callee = CreatePeerConnectionWithAudioVideo();
392 
393   auto offer = caller->CreateOfferAndSetAsLocal();
394   RemoveIceUfragPwd(offer.get());
395 
396   EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer)));
397 }
398 
399 // Test that doing an offer/answer exchange with no transport (i.e., no data
400 // channel or media) results in the ICE connection state staying at New.
TEST_P(PeerConnectionIceTest,OfferAnswerWithNoTransportsDoesNotChangeIceConnectionState)401 TEST_P(PeerConnectionIceTest,
402        OfferAnswerWithNoTransportsDoesNotChangeIceConnectionState) {
403   auto caller = CreatePeerConnection();
404   auto callee = CreatePeerConnection();
405 
406   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
407 
408   EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
409             caller->pc()->ice_connection_state());
410   EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
411             callee->pc()->ice_connection_state());
412 }
413 
414 // The following group tests that ICE candidates are not generated before
415 // SetLocalDescription is called on a PeerConnection.
416 
TEST_P(PeerConnectionIceTest,NoIceCandidatesBeforeSetLocalDescription)417 TEST_P(PeerConnectionIceTest, NoIceCandidatesBeforeSetLocalDescription) {
418   const SocketAddress kLocalAddress("1.1.1.1", 0);
419 
420   auto caller = CreatePeerConnectionWithAudioVideo();
421   caller->network()->AddInterface(kLocalAddress);
422 
423   // Pump for 1 second and verify that no candidates are generated.
424   rtc::Thread::Current()->ProcessMessages(1000);
425 
426   EXPECT_EQ(0u, caller->observer()->candidates_.size());
427 }
TEST_P(PeerConnectionIceTest,NoIceCandidatesBeforeAnswerSetAsLocalDescription)428 TEST_P(PeerConnectionIceTest,
429        NoIceCandidatesBeforeAnswerSetAsLocalDescription) {
430   const SocketAddress kCallerAddress("1.1.1.1", 1111);
431 
432   auto caller = CreatePeerConnectionWithAudioVideo();
433   auto callee = CreatePeerConnectionWithAudioVideo();
434   caller->network()->AddInterface(kCallerAddress);
435 
436   auto offer = caller->CreateOfferAndSetAsLocal();
437   cricket::Candidate candidate = CreateLocalUdpCandidate(kCallerAddress);
438   AddCandidateToFirstTransport(&candidate, offer.get());
439   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
440 
441   // Pump for 1 second and verify that no candidates are generated.
442   rtc::Thread::Current()->ProcessMessages(1000);
443 
444   EXPECT_EQ(0u, callee->observer()->candidates_.size());
445 }
446 
TEST_P(PeerConnectionIceTest,CannotAddCandidateWhenRemoteDescriptionNotSet)447 TEST_P(PeerConnectionIceTest, CannotAddCandidateWhenRemoteDescriptionNotSet) {
448   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
449 
450   auto caller = CreatePeerConnectionWithAudioVideo();
451   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
452   std::unique_ptr<IceCandidateInterface> jsep_candidate =
453       CreateIceCandidate(cricket::CN_AUDIO, 0, candidate);
454 
455   EXPECT_FALSE(caller->pc()->AddIceCandidate(jsep_candidate.get()));
456 
457   caller->CreateOfferAndSetAsLocal();
458 
459   EXPECT_FALSE(caller->pc()->AddIceCandidate(jsep_candidate.get()));
460   EXPECT_METRIC_THAT(
461       webrtc::metrics::Samples("WebRTC.PeerConnection.AddIceCandidate"),
462       ElementsAre(Pair(kAddIceCandidateFailNoRemoteDescription, 2)));
463 }
464 
TEST_P(PeerConnectionIceTest,CannotAddCandidateWhenPeerConnectionClosed)465 TEST_P(PeerConnectionIceTest, CannotAddCandidateWhenPeerConnectionClosed) {
466   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
467 
468   auto caller = CreatePeerConnectionWithAudioVideo();
469   auto callee = CreatePeerConnectionWithAudioVideo();
470 
471   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
472 
473   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
474   auto* audio_content = cricket::GetFirstAudioContent(
475       caller->pc()->local_description()->description());
476   std::unique_ptr<IceCandidateInterface> jsep_candidate =
477       CreateIceCandidate(audio_content->name, 0, candidate);
478 
479   caller->pc()->Close();
480 
481   EXPECT_FALSE(caller->pc()->AddIceCandidate(jsep_candidate.get()));
482 }
483 
TEST_P(PeerConnectionIceTest,DuplicateIceCandidateIgnoredWhenAdded)484 TEST_P(PeerConnectionIceTest, DuplicateIceCandidateIgnoredWhenAdded) {
485   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
486 
487   auto caller = CreatePeerConnectionWithAudioVideo();
488   auto callee = CreatePeerConnectionWithAudioVideo();
489 
490   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
491   ASSERT_TRUE(
492       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
493 
494   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
495   caller->AddIceCandidate(&candidate);
496   EXPECT_TRUE(caller->AddIceCandidate(&candidate));
497   EXPECT_EQ(1u, caller->GetIceCandidatesFromRemoteDescription().size());
498 }
499 
TEST_P(PeerConnectionIceTest,CannotRemoveIceCandidatesWhenPeerConnectionClosed)500 TEST_P(PeerConnectionIceTest,
501        CannotRemoveIceCandidatesWhenPeerConnectionClosed) {
502   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
503 
504   auto caller = CreatePeerConnectionWithAudioVideo();
505   auto callee = CreatePeerConnectionWithAudioVideo();
506 
507   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
508 
509   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
510   auto* audio_content = cricket::GetFirstAudioContent(
511       caller->pc()->local_description()->description());
512   std::unique_ptr<IceCandidateInterface> ice_candidate =
513       CreateIceCandidate(audio_content->name, 0, candidate);
514 
515   ASSERT_TRUE(caller->pc()->AddIceCandidate(ice_candidate.get()));
516 
517   caller->pc()->Close();
518 
519   EXPECT_FALSE(caller->pc()->RemoveIceCandidates({candidate}));
520 }
521 
TEST_P(PeerConnectionIceTest,AddRemoveCandidateWithEmptyTransportDoesNotCrash)522 TEST_P(PeerConnectionIceTest,
523        AddRemoveCandidateWithEmptyTransportDoesNotCrash) {
524   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
525 
526   auto caller = CreatePeerConnectionWithAudioVideo();
527   auto callee = CreatePeerConnectionWithAudioVideo();
528 
529   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
530   ASSERT_TRUE(
531       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
532 
533   // |candidate.transport_name()| is empty.
534   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
535   auto* audio_content = cricket::GetFirstAudioContent(
536       caller->pc()->local_description()->description());
537   std::unique_ptr<IceCandidateInterface> ice_candidate =
538       CreateIceCandidate(audio_content->name, 0, candidate);
539   EXPECT_TRUE(caller->pc()->AddIceCandidate(ice_candidate.get()));
540   EXPECT_TRUE(caller->pc()->RemoveIceCandidates({candidate}));
541 }
542 
TEST_P(PeerConnectionIceTest,RemoveCandidateRemovesFromRemoteDescription)543 TEST_P(PeerConnectionIceTest, RemoveCandidateRemovesFromRemoteDescription) {
544   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
545 
546   auto caller = CreatePeerConnectionWithAudioVideo();
547   auto callee = CreatePeerConnectionWithAudioVideo();
548 
549   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
550   ASSERT_TRUE(
551       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
552 
553   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
554   ASSERT_TRUE(caller->AddIceCandidate(&candidate));
555   EXPECT_TRUE(caller->pc()->RemoveIceCandidates({candidate}));
556   EXPECT_EQ(0u, caller->GetIceCandidatesFromRemoteDescription().size());
557 }
558 
559 // Test that if a candidate is added via AddIceCandidate and via an updated
560 // remote description, then both candidates appear in the stored remote
561 // description.
TEST_P(PeerConnectionIceTest,CandidateInSubsequentOfferIsAddedToRemoteDescription)562 TEST_P(PeerConnectionIceTest,
563        CandidateInSubsequentOfferIsAddedToRemoteDescription) {
564   const SocketAddress kCallerAddress1("1.1.1.1", 1111);
565   const SocketAddress kCallerAddress2("2.2.2.2", 2222);
566 
567   auto caller = CreatePeerConnectionWithAudioVideo();
568   auto callee = CreatePeerConnectionWithAudioVideo();
569 
570   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
571   ASSERT_TRUE(
572       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
573 
574   // Add one candidate via |AddIceCandidate|.
575   cricket::Candidate candidate1 = CreateLocalUdpCandidate(kCallerAddress1);
576   ASSERT_TRUE(callee->AddIceCandidate(&candidate1));
577 
578   // Add the second candidate via a reoffer.
579   auto offer = caller->CreateOffer();
580   cricket::Candidate candidate2 = CreateLocalUdpCandidate(kCallerAddress2);
581   AddCandidateToFirstTransport(&candidate2, offer.get());
582 
583   // Expect both candidates to appear in the callee's remote description.
584   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
585   EXPECT_EQ(2u, callee->GetIceCandidatesFromRemoteDescription().size());
586 }
587 
588 // The follow test verifies that SetLocal/RemoteDescription fails when an offer
589 // has either ICE ufrag/pwd too short or too long and succeeds otherwise.
590 // The standard (https://tools.ietf.org/html/rfc5245#section-15.4) says that
591 // pwd must be 22-256 characters and ufrag must be 4-256 characters.
TEST_P(PeerConnectionIceTest,VerifyUfragPwdLength)592 TEST_P(PeerConnectionIceTest, VerifyUfragPwdLength) {
593   auto set_local_description_with_ufrag_pwd_length = [this](int ufrag_len,
594                                                             int pwd_len) {
595     auto pc = CreatePeerConnectionWithAudioVideo();
596     auto offer = pc->CreateOffer();
597     SetIceUfragPwd(offer.get(), std::string(ufrag_len, 'x'),
598                    std::string(pwd_len, 'x'));
599     return pc->SetLocalDescription(std::move(offer));
600   };
601 
602   auto set_remote_description_with_ufrag_pwd_length = [this](int ufrag_len,
603                                                              int pwd_len) {
604     auto pc = CreatePeerConnectionWithAudioVideo();
605     auto offer = pc->CreateOffer();
606     SetIceUfragPwd(offer.get(), std::string(ufrag_len, 'x'),
607                    std::string(pwd_len, 'x'));
608     return pc->SetRemoteDescription(std::move(offer));
609   };
610 
611   EXPECT_FALSE(set_local_description_with_ufrag_pwd_length(3, 22));
612   EXPECT_FALSE(set_remote_description_with_ufrag_pwd_length(3, 22));
613   EXPECT_FALSE(set_local_description_with_ufrag_pwd_length(257, 22));
614   EXPECT_FALSE(set_remote_description_with_ufrag_pwd_length(257, 22));
615   EXPECT_FALSE(set_local_description_with_ufrag_pwd_length(4, 21));
616   EXPECT_FALSE(set_remote_description_with_ufrag_pwd_length(4, 21));
617   EXPECT_FALSE(set_local_description_with_ufrag_pwd_length(4, 257));
618   EXPECT_FALSE(set_remote_description_with_ufrag_pwd_length(4, 257));
619   EXPECT_TRUE(set_local_description_with_ufrag_pwd_length(4, 22));
620   EXPECT_TRUE(set_remote_description_with_ufrag_pwd_length(4, 22));
621   EXPECT_TRUE(set_local_description_with_ufrag_pwd_length(256, 256));
622   EXPECT_TRUE(set_remote_description_with_ufrag_pwd_length(256, 256));
623 }
624 
AssertIpInCandidates(const char * address_expr,const char * candidates_expr,const SocketAddress & address,const std::vector<IceCandidateInterface * > candidates)625 ::testing::AssertionResult AssertIpInCandidates(
626     const char* address_expr,
627     const char* candidates_expr,
628     const SocketAddress& address,
629     const std::vector<IceCandidateInterface*> candidates) {
630   rtc::StringBuilder candidate_hosts;
631   for (const auto* candidate : candidates) {
632     const auto& candidate_ip = candidate->candidate().address().ipaddr();
633     if (candidate_ip == address.ipaddr()) {
634       return ::testing::AssertionSuccess();
635     }
636     candidate_hosts << "\n" << candidate_ip.ToString();
637   }
638   return ::testing::AssertionFailure()
639          << address_expr << " (host " << address.HostAsURIString()
640          << ") not in " << candidates_expr
641          << " which have the following address hosts:" << candidate_hosts.str();
642 }
643 
TEST_P(PeerConnectionIceTest,CandidatesGeneratedForEachLocalInterface)644 TEST_P(PeerConnectionIceTest, CandidatesGeneratedForEachLocalInterface) {
645   const SocketAddress kLocalAddress1("1.1.1.1", 0);
646   const SocketAddress kLocalAddress2("2.2.2.2", 0);
647 
648   auto caller = CreatePeerConnectionWithAudioVideo();
649   caller->network()->AddInterface(kLocalAddress1);
650   caller->network()->AddInterface(kLocalAddress2);
651 
652   caller->CreateOfferAndSetAsLocal();
653   EXPECT_TRUE_WAIT(caller->IsIceGatheringDone(), kIceCandidatesTimeout);
654 
655   auto candidates = caller->observer()->GetCandidatesByMline(0);
656   EXPECT_PRED_FORMAT2(AssertIpInCandidates, kLocalAddress1, candidates);
657   EXPECT_PRED_FORMAT2(AssertIpInCandidates, kLocalAddress2, candidates);
658 }
659 
TEST_P(PeerConnectionIceTest,TrickledSingleCandidateAddedToRemoteDescription)660 TEST_P(PeerConnectionIceTest, TrickledSingleCandidateAddedToRemoteDescription) {
661   const SocketAddress kCallerAddress("1.1.1.1", 1111);
662 
663   auto caller = CreatePeerConnectionWithAudioVideo();
664   auto callee = CreatePeerConnectionWithAudioVideo();
665 
666   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
667 
668   cricket::Candidate candidate = CreateLocalUdpCandidate(kCallerAddress);
669   callee->AddIceCandidate(&candidate);
670   auto candidates = callee->GetIceCandidatesFromRemoteDescription();
671   ASSERT_EQ(1u, candidates.size());
672   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate,
673                       candidates[0]->candidate());
674 }
675 
TEST_P(PeerConnectionIceTest,TwoTrickledCandidatesAddedToRemoteDescription)676 TEST_P(PeerConnectionIceTest, TwoTrickledCandidatesAddedToRemoteDescription) {
677   const SocketAddress kCalleeAddress1("1.1.1.1", 1111);
678   const SocketAddress kCalleeAddress2("2.2.2.2", 2222);
679 
680   auto caller = CreatePeerConnectionWithAudioVideo();
681   auto callee = CreatePeerConnectionWithAudioVideo();
682 
683   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
684   ASSERT_TRUE(
685       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
686 
687   cricket::Candidate candidate1 = CreateLocalUdpCandidate(kCalleeAddress1);
688   caller->AddIceCandidate(&candidate1);
689 
690   cricket::Candidate candidate2 = CreateLocalUdpCandidate(kCalleeAddress2);
691   caller->AddIceCandidate(&candidate2);
692 
693   auto candidates = caller->GetIceCandidatesFromRemoteDescription();
694   ASSERT_EQ(2u, candidates.size());
695   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate1,
696                       candidates[0]->candidate());
697   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate2,
698                       candidates[1]->candidate());
699 }
700 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateIsAddedToRemoteDescription)701 TEST_P(PeerConnectionIceTest, AsyncAddIceCandidateIsAddedToRemoteDescription) {
702   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
703 
704   auto caller = CreatePeerConnectionWithAudioVideo();
705   auto callee = CreatePeerConnectionWithAudioVideo();
706 
707   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
708 
709   auto jsep_candidate =
710       callee->CreateJsepCandidateForFirstTransport(&candidate);
711   bool operation_completed = false;
712   callee->pc()->AddIceCandidate(std::move(jsep_candidate),
713                                 [&operation_completed](RTCError result) {
714                                   EXPECT_TRUE(result.ok());
715                                   operation_completed = true;
716                                 });
717   EXPECT_TRUE_WAIT(operation_completed, kWaitTimeout);
718 
719   auto candidates = callee->GetIceCandidatesFromRemoteDescription();
720   ASSERT_EQ(1u, candidates.size());
721   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate,
722                       candidates[0]->candidate());
723 }
724 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateCompletesImmediatelyIfNoPendingOperation)725 TEST_P(PeerConnectionIceTest,
726        AsyncAddIceCandidateCompletesImmediatelyIfNoPendingOperation) {
727   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
728 
729   auto caller = CreatePeerConnectionWithAudioVideo();
730   auto callee = CreatePeerConnectionWithAudioVideo();
731 
732   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
733 
734   auto jsep_candidate =
735       callee->CreateJsepCandidateForFirstTransport(&candidate);
736   bool operation_completed = false;
737   callee->pc()->AddIceCandidate(
738       std::move(jsep_candidate),
739       [&operation_completed](RTCError result) { operation_completed = true; });
740   EXPECT_TRUE(operation_completed);
741 }
742 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateCompletesWhenPendingOperationCompletes)743 TEST_P(PeerConnectionIceTest,
744        AsyncAddIceCandidateCompletesWhenPendingOperationCompletes) {
745   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
746 
747   auto caller = CreatePeerConnectionWithAudioVideo();
748   auto callee = CreatePeerConnectionWithAudioVideo();
749 
750   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
751 
752   // Chain an operation that will block AddIceCandidate() from executing.
753   rtc::scoped_refptr<MockCreateSessionDescriptionObserver> answer_observer(
754       new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
755   callee->pc()->CreateAnswer(answer_observer, RTCOfferAnswerOptions());
756 
757   auto jsep_candidate =
758       callee->CreateJsepCandidateForFirstTransport(&candidate);
759   bool operation_completed = false;
760   callee->pc()->AddIceCandidate(
761       std::move(jsep_candidate),
762       [&operation_completed](RTCError result) { operation_completed = true; });
763   // The operation will not be able to complete until we EXPECT_TRUE_WAIT()
764   // allowing CreateAnswer() to complete.
765   EXPECT_FALSE(operation_completed);
766   EXPECT_TRUE_WAIT(answer_observer->called(), kWaitTimeout);
767   // As soon as it does, AddIceCandidate() will execute without delay, so it
768   // must also have completed.
769   EXPECT_TRUE(operation_completed);
770 }
771 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateFailsBeforeSetRemoteDescription)772 TEST_P(PeerConnectionIceTest,
773        AsyncAddIceCandidateFailsBeforeSetRemoteDescription) {
774   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
775 
776   auto caller = CreatePeerConnectionWithAudioVideo();
777   std::unique_ptr<IceCandidateInterface> jsep_candidate =
778       CreateIceCandidate(cricket::CN_AUDIO, 0, candidate);
779 
780   bool operation_completed = false;
781   caller->pc()->AddIceCandidate(
782       std::move(jsep_candidate), [&operation_completed](RTCError result) {
783         EXPECT_FALSE(result.ok());
784         EXPECT_EQ(result.message(),
785                   std::string("Error processing ICE candidate"));
786         operation_completed = true;
787       });
788   EXPECT_TRUE_WAIT(operation_completed, kWaitTimeout);
789 }
790 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateFailsIfPeerConnectionDestroyed)791 TEST_P(PeerConnectionIceTest,
792        AsyncAddIceCandidateFailsIfPeerConnectionDestroyed) {
793   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
794 
795   auto caller = CreatePeerConnectionWithAudioVideo();
796   auto callee = CreatePeerConnectionWithAudioVideo();
797 
798   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
799 
800   // Chain an operation that will block AddIceCandidate() from executing.
801   rtc::scoped_refptr<MockCreateSessionDescriptionObserver> answer_observer(
802       new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
803   callee->pc()->CreateAnswer(answer_observer, RTCOfferAnswerOptions());
804 
805   auto jsep_candidate =
806       callee->CreateJsepCandidateForFirstTransport(&candidate);
807   bool operation_completed = false;
808   callee->pc()->AddIceCandidate(
809       std::move(jsep_candidate), [&operation_completed](RTCError result) {
810         EXPECT_FALSE(result.ok());
811         EXPECT_EQ(
812             result.message(),
813             std::string(
814                 "AddIceCandidate failed because the session was shut down"));
815         operation_completed = true;
816       });
817   // The operation will not be able to run until EXPECT_TRUE_WAIT(), giving us
818   // time to remove all references to the PeerConnection.
819   EXPECT_FALSE(operation_completed);
820   // This should delete the callee PC.
821   callee = nullptr;
822   EXPECT_TRUE_WAIT(operation_completed, kWaitTimeout);
823 }
824 
TEST_P(PeerConnectionIceTest,LocalDescriptionUpdatedWhenContinualGathering)825 TEST_P(PeerConnectionIceTest, LocalDescriptionUpdatedWhenContinualGathering) {
826   const SocketAddress kLocalAddress("1.1.1.1", 0);
827 
828   RTCConfiguration config;
829   config.continual_gathering_policy =
830       PeerConnectionInterface::GATHER_CONTINUALLY;
831   auto caller = CreatePeerConnectionWithAudioVideo(config);
832   caller->network()->AddInterface(kLocalAddress);
833 
834   // Start ICE candidate gathering by setting the local offer.
835   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
836 
837   // Since we're using continual gathering, we won't get "gathering done".
838   EXPECT_TRUE_WAIT(
839       caller->pc()->local_description()->candidates(0)->count() > 0,
840       kIceCandidatesTimeout);
841 }
842 
843 // Test that when continual gathering is enabled, and a network interface goes
844 // down, the candidate is signaled as removed and removed from the local
845 // description.
TEST_P(PeerConnectionIceTest,LocalCandidatesRemovedWhenNetworkDownIfGatheringContinually)846 TEST_P(PeerConnectionIceTest,
847        LocalCandidatesRemovedWhenNetworkDownIfGatheringContinually) {
848   const SocketAddress kLocalAddress("1.1.1.1", 0);
849 
850   RTCConfiguration config;
851   config.continual_gathering_policy =
852       PeerConnectionInterface::GATHER_CONTINUALLY;
853   auto caller = CreatePeerConnectionWithAudioVideo(config);
854   caller->network()->AddInterface(kLocalAddress);
855 
856   // Start ICE candidate gathering by setting the local offer.
857   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
858 
859   EXPECT_TRUE_WAIT(
860       caller->pc()->local_description()->candidates(0)->count() > 0,
861       kIceCandidatesTimeout);
862 
863   // Remove the only network interface, causing the PeerConnection to signal
864   // the removal of all candidates derived from this interface.
865   caller->network()->RemoveInterface(kLocalAddress);
866 
867   EXPECT_EQ_WAIT(0u, caller->pc()->local_description()->candidates(0)->count(),
868                  kIceCandidatesTimeout);
869   EXPECT_LT(0, caller->observer()->num_candidates_removed_);
870 }
871 
TEST_P(PeerConnectionIceTest,LocalCandidatesNotRemovedWhenNetworkDownIfGatheringOnce)872 TEST_P(PeerConnectionIceTest,
873        LocalCandidatesNotRemovedWhenNetworkDownIfGatheringOnce) {
874   const SocketAddress kLocalAddress("1.1.1.1", 0);
875 
876   RTCConfiguration config;
877   config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
878   auto caller = CreatePeerConnectionWithAudioVideo(config);
879   caller->network()->AddInterface(kLocalAddress);
880 
881   // Start ICE candidate gathering by setting the local offer.
882   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
883 
884   EXPECT_TRUE_WAIT(caller->IsIceGatheringDone(), kIceCandidatesTimeout);
885 
886   caller->network()->RemoveInterface(kLocalAddress);
887 
888   // Verify that the local candidates are not removed;
889   rtc::Thread::Current()->ProcessMessages(1000);
890   EXPECT_EQ(0, caller->observer()->num_candidates_removed_);
891 }
892 
893 // The following group tests that when an offer includes a new ufrag or pwd
894 // (indicating an ICE restart) the old candidates are removed and new candidates
895 // added to the remote description.
896 
TEST_P(PeerConnectionIceTest,IceRestartOfferClearsExistingCandidate)897 TEST_P(PeerConnectionIceTest, IceRestartOfferClearsExistingCandidate) {
898   const SocketAddress kCallerAddress("1.1.1.1", 1111);
899 
900   auto caller = CreatePeerConnectionWithAudioVideo();
901   auto callee = CreatePeerConnectionWithAudioVideo();
902 
903   auto offer = caller->CreateOfferAndSetAsLocal();
904   cricket::Candidate candidate = CreateLocalUdpCandidate(kCallerAddress);
905   AddCandidateToFirstTransport(&candidate, offer.get());
906 
907   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
908 
909   RTCOfferAnswerOptions options;
910   options.ice_restart = true;
911   ASSERT_TRUE(
912       callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal(options)));
913 
914   EXPECT_EQ(0u, callee->GetIceCandidatesFromRemoteDescription().size());
915 }
TEST_P(PeerConnectionIceTest,IceRestartOfferCandidateReplacesExistingCandidate)916 TEST_P(PeerConnectionIceTest,
917        IceRestartOfferCandidateReplacesExistingCandidate) {
918   const SocketAddress kFirstCallerAddress("1.1.1.1", 1111);
919   const SocketAddress kRestartedCallerAddress("2.2.2.2", 2222);
920 
921   auto caller = CreatePeerConnectionWithAudioVideo();
922   auto callee = CreatePeerConnectionWithAudioVideo();
923 
924   auto offer = caller->CreateOfferAndSetAsLocal();
925   cricket::Candidate old_candidate =
926       CreateLocalUdpCandidate(kFirstCallerAddress);
927   AddCandidateToFirstTransport(&old_candidate, offer.get());
928 
929   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
930 
931   RTCOfferAnswerOptions options;
932   options.ice_restart = true;
933   auto restart_offer = caller->CreateOfferAndSetAsLocal(options);
934   cricket::Candidate new_candidate =
935       CreateLocalUdpCandidate(kRestartedCallerAddress);
936   AddCandidateToFirstTransport(&new_candidate, restart_offer.get());
937 
938   ASSERT_TRUE(callee->SetRemoteDescription(std::move(restart_offer)));
939 
940   auto remote_candidates = callee->GetIceCandidatesFromRemoteDescription();
941   ASSERT_EQ(1u, remote_candidates.size());
942   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, new_candidate,
943                       remote_candidates[0]->candidate());
944 }
945 
946 // Test that if there is not an ICE restart (i.e., nothing changes), then the
947 // answer to a later offer should have the same ufrag/pwd as the first answer.
TEST_P(PeerConnectionIceTest,LaterAnswerHasSameIceCredentialsIfNoIceRestart)948 TEST_P(PeerConnectionIceTest, LaterAnswerHasSameIceCredentialsIfNoIceRestart) {
949   auto caller = CreatePeerConnectionWithAudioVideo();
950   auto callee = CreatePeerConnectionWithAudioVideo();
951 
952   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
953   ASSERT_TRUE(
954       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
955 
956   // Re-offer.
957   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
958 
959   auto answer = callee->CreateAnswer();
960   auto* answer_transport_desc = GetFirstTransportDescription(answer.get());
961   auto* local_transport_desc =
962       GetFirstTransportDescription(callee->pc()->local_description());
963 
964   EXPECT_EQ(answer_transport_desc->ice_ufrag, local_transport_desc->ice_ufrag);
965   EXPECT_EQ(answer_transport_desc->ice_pwd, local_transport_desc->ice_pwd);
966 }
967 
TEST_P(PeerConnectionIceTest,RestartIceGeneratesNewCredentials)968 TEST_P(PeerConnectionIceTest, RestartIceGeneratesNewCredentials) {
969   auto caller = CreatePeerConnectionWithAudioVideo();
970   auto callee = CreatePeerConnectionWithAudioVideo();
971 
972   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
973   auto initial_ice_credentials =
974       GetIceCredentials(caller->pc()->local_description());
975   caller->pc()->RestartIce();
976   ASSERT_TRUE(caller->CreateOfferAndSetAsLocal());
977   auto restarted_ice_credentials =
978       GetIceCredentials(caller->pc()->local_description());
979   EXPECT_NE(initial_ice_credentials, restarted_ice_credentials);
980 }
981 
TEST_P(PeerConnectionIceTest,RestartIceWhileLocalOfferIsPendingGeneratesNewCredentialsInNextOffer)982 TEST_P(PeerConnectionIceTest,
983        RestartIceWhileLocalOfferIsPendingGeneratesNewCredentialsInNextOffer) {
984   auto caller = CreatePeerConnectionWithAudioVideo();
985   auto callee = CreatePeerConnectionWithAudioVideo();
986 
987   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
988   auto initial_ice_credentials =
989       GetIceCredentials(caller->pc()->local_description());
990   // ICE restart becomes needed while an O/A is pending and |caller| is the
991   // offerer.
992   caller->pc()->RestartIce();
993   ASSERT_TRUE(
994       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
995   ASSERT_TRUE(caller->CreateOfferAndSetAsLocal());
996   auto restarted_ice_credentials =
997       GetIceCredentials(caller->pc()->local_description());
998   EXPECT_NE(initial_ice_credentials, restarted_ice_credentials);
999 }
1000 
TEST_P(PeerConnectionIceTest,RestartIceWhileRemoteOfferIsPendingGeneratesNewCredentialsInNextOffer)1001 TEST_P(PeerConnectionIceTest,
1002        RestartIceWhileRemoteOfferIsPendingGeneratesNewCredentialsInNextOffer) {
1003   auto caller = CreatePeerConnectionWithAudioVideo();
1004   auto callee = CreatePeerConnectionWithAudioVideo();
1005 
1006   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1007   auto initial_ice_credentials =
1008       GetIceCredentials(caller->pc()->local_description());
1009   ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateOfferAndSetAsLocal()));
1010   // ICE restart becomes needed while an O/A is pending and |caller| is the
1011   // answerer.
1012   caller->pc()->RestartIce();
1013   ASSERT_TRUE(
1014       callee->SetRemoteDescription(caller->CreateAnswerAndSetAsLocal()));
1015   ASSERT_TRUE(caller->CreateOfferAndSetAsLocal());
1016   auto restarted_ice_credentials =
1017       GetIceCredentials(caller->pc()->local_description());
1018   EXPECT_NE(initial_ice_credentials, restarted_ice_credentials);
1019 }
1020 
TEST_P(PeerConnectionIceTest,RestartIceTriggeredByRemoteSide)1021 TEST_P(PeerConnectionIceTest, RestartIceTriggeredByRemoteSide) {
1022   auto caller = CreatePeerConnectionWithAudioVideo();
1023   auto callee = CreatePeerConnectionWithAudioVideo();
1024 
1025   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1026   auto initial_ice_credentials =
1027       GetIceCredentials(caller->pc()->local_description());
1028 
1029   // Remote restart and O/A exchange with |caller| as the answerer should
1030   // restart ICE locally as well.
1031   callee->pc()->RestartIce();
1032   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
1033 
1034   auto restarted_ice_credentials =
1035       GetIceCredentials(caller->pc()->local_description());
1036   EXPECT_NE(initial_ice_credentials, restarted_ice_credentials);
1037 }
1038 
TEST_P(PeerConnectionIceTest,RestartIceCausesNegotiationNeeded)1039 TEST_P(PeerConnectionIceTest, RestartIceCausesNegotiationNeeded) {
1040   auto caller = CreatePeerConnectionWithAudioVideo();
1041   auto callee = CreatePeerConnectionWithAudioVideo();
1042 
1043   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1044   caller->observer()->clear_negotiation_needed();
1045   caller->pc()->RestartIce();
1046   EXPECT_TRUE(caller->observer()->negotiation_needed());
1047 }
1048 
1049 // In Unified Plan, "onnegotiationneeded" is spec-compliant, including not
1050 // firing multipe times in a row, or firing when returning to the stable
1051 // signaling state if negotiation is still needed. In Plan B it fires any time
1052 // something changes. As such, some tests are SdpSemantics-specific.
1053 class PeerConnectionIceTestUnifiedPlan : public PeerConnectionIceBaseTest {
1054  protected:
PeerConnectionIceTestUnifiedPlan()1055   PeerConnectionIceTestUnifiedPlan()
1056       : PeerConnectionIceBaseTest(SdpSemantics::kUnifiedPlan) {}
1057 };
1058 
TEST_F(PeerConnectionIceTestUnifiedPlan,RestartIceWhileLocalOfferIsPendingCausesNegotiationNeededWhenStable)1059 TEST_F(PeerConnectionIceTestUnifiedPlan,
1060        RestartIceWhileLocalOfferIsPendingCausesNegotiationNeededWhenStable) {
1061   auto caller = CreatePeerConnectionWithAudioVideo();
1062   auto callee = CreatePeerConnectionWithAudioVideo();
1063 
1064   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1065   // ICE restart becomes needed while an O/A is pending and |caller| is the
1066   // offerer.
1067   caller->observer()->clear_negotiation_needed();
1068   caller->pc()->RestartIce();
1069   // In Unified Plan, the event should not fire until we are back in the stable
1070   // signaling state.
1071   EXPECT_FALSE(caller->observer()->negotiation_needed());
1072   ASSERT_TRUE(
1073       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1074   EXPECT_TRUE(caller->observer()->negotiation_needed());
1075 }
1076 
TEST_F(PeerConnectionIceTestUnifiedPlan,RestartIceWhileRemoteOfferIsPendingCausesNegotiationNeededWhenStable)1077 TEST_F(PeerConnectionIceTestUnifiedPlan,
1078        RestartIceWhileRemoteOfferIsPendingCausesNegotiationNeededWhenStable) {
1079   auto caller = CreatePeerConnectionWithAudioVideo();
1080   auto callee = CreatePeerConnectionWithAudioVideo();
1081 
1082   // Establish initial credentials as the caller.
1083   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1084   ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateOfferAndSetAsLocal()));
1085   // ICE restart becomes needed while an O/A is pending and |caller| is the
1086   // answerer.
1087   caller->observer()->clear_negotiation_needed();
1088   caller->pc()->RestartIce();
1089   // In Unified Plan, the event should not fire until we are back in the stable
1090   // signaling state.
1091   EXPECT_FALSE(caller->observer()->negotiation_needed());
1092   ASSERT_TRUE(
1093       callee->SetRemoteDescription(caller->CreateAnswerAndSetAsLocal()));
1094   EXPECT_TRUE(caller->observer()->negotiation_needed());
1095 }
1096 
TEST_F(PeerConnectionIceTestUnifiedPlan,RestartIceTriggeredByRemoteSideCauseNegotiationNotNeeded)1097 TEST_F(PeerConnectionIceTestUnifiedPlan,
1098        RestartIceTriggeredByRemoteSideCauseNegotiationNotNeeded) {
1099   auto caller = CreatePeerConnectionWithAudioVideo();
1100   auto callee = CreatePeerConnectionWithAudioVideo();
1101 
1102   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1103   // Local restart.
1104   caller->pc()->RestartIce();
1105   caller->observer()->clear_negotiation_needed();
1106   // Remote restart and O/A exchange with |caller| as the answerer should
1107   // restart ICE locally as well.
1108   callee->pc()->RestartIce();
1109   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
1110   // Having restarted ICE by the remote offer, we do not need to renegotiate ICE
1111   // credentials when back in the stable signaling state.
1112   EXPECT_FALSE(caller->observer()->negotiation_needed());
1113 }
1114 
TEST_F(PeerConnectionIceTestUnifiedPlan,RestartIceTwiceDoesNotFireNegotiationNeededTwice)1115 TEST_F(PeerConnectionIceTestUnifiedPlan,
1116        RestartIceTwiceDoesNotFireNegotiationNeededTwice) {
1117   auto caller = CreatePeerConnectionWithAudioVideo();
1118   auto callee = CreatePeerConnectionWithAudioVideo();
1119 
1120   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1121   caller->pc()->RestartIce();
1122   EXPECT_TRUE(caller->observer()->negotiation_needed());
1123   caller->observer()->clear_negotiation_needed();
1124   caller->pc()->RestartIce();
1125   EXPECT_FALSE(caller->observer()->negotiation_needed());
1126 }
1127 
1128 // In Plan B, "onnegotiationneeded" is not spec-compliant, firing based on if
1129 // something changed rather than if negotiation is needed. In Unified Plan it
1130 // fires according to spec. As such, some tests are SdpSemantics-specific.
1131 class PeerConnectionIceTestPlanB : public PeerConnectionIceBaseTest {
1132  protected:
PeerConnectionIceTestPlanB()1133   PeerConnectionIceTestPlanB()
1134       : PeerConnectionIceBaseTest(SdpSemantics::kPlanB) {}
1135 };
1136 
TEST_F(PeerConnectionIceTestPlanB,RestartIceWhileOfferIsPendingCausesNegotiationNeededImmediately)1137 TEST_F(PeerConnectionIceTestPlanB,
1138        RestartIceWhileOfferIsPendingCausesNegotiationNeededImmediately) {
1139   auto caller = CreatePeerConnectionWithAudioVideo();
1140   auto callee = CreatePeerConnectionWithAudioVideo();
1141 
1142   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1143   caller->observer()->clear_negotiation_needed();
1144   caller->pc()->RestartIce();
1145   EXPECT_TRUE(caller->observer()->negotiation_needed());
1146   caller->observer()->clear_negotiation_needed();
1147   ASSERT_TRUE(
1148       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1149   // In Plan B, the event fired early so we don't expect it to fire now. This is
1150   // not spec-compliant but follows the pattern of existing Plan B behavior.
1151   EXPECT_FALSE(caller->observer()->negotiation_needed());
1152 }
1153 
TEST_F(PeerConnectionIceTestPlanB,RestartIceTwiceDoesFireNegotiationNeededTwice)1154 TEST_F(PeerConnectionIceTestPlanB,
1155        RestartIceTwiceDoesFireNegotiationNeededTwice) {
1156   auto caller = CreatePeerConnectionWithAudioVideo();
1157   auto callee = CreatePeerConnectionWithAudioVideo();
1158 
1159   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1160   caller->observer()->clear_negotiation_needed();
1161   caller->pc()->RestartIce();
1162   EXPECT_TRUE(caller->observer()->negotiation_needed());
1163   caller->observer()->clear_negotiation_needed();
1164   caller->pc()->RestartIce();
1165   // In Plan B, the event fires every time something changed, even if we have
1166   // already fired the event. This is not spec-compliant but follows the same
1167   // pattern of existing Plan B behavior.
1168   EXPECT_TRUE(caller->observer()->negotiation_needed());
1169 }
1170 
1171 // The following parameterized test verifies that if an offer is sent with a
1172 // modified ICE ufrag and/or ICE pwd, then the answer should identify that the
1173 // other side has initiated an ICE restart and generate a new ufrag and pwd.
1174 // RFC 5245 says: "If the offer contained a change in the a=ice-ufrag or
1175 // a=ice-pwd attributes compared to the previous SDP from the peer, it
1176 // indicates that ICE is restarting for this media stream."
1177 
1178 class PeerConnectionIceUfragPwdAnswerTest
1179     : public PeerConnectionIceBaseTest,
1180       public ::testing::WithParamInterface<
1181           std::tuple<SdpSemantics, std::tuple<bool, bool>>> {
1182  protected:
PeerConnectionIceUfragPwdAnswerTest()1183   PeerConnectionIceUfragPwdAnswerTest()
1184       : PeerConnectionIceBaseTest(std::get<0>(GetParam())) {
1185     auto param = std::get<1>(GetParam());
1186     offer_new_ufrag_ = std::get<0>(param);
1187     offer_new_pwd_ = std::get<1>(param);
1188   }
1189 
1190   bool offer_new_ufrag_;
1191   bool offer_new_pwd_;
1192 };
1193 
TEST_P(PeerConnectionIceUfragPwdAnswerTest,TestIncludedInAnswer)1194 TEST_P(PeerConnectionIceUfragPwdAnswerTest, TestIncludedInAnswer) {
1195   auto caller = CreatePeerConnectionWithAudioVideo();
1196   auto callee = CreatePeerConnectionWithAudioVideo();
1197 
1198   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1199   ASSERT_TRUE(
1200       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1201 
1202   auto offer = caller->CreateOffer();
1203   auto* offer_transport_desc = GetFirstTransportDescription(offer.get());
1204   if (offer_new_ufrag_) {
1205     offer_transport_desc->ice_ufrag += "+new";
1206   }
1207   if (offer_new_pwd_) {
1208     offer_transport_desc->ice_pwd += "+new";
1209   }
1210 
1211   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1212 
1213   auto answer = callee->CreateAnswer();
1214   auto* answer_transport_desc = GetFirstTransportDescription(answer.get());
1215   auto* local_transport_desc =
1216       GetFirstTransportDescription(callee->pc()->local_description());
1217 
1218   EXPECT_NE(answer_transport_desc->ice_ufrag, local_transport_desc->ice_ufrag);
1219   EXPECT_NE(answer_transport_desc->ice_pwd, local_transport_desc->ice_pwd);
1220 }
1221 
1222 INSTANTIATE_TEST_SUITE_P(
1223     PeerConnectionIceTest,
1224     PeerConnectionIceUfragPwdAnswerTest,
1225     Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
1226             Values(std::make_pair(true, true),      // Both changed.
1227                    std::make_pair(true, false),     // Only ufrag changed.
1228                    std::make_pair(false, true))));  // Only pwd changed.
1229 
1230 // Test that if an ICE restart is offered on one media section, then the answer
1231 // will only change ICE ufrag/pwd for that section and keep the other sections
1232 // the same.
1233 // Note that this only works if we have disabled BUNDLE, otherwise all media
1234 // sections will share the same transport.
TEST_P(PeerConnectionIceTest,CreateAnswerHasNewUfragPwdForOnlyMediaSectionWhichRestarted)1235 TEST_P(PeerConnectionIceTest,
1236        CreateAnswerHasNewUfragPwdForOnlyMediaSectionWhichRestarted) {
1237   auto caller = CreatePeerConnectionWithAudioVideo();
1238   auto callee = CreatePeerConnectionWithAudioVideo();
1239 
1240   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1241   ASSERT_TRUE(
1242       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1243 
1244   RTCOfferAnswerOptions disable_bundle_options;
1245   disable_bundle_options.use_rtp_mux = false;
1246 
1247   auto offer = caller->CreateOffer(disable_bundle_options);
1248 
1249   // Signal ICE restart on the first media section.
1250   auto* offer_transport_desc = GetFirstTransportDescription(offer.get());
1251   offer_transport_desc->ice_ufrag += "+new";
1252   offer_transport_desc->ice_pwd += "+new";
1253 
1254   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1255 
1256   auto answer = callee->CreateAnswer(disable_bundle_options);
1257   const auto& answer_transports = answer->description()->transport_infos();
1258   const auto& local_transports =
1259       callee->pc()->local_description()->description()->transport_infos();
1260 
1261   EXPECT_NE(answer_transports[0].description.ice_ufrag,
1262             local_transports[0].description.ice_ufrag);
1263   EXPECT_NE(answer_transports[0].description.ice_pwd,
1264             local_transports[0].description.ice_pwd);
1265   EXPECT_EQ(answer_transports[1].description.ice_ufrag,
1266             local_transports[1].description.ice_ufrag);
1267   EXPECT_EQ(answer_transports[1].description.ice_pwd,
1268             local_transports[1].description.ice_pwd);
1269 }
1270 
1271 // Test that when the initial offerer (caller) uses the lite implementation of
1272 // ICE and the callee uses the full implementation, the caller takes the
1273 // CONTROLLED role and the callee takes the CONTROLLING role. This is specified
1274 // in RFC5245 Section 5.1.1.
TEST_P(PeerConnectionIceTest,OfferFromLiteIceControlledAndAnswerFromFullIceControlling)1275 TEST_P(PeerConnectionIceTest,
1276        OfferFromLiteIceControlledAndAnswerFromFullIceControlling) {
1277   auto caller = CreatePeerConnectionWithAudioVideo();
1278   auto callee = CreatePeerConnectionWithAudioVideo();
1279 
1280   auto offer = caller->CreateOffer();
1281   SetIceMode(offer.get(), cricket::IceMode::ICEMODE_LITE);
1282   ASSERT_TRUE(
1283       caller->SetLocalDescription(CloneSessionDescription(offer.get())));
1284   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1285 
1286   auto answer = callee->CreateAnswer();
1287   SetIceMode(answer.get(), cricket::IceMode::ICEMODE_FULL);
1288   ASSERT_TRUE(
1289       callee->SetLocalDescription(CloneSessionDescription(answer.get())));
1290   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
1291 
1292   EXPECT_EQ(cricket::ICEROLE_CONTROLLED, GetIceRole(caller));
1293   EXPECT_EQ(cricket::ICEROLE_CONTROLLING, GetIceRole(callee));
1294 }
1295 
1296 // Test that when the caller and the callee both use the lite implementation of
1297 // ICE, the initial offerer (caller) takes the CONTROLLING role and the callee
1298 // takes the CONTROLLED role. This is specified in RFC5245 Section 5.1.1.
TEST_P(PeerConnectionIceTest,OfferFromLiteIceControllingAndAnswerFromLiteIceControlled)1299 TEST_P(PeerConnectionIceTest,
1300        OfferFromLiteIceControllingAndAnswerFromLiteIceControlled) {
1301   auto caller = CreatePeerConnectionWithAudioVideo();
1302   auto callee = CreatePeerConnectionWithAudioVideo();
1303 
1304   auto offer = caller->CreateOffer();
1305   SetIceMode(offer.get(), cricket::IceMode::ICEMODE_LITE);
1306   ASSERT_TRUE(
1307       caller->SetLocalDescription(CloneSessionDescription(offer.get())));
1308   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1309 
1310   auto answer = callee->CreateAnswer();
1311   SetIceMode(answer.get(), cricket::IceMode::ICEMODE_LITE);
1312   ASSERT_TRUE(
1313       callee->SetLocalDescription(CloneSessionDescription(answer.get())));
1314   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
1315 
1316   EXPECT_EQ(cricket::ICEROLE_CONTROLLING, GetIceRole(caller));
1317   EXPECT_EQ(cricket::ICEROLE_CONTROLLED, GetIceRole(callee));
1318 }
1319 
1320 INSTANTIATE_TEST_SUITE_P(PeerConnectionIceTest,
1321                          PeerConnectionIceTest,
1322                          Values(SdpSemantics::kPlanB,
1323                                 SdpSemantics::kUnifiedPlan));
1324 
1325 class PeerConnectionIceConfigTest : public ::testing::Test {
1326  protected:
SetUp()1327   void SetUp() override {
1328     pc_factory_ = CreatePeerConnectionFactory(
1329         rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
1330         FakeAudioCaptureModule::Create(), CreateBuiltinAudioEncoderFactory(),
1331         CreateBuiltinAudioDecoderFactory(), CreateBuiltinVideoEncoderFactory(),
1332         CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
1333         nullptr /* audio_processing */);
1334   }
CreatePeerConnection(const RTCConfiguration & config)1335   void CreatePeerConnection(const RTCConfiguration& config) {
1336     std::unique_ptr<cricket::FakePortAllocator> port_allocator(
1337         new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
1338     port_allocator_ = port_allocator.get();
1339     rtc::scoped_refptr<PeerConnectionInterface> pc(
1340         pc_factory_->CreatePeerConnection(config, std::move(port_allocator),
1341                                           nullptr /* cert_generator */,
1342                                           &observer_));
1343     EXPECT_TRUE(pc.get());
1344     pc_ = std::move(pc);
1345   }
1346 
1347   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_ = nullptr;
1348   rtc::scoped_refptr<PeerConnectionInterface> pc_ = nullptr;
1349   cricket::FakePortAllocator* port_allocator_ = nullptr;
1350 
1351   MockPeerConnectionObserver observer_;
1352 };
1353 
TEST_F(PeerConnectionIceConfigTest,SetStunCandidateKeepaliveInterval)1354 TEST_F(PeerConnectionIceConfigTest, SetStunCandidateKeepaliveInterval) {
1355   RTCConfiguration config;
1356   config.stun_candidate_keepalive_interval = 123;
1357   config.ice_candidate_pool_size = 1;
1358   CreatePeerConnection(config);
1359   ASSERT_NE(port_allocator_, nullptr);
1360   absl::optional<int> actual_stun_keepalive_interval =
1361       port_allocator_->stun_candidate_keepalive_interval();
1362   EXPECT_EQ(actual_stun_keepalive_interval.value_or(-1), 123);
1363   config.stun_candidate_keepalive_interval = 321;
1364   ASSERT_TRUE(pc_->SetConfiguration(config).ok());
1365   actual_stun_keepalive_interval =
1366       port_allocator_->stun_candidate_keepalive_interval();
1367   EXPECT_EQ(actual_stun_keepalive_interval.value_or(-1), 321);
1368 }
1369 
TEST_P(PeerConnectionIceTest,IceCredentialsCreateOffer)1370 TEST_P(PeerConnectionIceTest, IceCredentialsCreateOffer) {
1371   RTCConfiguration config;
1372   config.ice_candidate_pool_size = 1;
1373   auto pc = CreatePeerConnectionWithAudioVideo(config);
1374   ASSERT_NE(pc->port_allocator_, nullptr);
1375   auto offer = pc->CreateOffer();
1376   auto credentials = pc->port_allocator_->GetPooledIceCredentials();
1377   ASSERT_EQ(1u, credentials.size());
1378 
1379   auto* desc = offer->description();
1380   for (const auto& content : desc->contents()) {
1381     auto* transport_info = desc->GetTransportInfoByName(content.name);
1382     EXPECT_EQ(transport_info->description.ice_ufrag, credentials[0].ufrag);
1383     EXPECT_EQ(transport_info->description.ice_pwd, credentials[0].pwd);
1384   }
1385 }
1386 
TEST_P(PeerConnectionIceTest,IceCredentialsCreateAnswer)1387 TEST_P(PeerConnectionIceTest, IceCredentialsCreateAnswer) {
1388   RTCConfiguration config;
1389   config.ice_candidate_pool_size = 1;
1390   auto pc = CreatePeerConnectionWithAudioVideo(config);
1391   ASSERT_NE(pc->port_allocator_, nullptr);
1392   auto offer = pc->CreateOffer();
1393   ASSERT_TRUE(pc->SetRemoteDescription(std::move(offer)));
1394   auto answer = pc->CreateAnswer();
1395 
1396   auto credentials = pc->port_allocator_->GetPooledIceCredentials();
1397   ASSERT_EQ(1u, credentials.size());
1398 
1399   auto* desc = answer->description();
1400   for (const auto& content : desc->contents()) {
1401     auto* transport_info = desc->GetTransportInfoByName(content.name);
1402     EXPECT_EQ(transport_info->description.ice_ufrag, credentials[0].ufrag);
1403     EXPECT_EQ(transport_info->description.ice_pwd, credentials[0].pwd);
1404   }
1405 }
1406 
1407 // Regression test for https://bugs.chromium.org/p/webrtc/issues/detail?id=4728
TEST_P(PeerConnectionIceTest,CloseDoesNotTransitionGatheringStateToComplete)1408 TEST_P(PeerConnectionIceTest, CloseDoesNotTransitionGatheringStateToComplete) {
1409   auto pc = CreatePeerConnectionWithAudioVideo();
1410   pc->pc()->Close();
1411   EXPECT_FALSE(pc->IsIceGatheringDone());
1412   EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
1413             pc->pc()->ice_gathering_state());
1414 }
1415 
1416 }  // namespace webrtc
1417