OLD | NEW |
| (Empty) |
1 /* | |
2 * libjingle | |
3 * Copyright 2012 Google Inc. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions are met: | |
7 * | |
8 * 1. Redistributions of source code must retain the above copyright notice, | |
9 * this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
11 * this list of conditions and the following disclaimer in the documentation | |
12 * and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 #include <string> | |
29 #include <utility> | |
30 | |
31 #include "talk/app/webrtc/mediastreaminterface.h" | |
32 #include "talk/app/webrtc/peerconnectionfactory.h" | |
33 #ifdef WEBRTC_ANDROID | |
34 #include "talk/app/webrtc/test/androidtestinitializer.h" | |
35 #endif | |
36 #include "talk/app/webrtc/test/fakedtlsidentitystore.h" | |
37 #include "talk/app/webrtc/test/fakevideotrackrenderer.h" | |
38 #include "talk/app/webrtc/videosourceinterface.h" | |
39 #include "webrtc/base/gunit.h" | |
40 #include "webrtc/base/scoped_ptr.h" | |
41 #include "webrtc/base/thread.h" | |
42 #include "webrtc/media/base/fakevideocapturer.h" | |
43 #include "webrtc/media/webrtc/webrtccommon.h" | |
44 #include "webrtc/media/webrtc/webrtcvoe.h" | |
45 #include "webrtc/p2p/client/fakeportallocator.h" | |
46 | |
47 using webrtc::DataChannelInterface; | |
48 using webrtc::DtlsIdentityStoreInterface; | |
49 using webrtc::FakeVideoTrackRenderer; | |
50 using webrtc::MediaStreamInterface; | |
51 using webrtc::PeerConnectionFactoryInterface; | |
52 using webrtc::PeerConnectionInterface; | |
53 using webrtc::PeerConnectionObserver; | |
54 using webrtc::VideoSourceInterface; | |
55 using webrtc::VideoTrackInterface; | |
56 | |
57 namespace { | |
58 | |
59 static const char kStunIceServer[] = "stun:stun.l.google.com:19302"; | |
60 static const char kTurnIceServer[] = "turn:test%40hello.com@test.com:1234"; | |
61 static const char kTurnIceServerWithTransport[] = | |
62 "turn:test@hello.com?transport=tcp"; | |
63 static const char kSecureTurnIceServer[] = | |
64 "turns:test@hello.com?transport=tcp"; | |
65 static const char kSecureTurnIceServerWithoutTransportParam[] = | |
66 "turns:test_no_transport@hello.com:443"; | |
67 static const char kSecureTurnIceServerWithoutTransportAndPortParam[] = | |
68 "turns:test_no_transport@hello.com"; | |
69 static const char kTurnIceServerWithNoUsernameInUri[] = | |
70 "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[] = | |
81 "turn:test@[2401:fa00:4::]:1234"; | |
82 | |
83 class NullPeerConnectionObserver : public PeerConnectionObserver { | |
84 public: | |
85 virtual void OnMessage(const std::string& msg) {} | |
86 virtual void OnSignalingMessage(const std::string& msg) {} | |
87 virtual void OnSignalingChange( | |
88 PeerConnectionInterface::SignalingState new_state) {} | |
89 virtual void OnAddStream(MediaStreamInterface* stream) {} | |
90 virtual void OnRemoveStream(MediaStreamInterface* stream) {} | |
91 virtual void OnDataChannel(DataChannelInterface* data_channel) {} | |
92 virtual void OnRenegotiationNeeded() {} | |
93 virtual void OnIceConnectionChange( | |
94 PeerConnectionInterface::IceConnectionState new_state) {} | |
95 virtual void OnIceGatheringChange( | |
96 PeerConnectionInterface::IceGatheringState new_state) {} | |
97 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {} | |
98 }; | |
99 | |
100 } // namespace | |
101 | |
102 class PeerConnectionFactoryTest : public testing::Test { | |
103 void SetUp() { | |
104 #ifdef WEBRTC_ANDROID | |
105 webrtc::InitializeAndroidObjects(); | |
106 #endif | |
107 factory_ = webrtc::CreatePeerConnectionFactory(rtc::Thread::Current(), | |
108 rtc::Thread::Current(), | |
109 NULL, | |
110 NULL, | |
111 NULL); | |
112 | |
113 ASSERT_TRUE(factory_.get() != NULL); | |
114 port_allocator_.reset( | |
115 new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr)); | |
116 raw_port_allocator_ = port_allocator_.get(); | |
117 } | |
118 | |
119 protected: | |
120 void VerifyStunServers(cricket::ServerAddresses stun_servers) { | |
121 EXPECT_EQ(stun_servers, raw_port_allocator_->stun_servers()); | |
122 } | |
123 | |
124 void VerifyTurnServers(std::vector<cricket::RelayServerConfig> turn_servers) { | |
125 EXPECT_EQ(turn_servers.size(), raw_port_allocator_->turn_servers().size()); | |
126 for (size_t i = 0; i < turn_servers.size(); ++i) { | |
127 ASSERT_EQ(1u, turn_servers[i].ports.size()); | |
128 EXPECT_EQ(1u, raw_port_allocator_->turn_servers()[i].ports.size()); | |
129 EXPECT_EQ( | |
130 turn_servers[i].ports[0].address.ToString(), | |
131 raw_port_allocator_->turn_servers()[i].ports[0].address.ToString()); | |
132 EXPECT_EQ(turn_servers[i].ports[0].proto, | |
133 raw_port_allocator_->turn_servers()[i].ports[0].proto); | |
134 EXPECT_EQ(turn_servers[i].credentials.username, | |
135 raw_port_allocator_->turn_servers()[i].credentials.username); | |
136 EXPECT_EQ(turn_servers[i].credentials.password, | |
137 raw_port_allocator_->turn_servers()[i].credentials.password); | |
138 } | |
139 } | |
140 | |
141 rtc::scoped_refptr<PeerConnectionFactoryInterface> factory_; | |
142 NullPeerConnectionObserver observer_; | |
143 rtc::scoped_ptr<cricket::FakePortAllocator> port_allocator_; | |
144 // Since the PC owns the port allocator after it's been initialized, | |
145 // this should only be used when known to be safe. | |
146 cricket::FakePortAllocator* raw_port_allocator_; | |
147 }; | |
148 | |
149 // Verify creation of PeerConnection using internal ADM, video factory and | |
150 // internal libjingle threads. | |
151 TEST(PeerConnectionFactoryTestInternal, CreatePCUsingInternalModules) { | |
152 #ifdef WEBRTC_ANDROID | |
153 webrtc::InitializeAndroidObjects(); | |
154 #endif | |
155 | |
156 rtc::scoped_refptr<PeerConnectionFactoryInterface> factory( | |
157 webrtc::CreatePeerConnectionFactory()); | |
158 | |
159 NullPeerConnectionObserver observer; | |
160 webrtc::PeerConnectionInterface::RTCConfiguration config; | |
161 | |
162 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store( | |
163 new FakeDtlsIdentityStore()); | |
164 rtc::scoped_refptr<PeerConnectionInterface> pc(factory->CreatePeerConnection( | |
165 config, nullptr, nullptr, std::move(dtls_identity_store), &observer)); | |
166 | |
167 EXPECT_TRUE(pc.get() != nullptr); | |
168 } | |
169 | |
170 // This test verifies creation of PeerConnection with valid STUN and TURN | |
171 // configuration. Also verifies the URL's parsed correctly as expected. | |
172 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServers) { | |
173 PeerConnectionInterface::RTCConfiguration config; | |
174 webrtc::PeerConnectionInterface::IceServer ice_server; | |
175 ice_server.uri = kStunIceServer; | |
176 config.servers.push_back(ice_server); | |
177 ice_server.uri = kTurnIceServer; | |
178 ice_server.password = kTurnPassword; | |
179 config.servers.push_back(ice_server); | |
180 ice_server.uri = kTurnIceServerWithTransport; | |
181 ice_server.password = kTurnPassword; | |
182 config.servers.push_back(ice_server); | |
183 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
184 new FakeDtlsIdentityStore()); | |
185 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
186 config, nullptr, std::move(port_allocator_), | |
187 std::move(dtls_identity_store), &observer_)); | |
188 ASSERT_TRUE(pc.get() != NULL); | |
189 cricket::ServerAddresses stun_servers; | |
190 rtc::SocketAddress stun1("stun.l.google.com", 19302); | |
191 stun_servers.insert(stun1); | |
192 VerifyStunServers(stun_servers); | |
193 std::vector<cricket::RelayServerConfig> turn_servers; | |
194 cricket::RelayServerConfig turn1("test.com", 1234, "test@hello.com", | |
195 kTurnPassword, cricket::PROTO_UDP, false); | |
196 turn_servers.push_back(turn1); | |
197 cricket::RelayServerConfig turn2("hello.com", kDefaultStunPort, "test", | |
198 kTurnPassword, cricket::PROTO_TCP, false); | |
199 turn_servers.push_back(turn2); | |
200 VerifyTurnServers(turn_servers); | |
201 } | |
202 | |
203 // This test verifies creation of PeerConnection with valid STUN and TURN | |
204 // configuration. Also verifies the list of URL's parsed correctly as expected. | |
205 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServersUrls) { | |
206 PeerConnectionInterface::RTCConfiguration config; | |
207 webrtc::PeerConnectionInterface::IceServer ice_server; | |
208 ice_server.urls.push_back(kStunIceServer); | |
209 ice_server.urls.push_back(kTurnIceServer); | |
210 ice_server.urls.push_back(kTurnIceServerWithTransport); | |
211 ice_server.password = kTurnPassword; | |
212 config.servers.push_back(ice_server); | |
213 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
214 new FakeDtlsIdentityStore()); | |
215 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
216 config, nullptr, std::move(port_allocator_), | |
217 std::move(dtls_identity_store), &observer_)); | |
218 ASSERT_TRUE(pc.get() != NULL); | |
219 cricket::ServerAddresses stun_servers; | |
220 rtc::SocketAddress stun1("stun.l.google.com", 19302); | |
221 stun_servers.insert(stun1); | |
222 VerifyStunServers(stun_servers); | |
223 std::vector<cricket::RelayServerConfig> turn_servers; | |
224 cricket::RelayServerConfig turn1("test.com", 1234, "test@hello.com", | |
225 kTurnPassword, cricket::PROTO_UDP, false); | |
226 turn_servers.push_back(turn1); | |
227 cricket::RelayServerConfig turn2("hello.com", kDefaultStunPort, "test", | |
228 kTurnPassword, cricket::PROTO_TCP, false); | |
229 turn_servers.push_back(turn2); | |
230 VerifyTurnServers(turn_servers); | |
231 } | |
232 | |
233 TEST_F(PeerConnectionFactoryTest, CreatePCUsingNoUsernameInUri) { | |
234 PeerConnectionInterface::RTCConfiguration config; | |
235 webrtc::PeerConnectionInterface::IceServer ice_server; | |
236 ice_server.uri = kStunIceServer; | |
237 config.servers.push_back(ice_server); | |
238 ice_server.uri = kTurnIceServerWithNoUsernameInUri; | |
239 ice_server.username = kTurnUsername; | |
240 ice_server.password = kTurnPassword; | |
241 config.servers.push_back(ice_server); | |
242 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
243 new FakeDtlsIdentityStore()); | |
244 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
245 config, nullptr, std::move(port_allocator_), | |
246 std::move(dtls_identity_store), &observer_)); | |
247 ASSERT_TRUE(pc.get() != NULL); | |
248 std::vector<cricket::RelayServerConfig> turn_servers; | |
249 cricket::RelayServerConfig turn("test.com", 1234, kTurnUsername, | |
250 kTurnPassword, cricket::PROTO_UDP, false); | |
251 turn_servers.push_back(turn); | |
252 VerifyTurnServers(turn_servers); | |
253 } | |
254 | |
255 // This test verifies the PeerConnection created properly with TURN url which | |
256 // has transport parameter in it. | |
257 TEST_F(PeerConnectionFactoryTest, CreatePCUsingTurnUrlWithTransportParam) { | |
258 PeerConnectionInterface::RTCConfiguration config; | |
259 webrtc::PeerConnectionInterface::IceServer ice_server; | |
260 ice_server.uri = kTurnIceServerWithTransport; | |
261 ice_server.password = kTurnPassword; | |
262 config.servers.push_back(ice_server); | |
263 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
264 new FakeDtlsIdentityStore()); | |
265 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
266 config, nullptr, std::move(port_allocator_), | |
267 std::move(dtls_identity_store), &observer_)); | |
268 ASSERT_TRUE(pc.get() != NULL); | |
269 std::vector<cricket::RelayServerConfig> turn_servers; | |
270 cricket::RelayServerConfig turn("hello.com", kDefaultStunPort, "test", | |
271 kTurnPassword, cricket::PROTO_TCP, false); | |
272 turn_servers.push_back(turn); | |
273 VerifyTurnServers(turn_servers); | |
274 } | |
275 | |
276 TEST_F(PeerConnectionFactoryTest, CreatePCUsingSecureTurnUrl) { | |
277 PeerConnectionInterface::RTCConfiguration config; | |
278 webrtc::PeerConnectionInterface::IceServer ice_server; | |
279 ice_server.uri = kSecureTurnIceServer; | |
280 ice_server.password = kTurnPassword; | |
281 config.servers.push_back(ice_server); | |
282 ice_server.uri = kSecureTurnIceServerWithoutTransportParam; | |
283 ice_server.password = kTurnPassword; | |
284 config.servers.push_back(ice_server); | |
285 ice_server.uri = kSecureTurnIceServerWithoutTransportAndPortParam; | |
286 ice_server.password = kTurnPassword; | |
287 config.servers.push_back(ice_server); | |
288 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
289 new FakeDtlsIdentityStore()); | |
290 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
291 config, nullptr, std::move(port_allocator_), | |
292 std::move(dtls_identity_store), &observer_)); | |
293 ASSERT_TRUE(pc.get() != NULL); | |
294 std::vector<cricket::RelayServerConfig> turn_servers; | |
295 cricket::RelayServerConfig turn1("hello.com", kDefaultStunTlsPort, "test", | |
296 kTurnPassword, cricket::PROTO_TCP, true); | |
297 turn_servers.push_back(turn1); | |
298 // TURNS with transport param should be default to tcp. | |
299 cricket::RelayServerConfig turn2("hello.com", 443, "test_no_transport", | |
300 kTurnPassword, cricket::PROTO_TCP, true); | |
301 turn_servers.push_back(turn2); | |
302 cricket::RelayServerConfig turn3("hello.com", kDefaultStunTlsPort, | |
303 "test_no_transport", kTurnPassword, | |
304 cricket::PROTO_TCP, true); | |
305 turn_servers.push_back(turn3); | |
306 VerifyTurnServers(turn_servers); | |
307 } | |
308 | |
309 TEST_F(PeerConnectionFactoryTest, CreatePCUsingIPLiteralAddress) { | |
310 PeerConnectionInterface::RTCConfiguration config; | |
311 webrtc::PeerConnectionInterface::IceServer ice_server; | |
312 ice_server.uri = kStunIceServerWithIPv4Address; | |
313 config.servers.push_back(ice_server); | |
314 ice_server.uri = kStunIceServerWithIPv4AddressWithoutPort; | |
315 config.servers.push_back(ice_server); | |
316 ice_server.uri = kStunIceServerWithIPv6Address; | |
317 config.servers.push_back(ice_server); | |
318 ice_server.uri = kStunIceServerWithIPv6AddressWithoutPort; | |
319 config.servers.push_back(ice_server); | |
320 ice_server.uri = kTurnIceServerWithIPv6Address; | |
321 ice_server.password = kTurnPassword; | |
322 config.servers.push_back(ice_server); | |
323 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store( | |
324 new FakeDtlsIdentityStore()); | |
325 rtc::scoped_refptr<PeerConnectionInterface> pc(factory_->CreatePeerConnection( | |
326 config, nullptr, std::move(port_allocator_), | |
327 std::move(dtls_identity_store), &observer_)); | |
328 ASSERT_TRUE(pc.get() != NULL); | |
329 cricket::ServerAddresses stun_servers; | |
330 rtc::SocketAddress stun1("1.2.3.4", 1234); | |
331 stun_servers.insert(stun1); | |
332 rtc::SocketAddress stun2("1.2.3.4", 3478); | |
333 stun_servers.insert(stun2); // Default port | |
334 rtc::SocketAddress stun3("2401:fa00:4::", 1234); | |
335 stun_servers.insert(stun3); | |
336 rtc::SocketAddress stun4("2401:fa00:4::", 3478); | |
337 stun_servers.insert(stun4); // Default port | |
338 VerifyStunServers(stun_servers); | |
339 | |
340 std::vector<cricket::RelayServerConfig> turn_servers; | |
341 cricket::RelayServerConfig turn1("2401:fa00:4::", 1234, "test", kTurnPassword, | |
342 cricket::PROTO_UDP, false); | |
343 turn_servers.push_back(turn1); | |
344 VerifyTurnServers(turn_servers); | |
345 } | |
346 | |
347 // This test verifies the captured stream is rendered locally using a | |
348 // local video track. | |
349 TEST_F(PeerConnectionFactoryTest, LocalRendering) { | |
350 cricket::FakeVideoCapturer* capturer = new cricket::FakeVideoCapturer(); | |
351 // The source take ownership of |capturer|. | |
352 rtc::scoped_refptr<VideoSourceInterface> source( | |
353 factory_->CreateVideoSource(capturer, NULL)); | |
354 ASSERT_TRUE(source.get() != NULL); | |
355 rtc::scoped_refptr<VideoTrackInterface> track( | |
356 factory_->CreateVideoTrack("testlabel", source)); | |
357 ASSERT_TRUE(track.get() != NULL); | |
358 FakeVideoTrackRenderer local_renderer(track); | |
359 | |
360 EXPECT_EQ(0, local_renderer.num_rendered_frames()); | |
361 EXPECT_TRUE(capturer->CaptureFrame()); | |
362 EXPECT_EQ(1, local_renderer.num_rendered_frames()); | |
363 EXPECT_FALSE(local_renderer.black_frame()); | |
364 | |
365 track->set_enabled(false); | |
366 EXPECT_TRUE(capturer->CaptureFrame()); | |
367 EXPECT_EQ(2, local_renderer.num_rendered_frames()); | |
368 EXPECT_TRUE(local_renderer.black_frame()); | |
369 | |
370 track->set_enabled(true); | |
371 EXPECT_TRUE(capturer->CaptureFrame()); | |
372 EXPECT_EQ(3, local_renderer.num_rendered_frames()); | |
373 EXPECT_FALSE(local_renderer.black_frame()); | |
374 } | |
OLD | NEW |