Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 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 #pragma once
      8 
      9 #include "build/build_config.h"
     10 
     11 #if defined(OS_WIN)
     12 #include <winsock2.h>
     13 #elif defined(OS_POSIX)
     14 #include <sys/socket.h>
     15 #include <errno.h>
     16 #include <arpa/inet.h>
     17 #endif
     18 
     19 #include "base/basictypes.h"
     20 #include "base/memory/scoped_ptr.h"
     21 #include "base/message_loop.h"
     22 #include "base/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/listen_socket.h"
     27 #include "net/base/net_util.h"
     28 #include "net/base/winsock_init.h"
     29 #include "testing/gtest/include/gtest/gtest.h"
     30 
     31 #if defined(OS_POSIX)
     32 // Used same name as in Windows to avoid #ifdef where refrenced
     33 #define SOCKET int
     34 const int INVALID_SOCKET = -1;
     35 const int SOCKET_ERROR = -1;
     36 #endif
     37 
     38 enum ActionType {
     39   ACTION_NONE = 0,
     40   ACTION_LISTEN = 1,
     41   ACTION_ACCEPT = 2,
     42   ACTION_READ = 3,
     43   ACTION_SEND = 4,
     44   ACTION_CLOSE = 5,
     45   ACTION_SHUTDOWN = 6
     46 };
     47 
     48 class ListenSocketTestAction {
     49  public:
     50   ListenSocketTestAction() : action_(ACTION_NONE) {}
     51   explicit ListenSocketTestAction(ActionType action) : action_(action) {}
     52   ListenSocketTestAction(ActionType action, std::string data)
     53       : action_(action),
     54         data_(data) {}
     55 
     56   const std::string data() const { return data_; }
     57   ActionType type() const { return action_; }
     58 
     59  private:
     60   ActionType action_;
     61   std::string data_;
     62 };
     63 
     64 
     65 // This had to be split out into a separate class because I couldn't
     66 // make a the testing::Test class refcounted.
     67 class ListenSocketTester :
     68     public ListenSocket::ListenSocketDelegate,
     69     public base::RefCountedThreadSafe<ListenSocketTester> {
     70 
     71  public:
     72   ListenSocketTester();
     73 
     74   void SetUp();
     75   void TearDown();
     76 
     77   void ReportAction(const ListenSocketTestAction& action);
     78   void NextAction();
     79 
     80   // read all pending data from the test socket
     81   int ClearTestSocket();
     82   // Release the connection and server sockets
     83   void Shutdown();
     84   void Listen();
     85   void SendFromTester();
     86   // verify the send/read from client to server
     87   void TestClientSend();
     88   // verify send/read of a longer string
     89   void TestClientSendLong();
     90   // verify a send/read from server to client
     91   void TestServerSend();
     92 
     93   virtual bool Send(SOCKET sock, const std::string& str);
     94 
     95   // ListenSocket::ListenSocketDelegate:
     96   virtual void DidAccept(ListenSocket *server, ListenSocket *connection);
     97   virtual void DidRead(ListenSocket *connection, const char* data, int len);
     98   virtual void DidClose(ListenSocket *sock);
     99 
    100   scoped_ptr<base::Thread> thread_;
    101   MessageLoopForIO* loop_;
    102   ListenSocket* server_;
    103   ListenSocket* connection_;
    104   ListenSocketTestAction last_action_;
    105 
    106   SOCKET test_socket_;
    107   static const int kTestPort;
    108 
    109   base::Lock lock_;  // protects |queue_| and wraps |cv_|
    110   base::ConditionVariable cv_;
    111   std::deque<ListenSocketTestAction> queue_;
    112 
    113  protected:
    114   friend class base::RefCountedThreadSafe<ListenSocketTester>;
    115 
    116   virtual ~ListenSocketTester();
    117 
    118   virtual ListenSocket* DoListen();
    119 };
    120 
    121 #endif  // NET_BASE_LISTEN_SOCKET_UNITTEST_H_
    122