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#ifndef NET_BASE_LISTEN_SOCKET_UNITTEST_H_
6#define NET_BASE_LISTEN_SOCKET_UNITTEST_H_
7
8#include "build/build_config.h"
9
10#if defined(OS_WIN)
11#include <winsock2.h>
12#elif defined(OS_POSIX)
13#include <arpa/inet.h>
14#include <errno.h>
15#include <sys/socket.h>
16#endif
17
18#include "base/basictypes.h"
19#include "base/memory/ref_counted.h"
20#include "base/memory/scoped_ptr.h"
21#include "base/message_loop/message_loop.h"
22#include "base/strings/string_util.h"
23#include "base/synchronization/condition_variable.h"
24#include "base/synchronization/lock.h"
25#include "base/threading/thread.h"
26#include "net/base/net_util.h"
27#include "net/base/winsock_init.h"
28#include "net/socket/tcp_listen_socket.h"
29#include "testing/gtest/include/gtest/gtest.h"
30
31namespace net {
32
33enum ActionType {
34  ACTION_NONE = 0,
35  ACTION_LISTEN = 1,
36  ACTION_ACCEPT = 2,
37  ACTION_READ = 3,
38  ACTION_SEND = 4,
39  ACTION_CLOSE = 5,
40  ACTION_SHUTDOWN = 6
41};
42
43class TCPListenSocketTestAction {
44 public:
45  TCPListenSocketTestAction() : action_(ACTION_NONE) {}
46  explicit TCPListenSocketTestAction(ActionType action) : action_(action) {}
47  TCPListenSocketTestAction(ActionType action, std::string data)
48      : action_(action),
49        data_(data) {}
50
51  const std::string data() const { return data_; }
52  ActionType type() const { return action_; }
53
54 private:
55  ActionType action_;
56  std::string data_;
57};
58
59
60// This had to be split out into a separate class because I couldn't
61// make the testing::Test class refcounted.
62class TCPListenSocketTester :
63    public StreamListenSocket::Delegate,
64    public base::RefCountedThreadSafe<TCPListenSocketTester> {
65
66 public:
67  TCPListenSocketTester();
68
69  void SetUp();
70  void TearDown();
71
72  void ReportAction(const TCPListenSocketTestAction& action);
73  void NextAction();
74
75  // read all pending data from the test socket
76  int ClearTestSocket();
77  // Release the connection and server sockets
78  void Shutdown();
79  void Listen();
80  void SendFromTester();
81  // verify the send/read from client to server
82  void TestClientSend();
83  // verify send/read of a longer string
84  void TestClientSendLong();
85  // verify a send/read from server to client
86  void TestServerSend();
87  // verify multiple sends and reads from server to client.
88  void TestServerSendMultiple();
89
90  virtual bool Send(SocketDescriptor sock, const std::string& str);
91
92  // StreamListenSocket::Delegate:
93  virtual void DidAccept(StreamListenSocket* server,
94                         scoped_ptr<StreamListenSocket> connection) OVERRIDE;
95  virtual void DidRead(StreamListenSocket* connection, const char* data,
96                       int len) OVERRIDE;
97  virtual void DidClose(StreamListenSocket* sock) OVERRIDE;
98
99  scoped_ptr<base::Thread> thread_;
100  base::MessageLoopForIO* loop_;
101  scoped_ptr<TCPListenSocket> server_;
102  scoped_ptr<StreamListenSocket> connection_;
103  TCPListenSocketTestAction last_action_;
104
105  SocketDescriptor test_socket_;
106
107  base::Lock lock_;  // Protects |queue_| and |server_port_|. Wraps |cv_|.
108  base::ConditionVariable cv_;
109  std::deque<TCPListenSocketTestAction> queue_;
110
111 private:
112  friend class base::RefCountedThreadSafe<TCPListenSocketTester>;
113
114  virtual ~TCPListenSocketTester();
115
116  virtual scoped_ptr<TCPListenSocket> DoListen();
117
118  // Getters/setters for |server_port_|. They use |lock_| for thread safety.
119  int GetServerPort();
120  void SetServerPort(int server_port);
121
122  // Port the server is using. Must have |lock_| to access. Set by Listen() on
123  // the server's thread.
124  int server_port_;
125};
126
127}  // namespace net
128
129#endif  // NET_BASE_LISTEN_SOCKET_UNITTEST_H_
130