1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_UNITTEST_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_UNITTEST_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "build/build_config.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <deque>
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <winsock2.h>
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sys/socket.h>
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <errno.h>
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <semaphore.h>
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <arpa/inet.h>
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_remote.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_remote_listen_socket.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_remote_message.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/listen_socket.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/winsock_init.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_POSIX)
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Used same name as in Windows to avoid #ifdef where refrenced
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define SOCKET int
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int INVALID_SOCKET = -1;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int SOCKET_ERROR = -1;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum ActionType {
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACTION_NONE = 0,
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACTION_LISTEN = 1,
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACTION_ACCEPT = 2,
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACTION_READ = 3,
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACTION_READ_MESSAGE = 4,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACTION_SEND = 5,
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACTION_CLOSE = 6,
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACTION_SHUTDOWN = 7
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ListenSocketTestAction {
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ListenSocketTestAction();
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  explicit ListenSocketTestAction(ActionType action);
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ListenSocketTestAction(ActionType action, std::string data);
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListenSocketTestAction(ActionType action,
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                         const DevToolsRemoteMessage& message);
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ~ListenSocketTestAction();
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string data() const { return data_; }
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const DevToolsRemoteMessage message() { return message_; }
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ActionType type() const { return action_; }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ActionType action_;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data_;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DevToolsRemoteMessage message_;
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This had to be split out into a separate class because I couldn't
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// make a the testing::Test class refcounted.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass DevToolsRemoteListenSocketTester :
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    public DevToolsRemoteListener {
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DevToolsRemoteListenSocketTester();
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp();
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown();
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ReportAction(const ListenSocketTestAction& action);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool NextAction(int timeout);
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DevToolsRemoteMessageHandler interface
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void HandleMessage(const DevToolsRemoteMessage& message);
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnAcceptConnection(ListenSocket* connection);
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnConnectionLost();
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // read all pending data from the test socket
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int ClearTestSocket();
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Release the connection and server sockets
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Shutdown();
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Listen();
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SendFromTester();
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool Send(SOCKET sock, const std::string& str);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // verify the send/read from client to server
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void TestClientSend();
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // verify a send/read from server to client
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void TestServerSend();
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CRITICAL_SECTION lock_;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HANDLE semaphore_;
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pthread_mutex_t lock_;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sem_t* semaphore_;
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<base::Thread> thread_;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoopForIO* loop_;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListenSocket* server_;
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListenSocket* connection_;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListenSocketTestAction last_action_;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::deque<ListenSocketTestAction> queue_;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SOCKET test_socket_;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kTestPort;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ListenSocket* DoListen();
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual ~DevToolsRemoteListenSocketTester();
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_UNITTEST_H_
130