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.
5 #include "base/files/file_util.h"
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/location.h"
8 #include "base/run_loop.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/values.h"
13 #include "components/devtools_http_handler/devtools_http_handler.h"
14 #include "components/devtools_http_handler/devtools_http_handler_delegate.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "content/public/test/test_utils.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/base/net_errors.h"
19 #include "net/socket/server_socket.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using content::BrowserThread
;
24 namespace devtools_http_handler
{
27 const uint16 kDummyPort
= 4321;
28 const base::FilePath::CharType kDevToolsActivePortFileName
[] =
29 FILE_PATH_LITERAL("DevToolsActivePort");
31 class DummyServerSocket
: public net::ServerSocket
{
33 DummyServerSocket() {}
35 // net::ServerSocket "implementation"
36 int Listen(const net::IPEndPoint
& address
, int backlog
) override
{
40 int GetLocalAddress(net::IPEndPoint
* address
) const override
{
41 net::IPAddressNumber number
;
42 EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &number
));
43 *address
= net::IPEndPoint(number
, kDummyPort
);
47 int Accept(scoped_ptr
<net::StreamSocket
>* socket
,
48 const net::CompletionCallback
& callback
) override
{
49 return net::ERR_IO_PENDING
;
53 void QuitFromHandlerThread(const base::Closure
& quit_closure
) {
54 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, quit_closure
);
57 class DummyServerSocketFactory
58 : public DevToolsHttpHandler::ServerSocketFactory
{
60 DummyServerSocketFactory(base::Closure quit_closure_1
,
61 base::Closure quit_closure_2
)
62 : quit_closure_1_(quit_closure_1
),
63 quit_closure_2_(quit_closure_2
) {}
65 ~DummyServerSocketFactory() override
{
66 BrowserThread::PostTask(
67 BrowserThread::UI
, FROM_HERE
, quit_closure_2_
);
71 scoped_ptr
<net::ServerSocket
> CreateForHttpServer() override
{
72 base::ThreadTaskRunnerHandle::Get()->PostTask(
73 FROM_HERE
, base::Bind(&QuitFromHandlerThread
, quit_closure_1_
));
74 return scoped_ptr
<net::ServerSocket
>(new DummyServerSocket());
77 base::Closure quit_closure_1_
;
78 base::Closure quit_closure_2_
;
81 class FailingServerSocketFactory
: public DummyServerSocketFactory
{
83 FailingServerSocketFactory(const base::Closure
& quit_closure_1
,
84 const base::Closure
& quit_closure_2
)
85 : DummyServerSocketFactory(quit_closure_1
, quit_closure_2
) {
89 scoped_ptr
<net::ServerSocket
> CreateForHttpServer() override
{
90 base::ThreadTaskRunnerHandle::Get()->PostTask(
91 FROM_HERE
, base::Bind(&QuitFromHandlerThread
, quit_closure_1_
));
92 return scoped_ptr
<net::ServerSocket
>();
96 class DummyDelegate
: public DevToolsHttpHandlerDelegate
{
98 std::string
GetDiscoveryPageHTML() override
{ return std::string(); }
100 std::string
GetFrontendResource(const std::string
& path
) override
{
101 return std::string();
104 std::string
GetPageThumbnailData(const GURL
& url
) override
{
105 return std::string();
111 class DevToolsHttpHandlerTest
: public testing::Test
{
113 DevToolsHttpHandlerTest() : testing::Test() { }
116 content::TestBrowserThreadBundle thread_bundle_
;
119 TEST_F(DevToolsHttpHandlerTest
, TestStartStop
) {
120 base::RunLoop run_loop
, run_loop_2
;
121 scoped_ptr
<DevToolsHttpHandler::ServerSocketFactory
> factory(
122 new DummyServerSocketFactory(run_loop
.QuitClosure(),
123 run_loop_2
.QuitClosure()));
124 scoped_ptr
<DevToolsHttpHandler
> devtools_http_handler(
125 new DevToolsHttpHandler(factory
.Pass(),
132 // Our dummy socket factory will post a quit message once the server will
135 devtools_http_handler
.reset();
136 // Make sure the handler actually stops.
140 TEST_F(DevToolsHttpHandlerTest
, TestServerSocketFailed
) {
141 base::RunLoop run_loop
, run_loop_2
;
142 scoped_ptr
<DevToolsHttpHandler::ServerSocketFactory
> factory(
143 new FailingServerSocketFactory(run_loop
.QuitClosure(),
144 run_loop_2
.QuitClosure()));
145 scoped_ptr
<DevToolsHttpHandler
> devtools_http_handler(
146 new DevToolsHttpHandler(factory
.Pass(),
153 // Our dummy socket factory will post a quit message once the server will
156 for (int i
= 0; i
< 5; i
++) {
157 RunAllPendingInMessageLoop(BrowserThread::UI
);
158 RunAllPendingInMessageLoop(BrowserThread::FILE);
160 devtools_http_handler
.reset();
161 // Make sure the handler actually stops.
166 TEST_F(DevToolsHttpHandlerTest
, TestDevToolsActivePort
) {
167 base::RunLoop run_loop
, run_loop_2
;
168 base::ScopedTempDir temp_dir
;
169 EXPECT_TRUE(temp_dir
.CreateUniqueTempDir());
170 scoped_ptr
<DevToolsHttpHandler::ServerSocketFactory
> factory(
171 new DummyServerSocketFactory(run_loop
.QuitClosure(),
172 run_loop_2
.QuitClosure()));
173 scoped_ptr
<DevToolsHttpHandler
> devtools_http_handler(
174 new DevToolsHttpHandler(factory
.Pass(),
181 // Our dummy socket factory will post a quit message once the server will
184 devtools_http_handler
.reset();
185 // Make sure the handler actually stops.
188 // Now make sure the DevToolsActivePort was written into the
189 // temporary directory and its contents are as expected.
190 base::FilePath active_port_file
= temp_dir
.path().Append(
191 kDevToolsActivePortFileName
);
192 EXPECT_TRUE(base::PathExists(active_port_file
));
193 std::string file_contents
;
194 EXPECT_TRUE(base::ReadFileToString(active_port_file
, &file_contents
));
196 EXPECT_TRUE(base::StringToInt(file_contents
, &port
));
197 EXPECT_EQ(static_cast<int>(kDummyPort
), port
);
200 } // namespace devtools_http_handler