Index: chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc |
diff --git a/chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc b/chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc |
deleted file mode 100644 |
index 26cbaa988513352ff32a0960135c7e863408f445..0000000000000000000000000000000000000000 |
--- a/chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc |
+++ /dev/null |
@@ -1,387 +0,0 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/debugger/devtools_remote_listen_socket_unittest.h" |
- |
-#include <fcntl.h> |
-#if defined(OS_POSIX) |
-#include <netinet/in.h> |
-#endif |
- |
-#include "base/bind.h" |
-#include "base/eintr_wrapper.h" |
-#include "base/test/test_timeouts.h" |
-#include "base/threading/platform_thread.h" |
-#include "net/base/net_util.h" |
-#include "testing/platform_test.h" |
- |
-const int DevToolsRemoteListenSocketTester::kTestPort = 9999; |
- |
-static const int kReadBufSize = 1024; |
-static const char* kChromeDevToolsHandshake = "ChromeDevToolsHandshake\r\n"; |
-static const char* kSimpleMessagePart1 = |
- "Tool:V8Debugger\r\n" |
- "Destination:2\r"; |
-static const char* kSimpleMessagePart2 = |
- "\n" |
- "Content-Length:0\r\n" |
- "\r\n"; |
-static const char* kTwoMessages = |
- "Tool:DevToolsService\r\n" |
- "Content-Length:300\r\n" |
- "\r\n" |
- "00000000000000000000000000000000000000000000000000" |
- "00000000000000000000000000000000000000000000000000" |
- "00000000000000000000000000000000000000000000000000" |
- "00000000000000000000000000000000000000000000000000" |
- "00000000000000000000000000000000000000000000000000" |
- "00000000000000000000000000000000000000000000000000" |
- "Tool:V8Debugger\r\n" |
- "Destination:1\r\n" |
- "Content-Length:0\r\n" |
- "\r\n"; |
- |
-static const int kMaxQueueSize = 20; |
-static const char* kLoopback = "127.0.0.1"; |
-#if defined(OS_POSIX) |
-static const char* kSemaphoreName = "chromium.listen_socket"; |
-#endif |
- |
- |
-ListenSocketTestAction::ListenSocketTestAction() : action_(ACTION_NONE) {} |
- |
-ListenSocketTestAction::ListenSocketTestAction(ActionType action) |
- : action_(action) {} |
- |
-ListenSocketTestAction::ListenSocketTestAction(ActionType action, |
- std::string data) |
- : action_(action), |
- data_(data) {} |
- |
-ListenSocketTestAction::ListenSocketTestAction( |
- ActionType action, |
- const DevToolsRemoteMessage& message) |
- : action_(action), |
- message_(message) {} |
- |
-ListenSocketTestAction::~ListenSocketTestAction() {} |
- |
-net::ListenSocket* DevToolsRemoteListenSocketTester::DoListen() { |
- return DevToolsRemoteListenSocket::Listen(kLoopback, kTestPort, this); |
-} |
- |
-DevToolsRemoteListenSocketTester::DevToolsRemoteListenSocketTester() |
- : semaphore_(NULL), |
- thread_(NULL), |
- loop_(NULL), |
- server_(NULL), |
- connection_(NULL), |
- test_socket_(INVALID_SOCKET) { |
- memset(&lock_, 0, sizeof(lock_)); |
-} |
- |
-void DevToolsRemoteListenSocketTester::SetUp() { |
-#if defined(OS_WIN) |
- InitializeCriticalSection(&lock_); |
- semaphore_ = CreateSemaphore(NULL, 0, kMaxQueueSize, NULL); |
- server_ = NULL; |
- net::EnsureWinsockInit(); |
-#elif defined(OS_POSIX) |
- ASSERT_EQ(0, pthread_mutex_init(&lock_, NULL)); |
- sem_unlink(kSemaphoreName); |
- semaphore_ = sem_open(kSemaphoreName, O_CREAT, 0, 0); |
- ASSERT_NE(SEM_FAILED, semaphore_); |
-#endif |
- base::Thread::Options options; |
- options.message_loop_type = MessageLoop::TYPE_IO; |
- thread_.reset(new base::Thread("socketio_test")); |
- thread_->StartWithOptions(options); |
- loop_ = static_cast<MessageLoopForIO*>(thread_->message_loop()); |
- |
- loop_->PostTask( |
- FROM_HERE, |
- base::Bind(&DevToolsRemoteListenSocketTester::Listen, this)); |
- |
- // verify Listen succeeded |
- ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); |
- ASSERT_FALSE(server_ == NULL); |
- ASSERT_EQ(ACTION_LISTEN, last_action_.type()); |
- |
- // verify the connect/accept and setup test_socket_ |
- test_socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
- ASSERT_NE(INVALID_SOCKET, test_socket_); |
- struct sockaddr_in client; |
- client.sin_family = AF_INET; |
- client.sin_addr.s_addr = inet_addr(kLoopback); |
- client.sin_port = htons(kTestPort); |
- int ret = HANDLE_EINTR(connect(test_socket_, |
- reinterpret_cast<sockaddr*>(&client), |
- sizeof(client))); |
- ASSERT_NE(ret, SOCKET_ERROR); |
- |
- net::SetNonBlocking(test_socket_); |
- ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); |
- ASSERT_EQ(ACTION_ACCEPT, last_action_.type()); |
-} |
- |
-void DevToolsRemoteListenSocketTester::TearDown() { |
- // verify close |
-#if defined(OS_WIN) |
- closesocket(test_socket_); |
-#elif defined(OS_POSIX) |
- int ret = HANDLE_EINTR(close(test_socket_)); |
- ASSERT_EQ(ret, 0); |
-#endif |
- ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); |
- ASSERT_EQ(ACTION_CLOSE, last_action_.type()); |
- |
- loop_->PostTask( |
- FROM_HERE, |
- base::Bind(&DevToolsRemoteListenSocketTester::Shutdown, this)); |
- ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); |
- ASSERT_EQ(ACTION_SHUTDOWN, last_action_.type()); |
- |
-#if defined(OS_WIN) |
- CloseHandle(semaphore_); |
- semaphore_ = 0; |
- DeleteCriticalSection(&lock_); |
-#elif defined(OS_POSIX) |
- ASSERT_EQ(0, pthread_mutex_lock(&lock_)); |
- semaphore_ = NULL; |
- ASSERT_EQ(0, pthread_mutex_unlock(&lock_)); |
- ASSERT_EQ(0, sem_unlink(kSemaphoreName)); |
- ASSERT_EQ(0, pthread_mutex_destroy(&lock_)); |
-#endif |
- |
- thread_.reset(); |
- loop_ = NULL; |
-} |
- |
-void DevToolsRemoteListenSocketTester::ReportAction( |
- const ListenSocketTestAction& action) { |
-#if defined(OS_WIN) |
- EnterCriticalSection(&lock_); |
- queue_.push_back(action); |
- LeaveCriticalSection(&lock_); |
- ReleaseSemaphore(semaphore_, 1, NULL); |
-#elif defined(OS_POSIX) |
- ASSERT_EQ(0, pthread_mutex_lock(&lock_)); |
- queue_.push_back(action); |
- ASSERT_EQ(0, pthread_mutex_unlock(&lock_)); |
- ASSERT_EQ(0, sem_post(semaphore_)); |
-#endif |
-} |
- |
-bool DevToolsRemoteListenSocketTester::NextAction(int timeout) { |
-#if defined(OS_WIN) |
- DWORD ret = ::WaitForSingleObject(semaphore_, timeout); |
- if (ret != WAIT_OBJECT_0) |
- return false; |
- EnterCriticalSection(&lock_); |
- if (queue_.empty()) { |
- LeaveCriticalSection(&lock_); |
- return false; |
- } |
- last_action_ = queue_.front(); |
- queue_.pop_front(); |
- LeaveCriticalSection(&lock_); |
- return true; |
-#elif defined(OS_POSIX) |
- if (semaphore_ == SEM_FAILED) |
- return false; |
- while (true) { |
- int result = sem_trywait(semaphore_); |
- base::PlatformThread::Sleep(1); // 1MS sleep |
- timeout--; |
- if (timeout <= 0) |
- return false; |
- if (result == 0) |
- break; |
- } |
- pthread_mutex_lock(&lock_); |
- if (queue_.empty()) { |
- pthread_mutex_unlock(&lock_); |
- return false; |
- } |
- last_action_ = queue_.front(); |
- queue_.pop_front(); |
- pthread_mutex_unlock(&lock_); |
- return true; |
-#endif |
-} |
- |
-int DevToolsRemoteListenSocketTester::ClearTestSocket() { |
- char buf[kReadBufSize]; |
- int len_ret = 0; |
- int time_out = 0; |
- do { |
- int len = HANDLE_EINTR(recv(test_socket_, buf, kReadBufSize, 0)); |
-#if defined(OS_WIN) |
- if (len == SOCKET_ERROR) { |
- int err = WSAGetLastError(); |
- if (err == WSAEWOULDBLOCK) { |
-#elif defined(OS_POSIX) |
- if (len == SOCKET_ERROR) { |
- if (errno == EWOULDBLOCK || errno == EAGAIN) { |
-#endif |
- base::PlatformThread::Sleep(1); |
- time_out++; |
- if (time_out > 10) |
- break; |
- continue; // still trying |
- } |
- } else if (len == 0) { |
- // socket closed |
- break; |
- } else { |
- time_out = 0; |
- len_ret += len; |
- } |
- } while (true); |
- return len_ret; |
-} |
- |
-void DevToolsRemoteListenSocketTester::Shutdown() { |
- server_->Release(); |
- server_ = NULL; |
- ReportAction(ListenSocketTestAction(ACTION_SHUTDOWN)); |
-} |
- |
-void DevToolsRemoteListenSocketTester::Listen() { |
- server_ = DoListen(); |
- server_->AddRef(); |
- ReportAction(ListenSocketTestAction(ACTION_LISTEN)); |
-} |
- |
-void DevToolsRemoteListenSocketTester::SendFromTester() { |
- connection_->Send(kChromeDevToolsHandshake); |
- ReportAction(ListenSocketTestAction(ACTION_SEND)); |
-} |
- |
-void DevToolsRemoteListenSocketTester::OnAcceptConnection( |
- net::ListenSocket* connection) { |
- connection_ = connection; |
- ReportAction(ListenSocketTestAction(ACTION_ACCEPT)); |
-} |
- |
-void DevToolsRemoteListenSocketTester::OnConnectionLost() { |
- connection_ = NULL; |
- ReportAction(ListenSocketTestAction(ACTION_CLOSE)); |
-} |
- |
-void DevToolsRemoteListenSocketTester::HandleMessage( |
- const DevToolsRemoteMessage& message) { |
- ReportAction(ListenSocketTestAction(ACTION_READ_MESSAGE, message)); |
-} |
- |
-bool DevToolsRemoteListenSocketTester::Send(SOCKET sock, |
- const std::string& str) { |
- int len = static_cast<int>(str.length()); |
- int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0)); |
- if (send_len == SOCKET_ERROR) { |
- LOG(ERROR) << "send failed: " << errno; |
- return false; |
- } else if (send_len != len) { |
- return false; |
- } |
- return true; |
-} |
- |
-void DevToolsRemoteListenSocketTester::TestClientSend() { |
- ASSERT_TRUE(Send(test_socket_, kChromeDevToolsHandshake)); |
- { |
- ASSERT_TRUE(Send(test_socket_, kSimpleMessagePart1)); |
- // sleep for 10ms to test message split between \r and \n |
- base::PlatformThread::Sleep(10); |
- ASSERT_TRUE(Send(test_socket_, kSimpleMessagePart2)); |
- ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); |
- ASSERT_EQ(ACTION_READ_MESSAGE, last_action_.type()); |
- const DevToolsRemoteMessage& message = last_action_.message(); |
- ASSERT_STREQ("V8Debugger", message.GetHeaderWithEmptyDefault( |
- DevToolsRemoteMessageHeaders::kTool).c_str()); |
- ASSERT_STREQ("2", message.GetHeaderWithEmptyDefault( |
- DevToolsRemoteMessageHeaders::kDestination).c_str()); |
- ASSERT_STREQ("0", message.GetHeaderWithEmptyDefault( |
- DevToolsRemoteMessageHeaders::kContentLength).c_str()); |
- ASSERT_EQ(0, static_cast<int>(message.content().size())); |
- } |
- ASSERT_TRUE(Send(test_socket_, kTwoMessages)); |
- { |
- ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); |
- ASSERT_EQ(ACTION_READ_MESSAGE, last_action_.type()); |
- const DevToolsRemoteMessage& message = last_action_.message(); |
- ASSERT_STREQ("DevToolsService", message.tool().c_str()); |
- ASSERT_STREQ("", message.destination().c_str()); |
- ASSERT_EQ(300, message.content_length()); |
- const std::string& content = message.content(); |
- ASSERT_EQ(300, static_cast<int>(content.size())); |
- for (int i = 0; i < 300; ++i) { |
- ASSERT_EQ('0', content[i]); |
- } |
- } |
- { |
- ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); |
- ASSERT_EQ(ACTION_READ_MESSAGE, last_action_.type()); |
- const DevToolsRemoteMessage& message = last_action_.message(); |
- ASSERT_STREQ("V8Debugger", message.GetHeaderWithEmptyDefault( |
- DevToolsRemoteMessageHeaders::kTool).c_str()); |
- ASSERT_STREQ("1", message.GetHeaderWithEmptyDefault( |
- DevToolsRemoteMessageHeaders::kDestination).c_str()); |
- ASSERT_STREQ("0", message.GetHeaderWithEmptyDefault( |
- DevToolsRemoteMessageHeaders::kContentLength).c_str()); |
- const std::string& content = message.content(); |
- ASSERT_EQ(0, static_cast<int>(content.size())); |
- } |
-} |
- |
-void DevToolsRemoteListenSocketTester::TestServerSend() { |
- loop_->PostTask( |
- FROM_HERE, |
- base::Bind(&DevToolsRemoteListenSocketTester::SendFromTester, this)); |
- ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); |
- ASSERT_EQ(ACTION_SEND, last_action_.type()); |
- // TODO(erikkay): Without this sleep, the recv seems to fail a small amount |
- // of the time. I could fix this by making the socket blocking, but then |
- // this test might hang in the case of errors. It would be nice to do |
- // something that felt more reliable here. |
- base::PlatformThread::Sleep(10); // sleep for 10ms |
- const int buf_len = 200; |
- char buf[buf_len+1]; |
- int recv_len = HANDLE_EINTR(recv(test_socket_, buf, buf_len, 0)); |
- ASSERT_NE(recv_len, SOCKET_ERROR); |
- buf[recv_len] = 0; |
- ASSERT_STREQ(buf, kChromeDevToolsHandshake); |
-} |
- |
-DevToolsRemoteListenSocketTester::~DevToolsRemoteListenSocketTester() {} |
- |
-class DevToolsRemoteListenSocketTest: public PlatformTest { |
- public: |
- DevToolsRemoteListenSocketTest() { |
- tester_ = NULL; |
- } |
- |
- virtual void SetUp() { |
- PlatformTest::SetUp(); |
- tester_ = new DevToolsRemoteListenSocketTester(); |
- tester_->SetUp(); |
- } |
- |
- virtual void TearDown() { |
- PlatformTest::TearDown(); |
- tester_->TearDown(); |
- tester_ = NULL; |
- } |
- |
- scoped_refptr<DevToolsRemoteListenSocketTester> tester_; |
-}; |
- |
-// This test is flaky; see comment in ::TestServerSend. |
-TEST_F(DevToolsRemoteListenSocketTest, ServerSend) { |
- tester_->TestServerSend(); |
-} |
- |
-TEST_F(DevToolsRemoteListenSocketTest, ClientSend) { |
- tester_->TestClientSend(); |
-} |