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 "base/bind.h"
      6 #include "chrome/browser/local_discovery/privet_device_lister_impl.h"
      7 #include "testing/gmock/include/gmock/gmock.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 using testing::SaveArg;
     11 using testing::_;
     12 
     13 namespace local_discovery {
     14 
     15 namespace {
     16 
     17 class MockServiceResolver;
     18 class MockServiceWatcher;
     19 
     20 class ServiceDiscoveryMockDelegate {
     21  public:
     22   virtual void ServiceWatcherStarted(const std::string& service_type,
     23                                      MockServiceWatcher* watcher) = 0;
     24   virtual void ServiceResolverStarted(const std::string& service_type,
     25                                       MockServiceResolver* resolver) = 0;
     26 };
     27 
     28 class MockServiceWatcher : public ServiceWatcher {
     29  public:
     30   MockServiceWatcher(const std::string& service_type,
     31                      const ServiceWatcher::UpdatedCallback& callback,
     32                      ServiceDiscoveryMockDelegate* mock_delegate)
     33       : started_(false), service_type_(service_type),  callback_(callback),
     34         mock_delegate_(mock_delegate) {
     35   }
     36 
     37   virtual ~MockServiceWatcher() {
     38   }
     39 
     40   virtual void Start() {
     41     DCHECK(!started_);
     42     started_ = true;
     43     mock_delegate_->ServiceWatcherStarted(service_type_, this);
     44   }
     45 
     46   MOCK_METHOD1(DiscoverNewServices, void(bool force_update));
     47 
     48   MOCK_METHOD1(SetActivelyRefreshServices, void(
     49       bool actively_refresh_services));
     50 
     51   virtual std::string GetServiceType() const {
     52     return service_type_;
     53   }
     54 
     55   bool started() {
     56     return started_;
     57   }
     58 
     59   ServiceWatcher::UpdatedCallback callback() {
     60     return callback_;
     61   }
     62 
     63  private:
     64   bool started_;
     65   std::string service_type_;
     66   ServiceWatcher::UpdatedCallback callback_;
     67   ServiceDiscoveryMockDelegate* mock_delegate_;
     68 };
     69 
     70 class MockServiceResolver : public ServiceResolver {
     71  public:
     72   MockServiceResolver(const std::string& service_name,
     73                       const ServiceResolver::ResolveCompleteCallback& callback,
     74                       ServiceDiscoveryMockDelegate* mock_delegate)
     75       : started_resolving_(false), service_name_(service_name),
     76         callback_(callback), mock_delegate_(mock_delegate) {
     77   }
     78 
     79   virtual ~MockServiceResolver() {
     80   }
     81 
     82   virtual void StartResolving() OVERRIDE {
     83     started_resolving_ = true;
     84     mock_delegate_->ServiceResolverStarted(service_name_, this);
     85   }
     86 
     87   bool IsResolving() const {
     88     return started_resolving_;
     89   }
     90 
     91   virtual std::string GetName() const OVERRIDE {
     92     return service_name_;
     93   }
     94 
     95   const ServiceResolver::ResolveCompleteCallback& callback() {
     96     return callback_; }
     97 
     98  private:
     99   bool started_resolving_;
    100   std::string service_name_;
    101   ServiceResolver::ResolveCompleteCallback callback_;
    102   ServiceDiscoveryMockDelegate* mock_delegate_;
    103 };
    104 
    105 class MockServiceDiscoveryClient : public ServiceDiscoveryClient {
    106  public:
    107   explicit MockServiceDiscoveryClient(
    108       ServiceDiscoveryMockDelegate* mock_delegate)
    109       : mock_delegate_(mock_delegate) {
    110   }
    111 
    112   virtual ~MockServiceDiscoveryClient() {
    113   }
    114 
    115   // Create a service watcher object listening for DNS-SD service announcements
    116   // on service type |service_type|.
    117   virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher(
    118       const std::string& service_type,
    119       const ServiceWatcher::UpdatedCallback& callback) OVERRIDE {
    120     scoped_ptr<MockServiceWatcher> mock_service_watcher(
    121         new MockServiceWatcher(service_type, callback, mock_delegate_));
    122     return mock_service_watcher.PassAs<ServiceWatcher>();
    123   }
    124 
    125   // Create a service resolver object for getting detailed service information
    126   // for the service called |service_name|.
    127   virtual scoped_ptr<ServiceResolver> CreateServiceResolver(
    128       const std::string& service_name,
    129       const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE {
    130     scoped_ptr<MockServiceResolver> mock_service_resolver(
    131         new MockServiceResolver(service_name, callback, mock_delegate_));
    132     return mock_service_resolver.PassAs<ServiceResolver>();
    133   }
    134 
    135   // Not used in this test.
    136   virtual scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver(
    137     const std::string& domain,
    138     net::AddressFamily address_family,
    139     const LocalDomainResolver::IPAddressCallback& callback) OVERRIDE {
    140     NOTREACHED();
    141     return scoped_ptr<LocalDomainResolver>();
    142   }
    143 
    144  private:
    145   ServiceDiscoveryMockDelegate* mock_delegate_;
    146 };
    147 
    148 class MockServiceDiscoveryMockDelegate : public ServiceDiscoveryMockDelegate {
    149  public:
    150   MOCK_METHOD2(ServiceWatcherStarted, void(const std::string& service_type,
    151                                            MockServiceWatcher* watcher));
    152   MOCK_METHOD2(ServiceResolverStarted, void(const std::string& service_type,
    153                                             MockServiceResolver* resolver));
    154 };
    155 
    156 class MockDeviceListerDelegate : public PrivetDeviceLister::Delegate {
    157  public:
    158   MockDeviceListerDelegate() {
    159   }
    160 
    161   virtual ~MockDeviceListerDelegate() {
    162   }
    163 
    164   MOCK_METHOD3(DeviceChanged, void(bool added,
    165                                    const std::string& name,
    166                                    const DeviceDescription& description));
    167 
    168   MOCK_METHOD1(DeviceRemoved, void(const std::string& name));
    169 
    170   MOCK_METHOD0(DeviceCacheFlushed, void());
    171 };
    172 
    173 class PrivetDeviceListerTest : public testing::Test {
    174  public:
    175   PrivetDeviceListerTest() : mock_client_(&mock_delegate_) {
    176   }
    177 
    178   virtual ~PrivetDeviceListerTest() {
    179   }
    180 
    181   virtual void SetUp() OVERRIDE {
    182     example_attrs_.push_back("tXtvers=1");
    183     example_attrs_.push_back("ty=My Printer");
    184     example_attrs_.push_back("nOte=This is my Printer");
    185     example_attrs_.push_back("CS=ONlInE");
    186     example_attrs_.push_back("id=");
    187 
    188     service_description_.service_name = "myprinter._privet._tcp.local";
    189     service_description_.address = net::HostPortPair("myprinter.local", 6006);
    190     service_description_.metadata = example_attrs_;
    191     service_description_.last_seen = base::Time() +
    192         base::TimeDelta::FromSeconds(5);
    193     service_description_.ip_address.push_back(1);
    194     service_description_.ip_address.push_back(2);
    195     service_description_.ip_address.push_back(3);
    196     service_description_.ip_address.push_back(4);
    197   }
    198 
    199  protected:
    200   testing::StrictMock<MockServiceDiscoveryMockDelegate> mock_delegate_;
    201   MockServiceDiscoveryClient mock_client_;
    202   MockDeviceListerDelegate delegate_;
    203   std::vector<std::string> example_attrs_;
    204   ServiceDescription service_description_;
    205 };
    206 
    207 TEST_F(PrivetDeviceListerTest, SimpleUpdateTest) {
    208   DeviceDescription outgoing_description;
    209 
    210   MockServiceWatcher* service_watcher;
    211   MockServiceResolver* service_resolver;
    212 
    213   EXPECT_CALL(mock_delegate_,
    214               ServiceWatcherStarted("_privet._tcp.local", _))
    215       .WillOnce(SaveArg<1>(&service_watcher));
    216   PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
    217   privet_lister.Start();
    218   testing::Mock::VerifyAndClear(&mock_delegate_);
    219 
    220   EXPECT_CALL(mock_delegate_,
    221               ServiceResolverStarted("myprinter._privet._tcp.local", _))
    222       .WillOnce(SaveArg<1>(&service_resolver));
    223   service_watcher->callback().Run(ServiceWatcher::UPDATE_ADDED,
    224                                   "myprinter._privet._tcp.local");
    225   testing::Mock::VerifyAndClear(&mock_delegate_);
    226 
    227   EXPECT_CALL(delegate_, DeviceChanged(true,
    228                                        "myprinter._privet._tcp.local",
    229                                        _))
    230               .WillOnce(SaveArg<2>(&outgoing_description));
    231 
    232   service_resolver->callback().Run(ServiceResolver::STATUS_SUCCESS,
    233                                    service_description_);
    234 
    235   EXPECT_EQ(service_description_.address.host(),
    236             outgoing_description.address.host());
    237   EXPECT_EQ(service_description_.address.port(),
    238             outgoing_description.address.port());
    239   EXPECT_EQ(service_description_.ip_address, outgoing_description.ip_address);
    240   EXPECT_EQ(service_description_.last_seen, outgoing_description.last_seen);
    241   EXPECT_EQ("My Printer", outgoing_description.name);
    242   EXPECT_EQ("This is my Printer", outgoing_description.description);
    243   EXPECT_EQ("", outgoing_description.id);
    244   EXPECT_EQ(DeviceDescription::ONLINE, outgoing_description.connection_state);
    245 
    246   EXPECT_CALL(delegate_, DeviceRemoved("myprinter._privet._tcp.local"));
    247 
    248   service_watcher->callback().Run(ServiceWatcher::UPDATE_REMOVED,
    249                                   "myprinter._privet._tcp.local");
    250 }
    251 
    252 TEST_F(PrivetDeviceListerTest, MultipleUpdatesPostResolve) {
    253   MockServiceWatcher* service_watcher;
    254   MockServiceResolver* service_resolver;
    255 
    256   EXPECT_CALL(mock_delegate_,
    257               ServiceWatcherStarted("_privet._tcp.local", _))
    258       .WillOnce(SaveArg<1>(&service_watcher));
    259   PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
    260   privet_lister.Start();
    261   testing::Mock::VerifyAndClear(&mock_delegate_);
    262 
    263   EXPECT_CALL(mock_delegate_,
    264               ServiceResolverStarted("myprinter._privet._tcp.local", _))
    265       .WillOnce(SaveArg<1>(&service_resolver));
    266 
    267   service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
    268                                   "myprinter._privet._tcp.local");
    269   testing::Mock::VerifyAndClear(&mock_delegate_);
    270 
    271   EXPECT_CALL(delegate_, DeviceChanged(false,
    272                                        "myprinter._privet._tcp.local",
    273                                        _));
    274   service_resolver->callback().Run(ServiceResolver::STATUS_SUCCESS,
    275                                    service_description_);
    276 
    277   EXPECT_CALL(mock_delegate_,
    278               ServiceResolverStarted("myprinter._privet._tcp.local", _));
    279   service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
    280                                   "myprinter._privet._tcp.local");
    281   testing::Mock::VerifyAndClear(&mock_delegate_);
    282 }
    283 
    284 // Check that the device lister does not create a still-working resolver
    285 TEST_F(PrivetDeviceListerTest, MultipleUpdatesPreResolve) {
    286   MockServiceWatcher* service_watcher;
    287 
    288   EXPECT_CALL(mock_delegate_,
    289               ServiceWatcherStarted("_privet._tcp.local", _))
    290       .WillOnce(SaveArg<1>(&service_watcher));
    291   PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
    292   privet_lister.Start();
    293   testing::Mock::VerifyAndClear(&mock_delegate_);
    294 
    295   EXPECT_CALL(mock_delegate_,
    296               ServiceResolverStarted("myprinter._privet._tcp.local", _))
    297       .Times(1);
    298   service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
    299                                   "myprinter._privet._tcp.local");
    300   service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
    301                                   "myprinter._privet._tcp.local");
    302 }
    303 
    304 TEST_F(PrivetDeviceListerTest, DiscoverNewDevices) {
    305   MockServiceWatcher* service_watcher;
    306 
    307   EXPECT_CALL(mock_delegate_,
    308               ServiceWatcherStarted("_privet._tcp.local", _))
    309       .WillOnce(SaveArg<1>(&service_watcher));
    310   PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
    311   privet_lister.Start();
    312   testing::Mock::VerifyAndClear(&mock_delegate_);
    313 
    314   EXPECT_CALL(*service_watcher, DiscoverNewServices(false));
    315   privet_lister.DiscoverNewDevices(false);
    316 }
    317 
    318 
    319 }  // namespace
    320 
    321 }  // namespace local_discovery
    322