15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/glue/channel_socket_adapter.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/libjingle/source/talk/p2p/base/transportchannel.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::IOBuffer; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace jingle_glue { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBufferSize = 4096; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTestData[] = "data"; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTestDataSize = 4; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTestError = -32123; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockTransportChannel : public cricket::TransportChannel { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockTransportChannel() : cricket::TransportChannel(std::string(), 0) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_writable(true); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_readable(true); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MOCK_METHOD4(SendPacket, int(const char* data, 3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t len, 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const rtc::PacketOptions& options, 4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int flags)); 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOCK_METHOD2(SetOption, int(rtc::Socket::Option opt, int value)); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD0(GetError, int()); 43c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch MOCK_CONST_METHOD0(GetIceRole, cricket::IceRole()); 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) MOCK_METHOD1(GetStats, bool(cricket::ConnectionInfos* infos)); 45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) MOCK_CONST_METHOD0(IsDtlsActive, bool()); 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOCK_CONST_METHOD1(GetSslRole, bool(rtc::SSLRole* role)); 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) MOCK_METHOD1(SetSrtpCiphers, bool(const std::vector<std::string>& ciphers)); 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) MOCK_METHOD1(GetSrtpCipher, bool(std::string* cipher)); 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOCK_CONST_METHOD1(GetLocalIdentity, bool(rtc::SSLIdentity** identity)); 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MOCK_CONST_METHOD1(GetRemoteCertificate, 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool(rtc::SSLCertificate** cert)); 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) MOCK_METHOD6(ExportKeyingMaterial, bool(const std::string& label, 53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const uint8* context, 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t context_len, 55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool use_context, 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) uint8* result, 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t result_len)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TransportChannelSocketAdapterTest : public testing::Test { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransportChannelSocketAdapterTest() 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : callback_(base::Bind(&TransportChannelSocketAdapterTest::Callback, 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_result_(0) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_.reset(new TransportChannelSocketAdapter(&channel_)); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Callback(int result) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_result_ = result; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockTransportChannel channel_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TransportChannelSocketAdapter> target_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback callback_; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int callback_result_; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForIO message_loop_; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that Read() returns net::ERR_IO_PENDING. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportChannelSocketAdapterTest, Read) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = target_->Read(buffer.get(), kBufferSize, callback_); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(net::ERR_IO_PENDING, result); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) channel_.SignalReadPacket(&channel_, kTestData, kTestDataSize, 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rtc::CreatePacketTime(0), 0); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kTestDataSize, callback_result_); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that Read() after Close() returns error. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportChannelSocketAdapterTest, ReadClose) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = target_->Read(buffer.get(), kBufferSize, callback_); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(net::ERR_IO_PENDING, result); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_->Close(kTestError); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kTestError, callback_result_); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All Read() calls after Close() should return the error. 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(kTestError, target_->Read(buffer.get(), kBufferSize, callback_)); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that Write sends the packet and returns correct result. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportChannelSocketAdapterTest, Write) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buffer(new IOBuffer(kTestDataSize)); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(channel_, SendPacket(buffer->data(), kTestDataSize, _, 0)) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(Return(kTestDataSize)); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = target_->Write(buffer.get(), kTestDataSize, callback_); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kTestDataSize, result); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that the message is still sent if Write() is called while 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// socket is not open yet. The result is the packet is lost. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportChannelSocketAdapterTest, WritePending) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IOBuffer> buffer(new IOBuffer(kTestDataSize)); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(channel_, SendPacket(buffer->data(), kTestDataSize, _, 0)) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(1) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(Return(SOCKET_ERROR)); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(channel_, GetError()) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(Return(EWOULDBLOCK)); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = target_->Write(buffer.get(), kTestDataSize, callback_); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(net::OK, result); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace jingle_glue 138