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 |