1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_BASE_LISTEN_SOCKET_UNITTEST_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_BASE_LISTEN_SOCKET_UNITTEST_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "build/build_config.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <winsock2.h> 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX) 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/socket.h> 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <errno.h> 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <arpa/inet.h> 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/condition_variable.h" 243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/lock.h" 253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h" 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/listen_socket.h" 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/net_util.h" 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/winsock_init.h" 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_POSIX) 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Used same name as in Windows to avoid #ifdef where refrenced 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SOCKET int 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int INVALID_SOCKET = -1; 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int SOCKET_ERROR = -1; 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottenum ActionType { 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ACTION_NONE = 0, 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ACTION_LISTEN = 1, 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ACTION_ACCEPT = 2, 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ACTION_READ = 3, 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ACTION_SEND = 4, 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ACTION_CLOSE = 5, 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ACTION_SHUTDOWN = 6 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ListenSocketTestAction { 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ListenSocketTestAction() : action_(ACTION_NONE) {} 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit ListenSocketTestAction(ActionType action) : action_(action) {} 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ListenSocketTestAction(ActionType action, std::string data) 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : action_(action), 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_(data) {} 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string data() const { return data_; } 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ActionType type() const { return action_; } 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ActionType action_; 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string data_; 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This had to be split out into a separate class because I couldn't 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// make a the testing::Test class refcounted. 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ListenSocketTester : 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public ListenSocket::ListenSocketDelegate, 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public base::RefCountedThreadSafe<ListenSocketTester> { 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ListenSocketTester(); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void SetUp(); 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void TearDown(); 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ReportAction(const ListenSocketTestAction& action); 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void NextAction(); 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // read all pending data from the test socket 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ClearTestSocket(); 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Release the connection and server sockets 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Shutdown(); 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Listen(); 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SendFromTester(); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // verify the send/read from client to server 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void TestClientSend(); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // verify send/read of a longer string 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void TestClientSendLong(); 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // verify a send/read from server to client 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void TestServerSend(); 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual bool Send(SOCKET sock, const std::string& str); 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // ListenSocket::ListenSocketDelegate: 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void DidAccept(ListenSocket *server, ListenSocket *connection); 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void DidRead(ListenSocket *connection, const char* data, int len); 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void DidClose(ListenSocket *sock); 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<base::Thread> thread_; 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoopForIO* loop_; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ListenSocket* server_; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ListenSocket* connection_; 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ListenSocketTestAction last_action_; 1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SOCKET test_socket_; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const int kTestPort; 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::Lock lock_; // protects |queue_| and wraps |cv_| 1103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::ConditionVariable cv_; 1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::deque<ListenSocketTestAction> queue_; 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen protected: 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen friend class base::RefCountedThreadSafe<ListenSocketTester>; 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual ~ListenSocketTester(); 11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual ListenSocket* DoListen(); 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_BASE_LISTEN_SOCKET_UNITTEST_H_ 122