blob: 66c2c0c72c27d7500e276f5bd991875d2364b77f [file] [log] [blame]
Darin Petkov002c58e2012-06-19 02:56:05 +02001// Copyright (c) 2012 The Chromium OS 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 "shill/dbus_manager.h"
6
7#include <base/bind.h>
8#include <base/memory/weak_ptr.h>
Darin Petkov002c58e2012-06-19 02:56:05 +02009
10#include "shill/error.h"
11#include "shill/mock_dbus_service_proxy.h"
Ben Chana55469d2014-01-27 16:35:29 -080012#include "shill/mock_proxy_factory.h"
13#include "shill/testing.h"
Darin Petkov002c58e2012-06-19 02:56:05 +020014
15using base::Bind;
Ben Chan084faca2013-07-02 14:25:12 -070016using base::Unretained;
Darin Petkov002c58e2012-06-19 02:56:05 +020017using std::string;
Ben Chand1fce552014-10-17 01:12:52 -070018using std::unique_ptr;
Ben Chan084faca2013-07-02 14:25:12 -070019using testing::Invoke;
20using testing::SaveArg;
21using testing::WithArg;
Darin Petkov002c58e2012-06-19 02:56:05 +020022using testing::_;
23
24namespace shill {
25
Ben Chan084faca2013-07-02 14:25:12 -070026namespace {
27
28const char kName1[] = "org.chromium.Service1";
29const char kOwner1[] = ":1.17";
30const char kName2[] = "org.chromium.Service2";
31const char kOwner2[] = ":1.27";
32
Paul Stewart3b30ca52015-06-16 13:13:10 -070033void SetErrorOperationFailed(Error* error) {
Ben Chan084faca2013-07-02 14:25:12 -070034 error->Populate(Error::kOperationFailed);
35}
36
37} // namespace
38
Darin Petkov002c58e2012-06-19 02:56:05 +020039class DBusManagerTest : public testing::Test {
40 public:
41 DBusManagerTest()
42 : proxy_(new MockDBusServiceProxy()),
Ben Chan084faca2013-07-02 14:25:12 -070043 manager_(new DBusManager()) {}
Darin Petkov002c58e2012-06-19 02:56:05 +020044
45 virtual void SetUp() {
46 // Replaces the real proxy factory with a local one providing mock proxies.
Ben Chan084faca2013-07-02 14:25:12 -070047 manager_->proxy_factory_ = &proxy_factory_;
Darin Petkov002c58e2012-06-19 02:56:05 +020048 }
49
50 protected:
Ben Chan084faca2013-07-02 14:25:12 -070051 class DBusNameWatcherCallbackObserver {
Darin Petkov002c58e2012-06-19 02:56:05 +020052 public:
Ben Chan084faca2013-07-02 14:25:12 -070053 DBusNameWatcherCallbackObserver()
54 : name_appeared_callback_(
55 Bind(&DBusNameWatcherCallbackObserver::OnNameAppeared,
56 Unretained(this))),
57 name_vanished_callback_(
58 Bind(&DBusNameWatcherCallbackObserver::OnNameVanished,
59 Unretained(this))) {}
Darin Petkov002c58e2012-06-19 02:56:05 +020060
Ben Chan084faca2013-07-02 14:25:12 -070061 virtual ~DBusNameWatcherCallbackObserver() {}
Darin Petkov002c58e2012-06-19 02:56:05 +020062
Paul Stewart3b30ca52015-06-16 13:13:10 -070063 MOCK_CONST_METHOD2(OnNameAppeared, void(const string& name,
64 const string& owner));
65 MOCK_CONST_METHOD1(OnNameVanished, void(const string& name));
Ben Chan084faca2013-07-02 14:25:12 -070066
Paul Stewart3b30ca52015-06-16 13:13:10 -070067 const DBusNameWatcher::NameAppearedCallback& name_appeared_callback()
Ben Chan084faca2013-07-02 14:25:12 -070068 const {
69 return name_appeared_callback_;
Darin Petkov002c58e2012-06-19 02:56:05 +020070 }
71
Paul Stewart3b30ca52015-06-16 13:13:10 -070072 const DBusNameWatcher::NameVanishedCallback& name_vanished_callback()
Ben Chan084faca2013-07-02 14:25:12 -070073 const {
74 return name_vanished_callback_;
Darin Petkov002c58e2012-06-19 02:56:05 +020075 }
76
77 private:
Ben Chan084faca2013-07-02 14:25:12 -070078 DBusNameWatcher::NameAppearedCallback name_appeared_callback_;
79 DBusNameWatcher::NameVanishedCallback name_vanished_callback_;
Darin Petkov002c58e2012-06-19 02:56:05 +020080
Ben Chan084faca2013-07-02 14:25:12 -070081 DISALLOW_COPY_AND_ASSIGN(DBusNameWatcherCallbackObserver);
Darin Petkov002c58e2012-06-19 02:56:05 +020082 };
83
Paul Stewart3b30ca52015-06-16 13:13:10 -070084 MockDBusServiceProxy* ExpectCreateDBusServiceProxy() {
Ben Chana55469d2014-01-27 16:35:29 -080085 EXPECT_CALL(proxy_factory_, CreateDBusServiceProxy())
86 .WillOnce(ReturnAndReleasePointee(&proxy_));
87 return proxy_.get();
88 }
89
Ben Chand1fce552014-10-17 01:12:52 -070090 unique_ptr<MockDBusServiceProxy> proxy_;
Ben Chana55469d2014-01-27 16:35:29 -080091 MockProxyFactory proxy_factory_;
Ben Chand1fce552014-10-17 01:12:52 -070092 unique_ptr<DBusManager> manager_;
Darin Petkov002c58e2012-06-19 02:56:05 +020093};
94
Ben Chan084faca2013-07-02 14:25:12 -070095TEST_F(DBusManagerTest, GetNameOwnerFails) {
Paul Stewart3b30ca52015-06-16 13:13:10 -070096 MockDBusServiceProxy* proxy = ExpectCreateDBusServiceProxy();
Darin Petkov002c58e2012-06-19 02:56:05 +020097
Ben Chan084faca2013-07-02 14:25:12 -070098 EXPECT_CALL(*proxy, set_name_owner_changed_callback(_));
99 manager_->Start();
100
101 EXPECT_CALL(*proxy, GetNameOwner(kName1, _, _, _))
102 .WillOnce(WithArg<1>(Invoke(SetErrorOperationFailed)));
103
104 DBusNameWatcherCallbackObserver observer;
105 EXPECT_CALL(observer, OnNameAppeared(_, _)).Times(0);
106 EXPECT_CALL(observer, OnNameVanished(kName1));
107
Ben Chand1fce552014-10-17 01:12:52 -0700108 unique_ptr<DBusNameWatcher> watcher(
Ben Chan084faca2013-07-02 14:25:12 -0700109 manager_->CreateNameWatcher(kName1,
110 observer.name_appeared_callback(),
111 observer.name_vanished_callback()));
112}
113
114TEST_F(DBusManagerTest,
Alex Vakulenko8a532292014-06-16 17:18:44 -0700115 GetNameOwnerReturnsAfterDBusManagerAndNameWatcherDestroyed) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700116 MockDBusServiceProxy* proxy = ExpectCreateDBusServiceProxy();
Ben Chan084faca2013-07-02 14:25:12 -0700117
118 EXPECT_CALL(*proxy, set_name_owner_changed_callback(_));
119 manager_->Start();
120
121 StringCallback get_name_owner_callback;
122 EXPECT_CALL(*proxy, GetNameOwner(kName1, _, _, _))
123 .WillOnce(SaveArg<2>(&get_name_owner_callback));
Ben Chand1fce552014-10-17 01:12:52 -0700124 unique_ptr<DBusNameWatcher> watcher(
Ben Chan084faca2013-07-02 14:25:12 -0700125 manager_->CreateNameWatcher(kName1,
126 DBusNameWatcher::NameAppearedCallback(),
127 DBusNameWatcher::NameVanishedCallback()));
128
129 // Expect no crash if the GetNameOwner callback is invoked after the
130 // DBusNameWatcher object is destroyed.
131 watcher.reset();
132 get_name_owner_callback.Run(kOwner1, Error());
133
134 // Expect no crash if the GetNameOwner callback is invoked after the
135 // DBusManager object is destroyed.
136 manager_.reset();
137 get_name_owner_callback.Run(kOwner1, Error());
138}
139
140TEST_F(DBusManagerTest, NameWatchers) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700141 MockDBusServiceProxy* proxy = ExpectCreateDBusServiceProxy();
Darin Petkov002c58e2012-06-19 02:56:05 +0200142
143 // Start the DBus service manager.
144 EXPECT_CALL(*proxy, set_name_owner_changed_callback(_));
Ben Chan084faca2013-07-02 14:25:12 -0700145 manager_->Start();
146 EXPECT_TRUE(manager_->proxy_.get());
Darin Petkov002c58e2012-06-19 02:56:05 +0200147
Ben Chan084faca2013-07-02 14:25:12 -0700148 // Expect no crash when DBusManager::Start() is invoked again.
149 manager_->Start();
Darin Petkov002c58e2012-06-19 02:56:05 +0200150
Ben Chan084faca2013-07-02 14:25:12 -0700151 StringCallback get_name_owner_callback;
Darin Petkov002c58e2012-06-19 02:56:05 +0200152
Ben Chan084faca2013-07-02 14:25:12 -0700153 // Register a name watcher 1a for kName1.
154 EXPECT_CALL(*proxy, GetNameOwner(kName1, _, _, _))
155 .WillOnce(SaveArg<2>(&get_name_owner_callback));
156 DBusNameWatcherCallbackObserver observer1a;
Ben Chand1fce552014-10-17 01:12:52 -0700157 unique_ptr<DBusNameWatcher> watcher1a(
Ben Chan084faca2013-07-02 14:25:12 -0700158 manager_->CreateNameWatcher(kName1,
159 observer1a.name_appeared_callback(),
160 observer1a.name_vanished_callback()));
Darin Petkov002c58e2012-06-19 02:56:05 +0200161
Ben Chan084faca2013-07-02 14:25:12 -0700162 // Observer 1a should be notified on the initial owner.
163 EXPECT_CALL(observer1a, OnNameAppeared(kName1, kOwner1));
164 EXPECT_CALL(observer1a, OnNameVanished(_)).Times(0);
165 get_name_owner_callback.Run(kOwner1, Error());
Darin Petkov002c58e2012-06-19 02:56:05 +0200166
Ben Chan084faca2013-07-02 14:25:12 -0700167 // Register an appear-only watcher 1b for kName1.
168 EXPECT_CALL(*proxy, GetNameOwner(kName1, _, _, _))
169 .WillOnce(SaveArg<2>(&get_name_owner_callback));
170 DBusNameWatcherCallbackObserver observer1b;
Ben Chand1fce552014-10-17 01:12:52 -0700171 unique_ptr<DBusNameWatcher> watcher1b(
Ben Chan084faca2013-07-02 14:25:12 -0700172 manager_->CreateNameWatcher(kName1,
173 observer1b.name_appeared_callback(),
174 DBusNameWatcher::NameVanishedCallback()));
Darin Petkov002c58e2012-06-19 02:56:05 +0200175
Ben Chan084faca2013-07-02 14:25:12 -0700176 // Observer 1b should be notified on the initial owner. Observer 1a should
177 // not get any notification.
178 EXPECT_CALL(observer1a, OnNameAppeared(_, _)).Times(0);
179 EXPECT_CALL(observer1b, OnNameAppeared(kName1, kOwner1));
180 get_name_owner_callback.Run(kOwner1, Error());
Darin Petkov002c58e2012-06-19 02:56:05 +0200181
Ben Chan084faca2013-07-02 14:25:12 -0700182 // Register a name watcher 2a for kName2.
183 EXPECT_CALL(*proxy, GetNameOwner(kName2, _, _, _))
184 .WillOnce(SaveArg<2>(&get_name_owner_callback));
185 DBusNameWatcherCallbackObserver observer2a;
Ben Chand1fce552014-10-17 01:12:52 -0700186 unique_ptr<DBusNameWatcher> watcher2a(
Ben Chan084faca2013-07-02 14:25:12 -0700187 manager_->CreateNameWatcher(kName2,
188 observer2a.name_appeared_callback(),
189 observer2a.name_vanished_callback()));
Darin Petkov002c58e2012-06-19 02:56:05 +0200190
Ben Chan084faca2013-07-02 14:25:12 -0700191 // Observer 2a should be notified on the lack of initial owner.
192 EXPECT_CALL(observer2a, OnNameAppeared(_, _)).Times(0);
193 EXPECT_CALL(observer2a, OnNameVanished(kName2));
194 get_name_owner_callback.Run(string(), Error());
Darin Petkov002c58e2012-06-19 02:56:05 +0200195
Ben Chan084faca2013-07-02 14:25:12 -0700196 // Register a vanish-only watcher 2b for kName2.
197 EXPECT_CALL(*proxy, GetNameOwner(kName2, _, _, _))
198 .WillOnce(SaveArg<2>(&get_name_owner_callback));
199 DBusNameWatcherCallbackObserver observer2b;
Ben Chand1fce552014-10-17 01:12:52 -0700200 unique_ptr<DBusNameWatcher> watcher2b(
Ben Chan084faca2013-07-02 14:25:12 -0700201 manager_->CreateNameWatcher(kName2,
202 DBusNameWatcher::NameAppearedCallback(),
203 observer2b.name_vanished_callback()));
Darin Petkov002c58e2012-06-19 02:56:05 +0200204
Ben Chan084faca2013-07-02 14:25:12 -0700205 // Observer 2b should be notified on the lack of initial owner. Observer 2a
206 // should not get any notification.
207 EXPECT_CALL(observer2a, OnNameVanished(_)).Times(0);
208 EXPECT_CALL(observer2b, OnNameVanished(kName2));
209 get_name_owner_callback.Run(string(), Error());
210
211 EXPECT_EQ(2, manager_->name_watchers_[kName1].size());
212 EXPECT_EQ(2, manager_->name_watchers_[kName2].size());
Darin Petkov002c58e2012-06-19 02:56:05 +0200213
214 // Toggle kName1 owner.
Ben Chan084faca2013-07-02 14:25:12 -0700215 EXPECT_CALL(observer1a, OnNameVanished(kName1));
216 EXPECT_CALL(observer1b, OnNameVanished(_)).Times(0);
217 manager_->OnNameOwnerChanged(kName1, kOwner1, string());
218 EXPECT_CALL(observer1a, OnNameAppeared(kName1, kOwner1));
219 EXPECT_CALL(observer1b, OnNameAppeared(kName1, kOwner1));
220 manager_->OnNameOwnerChanged(kName1, string(), kOwner1);
Darin Petkov002c58e2012-06-19 02:56:05 +0200221
222 // Toggle kName2 owner.
Ben Chan084faca2013-07-02 14:25:12 -0700223 EXPECT_CALL(observer2a, OnNameAppeared(kName2, kOwner2));
224 EXPECT_CALL(observer2b, OnNameAppeared(_, _)).Times(0);
225 manager_->OnNameOwnerChanged(kName2, string(), kOwner2);
226 EXPECT_CALL(observer2a, OnNameVanished(kName2));
227 EXPECT_CALL(observer2b, OnNameVanished(kName2));
228 manager_->OnNameOwnerChanged(kName2, kOwner2, string());
Darin Petkov002c58e2012-06-19 02:56:05 +0200229
230 // Invalidate kName1 callbacks, ensure no crashes.
231 watcher1a.reset();
232 watcher1b.reset();
Ben Chan084faca2013-07-02 14:25:12 -0700233 manager_->OnNameOwnerChanged(kName1, kOwner1, string());
234 manager_->OnNameOwnerChanged(kName1, string(), kOwner1);
Darin Petkov002c58e2012-06-19 02:56:05 +0200235
236 // Stop the DBus service manager.
Ben Chan084faca2013-07-02 14:25:12 -0700237 manager_->Stop();
238 EXPECT_FALSE(manager_->proxy_.get());
239 EXPECT_TRUE(manager_->name_watchers_.empty());
Darin Petkov002c58e2012-06-19 02:56:05 +0200240
Ben Chan084faca2013-07-02 14:25:12 -0700241 // Ensure no crash if DBusManager::Stop() is inovked again.
242 manager_->Stop();
Darin Petkov002c58e2012-06-19 02:56:05 +0200243}
244
245} // namespace shill