Home | History | Annotate | Download | only in local_discovery
      1 // Copyright 2013 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 "chrome/utility/local_discovery/service_discovery_client_impl.h"
      6 #include "net/dns/mdns_client_impl.h"
      7 #include "net/dns/mock_mdns_socket_factory.h"
      8 #include "testing/gmock/include/gmock/gmock.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 using ::testing::_;
     12 
     13 namespace local_discovery {
     14 
     15 namespace {
     16 
     17 const uint8 kSamplePacketA[] = {
     18   // Header
     19   0x00, 0x00,               // ID is zeroed out
     20   0x81, 0x80,               // Standard query response, RA, no error
     21   0x00, 0x00,               // No questions (for simplicity)
     22   0x00, 0x01,               // 1 RR (answers)
     23   0x00, 0x00,               // 0 authority RRs
     24   0x00, 0x00,               // 0 additional RRs
     25 
     26   0x07, 'm', 'y', 'h', 'e', 'l', 'l', 'o',
     27   0x05, 'l', 'o', 'c', 'a', 'l',
     28   0x00,
     29   0x00, 0x01,        // TYPE is A.
     30   0x00, 0x01,        // CLASS is IN.
     31   0x00, 0x00,        // TTL (4 bytes) is 16 seconds.
     32   0x00, 0x10,
     33   0x00, 0x04,        // RDLENGTH is 4 bytes.
     34   0x01, 0x02,
     35   0x03, 0x04,
     36 };
     37 
     38 const uint8 kSamplePacketAAAA[] = {
     39   // Header
     40   0x00, 0x00,               // ID is zeroed out
     41   0x81, 0x80,               // Standard query response, RA, no error
     42   0x00, 0x00,               // No questions (for simplicity)
     43   0x00, 0x01,               // 1 RR (answers)
     44   0x00, 0x00,               // 0 authority RRs
     45   0x00, 0x00,               // 0 additional RRs
     46 
     47   0x07, 'm', 'y', 'h', 'e', 'l', 'l', 'o',
     48   0x05, 'l', 'o', 'c', 'a', 'l',
     49   0x00,
     50   0x00, 0x1C,        // TYPE is AAAA.
     51   0x00, 0x01,        // CLASS is IN.
     52   0x00, 0x00,        // TTL (4 bytes) is 16 seconds.
     53   0x00, 0x10,
     54   0x00, 0x10,        // RDLENGTH is 4 bytes.
     55   0x00, 0x0A, 0x00, 0x00,
     56   0x00, 0x00, 0x00, 0x00,
     57   0x00, 0x01, 0x00, 0x02,
     58   0x00, 0x03, 0x00, 0x04,
     59 };
     60 
     61 class LocalDomainResolverTest : public testing::Test {
     62  public:
     63   LocalDomainResolverTest() : socket_factory_(new net::MockMDnsSocketFactory),
     64     mdns_client_(
     65         scoped_ptr<net::MDnsConnection::SocketFactory>(
     66             socket_factory_)) {
     67   }
     68 
     69   ~LocalDomainResolverTest() {
     70   }
     71 
     72   virtual void SetUp() OVERRIDE {
     73     mdns_client_.StartListening();
     74   }
     75 
     76   void AddressCallback(bool resolved, const net::IPAddressNumber& address) {
     77     if (address == net::IPAddressNumber()) {
     78       AddressCallbackInternal(resolved, "");
     79     } else {
     80       AddressCallbackInternal(resolved, net::IPAddressToString(address));
     81     }
     82   }
     83 
     84   void RunFor(base::TimeDelta time_period) {
     85     base::CancelableCallback<void()> callback(base::Bind(
     86         &base::MessageLoop::Quit,
     87         base::Unretained(base::MessageLoop::current())));
     88     base::MessageLoop::current()->PostDelayedTask(
     89         FROM_HERE, callback.callback(), time_period);
     90 
     91     base::MessageLoop::current()->Run();
     92     callback.Cancel();
     93   }
     94 
     95   MOCK_METHOD2(AddressCallbackInternal,
     96                void(bool resolved, std::string address));
     97 
     98   net::MockMDnsSocketFactory* socket_factory_;
     99   net::MDnsClientImpl mdns_client_;
    100   base::MessageLoop message_loop_;
    101 };
    102 
    103 TEST_F(LocalDomainResolverTest, ResolveDomainA) {
    104   LocalDomainResolverImpl resolver(
    105       "myhello.local", net::ADDRESS_FAMILY_IPV4,
    106       base::Bind(&LocalDomainResolverTest::AddressCallback,
    107                  base::Unretained(this)), &mdns_client_);
    108 
    109   EXPECT_CALL(*socket_factory_, OnSendTo(_))
    110       .Times(2);  // Twice per query
    111 
    112   resolver.Start();
    113 
    114   EXPECT_CALL(*this, AddressCallbackInternal(true, "1.2.3.4"));
    115 
    116   socket_factory_->SimulateReceive(
    117       kSamplePacketA, sizeof(kSamplePacketA));
    118 }
    119 
    120 TEST_F(LocalDomainResolverTest, ResolveDomainAAAA) {
    121   LocalDomainResolverImpl resolver(
    122       "myhello.local", net::ADDRESS_FAMILY_IPV6,
    123       base::Bind(&LocalDomainResolverTest::AddressCallback,
    124                  base::Unretained(this)), &mdns_client_);
    125 
    126   EXPECT_CALL(*socket_factory_, OnSendTo(_))
    127       .Times(2);  // Twice per query
    128 
    129   resolver.Start();
    130 
    131   EXPECT_CALL(*this, AddressCallbackInternal(true, "a::1:2:3:4"));
    132 
    133   socket_factory_->SimulateReceive(
    134       kSamplePacketAAAA, sizeof(kSamplePacketAAAA));
    135 }
    136 
    137 TEST_F(LocalDomainResolverTest, ResolveDomainAny) {
    138   LocalDomainResolverImpl resolver(
    139       "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED,
    140       base::Bind(&LocalDomainResolverTest::AddressCallback,
    141                  base::Unretained(this)), &mdns_client_);
    142 
    143   EXPECT_CALL(*socket_factory_, OnSendTo(_))
    144       .Times(4);  // Twice per query
    145 
    146   resolver.Start();
    147 
    148   EXPECT_CALL(*this, AddressCallbackInternal(true, "a::1:2:3:4"));
    149 
    150   socket_factory_->SimulateReceive(
    151       kSamplePacketAAAA, sizeof(kSamplePacketAAAA));
    152 }
    153 
    154 TEST_F(LocalDomainResolverTest, ResolveDomainNone) {
    155   LocalDomainResolverImpl resolver(
    156       "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED,
    157       base::Bind(&LocalDomainResolverTest::AddressCallback,
    158                  base::Unretained(this)), &mdns_client_);
    159 
    160   EXPECT_CALL(*socket_factory_, OnSendTo(_))
    161       .Times(4);  // Twice per query
    162 
    163   resolver.Start();
    164 
    165   EXPECT_CALL(*this, AddressCallbackInternal(false, ""));
    166 
    167   RunFor(base::TimeDelta::FromSeconds(4));
    168 }
    169 
    170 }  // namespace
    171 
    172 }  // namespace local_discovery
    173