Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / devtools / devtools_http_handler_unittest.cc
blobe8c131b2c9e767ca30f0dc36fdf77ae174bb11c5
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"
20 namespace content {
21 namespace {
23 const uint16 kDummyPort = 4321;
24 const base::FilePath::CharType kDevToolsActivePortFileName[] =
25 FILE_PATH_LITERAL("DevToolsActivePort");
27 class DummyServerSocket : public net::ServerSocket {
28 public:
29 DummyServerSocket() {}
31 // net::ServerSocket "implementation"
32 int Listen(const net::IPEndPoint& address, int backlog) override {
33 return net::OK;
36 int GetLocalAddress(net::IPEndPoint* address) const override {
37 net::IPAddressNumber number;
38 EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &number));
39 *address = net::IPEndPoint(number, kDummyPort);
40 return net::OK;
43 int Accept(scoped_ptr<net::StreamSocket>* socket,
44 const net::CompletionCallback& callback) override {
45 return net::ERR_IO_PENDING;
49 void QuitFromHandlerThread(const base::Closure& quit_closure) {
50 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_closure);
53 class DummyServerSocketFactory
54 : public DevToolsHttpHandler::ServerSocketFactory {
55 public:
56 DummyServerSocketFactory(base::Closure quit_closure_1,
57 base::Closure quit_closure_2)
58 : quit_closure_1_(quit_closure_1),
59 quit_closure_2_(quit_closure_2) {}
61 ~DummyServerSocketFactory() override {
62 BrowserThread::PostTask(
63 BrowserThread::UI, FROM_HERE, quit_closure_2_);
66 protected:
67 scoped_ptr<net::ServerSocket> CreateForHttpServer() override {
68 base::MessageLoopProxy::current()->PostTask(FROM_HERE,
69 base::Bind(&QuitFromHandlerThread, quit_closure_1_));
70 return scoped_ptr<net::ServerSocket>(new DummyServerSocket());
73 base::Closure quit_closure_1_;
74 base::Closure quit_closure_2_;
77 class FailingServerSocketFactory : public DummyServerSocketFactory {
78 public:
79 FailingServerSocketFactory(const base::Closure& quit_closure_1,
80 const base::Closure& quit_closure_2)
81 : DummyServerSocketFactory(quit_closure_1, quit_closure_2) {
84 private:
85 scoped_ptr<net::ServerSocket> CreateForHttpServer() override {
86 base::MessageLoopProxy::current()->PostTask(FROM_HERE,
87 base::Bind(&QuitFromHandlerThread, quit_closure_1_));
88 return scoped_ptr<net::ServerSocket>();
92 class DummyDelegate : public DevToolsHttpHandlerDelegate {
93 public:
94 std::string GetDiscoveryPageHTML() override { return std::string(); }
96 bool BundlesFrontendResources() override { return true; }
98 base::FilePath GetDebugFrontendDir() override { return base::FilePath(); }
103 class DevToolsHttpHandlerTest : public testing::Test {
104 public:
105 DevToolsHttpHandlerTest()
106 : ui_thread_(BrowserThread::UI, &message_loop_) {
109 protected:
110 void SetUp() override {
111 file_thread_.reset(new BrowserThreadImpl(BrowserThread::FILE));
112 file_thread_->Start();
115 void TearDown() override { file_thread_->Stop(); }
117 private:
118 base::MessageLoopForIO message_loop_;
119 BrowserThreadImpl ui_thread_;
120 scoped_ptr<BrowserThreadImpl> file_thread_;
123 TEST_F(DevToolsHttpHandlerTest, TestStartStop) {
124 base::RunLoop run_loop, run_loop_2;
125 scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(
126 new DummyServerSocketFactory(run_loop.QuitClosure(),
127 run_loop_2.QuitClosure()));
128 scoped_ptr<content::DevToolsHttpHandler> devtools_http_handler(
129 content::DevToolsHttpHandler::Start(factory.Pass(),
130 std::string(),
131 new DummyDelegate(),
132 base::FilePath()));
133 // Our dummy socket factory will post a quit message once the server will
134 // become ready.
135 run_loop.Run();
136 devtools_http_handler.reset();
137 // Make sure the handler actually stops.
138 run_loop_2.Run();
141 TEST_F(DevToolsHttpHandlerTest, TestServerSocketFailed) {
142 base::RunLoop run_loop, run_loop_2;
143 scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(
144 new FailingServerSocketFactory(run_loop.QuitClosure(),
145 run_loop_2.QuitClosure()));
146 scoped_ptr<content::DevToolsHttpHandler> devtools_http_handler(
147 content::DevToolsHttpHandler::Start(factory.Pass(),
148 std::string(),
149 new DummyDelegate(),
150 base::FilePath()));
151 // Our dummy socket factory will post a quit message once the server will
152 // become ready.
153 run_loop.Run();
154 for (int i = 0; i < 5; i++) {
155 RunAllPendingInMessageLoop(BrowserThread::UI);
156 RunAllPendingInMessageLoop(BrowserThread::FILE);
158 devtools_http_handler.reset();
159 // Make sure the handler actually stops.
160 run_loop_2.Run();
164 TEST_F(DevToolsHttpHandlerTest, TestDevToolsActivePort) {
165 base::RunLoop run_loop, run_loop_2;
166 base::ScopedTempDir temp_dir;
167 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
168 scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(
169 new DummyServerSocketFactory(run_loop.QuitClosure(),
170 run_loop_2.QuitClosure()));
171 scoped_ptr<content::DevToolsHttpHandler> devtools_http_handler(
172 content::DevToolsHttpHandler::Start(factory.Pass(),
173 std::string(),
174 new DummyDelegate(),
175 temp_dir.path()));
176 // Our dummy socket factory will post a quit message once the server will
177 // become ready.
178 run_loop.Run();
179 devtools_http_handler.reset();
180 // Make sure the handler actually stops.
181 run_loop_2.Run();
183 // Now make sure the DevToolsActivePort was written into the
184 // temporary directory and its contents are as expected.
185 base::FilePath active_port_file = temp_dir.path().Append(
186 kDevToolsActivePortFileName);
187 EXPECT_TRUE(base::PathExists(active_port_file));
188 std::string file_contents;
189 EXPECT_TRUE(base::ReadFileToString(active_port_file, &file_contents));
190 int port = 0;
191 EXPECT_TRUE(base::StringToInt(file_contents, &port));
192 EXPECT_EQ(static_cast<int>(kDummyPort), port);
195 } // namespace content