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/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/stream_listen_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 using net::StreamListenSocket;
     27 
     28 class DummyListenSocket : public StreamListenSocket,
     29                           public StreamListenSocket::Delegate {
     30  public:
     31   DummyListenSocket()
     32       : StreamListenSocket(net::kInvalidSocket, this) {}
     33 
     34   // StreamListenSocket::Delegate "implementation"
     35   virtual void DidAccept(StreamListenSocket* server,
     36                          scoped_ptr<StreamListenSocket> connection) OVERRIDE {}
     37   virtual void DidRead(StreamListenSocket* connection,
     38                        const char* data,
     39                        int len) OVERRIDE {}
     40   virtual void DidClose(StreamListenSocket* sock) OVERRIDE {}
     41  protected:
     42   virtual ~DummyListenSocket() {}
     43   virtual void Accept() OVERRIDE {}
     44   virtual int GetLocalAddress(net::IPEndPoint* address) OVERRIDE {
     45     net::IPAddressNumber number;
     46     EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &number));
     47     *address = net::IPEndPoint(number, kDummyPort);
     48     return net::OK;
     49   }
     50 };
     51 
     52 class DummyListenSocketFactory : public net::StreamListenSocketFactory {
     53  public:
     54   DummyListenSocketFactory(
     55       base::Closure quit_closure_1, base::Closure quit_closure_2)
     56       : quit_closure_1_(quit_closure_1), quit_closure_2_(quit_closure_2) {}
     57   virtual ~DummyListenSocketFactory() {
     58     BrowserThread::PostTask(
     59         BrowserThread::UI, FROM_HERE, quit_closure_2_);
     60   }
     61 
     62   virtual scoped_ptr<StreamListenSocket> CreateAndListen(
     63       StreamListenSocket::Delegate* delegate) const OVERRIDE {
     64     BrowserThread::PostTask(
     65         BrowserThread::UI, FROM_HERE, quit_closure_1_);
     66     return scoped_ptr<net::StreamListenSocket>(new DummyListenSocket());
     67   }
     68  private:
     69   base::Closure quit_closure_1_;
     70   base::Closure quit_closure_2_;
     71 };
     72 
     73 class DummyDelegate : public DevToolsHttpHandlerDelegate {
     74  public:
     75   virtual std::string GetDiscoveryPageHTML() OVERRIDE { return std::string(); }
     76   virtual bool BundlesFrontendResources() OVERRIDE { return true; }
     77   virtual base::FilePath GetDebugFrontendDir() OVERRIDE {
     78     return base::FilePath();
     79   }
     80   virtual std::string GetPageThumbnailData(const GURL& url) OVERRIDE {
     81     return std::string();
     82   }
     83   virtual scoped_ptr<DevToolsTarget> CreateNewTarget(const GURL& url) OVERRIDE {
     84     return scoped_ptr<DevToolsTarget>();
     85   }
     86   virtual void EnumerateTargets(TargetCallback callback) OVERRIDE {
     87     callback.Run(TargetList());
     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  protected:
    104   virtual void SetUp() {
    105     file_thread_.reset(new BrowserThreadImpl(BrowserThread::FILE));
    106     file_thread_->Start();
    107   }
    108   virtual void TearDown() {
    109     file_thread_->Stop();
    110   }
    111  private:
    112   base::MessageLoopForIO message_loop_;
    113   BrowserThreadImpl ui_thread_;
    114   scoped_ptr<BrowserThreadImpl> file_thread_;
    115 };
    116 
    117 TEST_F(DevToolsHttpHandlerTest, TestStartStop) {
    118   base::RunLoop run_loop, run_loop_2;
    119   content::DevToolsHttpHandler* devtools_http_handler_ =
    120       content::DevToolsHttpHandler::Start(
    121           new DummyListenSocketFactory(run_loop.QuitClosure(),
    122                                        run_loop_2.QuitClosure()),
    123           std::string(),
    124           new DummyDelegate(),
    125           base::FilePath());
    126   // Our dummy socket factory will post a quit message once the server will
    127   // become ready.
    128   run_loop.Run();
    129   devtools_http_handler_->Stop();
    130   // Make sure the handler actually stops.
    131   run_loop_2.Run();
    132 }
    133 
    134 TEST_F(DevToolsHttpHandlerTest, TestDevToolsActivePort) {
    135   base::RunLoop run_loop, run_loop_2;
    136   base::ScopedTempDir temp_dir;
    137   EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
    138   content::DevToolsHttpHandler* devtools_http_handler_ =
    139       content::DevToolsHttpHandler::Start(
    140           new DummyListenSocketFactory(run_loop.QuitClosure(),
    141                                        run_loop_2.QuitClosure()),
    142           std::string(),
    143           new DummyDelegate(),
    144           temp_dir.path());
    145   // Our dummy socket factory will post a quit message once the server will
    146   // become ready.
    147   run_loop.Run();
    148   devtools_http_handler_->Stop();
    149   // Make sure the handler actually stops.
    150   run_loop_2.Run();
    151 
    152   // Now make sure the DevToolsActivePort was written into the
    153   // temporary directory and its contents are as expected.
    154   base::FilePath active_port_file = temp_dir.path().Append(
    155       kDevToolsActivePortFileName);
    156   EXPECT_TRUE(base::PathExists(active_port_file));
    157   std::string file_contents;
    158   EXPECT_TRUE(base::ReadFileToString(active_port_file, &file_contents));
    159   int port = 0;
    160   EXPECT_TRUE(base::StringToInt(file_contents, &port));
    161   EXPECT_EQ(kDummyPort, port);
    162 }
    163 
    164 }  // namespace content
    165