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 ~MockServiceResolver() override {}
81 void StartResolving() override {
82 started_resolving_ = true;
83 mock_delegate_->ServiceResolverStarted(service_name_, this);
86 bool IsResolving() const {
87 return started_resolving_;
90 std::string GetName() const override { return service_name_; }
92 const ServiceResolver::ResolveCompleteCallback& callback() {
96 bool started_resolving_;
97 std::string service_name_;
98 ServiceResolver::ResolveCompleteCallback callback_;
99 ServiceDiscoveryMockDelegate* mock_delegate_;
102 class MockServiceDiscoveryClient : public ServiceDiscoveryClient {
104 explicit MockServiceDiscoveryClient(
105 ServiceDiscoveryMockDelegate* mock_delegate)
106 : mock_delegate_(mock_delegate) {
109 ~MockServiceDiscoveryClient() override {}
111 // Create a service watcher object listening for DNS-SD service announcements
112 // on service type |service_type|.
113 scoped_ptr<ServiceWatcher> CreateServiceWatcher(
114 const std::string& service_type,
115 const ServiceWatcher::UpdatedCallback& callback) override {
116 return make_scoped_ptr(
117 new MockServiceWatcher(service_type, callback, mock_delegate_));
120 // Create a service resolver object for getting detailed service information
121 // for the service called |service_name|.
122 scoped_ptr<ServiceResolver> CreateServiceResolver(
123 const std::string& service_name,
124 const ServiceResolver::ResolveCompleteCallback& callback) override {
125 return make_scoped_ptr(
126 new MockServiceResolver(service_name, callback, mock_delegate_));
129 // Not used in this test.
130 scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver(
131 const std::string& domain,
132 net::AddressFamily address_family,
133 const LocalDomainResolver::IPAddressCallback& callback) override {
135 return scoped_ptr<LocalDomainResolver>();
139 ServiceDiscoveryMockDelegate* mock_delegate_;
142 class MockServiceDiscoveryMockDelegate : public ServiceDiscoveryMockDelegate {
144 MOCK_METHOD2(ServiceWatcherStarted, void(const std::string& service_type,
145 MockServiceWatcher* watcher));
146 MOCK_METHOD2(ServiceResolverStarted, void(const std::string& service_type,
147 MockServiceResolver* resolver));
150 class MockDeviceListerDelegate : public PrivetDeviceLister::Delegate {
152 MockDeviceListerDelegate() {
155 virtual ~MockDeviceListerDelegate() {
158 MOCK_METHOD3(DeviceChanged, void(bool added,
159 const std::string& name,
160 const DeviceDescription& description));
162 MOCK_METHOD1(DeviceRemoved, void(const std::string& name));
164 MOCK_METHOD0(DeviceCacheFlushed, void());
167 class PrivetDeviceListerTest : public testing::Test {
169 PrivetDeviceListerTest() : mock_client_(&mock_delegate_) {
172 virtual ~PrivetDeviceListerTest() {
175 virtual void SetUp() override {
176 example_attrs_.push_back("tXtvers=1");
177 example_attrs_.push_back("ty=My Printer");
178 example_attrs_.push_back("nOte=This is my Printer");
179 example_attrs_.push_back("CS=ONlInE");
180 example_attrs_.push_back("id=");
182 service_description_.service_name = "myprinter._privet._tcp.local";
183 service_description_.address = net::HostPortPair("myprinter.local", 6006);
184 service_description_.metadata = example_attrs_;
185 service_description_.last_seen = base::Time() +
186 base::TimeDelta::FromSeconds(5);
187 service_description_.ip_address.push_back(1);
188 service_description_.ip_address.push_back(2);
189 service_description_.ip_address.push_back(3);
190 service_description_.ip_address.push_back(4);
194 testing::StrictMock<MockServiceDiscoveryMockDelegate> mock_delegate_;
195 MockServiceDiscoveryClient mock_client_;
196 MockDeviceListerDelegate delegate_;
197 std::vector<std::string> example_attrs_;
198 ServiceDescription service_description_;
201 TEST_F(PrivetDeviceListerTest, SimpleUpdateTest) {
202 DeviceDescription outgoing_description;
204 MockServiceWatcher* service_watcher;
205 MockServiceResolver* service_resolver;
207 EXPECT_CALL(mock_delegate_,
208 ServiceWatcherStarted("_privet._tcp.local", _))
209 .WillOnce(SaveArg<1>(&service_watcher));
210 PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
211 privet_lister.Start();
212 testing::Mock::VerifyAndClear(&mock_delegate_);
214 EXPECT_CALL(mock_delegate_,
215 ServiceResolverStarted("myprinter._privet._tcp.local", _))
216 .WillOnce(SaveArg<1>(&service_resolver));
217 service_watcher->callback().Run(ServiceWatcher::UPDATE_ADDED,
218 "myprinter._privet._tcp.local");
219 testing::Mock::VerifyAndClear(&mock_delegate_);
221 EXPECT_CALL(delegate_, DeviceChanged(true,
222 "myprinter._privet._tcp.local",
224 .WillOnce(SaveArg<2>(&outgoing_description));
226 service_resolver->callback().Run(ServiceResolver::STATUS_SUCCESS,
227 service_description_);
229 EXPECT_EQ(service_description_.address.host(),
230 outgoing_description.address.host());
231 EXPECT_EQ(service_description_.address.port(),
232 outgoing_description.address.port());
233 EXPECT_EQ(service_description_.ip_address, outgoing_description.ip_address);
234 EXPECT_EQ(service_description_.last_seen, outgoing_description.last_seen);
235 EXPECT_EQ("My Printer", outgoing_description.name);
236 EXPECT_EQ("This is my Printer", outgoing_description.description);
237 EXPECT_EQ("", outgoing_description.id);
238 EXPECT_EQ(DeviceDescription::ONLINE, outgoing_description.connection_state);
240 EXPECT_CALL(delegate_, DeviceRemoved("myprinter._privet._tcp.local"));
242 service_watcher->callback().Run(ServiceWatcher::UPDATE_REMOVED,
243 "myprinter._privet._tcp.local");
246 TEST_F(PrivetDeviceListerTest, MultipleUpdatesPostResolve) {
247 MockServiceWatcher* service_watcher;
248 MockServiceResolver* service_resolver;
250 EXPECT_CALL(mock_delegate_,
251 ServiceWatcherStarted("_privet._tcp.local", _))
252 .WillOnce(SaveArg<1>(&service_watcher));
253 PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
254 privet_lister.Start();
255 testing::Mock::VerifyAndClear(&mock_delegate_);
257 EXPECT_CALL(mock_delegate_,
258 ServiceResolverStarted("myprinter._privet._tcp.local", _))
259 .WillOnce(SaveArg<1>(&service_resolver));
261 service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
262 "myprinter._privet._tcp.local");
263 testing::Mock::VerifyAndClear(&mock_delegate_);
265 EXPECT_CALL(delegate_, DeviceChanged(false,
266 "myprinter._privet._tcp.local",
268 service_resolver->callback().Run(ServiceResolver::STATUS_SUCCESS,
269 service_description_);
271 EXPECT_CALL(mock_delegate_,
272 ServiceResolverStarted("myprinter._privet._tcp.local", _));
273 service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
274 "myprinter._privet._tcp.local");
275 testing::Mock::VerifyAndClear(&mock_delegate_);
278 // Check that the device lister does not create a still-working resolver
279 TEST_F(PrivetDeviceListerTest, MultipleUpdatesPreResolve) {
280 MockServiceWatcher* service_watcher;
282 EXPECT_CALL(mock_delegate_,
283 ServiceWatcherStarted("_privet._tcp.local", _))
284 .WillOnce(SaveArg<1>(&service_watcher));
285 PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
286 privet_lister.Start();
287 testing::Mock::VerifyAndClear(&mock_delegate_);
289 EXPECT_CALL(mock_delegate_,
290 ServiceResolverStarted("myprinter._privet._tcp.local", _))
292 service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
293 "myprinter._privet._tcp.local");
294 service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
295 "myprinter._privet._tcp.local");
298 TEST_F(PrivetDeviceListerTest, DiscoverNewDevices) {
299 MockServiceWatcher* service_watcher;
301 EXPECT_CALL(mock_delegate_,
302 ServiceWatcherStarted("_privet._tcp.local", _))
303 .WillOnce(SaveArg<1>(&service_watcher));
304 PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
305 privet_lister.Start();
306 testing::Mock::VerifyAndClear(&mock_delegate_);
308 EXPECT_CALL(*service_watcher, DiscoverNewServices(false));
309 privet_lister.DiscoverNewDevices(false);
315 } // namespace local_discovery