deadbeef | e814a0d | 2017-02-25 18:15:09 -0800 | [diff] [blame] | 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 "webrtc/base/fakenetwork.h" |
| 14 | #include "webrtc/base/gunit.h" |
| 15 | #include "webrtc/base/physicalsocketserver.h" |
| 16 | #include "webrtc/base/virtualsocketserver.h" |
| 17 | #include "webrtc/media/base/fakemediaengine.h" |
| 18 | #include "webrtc/ortc/ortcfactory.h" |
| 19 | #include "webrtc/ortc/testrtpparameters.h" |
| 20 | #include "webrtc/p2p/base/fakepackettransport.h" |
| 21 | |
| 22 | namespace webrtc { |
| 23 | |
| 24 | // This test uses a virtual network and fake media engine, in order to test the |
| 25 | // OrtcFactory at only an API level. Any end-to-end test should go in |
| 26 | // ortcfactory_integrationtest.cc instead. |
| 27 | class OrtcFactoryTest : public testing::Test { |
| 28 | public: |
| 29 | OrtcFactoryTest() |
| 30 | : virtual_socket_server_(&physical_socket_server_), |
| 31 | socket_server_scope_(&virtual_socket_server_), |
| 32 | fake_packet_transport_("fake transport") { |
| 33 | ortc_factory_ = |
| 34 | OrtcFactory::Create(nullptr, nullptr, &fake_network_manager_, nullptr, |
| 35 | nullptr, |
| 36 | std::unique_ptr<cricket::MediaEngineInterface>( |
| 37 | new cricket::FakeMediaEngine())) |
| 38 | .MoveValue(); |
| 39 | } |
| 40 | |
| 41 | protected: |
| 42 | // Uses a single pre-made FakePacketTransport, so shouldn't be called twice in |
| 43 | // the same test. |
| 44 | std::unique_ptr<RtpTransportInterface> |
| 45 | CreateRtpTransportWithFakePacketTransport() { |
| 46 | return ortc_factory_ |
| 47 | ->CreateRtpTransport(MakeRtcpMuxParameters(), &fake_packet_transport_, |
| 48 | nullptr, nullptr) |
| 49 | .MoveValue(); |
| 50 | } |
| 51 | |
| 52 | rtc::PhysicalSocketServer physical_socket_server_; |
| 53 | rtc::VirtualSocketServer virtual_socket_server_; |
| 54 | rtc::SocketServerScope socket_server_scope_; |
| 55 | rtc::FakeNetworkManager fake_network_manager_; |
| 56 | rtc::FakePacketTransport fake_packet_transport_; |
| 57 | std::unique_ptr<OrtcFactoryInterface> ortc_factory_; |
| 58 | }; |
| 59 | |
| 60 | TEST_F(OrtcFactoryTest, CanCreateMultipleRtpTransportControllers) { |
| 61 | auto controller_result1 = ortc_factory_->CreateRtpTransportController(); |
| 62 | EXPECT_TRUE(controller_result1.ok()); |
| 63 | auto controller_result2 = ortc_factory_->CreateRtpTransportController(); |
| 64 | EXPECT_TRUE(controller_result1.ok()); |
| 65 | } |
| 66 | |
| 67 | // Simple test for the successful cases of CreateRtpTransport. |
| 68 | TEST_F(OrtcFactoryTest, CreateRtpTransportWithAndWithoutMux) { |
| 69 | rtc::FakePacketTransport rtp("rtp"); |
| 70 | rtc::FakePacketTransport rtcp("rtcp"); |
| 71 | // With muxed RTCP. |
| 72 | RtcpParameters rtcp_parameters; |
| 73 | rtcp_parameters.mux = true; |
| 74 | auto result = ortc_factory_->CreateRtpTransport(rtcp_parameters, &rtp, |
| 75 | nullptr, nullptr); |
| 76 | EXPECT_TRUE(result.ok()); |
| 77 | result.MoveValue().reset(); |
| 78 | // With non-muxed RTCP. |
| 79 | rtcp_parameters.mux = false; |
| 80 | result = |
| 81 | ortc_factory_->CreateRtpTransport(rtcp_parameters, &rtp, &rtcp, nullptr); |
| 82 | EXPECT_TRUE(result.ok()); |
| 83 | } |
| 84 | |
zhihuang | d3501ad | 2017-03-03 14:39:06 -0800 | [diff] [blame^] | 85 | // Simple test for the successful cases of CreateSrtpTransport. |
| 86 | TEST_F(OrtcFactoryTest, CreateSrtpTransport) { |
| 87 | rtc::FakePacketTransport rtp("rtp"); |
| 88 | rtc::FakePacketTransport rtcp("rtcp"); |
| 89 | // With muxed RTCP. |
| 90 | RtcpParameters rtcp_parameters; |
| 91 | rtcp_parameters.mux = true; |
| 92 | auto result = ortc_factory_->CreateSrtpTransport(rtcp_parameters, &rtp, |
| 93 | nullptr, nullptr); |
| 94 | EXPECT_TRUE(result.ok()); |
| 95 | result.MoveValue().reset(); |
| 96 | // With non-muxed RTCP. |
| 97 | rtcp_parameters.mux = false; |
| 98 | result = |
| 99 | ortc_factory_->CreateSrtpTransport(rtcp_parameters, &rtp, &rtcp, nullptr); |
| 100 | EXPECT_TRUE(result.ok()); |
| 101 | } |
| 102 | |
deadbeef | e814a0d | 2017-02-25 18:15:09 -0800 | [diff] [blame] | 103 | // If no CNAME is provided, one should be generated and returned by |
| 104 | // GetRtpParameters. |
| 105 | TEST_F(OrtcFactoryTest, CreateRtpTransportGeneratesCname) { |
| 106 | rtc::FakePacketTransport rtp("rtp"); |
| 107 | RtcpParameters rtcp_parameters; |
| 108 | rtcp_parameters.mux = true; |
| 109 | auto result = ortc_factory_->CreateRtpTransport(rtcp_parameters, &rtp, |
| 110 | nullptr, nullptr); |
| 111 | ASSERT_TRUE(result.ok()); |
| 112 | EXPECT_FALSE(result.value()->GetRtcpParameters().cname.empty()); |
| 113 | } |
| 114 | |
| 115 | // Extension of the above test; multiple transports created by the same factory |
| 116 | // should use the same generated CNAME. |
| 117 | TEST_F(OrtcFactoryTest, MultipleRtpTransportsUseSameGeneratedCname) { |
| 118 | rtc::FakePacketTransport packet_transport1("1"); |
| 119 | rtc::FakePacketTransport packet_transport2("2"); |
| 120 | RtcpParameters rtcp_parameters; |
| 121 | rtcp_parameters.mux = true; |
| 122 | // Sanity check. |
| 123 | ASSERT_TRUE(rtcp_parameters.cname.empty()); |
| 124 | auto result = ortc_factory_->CreateRtpTransport( |
| 125 | rtcp_parameters, &packet_transport1, nullptr, nullptr); |
| 126 | ASSERT_TRUE(result.ok()); |
| 127 | auto rtp_transport1 = result.MoveValue(); |
| 128 | result = ortc_factory_->CreateRtpTransport( |
| 129 | rtcp_parameters, &packet_transport2, nullptr, nullptr); |
| 130 | ASSERT_TRUE(result.ok()); |
| 131 | auto rtp_transport2 = result.MoveValue(); |
| 132 | RtcpParameters params1 = rtp_transport1->GetRtcpParameters(); |
| 133 | RtcpParameters params2 = rtp_transport2->GetRtcpParameters(); |
| 134 | EXPECT_FALSE(params1.cname.empty()); |
| 135 | EXPECT_EQ(params1.cname, params2.cname); |
| 136 | } |
| 137 | |
| 138 | TEST_F(OrtcFactoryTest, CreateRtpTransportWithNoPacketTransport) { |
| 139 | auto result = ortc_factory_->CreateRtpTransport(MakeRtcpMuxParameters(), |
| 140 | nullptr, nullptr, nullptr); |
| 141 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| 142 | } |
| 143 | |
| 144 | // If the |mux| member of the RtcpParameters is false, both an RTP and RTCP |
| 145 | // packet transport are needed. |
| 146 | TEST_F(OrtcFactoryTest, CreateRtpTransportWithMissingRtcpTransport) { |
| 147 | rtc::FakePacketTransport rtp("rtp"); |
| 148 | RtcpParameters rtcp_parameters; |
| 149 | rtcp_parameters.mux = false; |
| 150 | auto result = ortc_factory_->CreateRtpTransport(rtcp_parameters, &rtp, |
| 151 | nullptr, nullptr); |
| 152 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| 153 | } |
| 154 | |
| 155 | // If the |mux| member of the RtcpParameters is true, only an RTP packet |
| 156 | // transport is necessary. So, passing in an RTCP transport is most likely |
| 157 | // an accident, and thus should be treated as an error. |
| 158 | TEST_F(OrtcFactoryTest, CreateRtpTransportWithExtraneousRtcpTransport) { |
| 159 | rtc::FakePacketTransport rtp("rtp"); |
| 160 | rtc::FakePacketTransport rtcp("rtcp"); |
| 161 | RtcpParameters rtcp_parameters; |
| 162 | rtcp_parameters.mux = true; |
| 163 | auto result = |
| 164 | ortc_factory_->CreateRtpTransport(rtcp_parameters, &rtp, &rtcp, nullptr); |
| 165 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| 166 | } |
| 167 | |
| 168 | // Basic test that CreateUdpTransport works with AF_INET and AF_INET6. |
| 169 | TEST_F(OrtcFactoryTest, CreateUdpTransport) { |
| 170 | auto result = ortc_factory_->CreateUdpTransport(AF_INET); |
| 171 | EXPECT_TRUE(result.ok()); |
| 172 | result = ortc_factory_->CreateUdpTransport(AF_INET6); |
| 173 | EXPECT_TRUE(result.ok()); |
| 174 | } |
| 175 | |
| 176 | // Test CreateUdpPort with the |min_port| and |max_port| arguments. |
| 177 | TEST_F(OrtcFactoryTest, CreateUdpTransportWithPortRange) { |
| 178 | auto socket_result1 = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| 179 | ASSERT_TRUE(socket_result1.ok()); |
| 180 | EXPECT_EQ(2000, socket_result1.value()->GetLocalAddress().port()); |
| 181 | auto socket_result2 = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| 182 | ASSERT_TRUE(socket_result2.ok()); |
| 183 | EXPECT_EQ(2001, socket_result2.value()->GetLocalAddress().port()); |
| 184 | auto socket_result3 = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| 185 | ASSERT_TRUE(socket_result3.ok()); |
| 186 | EXPECT_EQ(2002, socket_result3.value()->GetLocalAddress().port()); |
| 187 | |
| 188 | // All sockets in the range have been exhausted, so the next call should |
| 189 | // fail. |
| 190 | auto failed_result = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| 191 | EXPECT_EQ(RTCErrorType::RESOURCE_EXHAUSTED, failed_result.error().type()); |
| 192 | |
| 193 | // If one socket is destroyed, that port should be freed up again. |
| 194 | socket_result2.MoveValue().reset(); |
| 195 | auto socket_result4 = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| 196 | ASSERT_TRUE(socket_result4.ok()); |
| 197 | EXPECT_EQ(2001, socket_result4.value()->GetLocalAddress().port()); |
| 198 | } |
| 199 | |
| 200 | // Basic test that CreateUdpTransport works with AF_INET and AF_INET6. |
| 201 | TEST_F(OrtcFactoryTest, CreateUdpTransportWithInvalidAddressFamily) { |
| 202 | auto result = ortc_factory_->CreateUdpTransport(12345); |
| 203 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| 204 | } |
| 205 | |
| 206 | TEST_F(OrtcFactoryTest, CreateUdpTransportWithInvalidPortRange) { |
| 207 | auto result = ortc_factory_->CreateUdpTransport(AF_INET, 3000, 2000); |
| 208 | EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type()); |
| 209 | } |
| 210 | |
| 211 | // Just sanity check that each "GetCapabilities" method returns some codecs. |
| 212 | TEST_F(OrtcFactoryTest, GetSenderAndReceiverCapabilities) { |
| 213 | RtpCapabilities audio_send_caps = |
| 214 | ortc_factory_->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO); |
| 215 | EXPECT_GT(audio_send_caps.codecs.size(), 0u); |
| 216 | RtpCapabilities video_send_caps = |
| 217 | ortc_factory_->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO); |
| 218 | EXPECT_GT(video_send_caps.codecs.size(), 0u); |
| 219 | RtpCapabilities audio_receive_caps = |
| 220 | ortc_factory_->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_AUDIO); |
| 221 | EXPECT_GT(audio_receive_caps.codecs.size(), 0u); |
| 222 | RtpCapabilities video_receive_caps = |
| 223 | ortc_factory_->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO); |
| 224 | EXPECT_GT(video_receive_caps.codecs.size(), 0u); |
| 225 | } |
| 226 | |
| 227 | // Calling CreateRtpSender with a null track should fail, since that makes it |
| 228 | // impossible to know whether to create an audio or video sender. The |
| 229 | // application should be using the method that takes a cricket::MediaType |
| 230 | // instead. |
| 231 | TEST_F(OrtcFactoryTest, CreateSenderWithNullTrack) { |
| 232 | auto rtp_transport = CreateRtpTransportWithFakePacketTransport(); |
| 233 | auto result = ortc_factory_->CreateRtpSender(nullptr, rtp_transport.get()); |
| 234 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| 235 | } |
| 236 | |
| 237 | // Calling CreateRtpSender or CreateRtpReceiver with MEDIA_TYPE_DATA should |
| 238 | // fail. |
| 239 | TEST_F(OrtcFactoryTest, CreateSenderOrReceieverWithInvalidKind) { |
| 240 | auto rtp_transport = CreateRtpTransportWithFakePacketTransport(); |
| 241 | auto sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_DATA, |
| 242 | rtp_transport.get()); |
| 243 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, sender_result.error().type()); |
| 244 | auto receiver_result = ortc_factory_->CreateRtpReceiver( |
| 245 | cricket::MEDIA_TYPE_DATA, rtp_transport.get()); |
| 246 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, receiver_result.error().type()); |
| 247 | } |
| 248 | |
| 249 | TEST_F(OrtcFactoryTest, CreateSendersOrReceieversWithNullTransport) { |
| 250 | auto sender_result = |
| 251 | ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_AUDIO, nullptr); |
| 252 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, sender_result.error().type()); |
| 253 | auto receiver_result = |
| 254 | ortc_factory_->CreateRtpReceiver(cricket::MEDIA_TYPE_AUDIO, nullptr); |
| 255 | EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, receiver_result.error().type()); |
| 256 | } |
| 257 | |
| 258 | } // namespace webrtc |