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)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/socket/tcp_socket.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/rand_callback.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/tcp_client_socket.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/tcp_server_socket.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::SaveArg;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockTCPSocket : public net::TCPClientSocket {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MockTCPSocket(const net::AddressList& address_list)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : net::TCPClientSocket(address_list, NULL, net::NetLog::Source()) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD3(Read, int(net::IOBuffer* buf, int buf_len,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const net::CompletionCallback& callback));
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD3(Write, int(net::IOBuffer* buf, int buf_len,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const net::CompletionCallback& callback));
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(SetKeepAlive, bool(bool enable, int delay));
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(SetNoDelay, bool(bool no_delay));
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsConnected() const OVERRIDE {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockTCPSocket);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockTCPServerSocket : public net::TCPServerSocket {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MockTCPServerSocket()
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : net::TCPServerSocket(NULL, net::NetLog::Source()) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(Listen, int(const net::IPEndPoint& address, int backlog));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(Accept, int(scoped_ptr<net::StreamSocket>* socket,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const net::CompletionCallback& callback));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockTCPServerSocket);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CompleteHandler {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteHandler() {}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(OnComplete, void(int result_code));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnReadComplete, void(int result_code,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_refptr<net::IOBuffer> io_buffer));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnAccept, void(int, net::TCPClientSocket*));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CompleteHandler);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string FAKE_ID = "abcdefghijklmnopqrst";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SocketTest, TestTCPSocketRead) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::AddressList address_list;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTCPSocket* tcp_client_socket = new MockTCPSocket(address_list);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteHandler handler;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tcp_client_socket, FAKE_ID, true));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_client_socket, Read(_, _, _))
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(handler, OnReadComplete(_, _))
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int count = 512;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket->Read(count, base::Bind(&CompleteHandler::OnReadComplete,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Unretained(&handler)));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SocketTest, TestTCPSocketWrite) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::AddressList address_list;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTCPSocket* tcp_client_socket = new MockTCPSocket(address_list);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteHandler handler;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tcp_client_socket, FAKE_ID, true));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback callback;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_client_socket, Write(_, _, _))
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(2)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(testing::DoAll(SaveArg<2>(&callback),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     Return(128)));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(handler, OnComplete(_))
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> io_buffer(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new net::IOBufferWithSize(256));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket->Write(io_buffer.get(), io_buffer->size(),
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&CompleteHandler::OnComplete, base::Unretained(&handler)));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SocketTest, TestTCPSocketBlockedWrite) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::AddressList address_list;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTCPSocket* tcp_client_socket = new MockTCPSocket(address_list);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteHandler handler;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tcp_client_socket, FAKE_ID, true));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback callback;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_client_socket, Write(_, _, _))
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(2)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(testing::DoAll(SaveArg<2>(&callback),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     Return(net::ERR_IO_PENDING)));
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> io_buffer(new net::IOBufferWithSize(42));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket->Write(io_buffer.get(), io_buffer->size(),
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&CompleteHandler::OnComplete, base::Unretained(&handler)));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Good. Original call came back unable to complete. Now pretend the socket
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // finished, and confirm that we passed the error back.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(handler, OnComplete(42))
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.Run(40);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.Run(2);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SocketTest, TestTCPSocketBlockedWriteReentry) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::AddressList address_list;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTCPSocket* tcp_client_socket = new MockTCPSocket(address_list);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteHandler handlers[5];
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      tcp_client_socket, FAKE_ID, true));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback callback;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_client_socket, Write(_, _, _))
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(5)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(testing::DoAll(SaveArg<2>(&callback),
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     Return(net::ERR_IO_PENDING)));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> io_buffers[5];
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = 0; i < 5; i++) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_buffers[i] = new net::IOBufferWithSize(128 + i * 50);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::IOBufferWithSize> io_buffer1(
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::IOBufferWithSize(42));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket->Write(io_buffers[i].get(), io_buffers[i]->size(),
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&CompleteHandler::OnComplete,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::Unretained(&handlers[i])));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(handlers[i], OnComplete(io_buffers[i]->size()))
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .Times(1);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = 0; i < 5; i++) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(128 + i * 50);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SocketTest, TestTCPSocketSetNoDelay) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::AddressList address_list;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTCPSocket* tcp_client_socket = new MockTCPSocket(address_list);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tcp_client_socket, FAKE_ID));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool no_delay = false;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_client_socket, SetNoDelay(_))
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(testing::DoAll(SaveArg<0>(&no_delay), Return(true)));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = socket->SetNoDelay(true);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(no_delay);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_client_socket, SetNoDelay(_))
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(testing::DoAll(SaveArg<0>(&no_delay), Return(false)));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = socket->SetNoDelay(false);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(no_delay);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SocketTest, TestTCPSocketSetKeepAlive) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::AddressList address_list;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTCPSocket* tcp_client_socket = new MockTCPSocket(address_list);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tcp_client_socket, FAKE_ID));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enable = false;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int delay = 0;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_client_socket, SetKeepAlive(_, _))
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(testing::DoAll(SaveArg<0>(&enable),
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               SaveArg<1>(&delay),
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               Return(true)));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = socket->SetKeepAlive(true, 4500);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enable);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4500, delay);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_client_socket, SetKeepAlive(_, _))
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(testing::DoAll(SaveArg<0>(&enable),
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               SaveArg<1>(&delay),
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               Return(false)));
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = socket->SetKeepAlive(false, 0);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(enable);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delay);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SocketTest, TestTCPServerSocketListenAccept) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTCPServerSocket* tcp_server_socket = new MockTCPServerSocket();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteHandler handler;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TCPSocket> socket(TCPSocket::CreateServerSocketForTesting(
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tcp_server_socket, FAKE_ID));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_server_socket, Accept(_, _)).Times(1);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*tcp_server_socket, Listen(_, _)).Times(1);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(handler, OnAccept(_, _));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string err_msg;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(net::OK, socket->Listen("127.0.0.1", 9999, 10, &err_msg));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket->Accept(base::Bind(&CompleteHandler::OnAccept,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Unretained(&handler)));
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
235