blob: a6fd3b3326f257a7187331019f4a1bc31e210d08 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/browser_thread_impl.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/devtools_http_handler_delegate.h"
#include "content/public/browser/devtools_target.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/socket/server_socket.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
const int kDummyPort = 4321;
const base::FilePath::CharType kDevToolsActivePortFileName[] =
FILE_PATH_LITERAL("DevToolsActivePort");
class DummyServerSocket : public net::ServerSocket {
public:
DummyServerSocket() {}
// net::ServerSocket "implementation"
int Listen(const net::IPEndPoint& address, int backlog) override {
return net::OK;
}
int ListenWithAddressAndPort(const std::string& ip_address,
int port,
int backlog) override {
return net::OK;
}
int GetLocalAddress(net::IPEndPoint* address) const override {
net::IPAddressNumber number;
EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &number));
*address = net::IPEndPoint(number, kDummyPort);
return net::OK;
}
int Accept(scoped_ptr<net::StreamSocket>* socket,
const net::CompletionCallback& callback) override {
return net::ERR_IO_PENDING;
}
};
class DummyServerSocketFactory
: public DevToolsHttpHandler::ServerSocketFactory {
public:
DummyServerSocketFactory(base::Closure quit_closure_1,
base::Closure quit_closure_2)
: DevToolsHttpHandler::ServerSocketFactory("", 0, 0),
quit_closure_1_(quit_closure_1),
quit_closure_2_(quit_closure_2) {}
~DummyServerSocketFactory() override {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, quit_closure_2_);
}
private:
scoped_ptr<net::ServerSocket> Create() const override {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, quit_closure_1_);
return scoped_ptr<net::ServerSocket>(new DummyServerSocket());
}
base::Closure quit_closure_1_;
base::Closure quit_closure_2_;
};
class DummyDelegate : public DevToolsHttpHandlerDelegate {
public:
std::string GetDiscoveryPageHTML() override { return std::string(); }
bool BundlesFrontendResources() override { return true; }
base::FilePath GetDebugFrontendDir() override { return base::FilePath(); }
scoped_ptr<net::StreamListenSocket> CreateSocketForTethering(
net::StreamListenSocket::Delegate* delegate,
std::string* name) override {
return scoped_ptr<net::StreamListenSocket>();
}
};
}
class DevToolsHttpHandlerTest : public testing::Test {
public:
DevToolsHttpHandlerTest()
: ui_thread_(BrowserThread::UI, &message_loop_) {
}
protected:
virtual void SetUp() {
file_thread_.reset(new BrowserThreadImpl(BrowserThread::FILE));
file_thread_->Start();
}
virtual void TearDown() {
file_thread_->Stop();
}
private:
base::MessageLoopForIO message_loop_;
BrowserThreadImpl ui_thread_;
scoped_ptr<BrowserThreadImpl> file_thread_;
};
TEST_F(DevToolsHttpHandlerTest, TestStartStop) {
base::RunLoop run_loop, run_loop_2;
scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(
new DummyServerSocketFactory(run_loop.QuitClosure(),
run_loop_2.QuitClosure()));
content::DevToolsHttpHandler* devtools_http_handler_ =
content::DevToolsHttpHandler::Start(factory.Pass(),
std::string(),
new DummyDelegate(),
base::FilePath());
// Our dummy socket factory will post a quit message once the server will
// become ready.
run_loop.Run();
devtools_http_handler_->Stop();
// Make sure the handler actually stops.
run_loop_2.Run();
}
TEST_F(DevToolsHttpHandlerTest, TestDevToolsActivePort) {
base::RunLoop run_loop, run_loop_2;
base::ScopedTempDir temp_dir;
EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(
new DummyServerSocketFactory(run_loop.QuitClosure(),
run_loop_2.QuitClosure()));
content::DevToolsHttpHandler* devtools_http_handler_ =
content::DevToolsHttpHandler::Start(factory.Pass(),
std::string(),
new DummyDelegate(),
temp_dir.path());
// Our dummy socket factory will post a quit message once the server will
// become ready.
run_loop.Run();
devtools_http_handler_->Stop();
// Make sure the handler actually stops.
run_loop_2.Run();
// Now make sure the DevToolsActivePort was written into the
// temporary directory and its contents are as expected.
base::FilePath active_port_file = temp_dir.path().Append(
kDevToolsActivePortFileName);
EXPECT_TRUE(base::PathExists(active_port_file));
std::string file_contents;
EXPECT_TRUE(base::ReadFileToString(active_port_file, &file_contents));
int port = 0;
EXPECT_TRUE(base::StringToInt(file_contents, &port));
EXPECT_EQ(kDummyPort, port);
}
} // namespace content