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 |