1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/memory/ref_counted.h" 6 #include "base/memory/scoped_ptr.h" 7 #include "base/message_loop/message_loop.h" 8 #include "jingle/glue/channel_socket_adapter.h" 9 #include "net/base/io_buffer.h" 10 #include "net/base/net_errors.h" 11 #include "net/socket/socket.h" 12 #include "testing/gmock/include/gmock/gmock.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "third_party/libjingle/source/talk/p2p/base/transportchannel.h" 15 16 using net::IOBuffer; 17 18 using testing::_; 19 using testing::Return; 20 21 namespace jingle_glue { 22 23 namespace { 24 const int kBufferSize = 4096; 25 const char kTestData[] = "data"; 26 const int kTestDataSize = 4; 27 const int kTestError = -32123; 28 } // namespace 29 30 class MockTransportChannel : public cricket::TransportChannel { 31 public: 32 MockTransportChannel() : cricket::TransportChannel(std::string(), 0) { 33 set_writable(true); 34 set_readable(true); 35 } 36 37 MOCK_METHOD3(SendPacket, int(const char* data, size_t len, int flags)); 38 MOCK_METHOD2(SetOption, int(talk_base::Socket::Option opt, int value)); 39 MOCK_METHOD0(GetError, int()); 40 MOCK_CONST_METHOD0(GetIceRole, cricket::IceRole()); 41 }; 42 43 class TransportChannelSocketAdapterTest : public testing::Test { 44 public: 45 TransportChannelSocketAdapterTest() 46 : callback_(base::Bind(&TransportChannelSocketAdapterTest::Callback, 47 base::Unretained(this))), 48 callback_result_(0) { 49 } 50 51 protected: 52 virtual void SetUp() { 53 target_.reset(new TransportChannelSocketAdapter(&channel_)); 54 } 55 56 void Callback(int result) { 57 callback_result_ = result; 58 } 59 60 MockTransportChannel channel_; 61 scoped_ptr<TransportChannelSocketAdapter> target_; 62 net::CompletionCallback callback_; 63 int callback_result_; 64 base::MessageLoopForIO message_loop_; 65 }; 66 67 // Verify that Read() returns net::ERR_IO_PENDING. 68 TEST_F(TransportChannelSocketAdapterTest, Read) { 69 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); 70 71 int result = target_->Read(buffer.get(), kBufferSize, callback_); 72 ASSERT_EQ(net::ERR_IO_PENDING, result); 73 74 channel_.SignalReadPacket(&channel_, kTestData, kTestDataSize, 0); 75 EXPECT_EQ(kTestDataSize, callback_result_); 76 } 77 78 // Verify that Read() after Close() returns error. 79 TEST_F(TransportChannelSocketAdapterTest, ReadClose) { 80 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); 81 82 int result = target_->Read(buffer.get(), kBufferSize, callback_); 83 ASSERT_EQ(net::ERR_IO_PENDING, result); 84 85 target_->Close(kTestError); 86 EXPECT_EQ(kTestError, callback_result_); 87 88 // All Read() calls after Close() should return the error. 89 EXPECT_EQ(kTestError, target_->Read(buffer.get(), kBufferSize, callback_)); 90 } 91 92 // Verify that Write sends the packet and returns correct result. 93 TEST_F(TransportChannelSocketAdapterTest, Write) { 94 scoped_refptr<IOBuffer> buffer(new IOBuffer(kTestDataSize)); 95 96 EXPECT_CALL(channel_, SendPacket(buffer->data(), kTestDataSize, 0)) 97 .WillOnce(Return(kTestDataSize)); 98 99 int result = target_->Write(buffer.get(), kTestDataSize, callback_); 100 EXPECT_EQ(kTestDataSize, result); 101 } 102 103 // Verify that the message is still sent if Write() is called while 104 // socket is not open yet. The result is the packet is lost. 105 TEST_F(TransportChannelSocketAdapterTest, WritePending) { 106 scoped_refptr<IOBuffer> buffer(new IOBuffer(kTestDataSize)); 107 108 EXPECT_CALL(channel_, SendPacket(buffer->data(), kTestDataSize, 0)) 109 .Times(1) 110 .WillOnce(Return(SOCKET_ERROR)); 111 112 EXPECT_CALL(channel_, GetError()) 113 .WillOnce(Return(EWOULDBLOCK)); 114 115 int result = target_->Write(buffer.get(), kTestDataSize, callback_); 116 ASSERT_EQ(net::OK, result); 117 } 118 119 } // namespace jingle_glue 120