| Index: chromeos/dbus/ibus/ibus_config_client_unittest.cc
|
| diff --git a/chromeos/dbus/ibus/ibus_config_client_unittest.cc b/chromeos/dbus/ibus/ibus_config_client_unittest.cc
|
| index 2b8e5c78eedee6007e5b3ee6dd804082981a9167..bb526d62b9fe646c5b7528193d43f27bf09fbed5 100644
|
| --- a/chromeos/dbus/ibus/ibus_config_client_unittest.cc
|
| +++ b/chromeos/dbus/ibus/ibus_config_client_unittest.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "chromeos/dbus/ibus/ibus_config_client.h"
|
|
|
| +#include <vector>
|
| +
|
| #include "base/bind.h"
|
| #include "base/message_loop.h"
|
| #include "base/values.h"
|
| @@ -37,6 +39,11 @@ class MockErrorCallback {
|
| MOCK_METHOD0(Run, void());
|
| };
|
|
|
| +class MockOnIBusConfigReadyCallback {
|
| + public:
|
| + MOCK_METHOD0(Run, void());
|
| +};
|
| +
|
| // The base class of each type specified SetValue function handler. This class
|
| // checks "section" and "key" field in SetValue message and callback success or
|
| // error callback based on given |success| flag.
|
| @@ -49,6 +56,8 @@ class SetValueVerifierBase {
|
| expected_key_(expected_key),
|
| behavior_(behavior) {}
|
|
|
| + virtual ~SetValueVerifierBase() {}
|
| +
|
| // Handles SetValue method call. This function checks "section" and "key"
|
| // field. For the "value" field, subclass checks it with over riding
|
| // VeirfyVariant member function.
|
| @@ -192,9 +201,79 @@ class SetStringListValueHandler : public SetValueVerifierBase {
|
| DISALLOW_COPY_AND_ASSIGN(SetStringListValueHandler);
|
| };
|
|
|
| +// The class verifies GetNameOwner method call and emits response callback
|
| +// asynchronouslly.
|
| +class MockGetNameOwnerMethodCallHandler {
|
| + public:
|
| + MockGetNameOwnerMethodCallHandler() {}
|
| +
|
| + // Handles CallMethod function.
|
| + void Run(dbus::MethodCall* method_call,
|
| + int timeout_ms,
|
| + const dbus::ObjectProxy::ResponseCallback& callback,
|
| + const dbus::ObjectProxy::ErrorCallback& error_callback) {
|
| + dbus::MessageReader reader(method_call);
|
| + std::string target_name;
|
| + EXPECT_TRUE(reader.PopString(&target_name));
|
| + EXPECT_EQ(ibus::config::kServiceName, target_name);
|
| + EXPECT_FALSE(reader.HasMoreData());
|
| +
|
| + callback_ = callback;
|
| + }
|
| +
|
| + // Invokes reply with given |callback_| in Run method.
|
| + void EmitReplyCallback(const std::string& owner) {
|
| + scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
|
| + dbus::MessageWriter writer(response.get());
|
| + writer.AppendString(owner);
|
| + callback_.Run(response.get());
|
| + }
|
| +
|
| + private:
|
| + dbus::ObjectProxy::ResponseCallback callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MockGetNameOwnerMethodCallHandler);
|
| +};
|
| +
|
| +
|
| +// The class emulate GetNameOwner signal.
|
| +class NameOwnerChangedHandler {
|
| + public:
|
| + NameOwnerChangedHandler() {}
|
| +
|
| + // OnConnectToSignal mock function.
|
| + void OnConnectToSignal(
|
| + const std::string& interface_name,
|
| + const std::string& signal_name,
|
| + const dbus::ObjectProxy::SignalCallback& signal_callback,
|
| + const dbus::ObjectProxy::OnConnectedCallback& on_connected_callback) {
|
| + callback_ = signal_callback;
|
| + on_connected_callback.Run(interface_name, signal_name, true);
|
| + }
|
| +
|
| + // Invokes reply with given |callback_| in Run method.
|
| + void InvokeSignal(const std::string& name,
|
| + const std::string& old_owner,
|
| + const std::string& new_owner) {
|
| + dbus::Signal signal(ibus::kDBusInterface, ibus::kGetNameOwnerMethod);
|
| + dbus::MessageWriter writer(&signal);
|
| + writer.AppendString(name);
|
| + writer.AppendString(old_owner);
|
| + writer.AppendString(new_owner);
|
| + callback_.Run(&signal);
|
| + }
|
| +
|
| + private:
|
| + dbus::ObjectProxy::SignalCallback callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(NameOwnerChangedHandler);
|
| +};
|
| +
|
| +
|
| class IBusConfigClientTest : public testing::Test {
|
| public:
|
| IBusConfigClientTest() {}
|
| +
|
| protected:
|
| virtual void SetUp() OVERRIDE {
|
| dbus::Bus::Options options;
|
| @@ -203,20 +282,50 @@ class IBusConfigClientTest : public testing::Test {
|
| ibus::kServiceName,
|
| dbus::ObjectPath(
|
| ibus::config::kServicePath));
|
| - EXPECT_CALL(*mock_bus_, GetObjectProxy(ibus::kServiceName,
|
| - dbus::ObjectPath(
|
| - ibus::config::kServicePath)))
|
| - .WillOnce(Return(mock_proxy_.get()));
|
| -
|
| EXPECT_CALL(*mock_bus_, ShutdownAndBlock());
|
| client_.reset(IBusConfigClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
|
| mock_bus_));
|
| +
|
| + // Surpress uninteresting mock function call warning.
|
| + EXPECT_CALL(*mock_bus_.get(), AssertOnOriginThread())
|
| + .WillRepeatedly(Return());
|
| }
|
|
|
| virtual void TearDown() OVERRIDE {
|
| mock_bus_->ShutdownAndBlock();
|
| }
|
|
|
| + // Initialize |client_| by replying valid owner name synchronously.
|
| + void InitializeSync() {
|
| + EXPECT_CALL(*mock_bus_, GetObjectProxy(ibus::config::kServiceName,
|
| + dbus::ObjectPath(
|
| + ibus::config::kServicePath)))
|
| + .WillOnce(Return(mock_proxy_.get()));
|
| +
|
| + scoped_refptr<dbus::MockObjectProxy> mock_dbus_proxy
|
| + = new dbus::MockObjectProxy(mock_bus_.get(),
|
| + ibus::kDBusServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath));
|
| + EXPECT_CALL(*mock_bus_,
|
| + GetObjectProxy(ibus::kServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath)))
|
| + .WillOnce(Return(mock_dbus_proxy.get()));
|
| +
|
| + MockGetNameOwnerMethodCallHandler mock_get_name_owner_method_call;
|
| + EXPECT_CALL(*mock_dbus_proxy, CallMethodWithErrorCallback(_, _, _, _))
|
| + .WillOnce(Invoke(&mock_get_name_owner_method_call,
|
| + &MockGetNameOwnerMethodCallHandler::Run));
|
| + NameOwnerChangedHandler handler;
|
| + EXPECT_CALL(*mock_dbus_proxy, ConnectToSignal(
|
| + ibus::kDBusInterface,
|
| + ibus::kNameOwnerChangedSignal,
|
| + _,
|
| + _)).WillOnce(Invoke(&handler,
|
| + &NameOwnerChangedHandler::OnConnectToSignal));
|
| + client_->InitializeAsync(base::Bind(&base::DoNothing));
|
| + mock_get_name_owner_method_call.EmitReplyCallback(":0.1");
|
| + }
|
| +
|
| // The IBus config client to be tested.
|
| scoped_ptr<IBusConfigClient> client_;
|
|
|
| @@ -228,6 +337,7 @@ class IBusConfigClientTest : public testing::Test {
|
|
|
| TEST_F(IBusConfigClientTest, SetStringValueTest) {
|
| // Set expectations
|
| + InitializeSync();
|
| const char value[] = "value";
|
| SetStringValueHandler handler(kSection, kKey, value, HANDLER_SUCCESS);
|
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _))
|
| @@ -243,6 +353,7 @@ TEST_F(IBusConfigClientTest, SetStringValueTest) {
|
|
|
| TEST_F(IBusConfigClientTest, SetStringValueTest_Fail) {
|
| // Set expectations
|
| + InitializeSync();
|
| const char value[] = "value";
|
| SetStringValueHandler handler(kSection, kKey, value, HANDLER_FAIL);
|
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _))
|
| @@ -258,6 +369,7 @@ TEST_F(IBusConfigClientTest, SetStringValueTest_Fail) {
|
|
|
| TEST_F(IBusConfigClientTest, SetIntValueTest) {
|
| // Set expectations
|
| + InitializeSync();
|
| const int value = 1234;
|
| SetIntValueHandler handler(kSection, kKey, value, HANDLER_SUCCESS);
|
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _))
|
| @@ -273,6 +385,7 @@ TEST_F(IBusConfigClientTest, SetIntValueTest) {
|
|
|
| TEST_F(IBusConfigClientTest, SetIntValueTest_Fail) {
|
| // Set expectations
|
| + InitializeSync();
|
| const int value = 1234;
|
| SetIntValueHandler handler(kSection, kKey, value, HANDLER_FAIL);
|
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _))
|
| @@ -288,6 +401,7 @@ TEST_F(IBusConfigClientTest, SetIntValueTest_Fail) {
|
|
|
| TEST_F(IBusConfigClientTest, SetBoolValueTest) {
|
| // Set expectations
|
| + InitializeSync();
|
| const bool value = true;
|
| SetBoolValueHandler handler(kSection, kKey, value, HANDLER_SUCCESS);
|
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _))
|
| @@ -303,6 +417,7 @@ TEST_F(IBusConfigClientTest, SetBoolValueTest) {
|
|
|
| TEST_F(IBusConfigClientTest, SetBoolValueTest_Fail) {
|
| // Set expectations
|
| + InitializeSync();
|
| const bool value = true;
|
| SetBoolValueHandler handler(kSection, kKey, value, HANDLER_FAIL);
|
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _))
|
| @@ -318,6 +433,7 @@ TEST_F(IBusConfigClientTest, SetBoolValueTest_Fail) {
|
|
|
| TEST_F(IBusConfigClientTest, SetStringListValueTest) {
|
| // Set expectations
|
| + InitializeSync();
|
| std::vector<std::string> value;
|
| value.push_back("Sample value 1");
|
| value.push_back("Sample value 2");
|
| @@ -336,6 +452,7 @@ TEST_F(IBusConfigClientTest, SetStringListValueTest) {
|
|
|
| TEST_F(IBusConfigClientTest, SetStringListValueTest_Fail) {
|
| // Set expectations
|
| + InitializeSync();
|
| std::vector<std::string> value;
|
| value.push_back("Sample value 1");
|
| value.push_back("Sample value 2");
|
| @@ -352,4 +469,163 @@ TEST_F(IBusConfigClientTest, SetStringListValueTest_Fail) {
|
| base::Unretained(&error_callback)));
|
| }
|
|
|
| +TEST_F(IBusConfigClientTest, IBusConfigDaemon_NotAvailableTest) {
|
| + MockGetNameOwnerMethodCallHandler mock_get_name_owner_method_call;
|
| +
|
| + EXPECT_CALL(*mock_bus_, GetObjectProxy(ibus::kServiceName,
|
| + dbus::ObjectPath(
|
| + ibus::config::kServicePath)))
|
| + .Times(0);
|
| +
|
| + scoped_refptr<dbus::MockObjectProxy> mock_dbus_proxy
|
| + = new dbus::MockObjectProxy(mock_bus_.get(),
|
| + ibus::kServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath));
|
| + EXPECT_CALL(*mock_bus_,
|
| + GetObjectProxy(ibus::kServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath)))
|
| + .WillOnce(Return(mock_dbus_proxy.get()));
|
| + EXPECT_CALL(*mock_dbus_proxy, CallMethodWithErrorCallback(_, _, _, _))
|
| + .WillOnce(Invoke(&mock_get_name_owner_method_call,
|
| + &MockGetNameOwnerMethodCallHandler::Run));
|
| + NameOwnerChangedHandler handler;
|
| + EXPECT_CALL(*mock_dbus_proxy, ConnectToSignal(
|
| + ibus::kDBusInterface,
|
| + ibus::kNameOwnerChangedSignal,
|
| + _,
|
| + _)).WillOnce(Invoke(&handler,
|
| + &NameOwnerChangedHandler::OnConnectToSignal));
|
| + client_->InitializeAsync(base::Bind(&base::DoNothing));
|
| +
|
| + // Passing empty string means there is no owner, thus ibus-config daemon is
|
| + // not ready.
|
| + mock_get_name_owner_method_call.EmitReplyCallback("");
|
| +
|
| + // Make sure not crashing by function call without initialize.
|
| + const bool value = true;
|
| + EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _)).Times(0);
|
| + MockErrorCallback error_callback;
|
| + EXPECT_CALL(error_callback, Run()).Times(0);
|
| + client_->SetBoolValue(kKey, kSection, value,
|
| + base::Bind(&MockErrorCallback::Run,
|
| + base::Unretained(&error_callback)));
|
| +}
|
| +
|
| +TEST_F(IBusConfigClientTest, IBusConfigDaemon_SlowInitializeTest) {
|
| + MockGetNameOwnerMethodCallHandler mock_get_name_owner_method_call;
|
| +
|
| + EXPECT_CALL(*mock_bus_, GetObjectProxy(ibus::config::kServiceName,
|
| + dbus::ObjectPath(
|
| + ibus::config::kServicePath)))
|
| + .WillOnce(Return(mock_proxy_.get()));
|
| +
|
| + scoped_refptr<dbus::MockObjectProxy> mock_dbus_proxy
|
| + = new dbus::MockObjectProxy(mock_bus_.get(),
|
| + ibus::kServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath));
|
| + EXPECT_CALL(*mock_bus_,
|
| + GetObjectProxy(ibus::kServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath)))
|
| + .WillOnce(Return(mock_dbus_proxy.get()));
|
| + EXPECT_CALL(*mock_dbus_proxy, CallMethodWithErrorCallback(_, _, _, _))
|
| + .WillOnce(Invoke(&mock_get_name_owner_method_call,
|
| + &MockGetNameOwnerMethodCallHandler::Run));
|
| + NameOwnerChangedHandler name_owner_changed_handler;
|
| + EXPECT_CALL(*mock_dbus_proxy, ConnectToSignal(
|
| + ibus::kDBusInterface,
|
| + ibus::kNameOwnerChangedSignal,
|
| + _,
|
| + _)).WillOnce(Invoke(&name_owner_changed_handler,
|
| + &NameOwnerChangedHandler::OnConnectToSignal));
|
| + client_->InitializeAsync(base::Bind(&base::DoNothing));
|
| +
|
| + // Passing empty string means there is no owner, thus ibus-config daemon is
|
| + // not ready.
|
| + mock_get_name_owner_method_call.EmitReplyCallback("");
|
| +
|
| + // Fire NameOwnerChanged signal to emulate ibus-config daemon was acquired
|
| + // well-known name.
|
| + name_owner_changed_handler.InvokeSignal(ibus::config::kServiceName,
|
| + "",
|
| + ":0.1");
|
| +
|
| + // Make sure it is possible to emit method calls.
|
| + const bool value = true;
|
| + SetBoolValueHandler handler(kSection, kKey, value, HANDLER_FAIL);
|
| + EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _))
|
| + .WillOnce(Invoke(&handler, &SetValueVerifierBase::Run));
|
| + MockErrorCallback error_callback;
|
| + EXPECT_CALL(error_callback, Run());
|
| +
|
| + // Call SetBoolValue.
|
| + client_->SetBoolValue(kKey, kSection, value,
|
| + base::Bind(&MockErrorCallback::Run,
|
| + base::Unretained(&error_callback)));
|
| +}
|
| +
|
| +TEST_F(IBusConfigClientTest, IBusConfigDaemon_ShutdownTest) {
|
| + MockGetNameOwnerMethodCallHandler mock_get_name_owner_method_call;
|
| +
|
| + EXPECT_CALL(*mock_bus_, GetObjectProxy(ibus::config::kServiceName,
|
| + dbus::ObjectPath(
|
| + ibus::config::kServicePath)))
|
| + .WillRepeatedly(Return(mock_proxy_.get()));
|
| +
|
| + scoped_refptr<dbus::MockObjectProxy> mock_dbus_proxy
|
| + = new dbus::MockObjectProxy(mock_bus_.get(),
|
| + ibus::kServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath));
|
| + EXPECT_CALL(*mock_bus_,
|
| + GetObjectProxy(ibus::kServiceName,
|
| + dbus::ObjectPath(ibus::kDBusObjectPath)))
|
| + .WillOnce(Return(mock_dbus_proxy.get()));
|
| + EXPECT_CALL(*mock_dbus_proxy, CallMethodWithErrorCallback(_, _, _, _))
|
| + .WillOnce(Invoke(&mock_get_name_owner_method_call,
|
| + &MockGetNameOwnerMethodCallHandler::Run));
|
| + NameOwnerChangedHandler name_owner_changed_handler;
|
| + EXPECT_CALL(*mock_dbus_proxy, ConnectToSignal(
|
| + ibus::kDBusInterface,
|
| + ibus::kNameOwnerChangedSignal,
|
| + _,
|
| + _)).WillOnce(Invoke(&name_owner_changed_handler,
|
| + &NameOwnerChangedHandler::OnConnectToSignal));
|
| + client_->InitializeAsync(base::Bind(&base::DoNothing));
|
| +
|
| + const bool value = true;
|
| + SetBoolValueHandler handler(kSection, kKey, value, HANDLER_FAIL);
|
| + EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _))
|
| + .WillRepeatedly(Invoke(&handler, &SetValueVerifierBase::Run));
|
| + MockErrorCallback error_callback;
|
| + EXPECT_CALL(error_callback, Run()).WillRepeatedly(Return());
|
| +
|
| + // Initialize succeeded sucessfully.
|
| + mock_get_name_owner_method_call.EmitReplyCallback(":0.2");
|
| +
|
| + // Call SetBoolValue.
|
| + client_->SetBoolValue(kKey, kSection, value,
|
| + base::Bind(&MockErrorCallback::Run,
|
| + base::Unretained(&error_callback)));
|
| +
|
| + // Fire NameOwnerChanged signal to emulate shutting down the ibus-config
|
| + // daemon.
|
| + name_owner_changed_handler.InvokeSignal(ibus::config::kServiceName,
|
| + ":0.1",
|
| + "");
|
| +
|
| + // Make sure not crashing on emitting method call.
|
| + client_->SetBoolValue(kKey, kSection, value,
|
| + base::Bind(&MockErrorCallback::Run,
|
| + base::Unretained(&error_callback)));
|
| +
|
| + // Fire NameOwnerChanged signal to emulate that ibus-daemon is revived.
|
| + name_owner_changed_handler.InvokeSignal(ibus::config::kServiceName,
|
| + "",
|
| + ":0.2");
|
| +
|
| + // Make sure it is possible to emit method calls.
|
| + client_->SetBoolValue(kKey, kSection, value,
|
| + base::Bind(&MockErrorCallback::Run,
|
| + base::Unretained(&error_callback)));
|
| +}
|
| +
|
| } // namespace chromeos
|
|
|