OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 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/fake_biod_client.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/macros.h" | |
9 #include "base/strings/string_util.h" | |
10 #include "base/test/test_simple_task_runner.h" | |
11 #include "base/threading/thread_task_runner_handle.h" | |
12 #include "chromeos/dbus/biod/biod_test_utils.h" | |
13 #include "dbus/object_path.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 | |
16 namespace chromeos { | |
17 | |
18 namespace { | |
19 | |
20 const char kTestUserId[] = "testuser@gmail.com"; | |
21 const char kTestLabel[] = "testLabel"; | |
22 // Template of a scan string to be used in GenerateTestFingerprint. The # and $ | |
23 // are two wildcards that will be replaced by numbers to ensure unique scans. | |
24 const char kTestScan[] = "finger#scan$"; | |
25 | |
26 } // namepsace | |
27 | |
28 class FakeBiodClientTest : public testing::Test { | |
29 public: | |
30 FakeBiodClientTest() | |
31 : task_runner_(new base::TestSimpleTaskRunner), | |
32 task_runner_handle_(task_runner_) {} | |
33 ~FakeBiodClientTest() override {} | |
34 | |
35 int NumRecords() { | |
36 return static_cast<int>(fake_biod_client_.records_.size()); | |
Daniel Erat
2017/04/07 23:40:56
this feels like it's testing the class's internals
sammiequon
2017/04/08 00:43:32
Yeah, think this was a temporary that i forgot to
| |
37 } | |
38 | |
39 int NumRecords(const std::string& user_id) { | |
Daniel Erat
2017/04/07 23:40:56
it'd probably be cleaner to call this GetRecordsFo
sammiequon
2017/04/08 00:43:33
Done.
| |
40 std::vector<dbus::ObjectPath> enrollment_paths; | |
41 fake_biod_client_.GetRecordsForUser( | |
42 kTestUserId, | |
43 base::Bind(&test_utils::CopyObjectPathArray, &enrollment_paths)); | |
44 task_runner_->RunUntilIdle(); | |
45 return static_cast<int>(enrollment_paths.size()); | |
46 } | |
47 | |
48 void SendAuthScanDone(const std::string& scan_data) { | |
Daniel Erat
2017/04/07 23:40:56
this is a single call to a public method. can the
sammiequon
2017/04/08 00:43:32
I thought it would be nice to make a helper since
Daniel Erat
2017/04/08 00:57:21
i agree that it's long! :-)
biod::ScanResult::SUC
sammiequon
2017/04/11 17:11:37
Done.
| |
49 fake_biod_client_.SendAuthScanDone(scan_data, | |
50 biod::ScanResult::SCAN_RESULT_SUCCESS); | |
51 } | |
52 | |
53 // Helper function which enrolls a fingerprint. Each element in | |
54 // |fingerprint_data| corresponds to a finger tap. | |
55 void EnrollFingerprint(const std::string& id, | |
56 const std::string& label, | |
57 const std::vector<std::string>& fingerprint_data) { | |
58 if (fingerprint_data.size() < 1) | |
Daniel Erat
2017/04/07 23:40:56
you can just use fingerprint_data.empty() instead,
sammiequon
2017/04/08 00:43:32
Done.
| |
59 return; | |
60 | |
61 dbus::ObjectPath returned_path; | |
62 fake_biod_client_.StartEnrollSession( | |
63 id, label, base::Bind(&test_utils::CopyObjectPath, &returned_path)); | |
64 task_runner_->RunUntilIdle(); | |
65 EXPECT_NE(returned_path, dbus::ObjectPath()); | |
Daniel Erat
2017/04/07 23:40:56
EXPECT_ and ASSERT_ expect parameters to be (expec
sammiequon
2017/04/08 00:43:32
Done.
| |
66 | |
67 // Send |fingerprint_data| size - 1 incomplete scans. | |
68 for (int i = 0; i < static_cast<int>(fingerprint_data.size()) - 1; ++i) { | |
Daniel Erat
2017/04/07 23:40:56
instead of casting, just make i be a size_t
sammiequon
2017/04/08 00:43:32
Done.
| |
69 fake_biod_client_.SendEnrollScanDone( | |
70 fingerprint_data[i], biod::ScanResult::SCAN_RESULT_SUCCESS, | |
71 false /* is_complete*/); | |
Daniel Erat
2017/04/07 23:40:56
/* is_complete */ (spaces on both sides)
sammiequon
2017/04/08 00:43:32
Done.
| |
72 } | |
73 | |
74 // Finish the enrollment by sending a complete scan signal. | |
75 fake_biod_client_.SendEnrollScanDone(fingerprint_data.back(), | |
76 biod::ScanResult::SCAN_RESULT_SUCCESS, | |
77 true /*is_complete*/); | |
Daniel Erat
2017/04/07 23:40:56
just move this into the above for loop and pass (i
sammiequon
2017/04/08 00:43:32
Done.
| |
78 } | |
79 | |
80 // Helper function which enrolls |n| fingerprints with the same |id|, |label| | |
81 // and |fingerprint_data|. | |
82 void EnrollNTestFingerprints(const std::string& id, | |
83 const std::string& label, | |
84 const std::vector<std::string>& fingerprint_data, | |
85 int n) { | |
86 for (int i = 0; i < n; ++i) | |
87 EnrollFingerprint(id, label, fingerprint_data); | |
88 } | |
89 | |
90 // Creates a new unique fingerprint consisting of unique scans. | |
91 std::vector<std::string> GenerateTestFingerprint(int scans) { | |
92 DCHECK_GE(scans, 0); | |
93 num_test_fingerprints_++; | |
94 | |
95 std::vector<std::string> fingerprint; | |
96 for (int i = 0; i < scans; ++i) { | |
97 std::string scan = kTestScan; | |
98 base::ReplaceSubstringsAfterOffset( | |
99 &scan, 0, "#", std::to_string(num_test_fingerprints_)); | |
100 base::ReplaceSubstringsAfterOffset(&scan, 0, "$", std::to_string(i)); | |
101 fingerprint.push_back(scan); | |
102 } | |
103 return fingerprint; | |
104 } | |
105 | |
106 protected: | |
107 FakeBiodClient fake_biod_client_; | |
108 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | |
109 base::ThreadTaskRunnerHandle task_runner_handle_; | |
110 | |
111 // This number is incremented each time GenerateTestFingerprint is called to | |
112 // ensure each fingerprint is unique. | |
113 int num_test_fingerprints_ = 0; | |
114 | |
115 private: | |
116 DISALLOW_COPY_AND_ASSIGN(FakeBiodClientTest); | |
117 }; | |
118 | |
119 TEST_F(FakeBiodClientTest, TestEnrollSessionWorkflow) { | |
120 test_utils::TestBiodObserver observer; | |
121 fake_biod_client_.AddObserver(&observer); | |
122 | |
123 auto kTestFingerprint = GenerateTestFingerprint(2); | |
Daniel Erat
2017/04/07 23:40:56
i think you need to write the type here instead of
sammiequon
2017/04/08 00:43:32
Done.
| |
124 // Verify that successful enrollments gets stored as expected. A fingerprint | |
Daniel Erat
2017/04/07 23:40:56
nit: s/gets/get/
sammiequon
2017/04/08 00:43:33
Done.
| |
125 // that was created with 2 scans should have 1 incomplete scans and 1 complete | |
126 // scans. | |
127 EnrollFingerprint(kTestUserId, kTestLabel, kTestFingerprint); | |
128 EXPECT_EQ(1, NumRecords()); | |
129 EXPECT_EQ(1, observer.num_incomplete_enroll_scans_received()); | |
130 EXPECT_EQ(1, observer.num_complete_enroll_scans_received()); | |
131 | |
132 // Verify that the enroll session worflow can be used repeatedly by enrolling | |
133 // 3 more fingerprints (each with 1 incomplete and 1 complete scans). | |
134 EnrollNTestFingerprints(kTestUserId, kTestLabel, kTestFingerprint, 3); | |
135 EXPECT_EQ(4, NumRecords()); | |
136 EXPECT_EQ(4, observer.num_incomplete_enroll_scans_received()); | |
137 EXPECT_EQ(4, observer.num_complete_enroll_scans_received()); | |
138 } | |
139 | |
140 // Test authentication when one user has one or more fingerprints registered. | |
141 // This should be the normal scenario. | |
142 TEST_F(FakeBiodClientTest, TestAuthSessionWorkflowSingleUser) { | |
143 test_utils::TestBiodObserver observer; | |
144 fake_biod_client_.AddObserver(&observer); | |
145 EXPECT_EQ(0, NumRecords(kTestUserId)); | |
146 | |
147 auto kTestFingerprint1 = GenerateTestFingerprint(2); | |
148 auto kTestFingerprint2 = GenerateTestFingerprint(2); | |
149 auto kTestFingerprint3 = GenerateTestFingerprint(2); | |
150 auto kTestFingerprint4 = GenerateTestFingerprint(2); | |
151 | |
152 // Add two fingerprints a and b and start an auth session. | |
Daniel Erat
2017/04/07 23:40:56
is this comment outdated? i don't see 'a' or 'b'
sammiequon
2017/04/08 00:43:32
Done.
| |
153 EnrollFingerprint(kTestUserId, kTestLabel, kTestFingerprint1); | |
154 EnrollFingerprint(kTestUserId, kTestLabel, kTestFingerprint2); | |
155 dbus::ObjectPath returned_path; | |
156 fake_biod_client_.StartAuthSession( | |
157 base::Bind(&test_utils::CopyObjectPath, &returned_path)); | |
158 task_runner_->RunUntilIdle(); | |
159 EXPECT_NE(returned_path, dbus::ObjectPath()); | |
160 | |
161 // Verify that by sending two attempts signals of fingerprints that have been | |
162 // enrolled, the observer should received two matches and zero unmatches. | |
Daniel Erat
2017/04/07 23:40:56
s/received/receive/, s/unmatches/non-matches/
sammiequon
2017/04/08 00:43:32
Done.
| |
163 SendAuthScanDone(kTestFingerprint1[0]); | |
164 SendAuthScanDone(kTestFingerprint2[0]); | |
165 EXPECT_EQ(2, observer.num_matched_auth_scans_received()); | |
166 EXPECT_EQ(0, observer.num_unmatched_auth_scans_received()); | |
167 | |
168 // Verify that by sending two attempts signals of fingerprints that have not | |
Daniel Erat
2017/04/07 23:40:57
s/attempts/attempt/
sammiequon
2017/04/08 00:43:33
Done.
| |
169 // been enrolled, the observer should received two unmatches and zero | |
Daniel Erat
2017/04/07 23:40:56
s/received/receive/, s/unmatches/non-matches/
sammiequon
2017/04/08 00:43:33
Done.
| |
170 // matches. | |
171 SendAuthScanDone(kTestFingerprint3[0]); | |
172 SendAuthScanDone(kTestFingerprint4[0]); | |
173 EXPECT_EQ(2, observer.num_matched_auth_scans_received()); | |
174 EXPECT_EQ(2, observer.num_unmatched_auth_scans_received()); | |
175 } | |
176 | |
177 // Test authentication when multiple users have fingerprints registered. Cover | |
178 // cases such as when both users use the same labels, a user had registered the | |
179 // same fingerprint multiple times, or two users use the same fingerprint. | |
180 TEST_F(FakeBiodClientTest, TestAuthenticateWorkflowMultipleUsers) { | |
181 test_utils::TestBiodObserver observer; | |
182 fake_biod_client_.AddObserver(&observer); | |
183 EXPECT_EQ(0, NumRecords(kTestUserId)); | |
184 | |
185 // Add two users, who have scanned three fingers between the two of them. | |
186 const std::string kUserOne = std::string(kTestUserId) + "1"; | |
187 const std::string kUserTwo = std::string(kTestUserId) + "2"; | |
188 | |
189 const std::string kLabelOne = std::string(kTestLabel) + "1"; | |
190 const std::string kLabelTwo = std::string(kTestLabel) + "2"; | |
191 const std::string kLabelThree = std::string(kTestLabel) + "3"; | |
192 | |
193 // Generate 2 test fingerprints per user. | |
194 auto kUser1Finger1 = GenerateTestFingerprint(2); | |
195 auto kUser1Finger2 = GenerateTestFingerprint(2); | |
196 auto kUser2Finger1 = GenerateTestFingerprint(2); | |
197 auto kUser2Finger2 = GenerateTestFingerprint(2); | |
198 | |
199 EnrollFingerprint(kUserOne, kLabelOne, kUser1Finger1); | |
200 EnrollFingerprint(kUserOne, kLabelTwo, kUser1Finger2); | |
201 // User one has registered finger two twice. | |
202 EnrollFingerprint(kUserOne, kLabelThree, kUser1Finger2); | |
203 EnrollFingerprint(kUserTwo, kLabelOne, kUser2Finger1); | |
204 EnrollFingerprint(kUserTwo, kLabelTwo, kUser2Finger2); | |
205 // User two has allowed user one to unlock his/her account with his/her | |
206 // first finger. | |
207 EnrollFingerprint(kUserTwo, kLabelThree, kUser1Finger1); | |
208 | |
209 dbus::ObjectPath returned_path; | |
210 fake_biod_client_.StartAuthSession( | |
211 base::Bind(&test_utils::CopyObjectPath, &returned_path)); | |
212 task_runner_->RunUntilIdle(); | |
213 EXPECT_NE(returned_path, dbus::ObjectPath()); | |
214 | |
215 // Verify that if a user registers the same finger to two different labels, | |
216 // both labels are returned as matches. | |
217 AuthScanMatches expected_auth_scans_matches; | |
218 expected_auth_scans_matches[kUserOne] = {kLabelTwo, kLabelThree}; | |
219 SendAuthScanDone(kUser1Finger2[0]); | |
220 EXPECT_TRUE( | |
221 observer.CheckExpectedLastAttemptMatches(expected_auth_scans_matches)); | |
222 | |
223 // Verify that a fingerprint associated with one user and one label returns a | |
224 // match with one user and one label. | |
225 expected_auth_scans_matches.clear(); | |
226 expected_auth_scans_matches[kUserTwo] = {kLabelOne}; | |
227 SendAuthScanDone(kUser2Finger1[0]); | |
228 EXPECT_TRUE( | |
229 observer.CheckExpectedLastAttemptMatches(expected_auth_scans_matches)); | |
230 | |
231 // Verify if two users register the same fingerprint, the matches contain | |
232 // both users. | |
233 expected_auth_scans_matches.clear(); | |
234 expected_auth_scans_matches[kUserOne] = {kLabelOne}; | |
235 expected_auth_scans_matches[kUserTwo] = {kLabelThree}; | |
236 SendAuthScanDone(kUser1Finger1[0]); | |
237 EXPECT_TRUE( | |
238 observer.CheckExpectedLastAttemptMatches(expected_auth_scans_matches)); | |
239 | |
240 // Verify if a unregistered finger is scanned, the matches are empty. | |
241 expected_auth_scans_matches.clear(); | |
242 SendAuthScanDone("Unregistered"); | |
243 EXPECT_TRUE( | |
244 observer.CheckExpectedLastAttemptMatches(expected_auth_scans_matches)); | |
245 } | |
246 | |
247 TEST_F(FakeBiodClientTest, TestGetAllRecords) { | |
248 // Verify that initially |kTestUserId| will have no fingerprints. | |
249 int num_fingerprints = -1; | |
250 fake_biod_client_.GetRecordsForUser( | |
251 kTestUserId, base::Bind(&test_utils::CopyNumRecords, &num_fingerprints)); | |
Daniel Erat
2017/04/07 23:40:56
why copy the number of records here instead of jus
sammiequon
2017/04/08 00:43:32
Done.
| |
252 task_runner_->RunUntilIdle(); | |
253 EXPECT_EQ(0, num_fingerprints); | |
254 | |
255 // Verify that after enrolling 2 fingerprints, a GetRecords call return 2 | |
256 // items. | |
257 EnrollNTestFingerprints(kTestUserId, kTestLabel, GenerateTestFingerprint(2), | |
258 2); | |
259 num_fingerprints = -1; | |
260 fake_biod_client_.GetRecordsForUser( | |
261 kTestUserId, base::Bind(&test_utils::CopyNumRecords, &num_fingerprints)); | |
262 task_runner_->RunUntilIdle(); | |
263 EXPECT_EQ(2, num_fingerprints); | |
264 | |
265 // Verify that GetRecords call for a user with no registered fingerprints | |
266 // should return 0 items. | |
267 num_fingerprints = -1; | |
268 fake_biod_client_.GetRecordsForUser( | |
269 "noregisteredginerprints@gmail.com", | |
270 base::Bind(&test_utils::CopyNumRecords, &num_fingerprints)); | |
271 task_runner_->RunUntilIdle(); | |
272 EXPECT_EQ(0, num_fingerprints); | |
273 } | |
274 | |
275 TEST_F(FakeBiodClientTest, TestDestroyingRecords) { | |
276 // Verify that after enrolling 2 fingerprints and destroying them, 0 | |
277 // fingerprints will remain. | |
278 EnrollNTestFingerprints(kTestUserId, kTestLabel, GenerateTestFingerprint(2), | |
279 2); | |
280 EXPECT_EQ(2, NumRecords(kTestUserId)); | |
281 fake_biod_client_.DestroyAllRecords(); | |
282 EXPECT_EQ(0, NumRecords(kTestUserId)); | |
283 } | |
284 | |
285 TEST_F(FakeBiodClientTest, TestGetAndSetRecordLabels) { | |
286 const std::string& kLabelOne = "Finger 1"; | |
Daniel Erat
2017/04/07 23:40:56
const std::string (no reference since this isn't a
sammiequon
2017/04/08 00:43:33
Done.
| |
287 const std::string& kLabelTwo = "Finger 2"; | |
288 | |
289 EnrollFingerprint(kTestUserId, kLabelOne, GenerateTestFingerprint(2)); | |
290 EnrollFingerprint(kTestUserId, kLabelTwo, GenerateTestFingerprint(2)); | |
291 EXPECT_EQ(2, NumRecords(kTestUserId)); | |
292 std::vector<dbus::ObjectPath> enrollment_paths; | |
293 fake_biod_client_.GetRecordsForUser( | |
294 kTestUserId, | |
295 base::Bind(&test_utils::CopyObjectPathArray, &enrollment_paths)); | |
296 task_runner_->RunUntilIdle(); | |
297 EXPECT_EQ(2u, enrollment_paths.size()); | |
298 | |
299 // Verify the labels we get using GetLabel are the same as the one we | |
300 // originally set. | |
301 std::string returned_label; | |
302 fake_biod_client_.RequestRecordLabel( | |
303 enrollment_paths[0], base::Bind(&test_utils::CopyLabel, &returned_label)); | |
304 task_runner_->RunUntilIdle(); | |
305 EXPECT_EQ(kLabelOne, returned_label); | |
306 | |
307 returned_label = ""; | |
308 fake_biod_client_.RequestRecordLabel( | |
309 enrollment_paths[1], base::Bind(&test_utils::CopyLabel, &returned_label)); | |
310 task_runner_->RunUntilIdle(); | |
311 EXPECT_EQ(kLabelTwo, returned_label); | |
312 | |
313 // Verify that by setting a new label, getting the label will return the value | |
314 // of the new label. | |
315 const std::string& kNewLabelTwo = "Finger 2 New"; | |
316 fake_biod_client_.SetRecordLabel(enrollment_paths[1], kNewLabelTwo); | |
317 fake_biod_client_.RequestRecordLabel( | |
318 enrollment_paths[1], base::Bind(&test_utils::CopyLabel, &returned_label)); | |
319 task_runner_->RunUntilIdle(); | |
320 EXPECT_EQ(kNewLabelTwo, returned_label); | |
321 } | |
322 | |
323 } // namespace chromeos | |
OLD | NEW |