1 /*
2 * Copyright 2012 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 "pc/peer_connection_factory.h"
12
13 #include <stddef.h>
14
15 #include <memory>
16 #include <string>
17 #include <utility>
18 #include <vector>
19
20 #include "api/audio/audio_mixer.h"
21 #include "api/audio_codecs/audio_decoder_factory.h"
22 #include "api/audio_codecs/audio_encoder_factory.h"
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/data_channel_interface.h"
27 #include "api/jsep.h"
28 #include "api/media_stream_interface.h"
29 #include "api/video_codecs/builtin_video_decoder_factory.h"
30 #include "api/video_codecs/builtin_video_encoder_factory.h"
31 #include "api/video_codecs/video_decoder_factory.h"
32 #include "api/video_codecs/video_encoder_factory.h"
33 #include "media/base/fake_frame_source.h"
34 #include "modules/audio_device/include/audio_device.h"
35 #include "modules/audio_processing/include/audio_processing.h"
36 #include "p2p/base/fake_port_allocator.h"
37 #include "p2p/base/port.h"
38 #include "p2p/base/port_interface.h"
39 #include "pc/test/fake_audio_capture_module.h"
40 #include "pc/test/fake_video_track_source.h"
41 #include "rtc_base/socket_address.h"
42 #include "test/gtest.h"
43
44 #ifdef WEBRTC_ANDROID
45 #include "pc/test/android_test_initializer.h"
46 #endif
47 #include "pc/test/fake_rtc_certificate_generator.h"
48 #include "pc/test/fake_video_track_renderer.h"
49
50 using webrtc::DataChannelInterface;
51 using webrtc::FakeVideoTrackRenderer;
52 using webrtc::MediaStreamInterface;
53 using webrtc::PeerConnectionFactoryInterface;
54 using webrtc::PeerConnectionInterface;
55 using webrtc::PeerConnectionObserver;
56 using webrtc::VideoTrackInterface;
57 using webrtc::VideoTrackSourceInterface;
58
59 namespace {
60
61 static const char kStunIceServer[] = "stun:stun.l.google.com:19302";
62 static const char kTurnIceServer[] = "turn:test.com:1234";
63 static const char kTurnIceServerWithTransport[] =
64 "turn:hello.com?transport=tcp";
65 static const char kSecureTurnIceServer[] = "turns:hello.com?transport=tcp";
66 static const char kSecureTurnIceServerWithoutTransportParam[] =
67 "turns:hello.com:443";
68 static const char kSecureTurnIceServerWithoutTransportAndPortParam[] =
69 "turns:hello.com";
70 static const char kTurnIceServerWithNoUsernameInUri[] = "turn:test.com:1234";
71 static const char kTurnPassword[] = "turnpassword";
72 static const int kDefaultStunPort = 3478;
73 static const int kDefaultStunTlsPort = 5349;
74 static const char kTurnUsername[] = "test";
75 static const char kStunIceServerWithIPv4Address[] = "stun:1.2.3.4:1234";
76 static const char kStunIceServerWithIPv4AddressWithoutPort[] = "stun:1.2.3.4";
77 static const char kStunIceServerWithIPv6Address[] = "stun:[2401:fa00:4::]:1234";
78 static const char kStunIceServerWithIPv6AddressWithoutPort[] =
79 "stun:[2401:fa00:4::]";
80 static const char kTurnIceServerWithIPv6Address[] = "turn:[2401:fa00:4::]:1234";
81
82 class NullPeerConnectionObserver : public PeerConnectionObserver {
83 public:
84 virtual ~NullPeerConnectionObserver() = default;
OnSignalingChange(PeerConnectionInterface::SignalingState new_state)85 void OnSignalingChange(
86 PeerConnectionInterface::SignalingState new_state) override {}
OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream)87 void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override {}
OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream)88 void OnRemoveStream(
89 rtc::scoped_refptr<MediaStreamInterface> stream) override {}
OnDataChannel(rtc::scoped_refptr<DataChannelInterface> data_channel)90 void OnDataChannel(
91 rtc::scoped_refptr<DataChannelInterface> data_channel) override {}
OnRenegotiationNeeded()92 void OnRenegotiationNeeded() override {}
OnIceConnectionChange(PeerConnectionInterface::IceConnectionState new_state)93 void OnIceConnectionChange(
94 PeerConnectionInterface::IceConnectionState new_state) override {}
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)95 void OnIceGatheringChange(
96 PeerConnectionInterface::IceGatheringState new_state) override {}
OnIceCandidate(const webrtc::IceCandidateInterface * candidate)97 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
98 }
99 };
100
101 } // namespace
102
103 class PeerConnectionFactoryTest : public ::testing::Test {
SetUp()104 void SetUp() {
105 #ifdef WEBRTC_ANDROID
106 webrtc::InitializeAndroidObjects();
107 #endif
108 // Use fake audio device module since we're only testing the interface
109 // level, and using a real one could make tests flaky e.g. when run in
110 // parallel.
111 factory_ = webrtc::CreatePeerConnectionFactory(
112 rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
113 rtc::scoped_refptr<webrtc::AudioDeviceModule>(
114 FakeAudioCaptureModule::Create()),
115 webrtc::CreateBuiltinAudioEncoderFactory(),
116 webrtc::CreateBuiltinAudioDecoderFactory(),
117 webrtc::CreateBuiltinVideoEncoderFactory(),
118 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
119 nullptr /* audio_processing */);
120
121 ASSERT_TRUE(factory_.get() != NULL);
122 port_allocator_.reset(
123 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
124 raw_port_allocator_ = port_allocator_.get();
125 }
126
127 protected:
VerifyStunServers(cricket::ServerAddresses stun_servers)128 void VerifyStunServers(cricket::ServerAddresses stun_servers) {
129 EXPECT_EQ(stun_servers, raw_port_allocator_->stun_servers());
130 }
131
VerifyTurnServers(std::vector<cricket::RelayServerConfig> turn_servers)132 void VerifyTurnServers(std::vector<cricket::RelayServerConfig> turn_servers) {
133 EXPECT_EQ(turn_servers.size(), raw_port_allocator_->turn_servers().size());
134 for (size_t i = 0; i < turn_servers.size(); ++i) {
135 ASSERT_EQ(1u, turn_servers[i].ports.size());
136 EXPECT_EQ(1u, raw_port_allocator_->turn_servers()[i].ports.size());
137 EXPECT_EQ(
138 turn_servers[i].ports[0].address.ToString(),
139 raw_port_allocator_->turn_servers()[i].ports[0].address.ToString());
140 EXPECT_EQ(turn_servers[i].ports[0].proto,
141 raw_port_allocator_->turn_servers()[i].ports[0].proto);
142 EXPECT_EQ(turn_servers[i].credentials.username,
143 raw_port_allocator_->turn_servers()[i].credentials.username);
144 EXPECT_EQ(turn_servers[i].credentials.password,
145 raw_port_allocator_->turn_servers()[i].credentials.password);
146 }
147 }
148
VerifyAudioCodecCapability(const webrtc::RtpCodecCapability & codec)149 void VerifyAudioCodecCapability(const webrtc::RtpCodecCapability& codec) {
150 EXPECT_EQ(codec.kind, cricket::MEDIA_TYPE_AUDIO);
151 EXPECT_FALSE(codec.name.empty());
152 EXPECT_GT(codec.clock_rate, 0);
153 EXPECT_GT(codec.num_channels, 0);
154 }
155
VerifyVideoCodecCapability(const webrtc::RtpCodecCapability & codec)156 void VerifyVideoCodecCapability(const webrtc::RtpCodecCapability& codec) {
157 EXPECT_EQ(codec.kind, cricket::MEDIA_TYPE_VIDEO);
158 EXPECT_FALSE(codec.name.empty());
159 EXPECT_GT(codec.clock_rate, 0);
160 }
161
162 rtc::scoped_refptr<PeerConnectionFactoryInterface> factory_;
163 NullPeerConnectionObserver observer_;
164 std::unique_ptr<cricket::FakePortAllocator> port_allocator_;
165 // Since the PC owns the port allocator after it's been initialized,
166 // this should only be used when known to be safe.
167 cricket::FakePortAllocator* raw_port_allocator_;
168 };
169
170 // Verify creation of PeerConnection using internal ADM, video factory and
171 // internal libjingle threads.
172 // TODO(henrika): disabling this test since relying on real audio can result in
173 // flaky tests and focus on details that are out of scope for you might expect
174 // for a PeerConnectionFactory unit test.
175 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7806 for details.
TEST(PeerConnectionFactoryTestInternal,DISABLED_CreatePCUsingInternalModules)176 TEST(PeerConnectionFactoryTestInternal, DISABLED_CreatePCUsingInternalModules) {
177 #ifdef WEBRTC_ANDROID
178 webrtc::InitializeAndroidObjects();
179 #endif
180
181 rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
182 webrtc::CreatePeerConnectionFactory(
183 nullptr /* network_thread */, nullptr /* worker_thread */,
184 nullptr /* signaling_thread */, nullptr /* default_adm */,
185 webrtc::CreateBuiltinAudioEncoderFactory(),
186 webrtc::CreateBuiltinAudioDecoderFactory(),
187 webrtc::CreateBuiltinVideoEncoderFactory(),
188 webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
189 nullptr /* audio_processing */));
190
191 NullPeerConnectionObserver observer;
192 webrtc::PeerConnectionInterface::RTCConfiguration config;
193
194 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
195 new FakeRTCCertificateGenerator());
196 rtc::scoped_refptr<PeerConnectionInterface> pc(factory->CreatePeerConnection(
197 config, nullptr, std::move(cert_generator), &observer));
198
199 EXPECT_TRUE(pc.get() != nullptr);
200 }
201
TEST_F(PeerConnectionFactoryTest,CheckRtpSenderAudioCapabilities)202 TEST_F(PeerConnectionFactoryTest, CheckRtpSenderAudioCapabilities) {
203 webrtc::RtpCapabilities audio_capabilities =
204 factory_->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO);
205 EXPECT_FALSE(audio_capabilities.codecs.empty());
206 for (const auto& codec : audio_capabilities.codecs) {
207 VerifyAudioCodecCapability(codec);
208 }
209 EXPECT_FALSE(audio_capabilities.header_extensions.empty());
210 for (const auto& header_extension : audio_capabilities.header_extensions) {
211 EXPECT_FALSE(header_extension.uri.empty());
212 }
213 }
214
TEST_F(PeerConnectionFactoryTest,CheckRtpSenderVideoCapabilities)215 TEST_F(PeerConnectionFactoryTest, CheckRtpSenderVideoCapabilities) {
216 webrtc::RtpCapabilities video_capabilities =
217 factory_->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO);
218 EXPECT_FALSE(video_capabilities.codecs.empty());
219 for (const auto& codec : video_capabilities.codecs) {
220 VerifyVideoCodecCapability(codec);
221 }
222 EXPECT_FALSE(video_capabilities.header_extensions.empty());
223 for (const auto& header_extension : video_capabilities.header_extensions) {
224 EXPECT_FALSE(header_extension.uri.empty());
225 }
226 }
227
TEST_F(PeerConnectionFactoryTest,CheckRtpSenderDataCapabilities)228 TEST_F(PeerConnectionFactoryTest, CheckRtpSenderDataCapabilities) {
229 webrtc::RtpCapabilities data_capabilities =
230 factory_->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_DATA);
231 EXPECT_TRUE(data_capabilities.codecs.empty());
232 EXPECT_TRUE(data_capabilities.header_extensions.empty());
233 }
234
TEST_F(PeerConnectionFactoryTest,CheckRtpReceiverAudioCapabilities)235 TEST_F(PeerConnectionFactoryTest, CheckRtpReceiverAudioCapabilities) {
236 webrtc::RtpCapabilities audio_capabilities =
237 factory_->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_AUDIO);
238 EXPECT_FALSE(audio_capabilities.codecs.empty());
239 for (const auto& codec : audio_capabilities.codecs) {
240 VerifyAudioCodecCapability(codec);
241 }
242 EXPECT_FALSE(audio_capabilities.header_extensions.empty());
243 for (const auto& header_extension : audio_capabilities.header_extensions) {
244 EXPECT_FALSE(header_extension.uri.empty());
245 }
246 }
247
TEST_F(PeerConnectionFactoryTest,CheckRtpReceiverVideoCapabilities)248 TEST_F(PeerConnectionFactoryTest, CheckRtpReceiverVideoCapabilities) {
249 webrtc::RtpCapabilities video_capabilities =
250 factory_->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO);
251 EXPECT_FALSE(video_capabilities.codecs.empty());
252 for (const auto& codec : video_capabilities.codecs) {
253 VerifyVideoCodecCapability(codec);
254 }
255 EXPECT_FALSE(video_capabilities.header_extensions.empty());
256 for (const auto& header_extension : video_capabilities.header_extensions) {
257 EXPECT_FALSE(header_extension.uri.empty());
258 }
259 }
260
TEST_F(PeerConnectionFactoryTest,CheckRtpReceiverDataCapabilities)261 TEST_F(PeerConnectionFactoryTest, CheckRtpReceiverDataCapabilities) {
262 webrtc::RtpCapabilities data_capabilities =
263 factory_->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_DATA);
264 EXPECT_TRUE(data_capabilities.codecs.empty());
265 EXPECT_TRUE(data_capabilities.header_extensions.empty());
266 }
267
268 // This test verifies creation of PeerConnection with valid STUN and TURN
269 // configuration. Also verifies the URL's parsed correctly as expected.
TEST_F(PeerConnectionFactoryTest,CreatePCUsingIceServers)270 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServers) {
271 PeerConnectionInterface::RTCConfiguration config;
272 webrtc::PeerConnectionInterface::IceServer ice_server;
273 ice_server.uri = kStunIceServer;
274 config.servers.push_back(ice_server);
275 ice_server.uri = kTurnIceServer;
276 ice_server.username = kTurnUsername;
277 ice_server.password = kTurnPassword;
278 config.servers.push_back(ice_server);
279 ice_server.uri = kTurnIceServerWithTransport;
280 ice_server.username = kTurnUsername;
281 ice_server.password = kTurnPassword;
282 config.servers.push_back(ice_server);
283 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
284 new FakeRTCCertificateGenerator());
285 rtc::scoped_refptr<PeerConnectionInterface> pc(
286 factory_->CreatePeerConnection(config, std::move(port_allocator_),
287 std::move(cert_generator), &observer_));
288 ASSERT_TRUE(pc.get() != NULL);
289 cricket::ServerAddresses stun_servers;
290 rtc::SocketAddress stun1("stun.l.google.com", 19302);
291 stun_servers.insert(stun1);
292 VerifyStunServers(stun_servers);
293 std::vector<cricket::RelayServerConfig> turn_servers;
294 cricket::RelayServerConfig turn1("test.com", 1234, kTurnUsername,
295 kTurnPassword, cricket::PROTO_UDP);
296 turn_servers.push_back(turn1);
297 cricket::RelayServerConfig turn2("hello.com", kDefaultStunPort, kTurnUsername,
298 kTurnPassword, cricket::PROTO_TCP);
299 turn_servers.push_back(turn2);
300 VerifyTurnServers(turn_servers);
301 }
302
303 // This test verifies creation of PeerConnection with valid STUN and TURN
304 // configuration. Also verifies the list of URL's parsed correctly as expected.
TEST_F(PeerConnectionFactoryTest,CreatePCUsingIceServersUrls)305 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServersUrls) {
306 PeerConnectionInterface::RTCConfiguration config;
307 webrtc::PeerConnectionInterface::IceServer ice_server;
308 ice_server.urls.push_back(kStunIceServer);
309 ice_server.urls.push_back(kTurnIceServer);
310 ice_server.urls.push_back(kTurnIceServerWithTransport);
311 ice_server.username = kTurnUsername;
312 ice_server.password = kTurnPassword;
313 config.servers.push_back(ice_server);
314 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
315 new FakeRTCCertificateGenerator());
316 rtc::scoped_refptr<PeerConnectionInterface> pc(
317 factory_->CreatePeerConnection(config, std::move(port_allocator_),
318 std::move(cert_generator), &observer_));
319 ASSERT_TRUE(pc.get() != NULL);
320 cricket::ServerAddresses stun_servers;
321 rtc::SocketAddress stun1("stun.l.google.com", 19302);
322 stun_servers.insert(stun1);
323 VerifyStunServers(stun_servers);
324 std::vector<cricket::RelayServerConfig> turn_servers;
325 cricket::RelayServerConfig turn1("test.com", 1234, kTurnUsername,
326 kTurnPassword, cricket::PROTO_UDP);
327 turn_servers.push_back(turn1);
328 cricket::RelayServerConfig turn2("hello.com", kDefaultStunPort, kTurnUsername,
329 kTurnPassword, cricket::PROTO_TCP);
330 turn_servers.push_back(turn2);
331 VerifyTurnServers(turn_servers);
332 }
333
TEST_F(PeerConnectionFactoryTest,CreatePCUsingNoUsernameInUri)334 TEST_F(PeerConnectionFactoryTest, CreatePCUsingNoUsernameInUri) {
335 PeerConnectionInterface::RTCConfiguration config;
336 webrtc::PeerConnectionInterface::IceServer ice_server;
337 ice_server.uri = kStunIceServer;
338 config.servers.push_back(ice_server);
339 ice_server.uri = kTurnIceServerWithNoUsernameInUri;
340 ice_server.username = kTurnUsername;
341 ice_server.password = kTurnPassword;
342 config.servers.push_back(ice_server);
343 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
344 new FakeRTCCertificateGenerator());
345 rtc::scoped_refptr<PeerConnectionInterface> pc(
346 factory_->CreatePeerConnection(config, std::move(port_allocator_),
347 std::move(cert_generator), &observer_));
348 ASSERT_TRUE(pc.get() != NULL);
349 std::vector<cricket::RelayServerConfig> turn_servers;
350 cricket::RelayServerConfig turn("test.com", 1234, kTurnUsername,
351 kTurnPassword, cricket::PROTO_UDP);
352 turn_servers.push_back(turn);
353 VerifyTurnServers(turn_servers);
354 }
355
356 // This test verifies the PeerConnection created properly with TURN url which
357 // has transport parameter in it.
TEST_F(PeerConnectionFactoryTest,CreatePCUsingTurnUrlWithTransportParam)358 TEST_F(PeerConnectionFactoryTest, CreatePCUsingTurnUrlWithTransportParam) {
359 PeerConnectionInterface::RTCConfiguration config;
360 webrtc::PeerConnectionInterface::IceServer ice_server;
361 ice_server.uri = kTurnIceServerWithTransport;
362 ice_server.username = kTurnUsername;
363 ice_server.password = kTurnPassword;
364 config.servers.push_back(ice_server);
365 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
366 new FakeRTCCertificateGenerator());
367 rtc::scoped_refptr<PeerConnectionInterface> pc(
368 factory_->CreatePeerConnection(config, std::move(port_allocator_),
369 std::move(cert_generator), &observer_));
370 ASSERT_TRUE(pc.get() != NULL);
371 std::vector<cricket::RelayServerConfig> turn_servers;
372 cricket::RelayServerConfig turn("hello.com", kDefaultStunPort, kTurnUsername,
373 kTurnPassword, cricket::PROTO_TCP);
374 turn_servers.push_back(turn);
375 VerifyTurnServers(turn_servers);
376 }
377
TEST_F(PeerConnectionFactoryTest,CreatePCUsingSecureTurnUrl)378 TEST_F(PeerConnectionFactoryTest, CreatePCUsingSecureTurnUrl) {
379 PeerConnectionInterface::RTCConfiguration config;
380 webrtc::PeerConnectionInterface::IceServer ice_server;
381 ice_server.uri = kSecureTurnIceServer;
382 ice_server.username = kTurnUsername;
383 ice_server.password = kTurnPassword;
384 config.servers.push_back(ice_server);
385 ice_server.uri = kSecureTurnIceServerWithoutTransportParam;
386 ice_server.username = kTurnUsername;
387 ice_server.password = kTurnPassword;
388 config.servers.push_back(ice_server);
389 ice_server.uri = kSecureTurnIceServerWithoutTransportAndPortParam;
390 ice_server.username = kTurnUsername;
391 ice_server.password = kTurnPassword;
392 config.servers.push_back(ice_server);
393 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
394 new FakeRTCCertificateGenerator());
395 rtc::scoped_refptr<PeerConnectionInterface> pc(
396 factory_->CreatePeerConnection(config, std::move(port_allocator_),
397 std::move(cert_generator), &observer_));
398 ASSERT_TRUE(pc.get() != NULL);
399 std::vector<cricket::RelayServerConfig> turn_servers;
400 cricket::RelayServerConfig turn1("hello.com", kDefaultStunTlsPort,
401 kTurnUsername, kTurnPassword,
402 cricket::PROTO_TLS);
403 turn_servers.push_back(turn1);
404 // TURNS with transport param should be default to tcp.
405 cricket::RelayServerConfig turn2("hello.com", 443, kTurnUsername,
406 kTurnPassword, cricket::PROTO_TLS);
407 turn_servers.push_back(turn2);
408 cricket::RelayServerConfig turn3("hello.com", kDefaultStunTlsPort,
409 kTurnUsername, kTurnPassword,
410 cricket::PROTO_TLS);
411 turn_servers.push_back(turn3);
412 VerifyTurnServers(turn_servers);
413 }
414
TEST_F(PeerConnectionFactoryTest,CreatePCUsingIPLiteralAddress)415 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIPLiteralAddress) {
416 PeerConnectionInterface::RTCConfiguration config;
417 webrtc::PeerConnectionInterface::IceServer ice_server;
418 ice_server.uri = kStunIceServerWithIPv4Address;
419 config.servers.push_back(ice_server);
420 ice_server.uri = kStunIceServerWithIPv4AddressWithoutPort;
421 config.servers.push_back(ice_server);
422 ice_server.uri = kStunIceServerWithIPv6Address;
423 config.servers.push_back(ice_server);
424 ice_server.uri = kStunIceServerWithIPv6AddressWithoutPort;
425 config.servers.push_back(ice_server);
426 ice_server.uri = kTurnIceServerWithIPv6Address;
427 ice_server.username = kTurnUsername;
428 ice_server.password = kTurnPassword;
429 config.servers.push_back(ice_server);
430 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
431 new FakeRTCCertificateGenerator());
432 rtc::scoped_refptr<PeerConnectionInterface> pc(
433 factory_->CreatePeerConnection(config, std::move(port_allocator_),
434 std::move(cert_generator), &observer_));
435 ASSERT_TRUE(pc.get() != NULL);
436 cricket::ServerAddresses stun_servers;
437 rtc::SocketAddress stun1("1.2.3.4", 1234);
438 stun_servers.insert(stun1);
439 rtc::SocketAddress stun2("1.2.3.4", 3478);
440 stun_servers.insert(stun2); // Default port
441 rtc::SocketAddress stun3("2401:fa00:4::", 1234);
442 stun_servers.insert(stun3);
443 rtc::SocketAddress stun4("2401:fa00:4::", 3478);
444 stun_servers.insert(stun4); // Default port
445 VerifyStunServers(stun_servers);
446
447 std::vector<cricket::RelayServerConfig> turn_servers;
448 cricket::RelayServerConfig turn1("2401:fa00:4::", 1234, kTurnUsername,
449 kTurnPassword, cricket::PROTO_UDP);
450 turn_servers.push_back(turn1);
451 VerifyTurnServers(turn_servers);
452 }
453
454 // This test verifies the captured stream is rendered locally using a
455 // local video track.
TEST_F(PeerConnectionFactoryTest,LocalRendering)456 TEST_F(PeerConnectionFactoryTest, LocalRendering) {
457 rtc::scoped_refptr<webrtc::FakeVideoTrackSource> source =
458 webrtc::FakeVideoTrackSource::Create(/*is_screencast=*/false);
459
460 cricket::FakeFrameSource frame_source(1280, 720,
461 rtc::kNumMicrosecsPerSec / 30);
462
463 ASSERT_TRUE(source.get() != NULL);
464 rtc::scoped_refptr<VideoTrackInterface> track(
465 factory_->CreateVideoTrack("testlabel", source));
466 ASSERT_TRUE(track.get() != NULL);
467 FakeVideoTrackRenderer local_renderer(track);
468
469 EXPECT_EQ(0, local_renderer.num_rendered_frames());
470 source->InjectFrame(frame_source.GetFrame());
471 EXPECT_EQ(1, local_renderer.num_rendered_frames());
472 EXPECT_FALSE(local_renderer.black_frame());
473
474 track->set_enabled(false);
475 source->InjectFrame(frame_source.GetFrame());
476 EXPECT_EQ(2, local_renderer.num_rendered_frames());
477 EXPECT_TRUE(local_renderer.black_frame());
478
479 track->set_enabled(true);
480 source->InjectFrame(frame_source.GetFrame());
481 EXPECT_EQ(3, local_renderer.num_rendered_frames());
482 EXPECT_FALSE(local_renderer.black_frame());
483 }
484