Chromium Code Reviews| 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 840690b76dbee36d6475a8c53e239415f616d8d6..698b298abfdde9f61dfabc070ed1584dbe38f05e 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 checkes "section" and "key" |
| // field. For the "value" field, subclass checks it with over riding |
| // VeirfyVariant member function. |
| @@ -192,9 +201,74 @@ 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) { |
| + 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() {} |
| + |
| + // SetNameOwnerChangedCallback mock function. |
| + void SetNameOwnerChangedCallback( |
| + dbus::ObjectProxy::SignalCallback callback) { |
| + callback_ = callback; |
| + } |
| + |
| + // 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 +277,45 @@ 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_| with success configuration. |
| + void SycnhronousInitialize() { |
|
satorux1
2012/11/28 06:43:12
InitializeSync() ? Please also add some comment ex
Seigo Nonaka
2012/11/28 07:00:37
Done.
|
| + EXPECT_CALL(*mock_bus_, GetObjectProxy(ibus::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())); |
| + |
| + MockGetNameOwnerMethodCallHandler mock_get_name_owner_method_call; |
| + EXPECT_CALL(*mock_dbus_proxy, CallMethod(_, _, _)) |
| + .WillOnce(Invoke(&mock_get_name_owner_method_call, |
| + &MockGetNameOwnerMethodCallHandler::Run)); |
| + EXPECT_CALL(*mock_dbus_proxy, SetNameOwnerChangedCallback(_)); |
| + client_->AsyncInitialize(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 +327,7 @@ class IBusConfigClientTest : public testing::Test { |
| TEST_F(IBusConfigClientTest, SetStringValueTest) { |
| // Set expectations |
| + SycnhronousInitialize(); |
| const char value[] = "value"; |
| SetStringValueHandler handler(kSection, kKey, value, HANDLER_SUCCESS); |
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| @@ -243,6 +343,7 @@ TEST_F(IBusConfigClientTest, SetStringValueTest) { |
| TEST_F(IBusConfigClientTest, SetStringValueTest_Fail) { |
| // Set expectations |
| + SycnhronousInitialize(); |
| const char value[] = "value"; |
| SetStringValueHandler handler(kSection, kKey, value, HANDLER_FAIL); |
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| @@ -258,6 +359,7 @@ TEST_F(IBusConfigClientTest, SetStringValueTest_Fail) { |
| TEST_F(IBusConfigClientTest, SetIntValueTest) { |
| // Set expectations |
| + SycnhronousInitialize(); |
| const int value = 1234; |
| SetIntValueHandler handler(kSection, kKey, value, HANDLER_SUCCESS); |
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| @@ -273,6 +375,7 @@ TEST_F(IBusConfigClientTest, SetIntValueTest) { |
| TEST_F(IBusConfigClientTest, SetIntValueTest_Fail) { |
| // Set expectations |
| + SycnhronousInitialize(); |
| const int value = 1234; |
| SetIntValueHandler handler(kSection, kKey, value, HANDLER_FAIL); |
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| @@ -288,6 +391,7 @@ TEST_F(IBusConfigClientTest, SetIntValueTest_Fail) { |
| TEST_F(IBusConfigClientTest, SetBoolValueTest) { |
| // Set expectations |
| + SycnhronousInitialize(); |
| const bool value = true; |
| SetBoolValueHandler handler(kSection, kKey, value, HANDLER_SUCCESS); |
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| @@ -303,6 +407,7 @@ TEST_F(IBusConfigClientTest, SetBoolValueTest) { |
| TEST_F(IBusConfigClientTest, SetBoolValueTest_Fail) { |
| // Set expectations |
| + SycnhronousInitialize(); |
| const bool value = true; |
| SetBoolValueHandler handler(kSection, kKey, value, HANDLER_FAIL); |
| EXPECT_CALL(*mock_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| @@ -318,6 +423,7 @@ TEST_F(IBusConfigClientTest, SetBoolValueTest_Fail) { |
| TEST_F(IBusConfigClientTest, SetStringListValueTest) { |
| // Set expectations |
| + SycnhronousInitialize(); |
| std::vector<std::string> value; |
| value.push_back("Sample value 1"); |
| value.push_back("Sample value 2"); |
| @@ -336,6 +442,7 @@ TEST_F(IBusConfigClientTest, SetStringListValueTest) { |
| TEST_F(IBusConfigClientTest, SetStringListValueTest_Fail) { |
| // Set expectations |
| + SycnhronousInitialize(); |
| std::vector<std::string> value; |
| value.push_back("Sample value 1"); |
| value.push_back("Sample value 2"); |
| @@ -352,4 +459,153 @@ 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, CallMethod(_, _, _)) |
| + .WillOnce(Invoke(&mock_get_name_owner_method_call, |
| + &MockGetNameOwnerMethodCallHandler::Run)); |
| + EXPECT_CALL(*mock_dbus_proxy, SetNameOwnerChangedCallback(_)); |
| + client_->AsyncInitialize(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::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, CallMethod(_, _, _)) |
| + .WillOnce(Invoke(&mock_get_name_owner_method_call, |
| + &MockGetNameOwnerMethodCallHandler::Run)); |
| + NameOwnerChangedHandler name_owner_changed_handler; |
| + EXPECT_CALL(*mock_dbus_proxy, SetNameOwnerChangedCallback(_)) |
| + .WillOnce(Invoke(&name_owner_changed_handler, |
| + &NameOwnerChangedHandler::SetNameOwnerChangedCallback)); |
| + |
| + client_->AsyncInitialize(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::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, CallMethod(_, _, _)) |
| + .WillOnce(Invoke(&mock_get_name_owner_method_call, |
| + &MockGetNameOwnerMethodCallHandler::Run)); |
| + NameOwnerChangedHandler name_owner_changed_handler; |
| + EXPECT_CALL(*mock_dbus_proxy, SetNameOwnerChangedCallback(_)) |
| + .WillOnce(Invoke(&name_owner_changed_handler, |
| + &NameOwnerChangedHandler::SetNameOwnerChangedCallback)); |
| + |
| + client_->AsyncInitialize(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 |