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.
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"
10 using testing::SaveArg;
13 namespace local_discovery {
17 class MockServiceResolver;
18 class MockServiceWatcher;
20 class ServiceDiscoveryMockDelegate {
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;
28 class MockServiceWatcher : public ServiceWatcher {
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) {
37 virtual ~MockServiceWatcher() {
40 virtual void Start() {
43 mock_delegate_->ServiceWatcherStarted(service_type_, this);
46 MOCK_METHOD1(DiscoverNewServices, void(bool force_update));
48 MOCK_METHOD1(SetActivelyRefreshServices, void(
49 bool actively_refresh_services));
51 virtual std::string GetServiceType() const {
59 ServiceWatcher::UpdatedCallback callback() {
65 std::string service_type_;
66 ServiceWatcher::UpdatedCallback callback_;
67 ServiceDiscoveryMockDelegate* mock_delegate_;
70 class MockServiceResolver : public ServiceResolver {
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) {
79 virtual ~MockServiceResolver() {
82 virtual void StartResolving() OVERRIDE {
83 started_resolving_ = true;
84 mock_delegate_->ServiceResolverStarted(service_name_, this);
87 bool IsResolving() const {
88 return started_resolving_;
91 virtual std::string GetName() const OVERRIDE {
95 const ServiceResolver::ResolveCompleteCallback& callback() {
99 bool started_resolving_;
100 std::string service_name_;
101 ServiceResolver::ResolveCompleteCallback callback_;
102 ServiceDiscoveryMockDelegate* mock_delegate_;
105 class MockServiceDiscoveryClient : public ServiceDiscoveryClient {
107 explicit MockServiceDiscoveryClient(
108 ServiceDiscoveryMockDelegate* mock_delegate)
109 : mock_delegate_(mock_delegate) {
112 virtual ~MockServiceDiscoveryClient() {
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>();
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>();
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 {
141 return scoped_ptr<LocalDomainResolver>();
145 ServiceDiscoveryMockDelegate* mock_delegate_;
148 class MockServiceDiscoveryMockDelegate : public ServiceDiscoveryMockDelegate {
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));
156 class MockDeviceListerDelegate : public PrivetDeviceLister::Delegate {
158 MockDeviceListerDelegate() {
161 virtual ~MockDeviceListerDelegate() {
164 MOCK_METHOD3(DeviceChanged, void(bool added,
165 const std::string& name,
166 const DeviceDescription& description));
168 MOCK_METHOD1(DeviceRemoved, void(const std::string& name));
170 MOCK_METHOD0(DeviceCacheFlushed, void());
173 class PrivetDeviceListerTest : public testing::Test {
175 PrivetDeviceListerTest() : mock_client_(&mock_delegate_) {
178 virtual ~PrivetDeviceListerTest() {
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=");
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);
200 testing::StrictMock<MockServiceDiscoveryMockDelegate> mock_delegate_;
201 MockServiceDiscoveryClient mock_client_;
202 MockDeviceListerDelegate delegate_;
203 std::vector<std::string> example_attrs_;
204 ServiceDescription service_description_;
207 TEST_F(PrivetDeviceListerTest, SimpleUpdateTest) {
208 DeviceDescription outgoing_description;
210 MockServiceWatcher* service_watcher;
211 MockServiceResolver* service_resolver;
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_);
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_);
227 EXPECT_CALL(delegate_, DeviceChanged(true,
228 "myprinter._privet._tcp.local",
230 .WillOnce(SaveArg<2>(&outgoing_description));
232 service_resolver->callback().Run(ServiceResolver::STATUS_SUCCESS,
233 service_description_);
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);
246 EXPECT_CALL(delegate_, DeviceRemoved("myprinter._privet._tcp.local"));
248 service_watcher->callback().Run(ServiceWatcher::UPDATE_REMOVED,
249 "myprinter._privet._tcp.local");
252 TEST_F(PrivetDeviceListerTest, MultipleUpdatesPostResolve) {
253 MockServiceWatcher* service_watcher;
254 MockServiceResolver* service_resolver;
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_);
263 EXPECT_CALL(mock_delegate_,
264 ServiceResolverStarted("myprinter._privet._tcp.local", _))
265 .WillOnce(SaveArg<1>(&service_resolver));
267 service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
268 "myprinter._privet._tcp.local");
269 testing::Mock::VerifyAndClear(&mock_delegate_);
271 EXPECT_CALL(delegate_, DeviceChanged(false,
272 "myprinter._privet._tcp.local",
274 service_resolver->callback().Run(ServiceResolver::STATUS_SUCCESS,
275 service_description_);
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_);
284 // Check that the device lister does not create a still-working resolver
285 TEST_F(PrivetDeviceListerTest, MultipleUpdatesPreResolve) {
286 MockServiceWatcher* service_watcher;
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_);
295 EXPECT_CALL(mock_delegate_,
296 ServiceResolverStarted("myprinter._privet._tcp.local", _))
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");
304 TEST_F(PrivetDeviceListerTest, DiscoverNewDevices) {
305 MockServiceWatcher* service_watcher;
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_);
314 EXPECT_CALL(*service_watcher, DiscoverNewServices(false));
315 privet_lister.DiscoverNewDevices(false);
321 } // namespace local_discovery