| /* |
| * Copyright 2017 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include <memory> |
| |
| #include "api/audio_codecs/builtin_audio_decoder_factory.h" |
| #include "api/audio_codecs/builtin_audio_encoder_factory.h" |
| #include "media/base/fakemediaengine.h" |
| #include "ortc/ortcfactory.h" |
| #include "ortc/testrtpparameters.h" |
| #include "p2p/base/fakepackettransport.h" |
| #include "rtc_base/fakenetwork.h" |
| #include "rtc_base/gunit.h" |
| #include "rtc_base/virtualsocketserver.h" |
| |
| namespace webrtc { |
| |
| // This test uses a virtual network and fake media engine, in order to test the |
| // OrtcFactory at only an API level. Any end-to-end test should go in |
| // ortcfactory_integrationtest.cc instead. |
| class OrtcFactoryTest : public testing::Test { |
| public: |
| OrtcFactoryTest() |
| : thread_(&virtual_socket_server_), |
| fake_packet_transport_("fake transport") { |
| ortc_factory_ = |
| OrtcFactory::Create(&thread_, nullptr, &fake_network_manager_, nullptr, |
| nullptr, |
| std::unique_ptr<cricket::MediaEngineInterface>( |
| new cricket::FakeMediaEngine()), |
| CreateBuiltinAudioEncoderFactory(), |
| CreateBuiltinAudioDecoderFactory()) |
| .MoveValue(); |
| } |
| |
| protected: |
| // Uses a single pre-made FakePacketTransport, so shouldn't be called twice in |
| // the same test. |
| std::unique_ptr<RtpTransportInterface> |
| CreateRtpTransportWithFakePacketTransport() { |
| return ortc_factory_ |
| ->CreateRtpTransport(MakeRtcpMuxParameters(), &fake_packet_transport_, |
| nullptr, nullptr) |
| .MoveValue(); |
| } |
| |
| rtc::VirtualSocketServer virtual_socket_server_; |
| rtc::AutoSocketServerThread thread_; |
| rtc::FakeNetworkManager fake_network_manager_; |
| rtc::FakePacketTransport fake_packet_transport_; |
| std::unique_ptr<OrtcFactoryInterface> ortc_factory_; |
| }; |
| |
| TEST_F(OrtcFactoryTest, CanCreateMultipleRtpTransportControllers) { |
| auto controller_result1 = ortc_factory_->CreateRtpTransportController(); |
| EXPECT_TRUE(controller_result1.ok()); |
| auto controller_result2 = ortc_factory_->CreateRtpTransportController(); |
| EXPECT_TRUE(controller_result1.ok()); |
| } |
| |
| // Simple test for the successful cases of CreateRtpTransport. |
| TEST_F(OrtcFactoryTest, CreateRtpTransportWithAndWithoutMux) { |
| rtc::FakePacketTransport rtp("rtp"); |
| rtc::FakePacketTransport rtcp("rtcp"); |
| // With muxed RTCP. |
| RtpTransportParameters parameters = MakeRtcpMuxParameters(); |
| auto result = |
| ortc_factory_->CreateRtpTransport(parameters, &rtp, nullptr, nullptr); |
| EXPECT_TRUE(result.ok()); |
| result.MoveValue().reset(); |
| // With non-muxed RTCP. |
| parameters.rtcp.mux = false; |
| result = ortc_factory_->CreateRtpTransport(parameters, &rtp, &rtcp, nullptr); |
| EXPECT_TRUE(result.ok()); |
| } |
| |
| // Simple test for the successful cases of CreateSrtpTransport. |
| TEST_F(OrtcFactoryTest, CreateSrtpTransport) { |
| rtc::FakePacketTransport rtp("rtp"); |
| rtc::FakePacketTransport rtcp("rtcp"); |
| // With muxed RTCP. |
| RtpTransportParameters parameters = MakeRtcpMuxParameters(); |
| auto result = |
| ortc_factory_->CreateSrtpTransport(parameters, &rtp, nullptr, nullptr); |
| EXPECT_TRUE(result.ok()); |
| result.MoveValue().reset(); |
| // With non-muxed RTCP. |
| parameters.rtcp.mux = false; |
| result = ortc_factory_->CreateSrtpTransport(parameters, &rtp, &rtcp, nullptr); |
| EXPECT_TRUE(result.ok()); |
| } |
| |
| // If no CNAME is provided, one should be generated and returned by |
| // GetRtpParameters. |
| TEST_F(OrtcFactoryTest, CreateRtpTransportGeneratesCname) { |
| rtc::FakePacketTransport rtp("rtp"); |
| auto result = ortc_factory_->CreateRtpTransport(MakeRtcpMuxParameters(), &rtp, |
| nullptr, nullptr); |
| ASSERT_TRUE(result.ok()); |
| EXPECT_FALSE(result.value()->GetParameters().rtcp.cname.empty()); |
| } |
| |
| // Extension of the above test; multiple transports created by the same factory |
| // should use the same generated CNAME. |
| TEST_F(OrtcFactoryTest, MultipleRtpTransportsUseSameGeneratedCname) { |
| rtc::FakePacketTransport packet_transport1("1"); |
| rtc::FakePacketTransport packet_transport2("2"); |
| RtpTransportParameters parameters = MakeRtcpMuxParameters(); |
| // Sanity check. |
| ASSERT_TRUE(parameters.rtcp.cname.empty()); |
| auto result = ortc_factory_->CreateRtpTransport( |
| parameters, &packet_transport1, nullptr, nullptr); |
| ASSERT_TRUE(result.ok()); |
| auto rtp_transport1 = result.MoveValue(); |
| result = ortc_factory_->CreateRtpTransport(parameters, &packet_transport2, |
| nullptr, nullptr); |
| ASSERT_TRUE(result.ok()); |
| auto rtp_transport2 = result.MoveValue(); |
| RtcpParameters params1 = rtp_transport1->GetParameters().rtcp; |
| RtcpParameters params2 = rtp_transport2->GetParameters().rtcp; |
| EXPECT_FALSE(params1.cname.empty()); |
| EXPECT_EQ(params1.cname, params2.cname); |
| } |
| |
| TEST_F(OrtcFactoryTest, CreateRtpTransportWithNoPacketTransport) { |
| auto result = ortc_factory_->CreateRtpTransport(MakeRtcpMuxParameters(), |
| nullptr, nullptr, nullptr); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| } |
| |
| // If the |mux| member of the RtcpParameters is false, both an RTP and RTCP |
| // packet transport are needed. |
| TEST_F(OrtcFactoryTest, CreateRtpTransportWithMissingRtcpTransport) { |
| rtc::FakePacketTransport rtp("rtp"); |
| RtpTransportParameters parameters; |
| parameters.rtcp.mux = false; |
| auto result = |
| ortc_factory_->CreateRtpTransport(parameters, &rtp, nullptr, nullptr); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| } |
| |
| // If the |mux| member of the RtcpParameters is true, only an RTP packet |
| // transport is necessary. So, passing in an RTCP transport is most likely |
| // an accident, and thus should be treated as an error. |
| TEST_F(OrtcFactoryTest, CreateRtpTransportWithExtraneousRtcpTransport) { |
| rtc::FakePacketTransport rtp("rtp"); |
| rtc::FakePacketTransport rtcp("rtcp"); |
| auto result = ortc_factory_->CreateRtpTransport(MakeRtcpMuxParameters(), &rtp, |
| &rtcp, nullptr); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| } |
| |
| // Basic test that CreateUdpTransport works with AF_INET and AF_INET6. |
| TEST_F(OrtcFactoryTest, CreateUdpTransport) { |
| auto result = ortc_factory_->CreateUdpTransport(AF_INET); |
| EXPECT_TRUE(result.ok()); |
| result = ortc_factory_->CreateUdpTransport(AF_INET6); |
| EXPECT_TRUE(result.ok()); |
| } |
| |
| // Test CreateUdpPort with the |min_port| and |max_port| arguments. |
| TEST_F(OrtcFactoryTest, CreateUdpTransportWithPortRange) { |
| auto socket_result1 = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| ASSERT_TRUE(socket_result1.ok()); |
| EXPECT_EQ(2000, socket_result1.value()->GetLocalAddress().port()); |
| auto socket_result2 = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| ASSERT_TRUE(socket_result2.ok()); |
| EXPECT_EQ(2001, socket_result2.value()->GetLocalAddress().port()); |
| auto socket_result3 = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| ASSERT_TRUE(socket_result3.ok()); |
| EXPECT_EQ(2002, socket_result3.value()->GetLocalAddress().port()); |
| |
| // All sockets in the range have been exhausted, so the next call should |
| // fail. |
| auto failed_result = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| EXPECT_EQ(RTCErrorType::RESOURCE_EXHAUSTED, failed_result.error().type()); |
| |
| // If one socket is destroyed, that port should be freed up again. |
| socket_result2.MoveValue().reset(); |
| auto socket_result4 = ortc_factory_->CreateUdpTransport(AF_INET, 2000, 2002); |
| ASSERT_TRUE(socket_result4.ok()); |
| EXPECT_EQ(2001, socket_result4.value()->GetLocalAddress().port()); |
| } |
| |
| // Basic test that CreateUdpTransport works with AF_INET and AF_INET6. |
| TEST_F(OrtcFactoryTest, CreateUdpTransportWithInvalidAddressFamily) { |
| auto result = ortc_factory_->CreateUdpTransport(12345); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| } |
| |
| TEST_F(OrtcFactoryTest, CreateUdpTransportWithInvalidPortRange) { |
| auto result = ortc_factory_->CreateUdpTransport(AF_INET, 3000, 2000); |
| EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type()); |
| } |
| |
| // Just sanity check that each "GetCapabilities" method returns some codecs. |
| TEST_F(OrtcFactoryTest, GetSenderAndReceiverCapabilities) { |
| RtpCapabilities audio_send_caps = |
| ortc_factory_->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO); |
| EXPECT_GT(audio_send_caps.codecs.size(), 0u); |
| RtpCapabilities video_send_caps = |
| ortc_factory_->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO); |
| EXPECT_GT(video_send_caps.codecs.size(), 0u); |
| RtpCapabilities audio_receive_caps = |
| ortc_factory_->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_AUDIO); |
| EXPECT_GT(audio_receive_caps.codecs.size(), 0u); |
| RtpCapabilities video_receive_caps = |
| ortc_factory_->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO); |
| EXPECT_GT(video_receive_caps.codecs.size(), 0u); |
| } |
| |
| // Calling CreateRtpSender with a null track should fail, since that makes it |
| // impossible to know whether to create an audio or video sender. The |
| // application should be using the method that takes a cricket::MediaType |
| // instead. |
| TEST_F(OrtcFactoryTest, CreateSenderWithNullTrack) { |
| auto rtp_transport = CreateRtpTransportWithFakePacketTransport(); |
| auto result = ortc_factory_->CreateRtpSender(nullptr, rtp_transport.get()); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); |
| } |
| |
| // Calling CreateRtpSender or CreateRtpReceiver with MEDIA_TYPE_DATA should |
| // fail. |
| TEST_F(OrtcFactoryTest, CreateSenderOrReceieverWithInvalidKind) { |
| auto rtp_transport = CreateRtpTransportWithFakePacketTransport(); |
| auto sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_DATA, |
| rtp_transport.get()); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, sender_result.error().type()); |
| auto receiver_result = ortc_factory_->CreateRtpReceiver( |
| cricket::MEDIA_TYPE_DATA, rtp_transport.get()); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, receiver_result.error().type()); |
| } |
| |
| TEST_F(OrtcFactoryTest, CreateSendersOrReceieversWithNullTransport) { |
| auto sender_result = |
| ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_AUDIO, nullptr); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, sender_result.error().type()); |
| auto receiver_result = |
| ortc_factory_->CreateRtpReceiver(cricket::MEDIA_TYPE_AUDIO, nullptr); |
| EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, receiver_result.error().type()); |
| } |
| |
| } // namespace webrtc |