Home | History | Annotate | Download | only in dial
      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/memory/ref_counted.h"
      6 #include "base/message_loop/message_loop.h"
      7 #include "chrome/browser/extensions/api/dial/dial_device_data.h"
      8 #include "chrome/browser/extensions/api/dial/dial_service.h"
      9 #include "net/base/capturing_net_log.h"
     10 #include "net/base/ip_endpoint.h"
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 using base::Time;
     15 using base::TimeDelta;
     16 using ::testing::A;
     17 using ::testing::AtLeast;
     18 using ::testing::Return;
     19 
     20 namespace {
     21 
     22 const char kValidResponse[] =
     23   "HTTP/1.1 OK\r\n"
     24   "LOCATION: http://127.0.0.1/dd.xml\r\n"
     25   "USN: some_id\r\n"
     26   "CACHE-CONTROL: max-age=1800\r\n"
     27   "CONFIGID.UPNP.ORG: 1\r\n\r\n";
     28 
     29 }  // namespace
     30 
     31 namespace extensions {
     32 
     33 class MockObserver : public DialService::Observer {
     34  public:
     35   MOCK_METHOD1(OnDiscoveryRequest, void(DialService*));
     36   MOCK_METHOD2(OnDeviceDiscovered, void(DialService*, const DialDeviceData&));
     37   MOCK_METHOD1(OnDiscoveryFinished, void(DialService*));
     38   MOCK_METHOD2(OnError, void(DialService*,
     39                              const DialService::DialServiceErrorCode&));
     40 };
     41 
     42 class DialServiceTest : public testing::Test {
     43  public:
     44   DialServiceTest() : dial_service_(&capturing_net_log_) {
     45     CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &mock_ip_));
     46     dial_service_.AddObserver(&mock_observer_);
     47   }
     48  protected:
     49   net::CapturingNetLog capturing_net_log_;
     50   net::IPAddressNumber mock_ip_;
     51   DialServiceImpl dial_service_;
     52   MockObserver mock_observer_;
     53 };
     54 
     55 TEST_F(DialServiceTest, TestSendMultipleRequests) {
     56   base::MessageLoop loop(base::MessageLoop::TYPE_IO);
     57   // Setting the finish delay to zero disables the timer that invokes
     58   // FinishDiscovery().
     59   dial_service_.finish_delay_ = TimeDelta::FromSeconds(0);
     60   dial_service_.request_interval_ = TimeDelta::FromSeconds(0);
     61   dial_service_.max_requests_ = 4;
     62   dial_service_.discovery_active_ = true;
     63   EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(4);
     64   EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
     65   dial_service_.BindSocketAndSendRequest(mock_ip_);
     66   loop.RunUntilIdle();
     67   dial_service_.FinishDiscovery();
     68 }
     69 
     70 TEST_F(DialServiceTest, TestOnDiscoveryRequest) {
     71   dial_service_.discovery_active_ = true;
     72   dial_service_.num_requests_sent_ = 1;
     73   dial_service_.max_requests_ = 1;
     74   size_t num_bytes = dial_service_.send_buffer_->size();
     75   EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(1);
     76   dial_service_.OnSocketWrite(num_bytes);
     77 }
     78 
     79 TEST_F(DialServiceTest, TestOnDeviceDiscovered) {
     80   dial_service_.discovery_active_ = true;
     81   int response_size = arraysize(kValidResponse) - 1;
     82   dial_service_.recv_buffer_ = new net::IOBufferWithSize(response_size);
     83   strncpy(dial_service_.recv_buffer_->data(), kValidResponse, response_size);
     84   dial_service_.recv_address_ = net::IPEndPoint(mock_ip_, 12345);
     85 
     86   DialDeviceData expected_device;
     87   expected_device.set_device_id("some_id");
     88 
     89   EXPECT_CALL(mock_observer_,
     90               OnDeviceDiscovered(A<DialService*>(), expected_device))
     91       .Times(1);
     92   dial_service_.OnSocketRead(response_size);
     93 };
     94 
     95 TEST_F(DialServiceTest, TestOnDiscoveryFinished) {
     96   dial_service_.discovery_active_ = true;
     97 
     98   EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
     99   dial_service_.FinishDiscovery();
    100   EXPECT_FALSE(dial_service_.discovery_active_);
    101 }
    102 
    103 TEST_F(DialServiceTest, TestResponseParsing) {
    104   Time now = Time::Now();
    105 
    106   // Successful case
    107   DialDeviceData parsed;
    108   EXPECT_TRUE(DialServiceImpl::ParseResponse(kValidResponse,
    109                                              now, &parsed));
    110   EXPECT_EQ("some_id", parsed.device_id());
    111   EXPECT_EQ("http://127.0.0.1/dd.xml", parsed.device_description_url().spec());
    112   EXPECT_EQ(1, parsed.config_id());
    113   EXPECT_EQ(now, parsed.response_time());
    114 
    115   // Failure cases
    116   DialDeviceData not_parsed;
    117 
    118   // Empty, garbage
    119   EXPECT_FALSE(DialServiceImpl::ParseResponse(std::string(), now, &not_parsed));
    120   EXPECT_FALSE(DialServiceImpl::ParseResponse(
    121     "\r\n\r\n",
    122     now, &not_parsed));
    123   EXPECT_FALSE(DialServiceImpl::ParseResponse(
    124     "xyzzy",
    125     now, &not_parsed));
    126 
    127   // No headers
    128   EXPECT_FALSE(DialServiceImpl::ParseResponse(
    129     "HTTP/1.1 OK\r\n\r\n",
    130     now, &not_parsed));
    131 
    132   // Missing LOCATION
    133   EXPECT_FALSE(DialServiceImpl::ParseResponse(
    134     "HTTP/1.1 OK\r\n"
    135     "USN: some_id\r\n\r\n",
    136     now, &not_parsed));
    137 
    138   // Empty LOCATION
    139   EXPECT_FALSE(DialServiceImpl::ParseResponse(
    140     "HTTP/1.1 OK\r\n"
    141     "LOCATION:\r\n"
    142     "USN: some_id\r\n\r\n",
    143     now, &not_parsed));
    144 
    145   // Missing USN
    146   EXPECT_FALSE(DialServiceImpl::ParseResponse(
    147     "HTTP/1.1 OK\r\n"
    148     "LOCATION: http://127.0.0.1/dd.xml\r\n\r\n",
    149     now, &not_parsed));
    150 
    151   // Empty USN
    152   EXPECT_FALSE(DialServiceImpl::ParseResponse(
    153     "HTTP/1.1 OK\r\n"
    154     "LOCATION: http://127.0.0.1/dd.xml\r\n"
    155     "USN:\r\n\r\n",
    156     now, &not_parsed));
    157 }
    158 
    159 }  // namespace extensions
    160