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

Unified Diff: chromeos/dbus/biod/fake_biod_client_unittest.cc

Issue 2644233002: cros: Added a fake fingerprint storage class. (Closed)
Patch Set: Rebased. 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 side-by-side diff with in-line comments
Download patch
Index: chromeos/dbus/biod/fake_biod_client_unittest.cc
diff --git a/chromeos/dbus/biod/fake_biod_client_unittest.cc b/chromeos/dbus/biod/fake_biod_client_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..82812c123aa3796b1dbffdd628548972eb2bfb32
--- /dev/null
+++ b/chromeos/dbus/biod/fake_biod_client_unittest.cc
@@ -0,0 +1,362 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/dbus/biod/fake_biod_client.h"
Daniel Erat 2017/04/07 18:27:56 add a blank line after this one
sammiequon 2017/04/07 20:45:51 Done.
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "dbus/object_path.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+namespace {
+
+const char kTestUserId[] = "testuser@gmail.com";
+const char kTestLabel[] = "testLabel";
+
+void CopyObjectPath(dbus::ObjectPath* dest_path,
Daniel Erat 2017/04/07 18:27:56 instead of copy-and-pasting code from biod_client_
sammiequon 2017/04/07 20:45:51 Yeah, sorry that should've been obvious. Done.
+ const dbus::ObjectPath& src_path) {
+ CHECK(dest_path);
+ *dest_path = src_path;
+}
+
+void CopyObjectPathArray(
+ std::vector<dbus::ObjectPath>* dest_object_paths,
+ const std::vector<dbus::ObjectPath>& src_object_paths) {
+ CHECK(dest_object_paths);
+ *dest_object_paths = src_object_paths;
+}
+
+void CopyNumRecords(int* out_num,
+ const std::vector<dbus::ObjectPath>& object_path_array) {
+ CHECK(out_num);
+ *out_num = int{object_path_array.size()};
Daniel Erat 2017/04/07 18:27:56 static_cast
sammiequon 2017/04/07 20:45:51 https://google.github.io/styleguide/cppguide.html#
Daniel Erat 2017/04/07 20:57:25 i think that this is one place where chromium styl
sammiequon 2017/04/07 22:43:55 Understood, I would say those half are mine :S (sm
+}
+
+void CopyLabel(std::string* expected_label, const std::string& src_label) {
+ CHECK(expected_label);
+ *expected_label = src_label;
+}
+
+// Implementation of BiodClient::Observer for testing.
+class TestBiometricsObserver : public BiodClient::Observer {
Daniel Erat 2017/04/07 18:27:56 put this into the utils class as well; it looks li
sammiequon 2017/04/07 20:45:50 Done.
+ public:
+ TestBiometricsObserver() {}
+ ~TestBiometricsObserver() override {}
+
+ bool CheckExpectedLastAttemptMatches(
+ const AuthScanMatches& expected_matches) {
+ return expected_matches == last_auth_scan_matches_;
+ }
+
+ int num_complete_enroll_scan_received() const {
+ return num_complete_enroll_scan_received_;
+ }
+
+ int num_incomplete_enroll_scan_received() const {
+ return num_incomplete_enroll_scan_received_;
+ }
+
+ int num_matched_auth_scan_received() const {
+ return num_matched_auth_scan_received_;
+ }
+
+ int num_unmatched_auth_scan_received() const {
+ return num_unmatched_auth_scan_received_;
+ }
+
+ // BiodClient::Observer:
+ void BiodServiceRestarted() override {}
+
+ void BiodEnrollScanDoneReceived(biod::ScanResult scan_result,
+ bool is_complete) override {
+ is_complete ? num_complete_enroll_scan_received_++
+ : num_incomplete_enroll_scan_received_++;
+ }
+
+ void BiodAuthScanDoneReceived(biod::ScanResult scan_result,
+ const AuthScanMatches& matches) override {
+ matches.empty() ? num_unmatched_auth_scan_received_++
+ : num_matched_auth_scan_received_++;
+ last_auth_scan_matches_ = matches;
+ }
+
+ void BiodSessionFailedReceived() override { num_failure_received_++; }
+
+ private:
+ int num_complete_enroll_scan_received_ = 0;
+ int num_incomplete_enroll_scan_received_ = 0;
+ int num_matched_auth_scan_received_ = 0;
+ int num_unmatched_auth_scan_received_ = 0;
+ int num_failure_received_ = 0;
+
+ // When auth scan is received, store the result.
+ AuthScanMatches last_auth_scan_matches_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestBiometricsObserver);
+};
+
+} // namepsace
+
+class FakeBiodClientTest : public testing::Test {
+ public:
+ FakeBiodClientTest()
+ : task_runner_(new base::TestSimpleTaskRunner),
+ task_runner_handle_(task_runner_) {}
+ ~FakeBiodClientTest() override {}
+
+ int NumRecords() { return int{fake_biod_client_.records_.size()}; }
Daniel Erat 2017/04/07 18:27:56 again, static_cast
sammiequon 2017/04/07 20:45:51 Done.
+
+ int NumRecords(const std::string& user_id) {
+ std::vector<dbus::ObjectPath> enrollment_paths;
+ fake_biod_client_.GetRecordsForUser(
+ kTestUserId, base::Bind(&CopyObjectPathArray, &enrollment_paths));
+ task_runner_->RunUntilIdle();
+ return int{enrollment_paths.size()};
Daniel Erat 2017/04/07 18:27:56 static_cast
sammiequon 2017/04/07 20:45:51 Done.
+ }
+
+ void SendAuthScanDone(char c) {
+ fake_biod_client_.SendAuthScanDone(c,
+ biod::ScanResult::SCAN_RESULT_SUCCESS);
+ }
+
+ // Helper function which enrolls a fingerprint. Each element in
+ // |fingerprint_data| corresponds to a finger tap.
+ void EnrollFingerprint(const std::string& id,
+ const std::string& label,
+ const std::string& fingerprint_data) {
+ if (fingerprint_data.size() < 1)
+ return;
+
+ dbus::ObjectPath returned_path;
+ fake_biod_client_.StartEnrollSession(
+ id, label, base::Bind(CopyObjectPath, &returned_path));
+ task_runner_->RunUntilIdle();
+ EXPECT_NE(returned_path, dbus::ObjectPath());
+
+ // Send |fingerprint_data| size - 1 incomplete scans.
+ for (int i = 0; i < int{fingerprint_data.size()} - 1; ++i) {
Daniel Erat 2017/04/07 18:27:56 static_cast
sammiequon 2017/04/07 20:45:51 Done.
+ fake_biod_client_.SendEnrollScanDone(
+ fingerprint_data[i], biod::ScanResult::SCAN_RESULT_SUCCESS,
+ false /* is_complete*/);
+ }
+
+ // Finish the enrollment by sending a complete scan signal.
+ fake_biod_client_.SendEnrollScanDone(fingerprint_data.back(),
+ biod::ScanResult::SCAN_RESULT_SUCCESS,
+ true /*is_complete*/);
+ }
+
+ // Helper function which enrolls |n| fingerprints with the same |id|, |label|
+ // and |fingerprint_data|.
+ void EnrollNTestFingerprints(const std::string& id,
+ const std::string& label,
+ const std::string& fingerprint_data,
+ int n) {
+ for (int i = 0; i < n; ++i)
+ EnrollFingerprint(id, label, fingerprint_data);
+ }
+
+ protected:
+ FakeBiodClient fake_biod_client_;
+ scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+ base::ThreadTaskRunnerHandle task_runner_handle_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeBiodClientTest);
+};
+
+TEST_F(FakeBiodClientTest, TestEnrollSessionWorkflow) {
+ TestBiometricsObserver observer;
+ fake_biod_client_.AddObserver(&observer);
+
+ // Verify that successful enrollments gets stored as expected. A fingerprint
+ // that was created with 3 chars should have 2 incomplete scans and 1 complete
+ // scans.
+ EnrollFingerprint(kTestUserId, kTestLabel, "aaa");
+ EXPECT_EQ(1, NumRecords());
+ EXPECT_EQ(2, observer.num_incomplete_enroll_scan_received());
+ EXPECT_EQ(1, observer.num_complete_enroll_scan_received());
+
+ // Verify that the enroll session worflow can be used repeatedly. A
+ // fingerprint that was created with 4 chars should have 3 incomplete scans
+ // and 1 complete scan.
+ EnrollNTestFingerprints(kTestUserId, kTestLabel, "aaaa", 2);
+ EXPECT_EQ(3, NumRecords());
+ EXPECT_EQ(8, observer.num_incomplete_enroll_scan_received());
+ EXPECT_EQ(3, observer.num_complete_enroll_scan_received());
+}
+
+// Test authentication when one user has one or more fingerprints registered.
+// This should be the normal scenario.
+TEST_F(FakeBiodClientTest, TestAuthSessionWorkflowSingleUser) {
+ TestBiometricsObserver observer;
+ fake_biod_client_.AddObserver(&observer);
+ EXPECT_EQ(0, NumRecords(kTestUserId));
+
+ // Add two fingerprints a and b and start an auth session.
+ EnrollFingerprint(kTestUserId, kTestLabel, "a");
+ EnrollFingerprint(kTestUserId, kTestLabel, "b");
+ dbus::ObjectPath returned_path;
+ fake_biod_client_.StartAuthSession(
+ base::Bind(CopyObjectPath, &returned_path));
+ task_runner_->RunUntilIdle();
+ EXPECT_NE(returned_path, dbus::ObjectPath());
+
+ // Verify that by sending two attempts signals of fingerprints that have been
+ // enrolled, the observer should received two matches and zero unmatches.
+ SendAuthScanDone('a');
+ SendAuthScanDone('b');
+ EXPECT_EQ(2, observer.num_matched_auth_scan_received());
+ EXPECT_EQ(0, observer.num_unmatched_auth_scan_received());
+
+ // Verify that by sending two attempts signals of fingerprints that have not
+ // been enrolled, the observer should received two unmatches and zero
+ // matches.
+ SendAuthScanDone('c');
+ SendAuthScanDone('d');
+ EXPECT_EQ(2, observer.num_matched_auth_scan_received());
+ EXPECT_EQ(2, observer.num_unmatched_auth_scan_received());
+}
+
+// Test authentication when multiple users have fingerprints registered. Cover
+// cases such as when both users use the same labels, a user had registered the
+// same fingerprint multiple times, or two users use the same fingerprint.
+TEST_F(FakeBiodClientTest, TestAuthenticateWorkflowMultipleUsers) {
+ TestBiometricsObserver observer;
+ fake_biod_client_.AddObserver(&observer);
+ EXPECT_EQ(0, NumRecords(kTestUserId));
+
+ // Add two users, who have scanned three fingers between the two of them.
+ const std::string& kUserOne = std::string(kTestUserId) + "1";
+ const std::string& kUserTwo = std::string(kTestUserId) + "2";
+
+ const std::string& kLabelOne = std::string(kTestLabel) + "1";
+ const std::string& kLabelTwo = std::string(kTestLabel) + "2";
+ const std::string& kLabelThree = std::string(kTestLabel) + "3";
+
+ EnrollFingerprint(kUserOne, kLabelOne, "a");
+ EnrollFingerprint(kUserOne, kLabelTwo, "b");
+ // User one has registered finger two twice.
+ EnrollFingerprint(kUserOne, kLabelThree, "b");
+ EnrollFingerprint(kUserTwo, kLabelOne, "d");
+ EnrollFingerprint(kUserTwo, kLabelTwo, "e");
+ // User two has allowed user one to unlock his/her account with his/her first
+ // finger.
+ EnrollFingerprint(kUserTwo, kLabelThree, "a");
+
+ dbus::ObjectPath returned_path;
+ fake_biod_client_.StartAuthSession(
+ base::Bind(CopyObjectPath, &returned_path));
+ task_runner_->RunUntilIdle();
+ EXPECT_NE(returned_path, dbus::ObjectPath());
+
+ // Verify that if a user registers the same finger to two different labels,
+ // both labels are returned as matches.
+ AuthScanMatches expected_auth_scan_matches;
+ expected_auth_scan_matches[kUserOne] = {kLabelTwo, kLabelThree};
+ SendAuthScanDone('b');
+ EXPECT_TRUE(
+ observer.CheckExpectedLastAttemptMatches(expected_auth_scan_matches));
+
+ // Verify that a fingerprint associated with one user and one label returns a
+ // match with one user and one label.
+ expected_auth_scan_matches.clear();
+ expected_auth_scan_matches[kUserTwo] = {kLabelOne};
+ SendAuthScanDone('d');
+ EXPECT_TRUE(
+ observer.CheckExpectedLastAttemptMatches(expected_auth_scan_matches));
+
+ // Verify if two users register the same fingerprint, the matches contain both
+ // users.
+ expected_auth_scan_matches.clear();
+ expected_auth_scan_matches[kUserOne] = {kLabelOne};
+ expected_auth_scan_matches[kUserTwo] = {kLabelThree};
+ SendAuthScanDone('a');
+ EXPECT_TRUE(
+ observer.CheckExpectedLastAttemptMatches(expected_auth_scan_matches));
+
+ // Verify if a unregistered finger is scanned, the matches are empty.
+ expected_auth_scan_matches.clear();
+ SendAuthScanDone('f');
+ EXPECT_TRUE(
+ observer.CheckExpectedLastAttemptMatches(expected_auth_scan_matches));
+}
+
+TEST_F(FakeBiodClientTest, TestGetAllRecords) {
+ // Verify that initially |kTestUserId| will have no fingerprints.
+ int num_fingerprints = -1;
+ fake_biod_client_.GetRecordsForUser(
+ kTestUserId, base::Bind(&CopyNumRecords, &num_fingerprints));
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(0, num_fingerprints);
+
+ // Verify that after enrolling 2 fingerprints, a GetRecords call return 2
+ // items.
+ EnrollNTestFingerprints(kTestUserId, kTestLabel, "aa", 2);
+ num_fingerprints = -1;
+ fake_biod_client_.GetRecordsForUser(
+ kTestUserId, base::Bind(&CopyNumRecords, &num_fingerprints));
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(2, num_fingerprints);
+
+ // Verify that GetRecords call for a user with no registered fingerprints
+ // should return 0 items.
+ num_fingerprints = -1;
+ fake_biod_client_.GetRecordsForUser(
+ "noregisteredginerprints@gmail.com",
+ base::Bind(&CopyNumRecords, &num_fingerprints));
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(0, num_fingerprints);
+}
+
+TEST_F(FakeBiodClientTest, TestDestroyingRecords) {
+ // Verify that after enrolling 2 fingerprints and destroying them, 0
+ // fingerprints will remain.
+ EnrollNTestFingerprints(kTestUserId, kTestLabel, "aaaa", 2);
+ EXPECT_EQ(2, NumRecords(kTestUserId));
+ fake_biod_client_.DestroyAllRecords();
+ EXPECT_EQ(0, NumRecords(kTestUserId));
+}
+
+TEST_F(FakeBiodClientTest, TestGetAndSetRecordLabels) {
+ const std::string& kLabelOne = "Finger 1";
+ const std::string& kLabelTwo = "Finger 2";
+
+ EnrollFingerprint(kTestUserId, kLabelOne, "abc");
+ EnrollFingerprint(kTestUserId, kLabelTwo, "abc");
+ EXPECT_EQ(2, NumRecords(kTestUserId));
+ std::vector<dbus::ObjectPath> enrollment_paths;
+ fake_biod_client_.GetRecordsForUser(
+ kTestUserId, base::Bind(&CopyObjectPathArray, &enrollment_paths));
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(2u, enrollment_paths.size());
+
+ // Verify the labels we get using GetLabel are the same as the one we
+ // originally set.
+ std::string returned_label;
+ fake_biod_client_.RequestRecordLabel(enrollment_paths[0],
+ base::Bind(&CopyLabel, &returned_label));
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(kLabelOne, returned_label);
+
+ returned_label = "";
+ fake_biod_client_.RequestRecordLabel(enrollment_paths[1],
+ base::Bind(&CopyLabel, &returned_label));
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(kLabelTwo, returned_label);
+
+ // Verify that by setting a new label, getting the label will return the value
+ // of the new label.
+ const std::string& kNewLabelTwo = "Finger 2 New";
+ fake_biod_client_.SetRecordLabel(enrollment_paths[1], kNewLabelTwo);
+ fake_biod_client_.RequestRecordLabel(enrollment_paths[1],
+ base::Bind(&CopyLabel, &returned_label));
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(kNewLabelTwo, returned_label);
+}
+
+} // namespace chromeos
« chromeos/dbus/biod/fake_biod_client.cc ('K') | « chromeos/dbus/biod/fake_biod_client.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698