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

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

Issue 2567813002: cros: DBUS client to interact with fingerprint DBUS API. (Closed)
Patch Set: Addressed comments. Created 3 years, 9 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
« no previous file with comments | « chromeos/dbus/biod/biod_biometrics_manager_client.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromeos/dbus/biod/biod_biometrics_manager_client_unittest.cc
diff --git a/chromeos/dbus/biod/biod_biometrics_manager_client_unittest.cc b/chromeos/dbus/biod/biod_biometrics_manager_client_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..93d742147cf35097f8317e00f85830e9a13d2d87
--- /dev/null
+++ b/chromeos/dbus/biod/biod_biometrics_manager_client_unittest.cc
@@ -0,0 +1,395 @@
+// Copyright 2016 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/biod_biometrics_manager_client.h"
+
+#include <map>
+#include <string>
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "dbus/mock_bus.h"
+#include "dbus/mock_object_proxy.h"
+#include "dbus/object_path.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::Return;
+
+namespace chromeos {
+
+namespace {
+
+// Shorthand for a commonly-used constant.
+const char* kInterface = biod::kBiometricsManagerInterface;
+
+void CheckObjectPathCallback(const dbus::ObjectPath& expected_object_path,
+ const dbus::ObjectPath& object_path) {
+ EXPECT_EQ(expected_object_path, object_path);
+}
+
+void CheckObjectPathArrayCallback(
+ const std::vector<dbus::ObjectPath>& expected_object_paths,
+ const std::vector<dbus::ObjectPath>& object_paths) {
+ CHECK_EQ(expected_object_paths.size(), object_paths.size());
+ for (size_t i = 0; i < expected_object_paths.size(); ++i)
+ EXPECT_EQ(expected_object_paths[i], object_paths[i]);
+}
+
+// Matcher that verifies that a dbus::Message has member |name|.
+MATCHER_P(HasMember, name, "") {
+ if (arg->GetMember() != name) {
+ *result_listener << "has member " << arg->GetMember();
+ return false;
+ }
+ return true;
+}
+
+// Runs |callback| with |response|. Needed due to ResponseCallback expecting a
+// bare pointer rather than an std::unique_ptr.
+void RunResponseCallback(dbus::ObjectProxy::ResponseCallback callback,
+ std::unique_ptr<dbus::Response> response) {
+ callback.Run(response.get());
+}
+
+// Implementation of BiodBiometricsManagerClient::Observer.
+class TestBiometricsObserver : public BiodBiometricsManagerClient::Observer {
+ public:
+ TestBiometricsObserver() {}
+ ~TestBiometricsObserver() override {}
+
+ int num_enroll_scan_received() const { return num_enroll_scan_received_; }
+ int num_auth_scan_received() const { return num_auth_scan_received_; }
+ int num_failure_received() const { return num_failure_received_; }
+
+ // BiodBiometricsManagerClient::Observer:
+ void BiodServiceRestarted() override {}
+
+ void BiodEnrollScanDoneReceived(biod::ScanResult scan_result,
+ bool enroll_sesion_complete) override {
+ num_enroll_scan_received_++;
+ }
+
+ void BiodAuthScanDoneReceived(biod::ScanResult scan_result,
+ const AuthScanMatches& matches) override {
+ num_auth_scan_received_++;
+ }
+
+ void BiodSessionFailedReceived() override { num_failure_received_++; }
+
+ private:
+ int num_enroll_scan_received_ = 0;
+ int num_auth_scan_received_ = 0;
+ int num_failure_received_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(TestBiometricsObserver);
+};
+
+} // namespace
+
+class BiodBiometricsManagerClientTest : public testing::Test {
+ public:
+ BiodBiometricsManagerClientTest() {}
+ ~BiodBiometricsManagerClientTest() override {}
+
+ void SetUp() override {
+ dbus::Bus::Options options;
+ options.bus_type = dbus::Bus::SYSTEM;
+ bus_ = new dbus::MockBus(options);
+
+ proxy_ =
+ new dbus::MockObjectProxy(bus_.get(), biod::kBiodServiceName,
+ dbus::ObjectPath(biod::kBiodServicePath));
+
+ // |client_|'s Init() method should request a proxy for communicating with
+ // biometrics api.
+ EXPECT_CALL(*bus_.get(),
+ GetObjectProxy(biod::kBiodServiceName,
+ dbus::ObjectPath(biod::kBiodServicePath)))
+ .WillRepeatedly(Return(proxy_.get()));
+
+ // Save |client_|'s signal callback.
+ EXPECT_CALL(*proxy_.get(), ConnectToSignal(kInterface, _, _, _))
+ .WillRepeatedly(
+ Invoke(this, &BiodBiometricsManagerClientTest::ConnectToSignal));
+
+ // |client_|'s Init() method should register methods.
+ EXPECT_CALL(
+ *proxy_.get(),
+ CallMethod(HasMember(biod::kBiometricsManagerStartEnrollSessionMethod),
+ _, _))
+ .WillRepeatedly(
+ Invoke(this, &BiodBiometricsManagerClientTest::OnCallMethod));
+ EXPECT_CALL(
+ *proxy_.get(),
+ CallMethod(HasMember(biod::kBiometricsManagerGetRecordsForUserMethod),
+ _, _))
+ .WillRepeatedly(
+ Invoke(this, &BiodBiometricsManagerClientTest::OnCallMethod));
+ EXPECT_CALL(
+ *proxy_.get(),
+ CallMethod(HasMember(biod::kBiometricsManagerDestroyAllRecordsMethod),
+ _, _))
+ .WillRepeatedly(
+ Invoke(this, &BiodBiometricsManagerClientTest::OnCallMethod));
+ EXPECT_CALL(
+ *proxy_.get(),
+ CallMethod(HasMember(biod::kBiometricsManagerStartAuthSessionMethod), _,
+ _))
+ .WillRepeatedly(
+ Invoke(this, &BiodBiometricsManagerClientTest::OnCallMethod));
+
+ client_.reset(
+ BiodBiometricsManagerClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION));
+ client_->Init(bus_.get());
+
+ // Execute callbacks posted by Init().
+ base::RunLoop().RunUntilIdle();
+ }
+
+ protected:
+ // Set the response a method is expected to have when a D-Bus method is
+ // called.
+ void SetExpectedResponse(std::unique_ptr<dbus::Response> response) {
+ expected_response_ = std::move(response);
+ }
+
+ // Synchronously passes |signal| to |client_|'s handler, simulating the signal
+ // from biometrics.
+ void EmitSignal(dbus::Signal* signal) {
+ const std::string signal_name = signal->GetMember();
+ const auto it = signal_callbacks_.find(signal_name);
+ ASSERT_TRUE(it != signal_callbacks_.end())
+ << "Client didn't register for signal " << signal_name;
+ it->second.Run(signal);
+ }
+
+ // Passes a enroll scan done signal to |client_|.
+ void EmitEnrollScanDoneSignal(biod::ScanResult scan_result,
+ bool enroll_session_complete) {
+ dbus::Signal signal(kInterface,
+ biod::kBiometricsManagerEnrollScanDoneSignal);
+ dbus::MessageWriter writer(&signal);
+ writer.AppendUint32(uint32_t{scan_result});
+ writer.AppendBool(enroll_session_complete);
+ EmitSignal(&signal);
+ }
+
+ // Passes a auth scan done signal to |client_|.
+ void EmitAuthScanDoneSignal(biod::ScanResult scan_result,
+ const AuthScanMatches& matches) {
+ dbus::Signal signal(kInterface, biod::kBiometricsManagerAuthScanDoneSignal);
+ dbus::MessageWriter writer(&signal);
+ writer.AppendUint32(uint32_t{scan_result});
+
+ dbus::MessageWriter array_writer(nullptr);
+ writer.OpenArray("{sx}", &array_writer);
+ for (auto& match : matches) {
+ dbus::MessageWriter entry_writer(nullptr);
+ array_writer.OpenDictEntry(&entry_writer);
+ entry_writer.AppendString(match.first);
+ entry_writer.AppendArrayOfStrings(match.second);
+ array_writer.CloseContainer(&entry_writer);
+ }
+ writer.CloseContainer(&array_writer);
+ EmitSignal(&signal);
+ }
+
+ // Passes a scan failed signal to |client_|.
+ void EmitScanFailedSignal() {
+ dbus::Signal signal(kInterface,
+ biod::kBiometricsManagerSessionFailedSignal);
+ EmitSignal(&signal);
+ }
+
+ std::unique_ptr<dbus::Response> expected_response_ = nullptr;
+
+ base::MessageLoop message_loop_;
+
+ // Mock bus and proxy for simulating calls.
+ scoped_refptr<dbus::MockBus> bus_;
+ scoped_refptr<dbus::MockObjectProxy> proxy_;
+
+ std::unique_ptr<BiodBiometricsManagerClient> client_;
+
+ // Maps from biod signal name to the corresponding callback provided by
+ // |client_|.
+ std::map<std::string, dbus::ObjectProxy::SignalCallback> signal_callbacks_;
+
+ private:
+ // Handles calls to |proxy_|'s ConnectToSignal() method.
+ void ConnectToSignal(
+ const std::string& interface_name,
+ const std::string& signal_name,
+ dbus::ObjectProxy::SignalCallback signal_callback,
+ dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
+ EXPECT_EQ(interface_name, kInterface);
+ signal_callbacks_[signal_name] = signal_callback;
+ message_loop_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(on_connected_callback, interface_name,
+ signal_name, true /* success */));
+ }
+
+ // Handles calls to |proxy_|'s CallMethod().
+ void OnCallMethod(dbus::MethodCall* method_call,
+ int timeout_ms,
+ const dbus::ObjectProxy::ResponseCallback& callback) {
+ message_loop_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&RunResponseCallback, callback,
+ base::Passed(&expected_response_)));
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(BiodBiometricsManagerClientTest);
+};
+
+TEST_F(BiodBiometricsManagerClientTest, TestStartEnrollSession) {
+ const std::string fake_id("fakeId");
+ const std::string fake_label("fakeLabel");
+ const dbus::ObjectPath fake_object_path(std::string("/fake/object/path"));
+
+ std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
+ dbus::MessageWriter writer(response.get());
+ writer.AppendObjectPath(fake_object_path);
+
+ // Create a fake response with a fake object path. The start enroll
+ // call should return this object path.
+ SetExpectedResponse(std::move(response));
+ client_->StartEnrollSession(
+ fake_id, fake_label,
+ base::Bind(&CheckObjectPathCallback, fake_object_path));
+ base::RunLoop().RunUntilIdle();
+
+ // Verify that by sending a empty reponse or a improperly formatted one, the
+ // response is an empty object path. Also, logs will get printed.
+ SetExpectedResponse(nullptr);
+ client_->StartEnrollSession(
+ fake_id, fake_label,
+ base::Bind(&CheckObjectPathCallback, dbus::ObjectPath()));
+ base::RunLoop().RunUntilIdle();
+
+ std::unique_ptr<dbus::Response> bad_response(dbus::Response::CreateEmpty());
+ dbus::MessageWriter bad_writer(bad_response.get());
+ bad_writer.AppendString("");
+ SetExpectedResponse(std::move(bad_response));
+ client_->StartEnrollSession(
+ fake_id, fake_label,
+ base::Bind(&CheckObjectPathCallback, dbus::ObjectPath()));
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(BiodBiometricsManagerClientTest, TestGetRecordsForUser) {
+ const std::string fake_id("fakeId");
+ const dbus::ObjectPath fake_object_path(std::string("/fake/object/path"));
+ const dbus::ObjectPath fake_object_path2(std::string("/fake/object/path2"));
+ const std::vector<dbus::ObjectPath> fake_object_paths = {fake_object_path,
+ fake_object_path2};
+
+ std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
+ dbus::MessageWriter writer(response.get());
+ writer.AppendArrayOfObjectPaths(fake_object_paths);
+
+ // Create a fake response with an array of fake object paths. The get
+ // enrollments call should return this array of object paths.
+ SetExpectedResponse(std::move(response));
+ client_->GetRecordsForUser(
+ fake_id, base::Bind(&CheckObjectPathArrayCallback, fake_object_paths));
+ base::RunLoop().RunUntilIdle();
+
+ // Verify that by sending a empty reponse the response is an empty array of
+ // object paths. Also, logs will get printed.
+ SetExpectedResponse(nullptr);
+ client_->GetRecordsForUser(fake_id,
+ base::Bind(&CheckObjectPathArrayCallback,
+ std::vector<dbus::ObjectPath>()));
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(BiodBiometricsManagerClientTest, TestDestroyAllRecords) {
+ std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
+
+ SetExpectedResponse(std::move(response));
+ client_->DestroyAllRecords();
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(BiodBiometricsManagerClientTest, TestStartAuthentication) {
+ const dbus::ObjectPath fake_object_path(std::string("/fake/object/path"));
+
+ // Create a fake response with a fake object path. The start authentication
+ // call should return this object path.
+ std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
+ dbus::MessageWriter writer(response.get());
+ writer.AppendObjectPath(fake_object_path);
+
+ SetExpectedResponse(std::move(response));
+ client_->StartAuthSession(
+ base::Bind(&CheckObjectPathCallback, fake_object_path));
+ base::RunLoop().RunUntilIdle();
+
+ // Verify that by sending a empty reponse or a improperly formatted one, the
+ // response is an empty object path. Also, logs will get printed.
+ SetExpectedResponse(nullptr);
+ client_->StartAuthSession(
+ base::Bind(&CheckObjectPathCallback, dbus::ObjectPath()));
+ base::RunLoop().RunUntilIdle();
+
+ std::unique_ptr<dbus::Response> bad_response(dbus::Response::CreateEmpty());
+ dbus::MessageWriter bad_writer(bad_response.get());
+ bad_writer.AppendString("");
+ SetExpectedResponse(std::move(bad_response));
+ client_->StartAuthSession(
+ base::Bind(&CheckObjectPathCallback, dbus::ObjectPath()));
+ base::RunLoop().RunUntilIdle();
+}
+
+// Verify when enroll scan done signals are mocked, observer(s) catch the
+// signals as expected.
+TEST_F(BiodBiometricsManagerClientTest, TestEnrollScanDoneObserver) {
+ TestBiometricsObserver observer1;
+ TestBiometricsObserver observer2;
+ client_->AddObserver(&observer1);
+
+ const biod::ScanResult scan_signal = biod::ScanResult::SCAN_RESULT_SUCCESS;
+ const bool enroll_session_complete = false;
+ EmitEnrollScanDoneSignal(scan_signal, enroll_session_complete);
+ EXPECT_EQ(1, observer1.num_enroll_scan_received());
+ EXPECT_EQ(0, observer2.num_enroll_scan_received());
+
+ client_->AddObserver(&observer2);
+ EmitEnrollScanDoneSignal(scan_signal, enroll_session_complete);
+ EXPECT_EQ(2, observer1.num_enroll_scan_received());
+ EXPECT_EQ(1, observer2.num_enroll_scan_received());
+
+ client_->RemoveObserver(&observer1);
+ EmitEnrollScanDoneSignal(scan_signal, enroll_session_complete);
+ EXPECT_EQ(2, observer1.num_enroll_scan_received());
+ EXPECT_EQ(2, observer2.num_enroll_scan_received());
+}
+
+// Verify when auth scan done signals are mocked, observer(s) catch the signals
+// as expected.
+TEST_F(BiodBiometricsManagerClientTest, TestAuthScanDoneObserver) {
+ TestBiometricsObserver observer1;
+ TestBiometricsObserver observer2;
+ client_->AddObserver(&observer1);
+
+ const biod::ScanResult scan_signal = biod::ScanResult::SCAN_RESULT_SUCCESS;
+ const AuthScanMatches test_attempt;
+ EmitAuthScanDoneSignal(scan_signal, test_attempt);
+ EXPECT_EQ(1, observer1.num_auth_scan_received());
+ EXPECT_EQ(0, observer2.num_auth_scan_received());
+
+ client_->AddObserver(&observer2);
+ EmitAuthScanDoneSignal(scan_signal, test_attempt);
+ EXPECT_EQ(2, observer1.num_auth_scan_received());
+ EXPECT_EQ(1, observer2.num_auth_scan_received());
+
+ client_->RemoveObserver(&observer1);
+ EmitAuthScanDoneSignal(scan_signal, test_attempt);
+ EXPECT_EQ(2, observer1.num_auth_scan_received());
+ EXPECT_EQ(2, observer2.num_auth_scan_received());
+}
+} // namespace chromeos
« no previous file with comments | « chromeos/dbus/biod/biod_biometrics_manager_client.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698