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