/* * Copyright 2018 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 "api/test/loopback_media_transport.h" #include #include #include #include "test/gmock.h" namespace webrtc { namespace { class MockMediaTransportAudioSinkInterface : public MediaTransportAudioSinkInterface { public: MOCK_METHOD2(OnData, void(uint64_t, MediaTransportEncodedAudioFrame)); }; class MockMediaTransportVideoSinkInterface : public MediaTransportVideoSinkInterface { public: MOCK_METHOD2(OnData, void(uint64_t, MediaTransportEncodedVideoFrame)); }; class MockMediaTransportKeyFrameRequestCallback : public MediaTransportKeyFrameRequestCallback { public: MOCK_METHOD1(OnKeyFrameRequested, void(uint64_t)); }; class MockDataChannelSink : public DataChannelSink { public: MOCK_METHOD3(OnDataReceived, void(int, DataMessageType, const rtc::CopyOnWriteBuffer&)); MOCK_METHOD1(OnChannelClosing, void(int)); MOCK_METHOD1(OnChannelClosed, void(int)); MOCK_METHOD0(OnReadyToSend, void()); }; class MockStateCallback : public MediaTransportStateCallback { public: MOCK_METHOD1(OnStateChanged, void(MediaTransportState)); }; } // namespace TEST(LoopbackMediaTransport, DataDeliveredToSink) { std::unique_ptr thread = rtc::Thread::Create(); thread->Start(); MediaTransportPair transport_pair(thread.get()); MockDataChannelSink sink; transport_pair.first_datagram_transport()->SetDataSink(&sink); const int channel_id = 1; EXPECT_CALL( sink, OnDataReceived( channel_id, DataMessageType::kText, ::testing::Property( &rtc::CopyOnWriteBuffer::cdata, ::testing::StrEq("foo")))); SendDataParams params; params.type = DataMessageType::kText; rtc::CopyOnWriteBuffer buffer("foo"); transport_pair.second_datagram_transport()->SendData(channel_id, params, buffer); transport_pair.FlushAsyncInvokes(); transport_pair.first_datagram_transport()->SetDataSink(nullptr); } TEST(LoopbackMediaTransport, CloseDeliveredToSink) { std::unique_ptr thread = rtc::Thread::Create(); thread->Start(); MediaTransportPair transport_pair(thread.get()); MockDataChannelSink first_sink; transport_pair.first_datagram_transport()->SetDataSink(&first_sink); MockDataChannelSink second_sink; transport_pair.second_datagram_transport()->SetDataSink(&second_sink); const int channel_id = 1; { ::testing::InSequence s; EXPECT_CALL(second_sink, OnChannelClosing(channel_id)); EXPECT_CALL(second_sink, OnChannelClosed(channel_id)); EXPECT_CALL(first_sink, OnChannelClosed(channel_id)); } transport_pair.first_datagram_transport()->CloseChannel(channel_id); transport_pair.FlushAsyncInvokes(); transport_pair.first_datagram_transport()->SetDataSink(nullptr); transport_pair.second_datagram_transport()->SetDataSink(nullptr); } TEST(LoopbackMediaTransport, InitialStateDeliveredWhenCallbackSet) { std::unique_ptr thread = rtc::Thread::Create(); thread->Start(); MediaTransportPair transport_pair(thread.get()); MockStateCallback state_callback; EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kPending)); thread->Invoke(RTC_FROM_HERE, [&transport_pair, &state_callback] { transport_pair.first_datagram_transport()->SetTransportStateCallback( &state_callback); }); transport_pair.FlushAsyncInvokes(); } TEST(LoopbackMediaTransport, ChangedStateDeliveredWhenCallbackSet) { std::unique_ptr thread = rtc::Thread::Create(); thread->Start(); MediaTransportPair transport_pair(thread.get()); transport_pair.SetState(MediaTransportState::kWritable); transport_pair.FlushAsyncInvokes(); MockStateCallback state_callback; EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kWritable)); thread->Invoke(RTC_FROM_HERE, [&transport_pair, &state_callback] { transport_pair.first_datagram_transport()->SetTransportStateCallback( &state_callback); }); transport_pair.FlushAsyncInvokes(); } TEST(LoopbackMediaTransport, StateChangeDeliveredToCallback) { std::unique_ptr thread = rtc::Thread::Create(); thread->Start(); MediaTransportPair transport_pair(thread.get()); MockStateCallback state_callback; EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kPending)); EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kWritable)); thread->Invoke(RTC_FROM_HERE, [&transport_pair, &state_callback] { transport_pair.first_datagram_transport()->SetTransportStateCallback( &state_callback); }); transport_pair.SetState(MediaTransportState::kWritable); transport_pair.FlushAsyncInvokes(); } TEST(LoopbackMediaTransport, NotReadyToSendWhenDataSinkSet) { std::unique_ptr thread = rtc::Thread::Create(); thread->Start(); MediaTransportPair transport_pair(thread.get()); MockDataChannelSink data_channel_sink; EXPECT_CALL(data_channel_sink, OnReadyToSend()).Times(0); transport_pair.first_datagram_transport()->SetDataSink(&data_channel_sink); transport_pair.FlushAsyncInvokes(); transport_pair.first_datagram_transport()->SetDataSink(nullptr); } TEST(LoopbackMediaTransport, ReadyToSendWhenDataSinkSet) { std::unique_ptr thread = rtc::Thread::Create(); thread->Start(); MediaTransportPair transport_pair(thread.get()); transport_pair.SetState(MediaTransportState::kWritable); transport_pair.FlushAsyncInvokes(); MockDataChannelSink data_channel_sink; EXPECT_CALL(data_channel_sink, OnReadyToSend()); transport_pair.first_datagram_transport()->SetDataSink(&data_channel_sink); transport_pair.FlushAsyncInvokes(); transport_pair.first_datagram_transport()->SetDataSink(nullptr); } TEST(LoopbackMediaTransport, StateChangeDeliveredToDataSink) { std::unique_ptr thread = rtc::Thread::Create(); thread->Start(); MediaTransportPair transport_pair(thread.get()); MockDataChannelSink data_channel_sink; EXPECT_CALL(data_channel_sink, OnReadyToSend()); transport_pair.first_datagram_transport()->SetDataSink(&data_channel_sink); transport_pair.SetState(MediaTransportState::kWritable); transport_pair.FlushAsyncInvokes(); transport_pair.first_datagram_transport()->SetDataSink(nullptr); } } // namespace webrtc