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/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "content/browser/browser_thread_impl.h"
11 #include "content/public/browser/devtools_http_handler.h"
12 #include "content/public/browser/devtools_http_handler_delegate.h"
13 #include "content/public/browser/devtools_target.h"
14 #include "content/public/test/test_utils.h"
15 #include "net/base/ip_endpoint.h"
16 #include "net/base/net_errors.h"
17 #include "net/socket/server_socket.h"
18 #include "testing/gtest/include/gtest/gtest.h"
23 const uint16 kDummyPort
= 4321;
24 const base::FilePath::CharType kDevToolsActivePortFileName
[] =
25 FILE_PATH_LITERAL("DevToolsActivePort");
27 class DummyServerSocket
: public net::ServerSocket
{
29 DummyServerSocket() {}
31 // net::ServerSocket "implementation"
32 int Listen(const net::IPEndPoint
& address
, int backlog
) override
{
36 int ListenWithAddressAndPort(const std::string
& ip_address
,
38 int backlog
) override
{
42 int GetLocalAddress(net::IPEndPoint
* address
) const override
{
43 net::IPAddressNumber number
;
44 EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &number
));
45 *address
= net::IPEndPoint(number
, kDummyPort
);
49 int Accept(scoped_ptr
<net::StreamSocket
>* socket
,
50 const net::CompletionCallback
& callback
) override
{
51 return net::ERR_IO_PENDING
;
55 void QuitFromHandlerThread(const base::Closure
& quit_closure
) {
56 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, quit_closure
);
59 class DummyServerSocketFactory
60 : public DevToolsHttpHandler::ServerSocketFactory
{
62 DummyServerSocketFactory(base::Closure quit_closure_1
,
63 base::Closure quit_closure_2
)
64 : DevToolsHttpHandler::ServerSocketFactory("", 0, 0),
65 quit_closure_1_(quit_closure_1
),
66 quit_closure_2_(quit_closure_2
) {}
68 ~DummyServerSocketFactory() override
{
69 BrowserThread::PostTask(
70 BrowserThread::UI
, FROM_HERE
, quit_closure_2_
);
74 scoped_ptr
<net::ServerSocket
> Create() const override
{
75 base::MessageLoopProxy::current()->PostTask(FROM_HERE
,
76 base::Bind(&QuitFromHandlerThread
, quit_closure_1_
));
77 return scoped_ptr
<net::ServerSocket
>(new DummyServerSocket());
80 base::Closure quit_closure_1_
;
81 base::Closure quit_closure_2_
;
84 class FailingServerSocketFactory
: public DummyServerSocketFactory
{
86 FailingServerSocketFactory(const base::Closure
& quit_closure_1
,
87 const base::Closure
& quit_closure_2
)
88 : DummyServerSocketFactory(quit_closure_1
, quit_closure_2
) {
92 scoped_ptr
<net::ServerSocket
> Create() const override
{
93 base::MessageLoopProxy::current()->PostTask(FROM_HERE
,
94 base::Bind(&QuitFromHandlerThread
, quit_closure_1_
));
99 class DummyDelegate
: public DevToolsHttpHandlerDelegate
{
101 std::string
GetDiscoveryPageHTML() override
{ return std::string(); }
103 bool BundlesFrontendResources() override
{ return true; }
105 base::FilePath
GetDebugFrontendDir() override
{ return base::FilePath(); }
107 scoped_ptr
<net::ServerSocket
>
108 CreateSocketForTethering(std::string
* name
) override
{
109 return scoped_ptr
<net::ServerSocket
>();
115 class DevToolsHttpHandlerTest
: public testing::Test
{
117 DevToolsHttpHandlerTest()
118 : ui_thread_(BrowserThread::UI
, &message_loop_
) {
122 void SetUp() override
{
123 file_thread_
.reset(new BrowserThreadImpl(BrowserThread::FILE));
124 file_thread_
->Start();
127 void TearDown() override
{ file_thread_
->Stop(); }
130 base::MessageLoopForIO message_loop_
;
131 BrowserThreadImpl ui_thread_
;
132 scoped_ptr
<BrowserThreadImpl
> file_thread_
;
135 TEST_F(DevToolsHttpHandlerTest
, TestStartStop
) {
136 base::RunLoop run_loop
, run_loop_2
;
137 scoped_ptr
<DevToolsHttpHandler::ServerSocketFactory
> factory(
138 new DummyServerSocketFactory(run_loop
.QuitClosure(),
139 run_loop_2
.QuitClosure()));
140 scoped_ptr
<content::DevToolsHttpHandler
> devtools_http_handler(
141 content::DevToolsHttpHandler::Start(factory
.Pass(),
145 // Our dummy socket factory will post a quit message once the server will
148 devtools_http_handler
.reset();
149 // Make sure the handler actually stops.
153 TEST_F(DevToolsHttpHandlerTest
, TestServerSocketFailed
) {
154 base::RunLoop run_loop
, run_loop_2
;
155 scoped_ptr
<DevToolsHttpHandler::ServerSocketFactory
> factory(
156 new FailingServerSocketFactory(run_loop
.QuitClosure(),
157 run_loop_2
.QuitClosure()));
158 scoped_ptr
<content::DevToolsHttpHandler
> devtools_http_handler(
159 content::DevToolsHttpHandler::Start(factory
.Pass(),
163 // Our dummy socket factory will post a quit message once the server will
166 for (int i
= 0; i
< 5; i
++) {
167 RunAllPendingInMessageLoop(BrowserThread::UI
);
168 RunAllPendingInMessageLoop(BrowserThread::FILE);
170 devtools_http_handler
.reset();
171 // Make sure the handler actually stops.
176 TEST_F(DevToolsHttpHandlerTest
, TestDevToolsActivePort
) {
177 base::RunLoop run_loop
, run_loop_2
;
178 base::ScopedTempDir temp_dir
;
179 EXPECT_TRUE(temp_dir
.CreateUniqueTempDir());
180 scoped_ptr
<DevToolsHttpHandler::ServerSocketFactory
> factory(
181 new DummyServerSocketFactory(run_loop
.QuitClosure(),
182 run_loop_2
.QuitClosure()));
183 scoped_ptr
<content::DevToolsHttpHandler
> devtools_http_handler(
184 content::DevToolsHttpHandler::Start(factory
.Pass(),
188 // Our dummy socket factory will post a quit message once the server will
191 devtools_http_handler
.reset();
192 // Make sure the handler actually stops.
195 // Now make sure the DevToolsActivePort was written into the
196 // temporary directory and its contents are as expected.
197 base::FilePath active_port_file
= temp_dir
.path().Append(
198 kDevToolsActivePortFileName
);
199 EXPECT_TRUE(base::PathExists(active_port_file
));
200 std::string file_contents
;
201 EXPECT_TRUE(base::ReadFileToString(active_port_file
, &file_contents
));
203 EXPECT_TRUE(base::StringToInt(file_contents
, &port
));
204 EXPECT_EQ(static_cast<int>(kDummyPort
), port
);
207 } // namespace content