Home | History | Annotate | Download | only in devtools
      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.
      4 
      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 "net/base/ip_endpoint.h"
     15 #include "net/base/net_errors.h"
     16 #include "net/socket/server_socket.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace content {
     20 namespace {
     21 
     22 const int kDummyPort = 4321;
     23 const base::FilePath::CharType kDevToolsActivePortFileName[] =
     24     FILE_PATH_LITERAL("DevToolsActivePort");
     25 
     26 class DummyServerSocket : public net::ServerSocket {
     27  public:
     28   DummyServerSocket() {}
     29 
     30   // net::ServerSocket "implementation"
     31   virtual int Listen(const net::IPEndPoint& address, int backlog) OVERRIDE {
     32     return net::OK;
     33   }
     34 
     35   virtual int ListenWithAddressAndPort(const std::string& ip_address,
     36                                        int port,
     37                                        int backlog) OVERRIDE {
     38     return net::OK;
     39   }
     40 
     41   virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE {
     42     net::IPAddressNumber number;
     43     EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &number));
     44     *address = net::IPEndPoint(number, kDummyPort);
     45     return net::OK;
     46   }
     47 
     48   virtual int Accept(scoped_ptr<net::StreamSocket>* socket,
     49                      const net::CompletionCallback& callback) OVERRIDE {
     50     return net::ERR_IO_PENDING;
     51   }
     52 };
     53 
     54 class DummyServerSocketFactory
     55     : public DevToolsHttpHandler::ServerSocketFactory {
     56  public:
     57   DummyServerSocketFactory(base::Closure quit_closure_1,
     58                            base::Closure quit_closure_2)
     59       : DevToolsHttpHandler::ServerSocketFactory("", 0, 0),
     60         quit_closure_1_(quit_closure_1),
     61         quit_closure_2_(quit_closure_2) {}
     62 
     63   virtual ~DummyServerSocketFactory() {
     64     BrowserThread::PostTask(
     65         BrowserThread::UI, FROM_HERE, quit_closure_2_);
     66   }
     67 
     68  private:
     69   virtual scoped_ptr<net::ServerSocket> Create() const OVERRIDE {
     70     BrowserThread::PostTask(
     71         BrowserThread::UI, FROM_HERE, quit_closure_1_);
     72     return scoped_ptr<net::ServerSocket>(new DummyServerSocket());
     73   }
     74 
     75   base::Closure quit_closure_1_;
     76   base::Closure quit_closure_2_;
     77 };
     78 
     79 class DummyDelegate : public DevToolsHttpHandlerDelegate {
     80  public:
     81   virtual std::string GetDiscoveryPageHTML() OVERRIDE { return std::string(); }
     82 
     83   virtual bool BundlesFrontendResources() OVERRIDE { return true; }
     84 
     85   virtual base::FilePath GetDebugFrontendDir() OVERRIDE {
     86     return base::FilePath();
     87   }
     88 
     89   virtual scoped_ptr<net::StreamListenSocket> CreateSocketForTethering(
     90       net::StreamListenSocket::Delegate* delegate,
     91       std::string* name) OVERRIDE {
     92     return scoped_ptr<net::StreamListenSocket>();
     93   }
     94 };
     95 
     96 }
     97 
     98 class DevToolsHttpHandlerTest : public testing::Test {
     99  public:
    100   DevToolsHttpHandlerTest()
    101       : ui_thread_(BrowserThread::UI, &message_loop_) {
    102   }
    103 
    104  protected:
    105   virtual void SetUp() {
    106     file_thread_.reset(new BrowserThreadImpl(BrowserThread::FILE));
    107     file_thread_->Start();
    108   }
    109 
    110   virtual void TearDown() {
    111     file_thread_->Stop();
    112   }
    113 
    114  private:
    115   base::MessageLoopForIO message_loop_;
    116   BrowserThreadImpl ui_thread_;
    117   scoped_ptr<BrowserThreadImpl> file_thread_;
    118 };
    119 
    120 TEST_F(DevToolsHttpHandlerTest, TestStartStop) {
    121   base::RunLoop run_loop, run_loop_2;
    122   scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(
    123       new DummyServerSocketFactory(run_loop.QuitClosure(),
    124                                    run_loop_2.QuitClosure()));
    125   content::DevToolsHttpHandler* devtools_http_handler_ =
    126       content::DevToolsHttpHandler::Start(factory.Pass(),
    127                                           std::string(),
    128                                           new DummyDelegate(),
    129                                           base::FilePath());
    130   // Our dummy socket factory will post a quit message once the server will
    131   // become ready.
    132   run_loop.Run();
    133   devtools_http_handler_->Stop();
    134   // Make sure the handler actually stops.
    135   run_loop_2.Run();
    136 }
    137 
    138 TEST_F(DevToolsHttpHandlerTest, TestDevToolsActivePort) {
    139   base::RunLoop run_loop, run_loop_2;
    140   base::ScopedTempDir temp_dir;
    141   EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
    142   scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(
    143       new DummyServerSocketFactory(run_loop.QuitClosure(),
    144                                    run_loop_2.QuitClosure()));
    145   content::DevToolsHttpHandler* devtools_http_handler_ =
    146       content::DevToolsHttpHandler::Start(factory.Pass(),
    147                                           std::string(),
    148                                           new DummyDelegate(),
    149                                           temp_dir.path());
    150   // Our dummy socket factory will post a quit message once the server will
    151   // become ready.
    152   run_loop.Run();
    153   devtools_http_handler_->Stop();
    154   // Make sure the handler actually stops.
    155   run_loop_2.Run();
    156 
    157   // Now make sure the DevToolsActivePort was written into the
    158   // temporary directory and its contents are as expected.
    159   base::FilePath active_port_file = temp_dir.path().Append(
    160       kDevToolsActivePortFileName);
    161   EXPECT_TRUE(base::PathExists(active_port_file));
    162   std::string file_contents;
    163   EXPECT_TRUE(base::ReadFileToString(active_port_file, &file_contents));
    164   int port = 0;
    165   EXPECT_TRUE(base::StringToInt(file_contents, &port));
    166   EXPECT_EQ(kDummyPort, port);
    167 }
    168 
    169 }  // namespace content
    170