12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/single_thread_task_runner.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/platform_thread.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/net/sync_websocket_impl.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/net/test_http_server.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/net/url_request_context_getter.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SyncWebSocketImplTest : public testing::Test { 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected: 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncWebSocketImplTest() 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : client_thread_("ClientThread"), 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) long_timeout_(base::TimeDelta::FromMinutes(1)) {} 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SyncWebSocketImplTest() {} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUp() OVERRIDE { 31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(client_thread_.StartWithOptions(options)); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_getter_ = new URLRequestContextGetter( 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_thread_.message_loop_proxy()); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(server_.Start()); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void TearDown() OVERRIDE { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_.Stop(); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Thread client_thread_; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestHttpServer server_; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<URLRequestContextGetter> context_getter_; 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::TimeDelta long_timeout_; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncWebSocketImplTest, CreateDestroy) { 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncWebSocketImplTest, Connect) { 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncWebSocketImplTest, ConnectFail) { 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(sock.Connect(GURL("ws://127.0.0.1:33333"))); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncWebSocketImplTest, SendReceive) { 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Send("hi")); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocket::kOk, 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sock.ReceiveNextMessage(&message, long_timeout_)); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ("hi", message.c_str()); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(SyncWebSocketImplTest, SendReceiveTimeout) { 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(sock.Send("hi")); 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string message; 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocket::kTimeout, 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sock.ReceiveNextMessage( 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &message, base::TimeDelta())); 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(SyncWebSocketImplTest, SendReceiveLarge) { 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string wrote_message(10 << 20, 'a'); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Send(wrote_message)); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocket::kOk, 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sock.ReceiveNextMessage(&message, long_timeout_)); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(wrote_message.length(), message.length()); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(wrote_message, message); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncWebSocketImplTest, SendReceiveMany) { 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Send("1")); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Send("2")); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocket::kOk, 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sock.ReceiveNextMessage(&message, long_timeout_)); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ("1", message.c_str()); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Send("3")); 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocket::kOk, 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sock.ReceiveNextMessage(&message, long_timeout_)); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ("2", message.c_str()); 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocket::kOk, 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sock.ReceiveNextMessage(&message, long_timeout_)); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ("3", message.c_str()); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncWebSocketImplTest, CloseOnReceive) { 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_.SetMessageAction(TestHttpServer::kCloseOnMessage); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Send("1")); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocket::kDisconnected, 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sock.ReceiveNextMessage(&message, long_timeout_)); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ("", message.c_str()); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncWebSocketImplTest, CloseOnSend) { 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_.Stop(); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(sock.Send("1")); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncWebSocketImplTest, Reconnect) { 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocketImpl sock(context_getter_.get()); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Send("1")); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Wait for SyncWebSocket to receive the response from the server. 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeTicks deadline = 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeTicks::Now() + base::TimeDelta::FromSeconds(20); 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) while (base::TimeTicks::Now() < deadline) { 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sock.IsConnected() && !sock.HasNextMessage()) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_.Stop(); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(sock.Send("2")); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(sock.IsConnected()); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server_.Start(); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.HasNextMessage()); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Connect(server_.web_socket_url())); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(sock.HasNextMessage()); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(sock.Send("3")); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SyncWebSocket::kOk, 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sock.ReceiveNextMessage(&message, long_timeout_)); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_STREQ("3", message.c_str()); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(sock.HasNextMessage()); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 167