Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(365)

Side by Side Diff: chromeos/dbus/biod/biod_biometrics_manager_client_unittest.cc

Issue 2567813002: cros: DBUS client to interact with fingerprint DBUS API. (Closed)
Patch Set: Fixed patch set 7 errors. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "chromeos/dbus/biod/biod_biometrics_manager_client.h"
6
7 #include <map>
8 #include <string>
9
10 #include "base/bind.h"
11 #include "base/run_loop.h"
12 #include "dbus/mock_bus.h"
13 #include "dbus/mock_object_proxy.h"
14 #include "dbus/object_path.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using ::testing::_;
19 using ::testing::Invoke;
20 using ::testing::Return;
21
22 namespace chromeos {
23
24 namespace {
25
26 // Shorthand for a commonly-used constant.
27 const char* kInterface = biod::kBiometricsManagerInterface;
28
29 void CheckObjectPathCallback(const dbus::ObjectPath& expected_object_path,
30 const dbus::ObjectPath& object_path) {
31 EXPECT_EQ(expected_object_path, object_path);
32 }
33
34 void CheckObjectPathArrayCallback(
35 const std::vector<dbus::ObjectPath>& expected_object_paths,
36 const std::vector<dbus::ObjectPath>& object_paths) {
37 EXPECT_EQ(expected_object_paths.size(), object_paths.size());
Daniel Erat 2017/03/28 00:14:35 you need ASSERT_EQ or CHECK_EQ here. otherwise you
sammiequon 2017/03/28 01:31:06 Done.
38 for (size_t i = 0; i < expected_object_paths.size(); ++i)
39 EXPECT_EQ(expected_object_paths[i], object_paths[i]);
40 }
41
42 // Implementation of BiodBiometricsManagerClient::Observer.
43 class TestBiometricsObserver : public BiodBiometricsManagerClient::Observer {
44 public:
45 TestBiometricsObserver() {}
46 ~TestBiometricsObserver() override {}
47
48 int num_enroll_scan_received() const { return num_enroll_scan_received_; }
49 int num_auth_scan_received() const { return num_auth_scan_received_; }
50 int num_failure_received() const { return num_failure_received_; }
51
52 // BiodBiometricsManagerClient::Observer:
53 void BiodServiceRestarted() override {}
54
55 void BiodEnrollScanDoneReceived(biod::ScanResult scan_result,
56 bool is_complete) override {
57 num_enroll_scan_received_++;
58 }
59
60 void BiodAuthScanDoneReceived(biod::ScanResult scan_result,
61 const AuthScanMatches& matches) override {
62 num_auth_scan_received_++;
63 }
64
65 void BiodSessionFailedReceived() override { num_failure_received_++; }
66
67 private:
68 int num_enroll_scan_received_ = 0;
69 int num_auth_scan_received_ = 0;
70 int num_failure_received_ = 0;
71
72 DISALLOW_COPY_AND_ASSIGN(TestBiometricsObserver);
73 };
74
75 } // namespace
76
77 class BiodBiometricsManagerClientTest : public testing::Test {
78 public:
79 BiodBiometricsManagerClientTest() {}
80 ~BiodBiometricsManagerClientTest() override {}
81
82 void SetUp() override {
83 dbus::Bus::Options options;
84 options.bus_type = dbus::Bus::SYSTEM;
85 bus_ = new dbus::MockBus(options);
86
87 proxy_ =
88 new dbus::MockObjectProxy(bus_.get(), biod::kBiodServiceName,
89 dbus::ObjectPath(biod::kBiodServicePath));
90
91 // |client_|'s Init() method should request a proxy for communicating with
92 // biometrics api.
93 EXPECT_CALL(*bus_.get(),
94 GetObjectProxy(biod::kBiodServiceName,
95 dbus::ObjectPath(biod::kBiodServicePath)))
96 .WillRepeatedly(Return(proxy_.get()));
97
98 // Save |client_|'s signal callback.
99 EXPECT_CALL(*proxy_.get(), ConnectToSignal(kInterface, _, _, _))
100 .WillRepeatedly(
101 Invoke(this, &BiodBiometricsManagerClientTest::ConnectToSignal));
102
103 // |client_|'s Init() method should register methods.
104 EXPECT_CALL(*proxy_.get(), CallMethod(_, _, _))
105 .WillRepeatedly(
106 Invoke(this, &BiodBiometricsManagerClientTest::OnCallMethod));
107
108 client_.reset(
109 BiodBiometricsManagerClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION));
110 client_->Init(bus_.get());
111
112 // Execute callbacks posted by Init().
113 base::RunLoop().RunUntilIdle();
114 }
115
116 protected:
117 // Set the values a method is expected to have when a dbus method is called.
118 void SetExpectedMethodArguments(const std::string& expected_interface,
119 const std::string& expected_name,
120 dbus::Response* response) {
Daniel Erat 2017/03/28 00:14:35 document memory ownership/lifetime when passing ra
sammiequon 2017/03/28 01:31:05 I changed this to use smart pointer is that ok? If
121 expected_interface_ = expected_interface;
122 expected_name_ = expected_name;
123 expected_response_ = response;
124 }
125
126 // Synchronously passes |signal| to |client_|'s handler, simulating the signal
127 // from biometrics.
128 void EmitSignal(dbus::Signal* signal) {
129 const std::string signal_name = signal->GetMember();
130 const auto it = signal_callbacks_.find(signal_name);
131 ASSERT_TRUE(it != signal_callbacks_.end())
132 << "Client didn't register for signal " << signal_name;
133 it->second.Run(signal);
134 }
135
136 // Passes a enroll scan done signal to |client_|.
137 void EmitEnrollScanDoneSignal(biod::ScanResult scan_result,
138 bool is_complete) {
139 dbus::Signal signal(kInterface,
140 biod::kBiometricsManagerEnrollScanDoneSignal);
141 dbus::MessageWriter writer(&signal);
142 writer.AppendUint32(uint32_t{scan_result});
143 writer.AppendBool(is_complete);
144 EmitSignal(&signal);
145 }
146
147 // Passes a auth scan done signal to |client_|.
148 void EmitAuthScanDoneSignal(biod::ScanResult scan_result,
149 const AuthScanMatches& matches) {
150 dbus::Signal signal(kInterface, biod::kBiometricsManagerAuthScanDoneSignal);
151 dbus::MessageWriter writer(&signal);
152 writer.AppendUint32(uint32_t{scan_result});
153
154 dbus::MessageWriter array_writer(NULL);
Daniel Erat 2017/03/28 00:14:35 s/NULL/nullptr/ throughout this file
sammiequon 2017/03/28 01:31:05 Done.
155 writer.OpenArray("{sx}", &array_writer);
156 for (auto& match : matches) {
157 dbus::MessageWriter entry_writer(NULL);
158 array_writer.OpenDictEntry(&entry_writer);
159 entry_writer.AppendString(match.first);
160 entry_writer.AppendArrayOfStrings(match.second);
161 array_writer.CloseContainer(&entry_writer);
162 }
163 writer.CloseContainer(&array_writer);
164 EmitSignal(&signal);
165 }
166
167 // Passes a scan failed signal to |client_|.
168 void EmitScanFailedSignal() {
169 dbus::Signal signal(kInterface,
170 biod::kBiometricsManagerSessionFailedSignal);
171 EmitSignal(&signal);
172 }
173
174 std::string expected_interface_;
175 std::string expected_name_;
176 dbus::Response* expected_response_;
Daniel Erat 2017/03/28 00:14:35 this memory looks like it's currently left uniniti
sammiequon 2017/03/28 01:31:05 Done.
177
178 base::MessageLoop message_loop_;
179
180 // Mock bus and proxy for simulating calls.
181 scoped_refptr<dbus::MockBus> bus_;
182 scoped_refptr<dbus::MockObjectProxy> proxy_;
183
184 std::unique_ptr<BiodBiometricsManagerClient> client_;
185
186 // Maps from powerd signal name to the corresponding callback provided by
Daniel Erat 2017/03/28 00:14:35 i see where this code came from. :-P please fix th
sammiequon 2017/03/28 01:31:05 Oops. Done.
187 // |client_|.
188 std::map<std::string, dbus::ObjectProxy::SignalCallback> signal_callbacks_;
189
190 private:
191 // Handles calls to |proxy_|'s ConnectToSignal() method.
192 void ConnectToSignal(
193 const std::string& interface_name,
194 const std::string& signal_name,
195 dbus::ObjectProxy::SignalCallback signal_callback,
196 dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
197 EXPECT_EQ(interface_name, kInterface);
198 signal_callbacks_[signal_name] = signal_callback;
199 message_loop_.task_runner()->PostTask(
200 FROM_HERE, base::Bind(on_connected_callback, interface_name,
201 signal_name, true /* success */));
202 }
203
204 // Handles calls to |proxy_|'s CallMethod().
205 void OnCallMethod(dbus::MethodCall* method_call,
206 int timeout_ms,
207 const dbus::ObjectProxy::ResponseCallback& callback) {
208 EXPECT_EQ(expected_interface_, method_call->GetInterface());
209 EXPECT_EQ(expected_name_, method_call->GetMember());
Daniel Erat 2017/03/28 00:14:35 this is fragile and will create a lot of future wo
sammiequon 2017/03/28 01:31:05 You mean consolidating all of this the d-bus calls
Daniel Erat 2017/03/28 01:44:30 i mean setting expectations similar to this (from
sammiequon 2017/03/28 03:17:54 I gave it a shot.
210
211 message_loop_.task_runner()->PostTask(
212 FROM_HERE, base::Bind(callback, expected_response_));
213 }
214
215 DISALLOW_COPY_AND_ASSIGN(BiodBiometricsManagerClientTest);
216 };
217
218 TEST_F(BiodBiometricsManagerClientTest, TestStartEnrollSession) {
219 const std::string& fake_id("fakeId");
Daniel Erat 2017/03/28 00:14:35 uh, const reference? string constants should be:
sammiequon 2017/03/28 01:31:05 I've believed I've seen this notation used in many
Daniel Erat 2017/03/28 01:44:30 yes, a const std::string is okay; it's the referen
sammiequon 2017/03/28 03:17:54 So this means i should use the kFoo naming instead
220 const std::string& fake_label("fakeLabel");
221 const dbus::ObjectPath& fake_object_path(std::string("/fake/object/path"));
222
223 std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
224 dbus::MessageWriter writer(response.get());
225 writer.AppendObjectPath(fake_object_path);
226
227 // Create a fake response with a fake object path. The start enroll
228 // call should return this object path.
229 SetExpectedMethodArguments(kInterface,
230 biod::kBiometricsManagerStartEnrollSessionMethod,
231 response.get());
232 client_->StartEnrollSession(
233 fake_id, fake_label,
234 base::Bind(&CheckObjectPathCallback, fake_object_path));
235
236 // Verify that by sending a empty reponse or a improperly formatted one, the
237 // response is an empty object path. Also, logs will get printed.
238 SetExpectedMethodArguments(
239 kInterface, biod::kBiometricsManagerStartEnrollSessionMethod, nullptr);
240 client_->StartEnrollSession(
241 fake_id, fake_label,
242 base::Bind(&CheckObjectPathCallback, dbus::ObjectPath()));
243
244 std::unique_ptr<dbus::Response> bad_response(dbus::Response::CreateEmpty());
245 dbus::MessageWriter bad_writer(bad_response.get());
246 bad_writer.AppendString("");
247 SetExpectedMethodArguments(kInterface,
248 biod::kBiometricsManagerStartEnrollSessionMethod,
249 bad_response.get());
250 client_->StartEnrollSession(
251 fake_id, fake_label,
252 base::Bind(&CheckObjectPathCallback, dbus::ObjectPath()));
253
254 base::RunLoop().RunUntilIdle();
255 }
256
257 TEST_F(BiodBiometricsManagerClientTest, TestGetRecordsForUser) {
258 const std::string& fake_id("fakeId");
259 const dbus::ObjectPath& fake_object_path(std::string("/fake/object/path"));
260 const dbus::ObjectPath& fake_object_path2(std::string("/fake/object/path2"));
261 const std::vector<dbus::ObjectPath>& fake_object_paths = {fake_object_path,
262 fake_object_path2};
263
264 std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
265 dbus::MessageWriter writer(response.get());
266 writer.AppendArrayOfObjectPaths(fake_object_paths);
267
268 // Create a fake response with an array fake object paths. The get enrollments
Daniel Erat 2017/03/28 00:14:35 nit: "array of"
sammiequon 2017/03/28 01:31:05 Done.
269 // call should return this array of object paths.
270 SetExpectedMethodArguments(kInterface,
271 biod::kBiometricsManagerGetRecordsForUserMethod,
272 response.get());
273 client_->GetRecordsForUser(
274 fake_id, base::Bind(&CheckObjectPathArrayCallback, fake_object_paths));
275
276 // Verify that by sending a empty reponse the response is an empty array of
277 // object paths. Also, logs will get printed.
278 SetExpectedMethodArguments(
279 kInterface, biod::kBiometricsManagerGetRecordsForUserMethod, nullptr);
280 client_->GetRecordsForUser(fake_id,
281 base::Bind(&CheckObjectPathArrayCallback,
282 std::vector<dbus::ObjectPath>()));
283
284 base::RunLoop().RunUntilIdle();
285 }
286
287 TEST_F(BiodBiometricsManagerClientTest, TestDestroyAllRecords) {
288 std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
289
290 SetExpectedMethodArguments(kInterface,
291 biod::kBiometricsManagerDestroyAllRecordsMethod,
292 response.get());
293 client_->DestroyAllRecords();
294
295 base::RunLoop().RunUntilIdle();
296 }
297
298 TEST_F(BiodBiometricsManagerClientTest, TestStartAuthentication) {
299 const dbus::ObjectPath& fake_object_path(std::string("/fake/object/path"));
300
301 // Create a fake response with a fake object path. The start authentication
302 // call should return this object path.
303 std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
304 dbus::MessageWriter writer(response.get());
305 writer.AppendObjectPath(fake_object_path);
306
307 SetExpectedMethodArguments(kInterface,
308 biod::kBiometricsManagerStartAuthSessionMethod,
309 response.get());
310 client_->StartAuthSession(
311 base::Bind(&CheckObjectPathCallback, fake_object_path));
312
313 // Verify that by sending a empty reponse or a improperly formatted one, the
314 // response is an empty object path. Also, logs will get printed.
315 SetExpectedMethodArguments(
316 kInterface, biod::kBiometricsManagerStartAuthSessionMethod, nullptr);
317 client_->StartAuthSession(
318 base::Bind(&CheckObjectPathCallback, dbus::ObjectPath()));
319
320 std::unique_ptr<dbus::Response> bad_response(dbus::Response::CreateEmpty());
321 dbus::MessageWriter bad_writer(bad_response.get());
322 bad_writer.AppendString("");
323 SetExpectedMethodArguments(kInterface,
324 biod::kBiometricsManagerStartAuthSessionMethod,
325 bad_response.get());
326 client_->StartAuthSession(
327 base::Bind(&CheckObjectPathCallback, dbus::ObjectPath()));
328
329 base::RunLoop().RunUntilIdle();
330 }
331
332 // Verify when enroll scan done signals are mocked, observer(s) catch the
333 // signals as expected.
334 TEST_F(BiodBiometricsManagerClientTest, TestEnrollScanDoneObserver) {
335 TestBiometricsObserver observer1;
336 TestBiometricsObserver observer2;
337 client_->AddObserver(&observer1);
338
339 const biod::ScanResult scan_signal = biod::ScanResult::SCAN_RESULT_SUCCESS;
340 const bool is_complete = false;
341 EmitEnrollScanDoneSignal(scan_signal, is_complete);
342 EXPECT_EQ(1, observer1.num_enroll_scan_received());
343 EXPECT_EQ(0, observer2.num_enroll_scan_received());
344
345 client_->AddObserver(&observer2);
346 EmitEnrollScanDoneSignal(scan_signal, is_complete);
347 EXPECT_EQ(2, observer1.num_enroll_scan_received());
348 EXPECT_EQ(1, observer2.num_enroll_scan_received());
349
350 client_->RemoveObserver(&observer1);
351 EmitEnrollScanDoneSignal(scan_signal, is_complete);
352 EXPECT_EQ(2, observer1.num_enroll_scan_received());
353 EXPECT_EQ(2, observer2.num_enroll_scan_received());
354 }
355
356 // Verify when auth scan done signals are mocked, observer(s) catch the signals
357 // as expected.
358 TEST_F(BiodBiometricsManagerClientTest, TestAuthScanDoneObserver) {
359 TestBiometricsObserver observer1;
360 TestBiometricsObserver observer2;
361 client_->AddObserver(&observer1);
362
363 const biod::ScanResult scan_signal = biod::ScanResult::SCAN_RESULT_SUCCESS;
364 const AuthScanMatches test_attempt;
365 EmitAuthScanDoneSignal(scan_signal, test_attempt);
366 EXPECT_EQ(1, observer1.num_auth_scan_received());
367 EXPECT_EQ(0, observer2.num_auth_scan_received());
368
369 client_->AddObserver(&observer2);
370 EmitAuthScanDoneSignal(scan_signal, test_attempt);
371 EXPECT_EQ(2, observer1.num_auth_scan_received());
372 EXPECT_EQ(1, observer2.num_auth_scan_received());
373
374 client_->RemoveObserver(&observer1);
375 EmitAuthScanDoneSignal(scan_signal, test_attempt);
376 EXPECT_EQ(2, observer1.num_auth_scan_received());
377 EXPECT_EQ(2, observer2.num_auth_scan_received());
378 }
379 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698