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#include <string> 6 7#include "base/compiler_specific.h" 8#include "base/memory/ref_counted.h" 9#include "base/message_loop/message_loop.h" 10#include "base/message_loop/message_loop_proxy.h" 11#include "base/single_thread_task_runner.h" 12#include "base/threading/platform_thread.h" 13#include "base/threading/thread.h" 14#include "base/time/time.h" 15#include "chrome/test/chromedriver/net/sync_websocket_impl.h" 16#include "chrome/test/chromedriver/net/test_http_server.h" 17#include "chrome/test/chromedriver/net/url_request_context_getter.h" 18#include "testing/gtest/include/gtest/gtest.h" 19#include "url/gurl.h" 20 21namespace { 22 23class SyncWebSocketImplTest : public testing::Test { 24 protected: 25 SyncWebSocketImplTest() 26 : client_thread_("ClientThread"), 27 long_timeout_(base::TimeDelta::FromMinutes(1)) {} 28 virtual ~SyncWebSocketImplTest() {} 29 30 virtual void SetUp() OVERRIDE { 31 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); 32 ASSERT_TRUE(client_thread_.StartWithOptions(options)); 33 context_getter_ = new URLRequestContextGetter( 34 client_thread_.message_loop_proxy()); 35 ASSERT_TRUE(server_.Start()); 36 } 37 38 virtual void TearDown() OVERRIDE { 39 server_.Stop(); 40 } 41 42 base::Thread client_thread_; 43 TestHttpServer server_; 44 scoped_refptr<URLRequestContextGetter> context_getter_; 45 const base::TimeDelta long_timeout_; 46}; 47 48} // namespace 49 50TEST_F(SyncWebSocketImplTest, CreateDestroy) { 51 SyncWebSocketImpl sock(context_getter_.get()); 52} 53 54TEST_F(SyncWebSocketImplTest, Connect) { 55 SyncWebSocketImpl sock(context_getter_.get()); 56 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 57} 58 59TEST_F(SyncWebSocketImplTest, ConnectFail) { 60 SyncWebSocketImpl sock(context_getter_.get()); 61 ASSERT_FALSE(sock.Connect(GURL("ws://127.0.0.1:33333"))); 62} 63 64TEST_F(SyncWebSocketImplTest, SendReceive) { 65 SyncWebSocketImpl sock(context_getter_.get()); 66 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 67 ASSERT_TRUE(sock.Send("hi")); 68 std::string message; 69 ASSERT_EQ( 70 SyncWebSocket::kOk, 71 sock.ReceiveNextMessage(&message, long_timeout_)); 72 ASSERT_STREQ("hi", message.c_str()); 73} 74 75TEST_F(SyncWebSocketImplTest, SendReceiveTimeout) { 76 SyncWebSocketImpl sock(context_getter_.get()); 77 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 78 ASSERT_TRUE(sock.Send("hi")); 79 std::string message; 80 ASSERT_EQ( 81 SyncWebSocket::kTimeout, 82 sock.ReceiveNextMessage( 83 &message, base::TimeDelta())); 84} 85 86TEST_F(SyncWebSocketImplTest, SendReceiveLarge) { 87 SyncWebSocketImpl sock(context_getter_.get()); 88 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 89 std::string wrote_message(10 << 20, 'a'); 90 ASSERT_TRUE(sock.Send(wrote_message)); 91 std::string message; 92 ASSERT_EQ( 93 SyncWebSocket::kOk, 94 sock.ReceiveNextMessage(&message, long_timeout_)); 95 ASSERT_EQ(wrote_message.length(), message.length()); 96 ASSERT_EQ(wrote_message, message); 97} 98 99TEST_F(SyncWebSocketImplTest, SendReceiveMany) { 100 SyncWebSocketImpl sock(context_getter_.get()); 101 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 102 ASSERT_TRUE(sock.Send("1")); 103 ASSERT_TRUE(sock.Send("2")); 104 std::string message; 105 ASSERT_EQ( 106 SyncWebSocket::kOk, 107 sock.ReceiveNextMessage(&message, long_timeout_)); 108 ASSERT_STREQ("1", message.c_str()); 109 ASSERT_TRUE(sock.Send("3")); 110 ASSERT_EQ( 111 SyncWebSocket::kOk, 112 sock.ReceiveNextMessage(&message, long_timeout_)); 113 ASSERT_STREQ("2", message.c_str()); 114 ASSERT_EQ( 115 SyncWebSocket::kOk, 116 sock.ReceiveNextMessage(&message, long_timeout_)); 117 ASSERT_STREQ("3", message.c_str()); 118} 119 120TEST_F(SyncWebSocketImplTest, CloseOnReceive) { 121 server_.SetMessageAction(TestHttpServer::kCloseOnMessage); 122 SyncWebSocketImpl sock(context_getter_.get()); 123 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 124 ASSERT_TRUE(sock.Send("1")); 125 std::string message; 126 ASSERT_EQ( 127 SyncWebSocket::kDisconnected, 128 sock.ReceiveNextMessage(&message, long_timeout_)); 129 ASSERT_STREQ("", message.c_str()); 130} 131 132TEST_F(SyncWebSocketImplTest, CloseOnSend) { 133 SyncWebSocketImpl sock(context_getter_.get()); 134 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 135 server_.Stop(); 136 ASSERT_FALSE(sock.Send("1")); 137} 138 139TEST_F(SyncWebSocketImplTest, Reconnect) { 140 SyncWebSocketImpl sock(context_getter_.get()); 141 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 142 ASSERT_TRUE(sock.Send("1")); 143 // Wait for SyncWebSocket to receive the response from the server. 144 base::TimeTicks deadline = 145 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(20); 146 while (base::TimeTicks::Now() < deadline) { 147 if (sock.IsConnected() && !sock.HasNextMessage()) 148 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); 149 else 150 break; 151 } 152 server_.Stop(); 153 ASSERT_FALSE(sock.Send("2")); 154 ASSERT_FALSE(sock.IsConnected()); 155 server_.Start(); 156 ASSERT_TRUE(sock.HasNextMessage()); 157 ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 158 ASSERT_FALSE(sock.HasNextMessage()); 159 ASSERT_TRUE(sock.Send("3")); 160 std::string message; 161 ASSERT_EQ( 162 SyncWebSocket::kOk, 163 sock.ReceiveNextMessage(&message, long_timeout_)); 164 ASSERT_STREQ("3", message.c_str()); 165 ASSERT_FALSE(sock.HasNextMessage()); 166} 167