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/browser/extensions/api/mdns/dns_sd_registry.h" 6 #include "chrome/browser/extensions/api/mdns/dns_sd_delegate.h" 7 #include "chrome/browser/extensions/api/mdns/dns_sd_device_lister.h" 8 #include "testing/gmock/include/gmock/gmock.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 namespace extensions { 12 13 class MockDnsSdDeviceLister : public DnsSdDeviceLister { 14 public: 15 MockDnsSdDeviceLister() : DnsSdDeviceLister(NULL, NULL, "") {} 16 virtual ~MockDnsSdDeviceLister() {} 17 18 virtual void Discover(bool force_update) OVERRIDE {} 19 }; 20 21 class TestDnsSdRegistry : public DnsSdRegistry { 22 public: 23 TestDnsSdRegistry() : DnsSdRegistry(NULL), delegate_(NULL) {} 24 virtual ~TestDnsSdRegistry() {} 25 26 MockDnsSdDeviceLister* GetListerForService(const std::string& service_type) { 27 return listers_[service_type]; 28 } 29 30 int GetServiceListenerCount(const std::string& service_type) { 31 if (service_data_map_.find(service_type) == service_data_map_.end()) 32 return 0; 33 34 return service_data_map_[service_type].get()->GetListenerCount(); 35 } 36 37 DnsSdDelegate* GetDelegate() { 38 return delegate_; 39 } 40 41 protected: 42 virtual DnsSdDeviceLister* CreateDnsSdDeviceLister( 43 DnsSdDelegate* delegate, 44 const std::string& service_type, 45 local_discovery::ServiceDiscoverySharedClient* discovery_client) 46 OVERRIDE { 47 delegate_ = delegate; 48 MockDnsSdDeviceLister* lister = new MockDnsSdDeviceLister(); 49 listers_[service_type] = lister; 50 return lister; 51 }; 52 53 private: 54 std::map<std::string, MockDnsSdDeviceLister*> listers_; 55 // The last delegate used or NULL. 56 DnsSdDelegate* delegate_; 57 }; 58 59 class MockDnsSdObserver : public DnsSdRegistry::DnsSdObserver { 60 public: 61 MOCK_METHOD2(OnDnsSdEvent, void(const std::string&, 62 const DnsSdRegistry::DnsSdServiceList&)); 63 }; 64 65 class DnsSdRegistryTest : public testing::Test { 66 public: 67 DnsSdRegistryTest() {} 68 virtual ~DnsSdRegistryTest() {} 69 70 virtual void SetUp() OVERRIDE { 71 registry_.reset(new TestDnsSdRegistry()); 72 registry_->AddObserver(&observer_); 73 } 74 75 protected: 76 scoped_ptr<TestDnsSdRegistry> registry_; 77 MockDnsSdObserver observer_; 78 }; 79 80 // Tests registering 2 listeners and removing one. The device lister should 81 // not be destroyed. 82 TEST_F(DnsSdRegistryTest, RegisterUnregisterListeners) { 83 const std::string service_type = "_testing._tcp.local"; 84 85 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, 86 DnsSdRegistry::DnsSdServiceList())).Times(2); 87 88 registry_->RegisterDnsSdListener(service_type); 89 registry_->RegisterDnsSdListener(service_type); 90 registry_->UnregisterDnsSdListener(service_type); 91 EXPECT_EQ(1, registry_->GetServiceListenerCount(service_type)); 92 93 registry_->UnregisterDnsSdListener(service_type); 94 EXPECT_EQ(0, registry_->GetServiceListenerCount(service_type)); 95 } 96 97 // Tests registering a listener and receiving an added and updated event. 98 TEST_F(DnsSdRegistryTest, AddAndUpdate) { 99 const std::string service_type = "_testing._tcp.local"; 100 const std::string ip_address1 = "192.168.0.100"; 101 const std::string ip_address2 = "192.168.0.101"; 102 103 DnsSdService service; 104 service.service_name = "_myDevice." + service_type; 105 service.ip_address = ip_address1; 106 107 DnsSdRegistry::DnsSdServiceList service_list; 108 109 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 110 111 // Add first service. 112 service_list.push_back(service); 113 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 114 115 // Clear services and add same one with different IP address. 116 service_list.clear(); 117 service.ip_address = ip_address2; 118 service_list.push_back(service); 119 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 120 121 registry_->RegisterDnsSdListener(service_type); 122 service.ip_address = ip_address1; 123 registry_->GetDelegate()->ServiceChanged(service_type, true, service); 124 service.ip_address = ip_address2; 125 registry_->GetDelegate()->ServiceChanged(service_type, false, service); 126 } 127 128 // Tests registering a listener and receiving an added and removed event. 129 TEST_F(DnsSdRegistryTest, AddAndRemove) { 130 const std::string service_type = "_testing._tcp.local"; 131 132 DnsSdService service; 133 service.service_name = "_myDevice." + service_type; 134 service.ip_address = "192.168.0.100"; 135 136 DnsSdRegistry::DnsSdServiceList service_list; 137 // Expect to be called twice with empty list (once on register, once after 138 // removing). 139 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)).Times(2); 140 service_list.push_back(service); 141 // Expect to be called twice with 1 item (once after adding, once after adding 142 // again after removal). 143 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)).Times(2); 144 145 registry_->RegisterDnsSdListener(service_type); 146 registry_->GetDelegate()->ServiceChanged(service_type, true, service); 147 registry_->GetDelegate()->ServiceRemoved(service_type, service.service_name); 148 registry_->GetDelegate()->ServiceChanged(service_type, true, service); 149 } 150 151 // Tests adding multiple services. 152 TEST_F(DnsSdRegistryTest, AddMultipleServices) { 153 const std::string service_type = "_testing._tcp.local"; 154 155 DnsSdService service; 156 service.service_name = "_myDevice." + service_type; 157 service.ip_address = "192.168.0.100"; 158 159 DnsSdService service2; 160 service.service_name = "_myDevice2." + service_type; 161 service.ip_address = "192.168.0.101"; 162 163 DnsSdRegistry::DnsSdServiceList service_list; 164 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 165 service_list.push_back(service); 166 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 167 service_list.push_back(service2); 168 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 169 170 registry_->RegisterDnsSdListener(service_type); 171 registry_->GetDelegate()->ServiceChanged(service_type, true, service); 172 registry_->GetDelegate()->ServiceChanged(service_type, true, service2); 173 } 174 175 // Tests adding multiple services and handling a flush event. 176 TEST_F(DnsSdRegistryTest, FlushCache) { 177 testing::InSequence s; 178 const std::string service_type = "_testing._tcp.local"; 179 180 DnsSdService service; 181 service.service_name = "_myDevice." + service_type; 182 service.ip_address = "192.168.0.100"; 183 184 DnsSdService service2; 185 service.service_name = "_myDevice2." + service_type; 186 service.ip_address = "192.168.0.101"; 187 188 DnsSdRegistry::DnsSdServiceList service_list; 189 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 190 service_list.push_back(service); 191 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 192 service_list.push_back(service2); 193 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 194 service_list.clear(); 195 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 196 197 registry_->RegisterDnsSdListener(service_type); 198 registry_->GetDelegate()->ServiceChanged(service_type, true, service); 199 registry_->GetDelegate()->ServiceChanged(service_type, true, service2); 200 registry_->GetDelegate()->ServicesFlushed(service_type); 201 } 202 203 // Tests receiving an update from the DnsSdDelegate that does not change the 204 // service object does not notify the observer. 205 TEST_F(DnsSdRegistryTest, UpdateOnlyIfChanged) { 206 const std::string service_type = "_testing._tcp.local"; 207 const std::string ip_address = "192.168.0.100"; 208 209 DnsSdService service; 210 service.service_name = "_myDevice." + service_type; 211 service.ip_address = ip_address; 212 213 DnsSdRegistry::DnsSdServiceList service_list; 214 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 215 216 // Expect service_list with initial service. 217 service_list.push_back(service); 218 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 219 220 // Expect service_list with updated service. 221 service_list.clear(); 222 service.ip_address = "192.168.0.101"; 223 service_list.push_back(service); 224 EXPECT_CALL(observer_, OnDnsSdEvent(service_type, service_list)); 225 // No more calls to observer_. 226 227 registry_->RegisterDnsSdListener(service_type); 228 service.ip_address = "192.168.0.100"; 229 registry_->GetDelegate()->ServiceChanged(service_type, true, service); 230 // Update with changed ip address. 231 service.ip_address = "192.168.0.101"; 232 registry_->GetDelegate()->ServiceChanged(service_type, false, service); 233 // Update with no changes to the service. 234 registry_->GetDelegate()->ServiceChanged(service_type, false, service); 235 } 236 237 } // namespace extensions 238