This source file includes following definitions.
- DummyHandler
- actual_quit_calls_
- Run
- QuitIfConditionIsSatisified
- OnServiceOwnerChanged
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
#include "dbus/bus.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "dbus/exported_object.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/scoped_dbus_error.h"
#include "dbus/test_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace dbus {
namespace {
DBusHandlerResult DummyHandler(DBusConnection* connection,
DBusMessage* raw_message,
void* user_data) {
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
class RunLoopWithExpectedCount {
public:
RunLoopWithExpectedCount() : expected_quit_calls_(0), actual_quit_calls_(0) {}
~RunLoopWithExpectedCount() {}
void Run(int expected_quit_calls) {
DCHECK_EQ(0, expected_quit_calls_);
DCHECK_EQ(0, actual_quit_calls_);
expected_quit_calls_ = expected_quit_calls;
run_loop_.reset(new base::RunLoop());
run_loop_->Run();
}
void QuitIfConditionIsSatisified() {
if (++actual_quit_calls_ != expected_quit_calls_)
return;
run_loop_->Quit();
expected_quit_calls_ = 0;
actual_quit_calls_ = 0;
}
private:
scoped_ptr<base::RunLoop> run_loop_;
int expected_quit_calls_;
int actual_quit_calls_;
DISALLOW_COPY_AND_ASSIGN(RunLoopWithExpectedCount);
};
void OnServiceOwnerChanged(RunLoopWithExpectedCount* run_loop_state,
std::string* service_owner,
int* num_of_owner_changes,
const std::string& new_service_owner) {
*service_owner = new_service_owner;
++(*num_of_owner_changes);
run_loop_state->QuitIfConditionIsSatisified();
}
}
TEST(BusTest, GetObjectProxy) {
Bus::Options options;
scoped_refptr<Bus> bus = new Bus(options);
ObjectProxy* object_proxy1 =
bus->GetObjectProxy("org.chromium.TestService",
ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy1);
ObjectProxy* object_proxy2 =
bus->GetObjectProxy("org.chromium.TestService",
ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy2);
EXPECT_EQ(object_proxy1, object_proxy2);
ObjectProxy* object_proxy3 =
bus->GetObjectProxy(
"org.chromium.TestService",
ObjectPath("/org/chromium/DifferentTestObject"));
ASSERT_TRUE(object_proxy3);
EXPECT_NE(object_proxy1, object_proxy3);
bus->ShutdownAndBlock();
}
TEST(BusTest, GetObjectProxyIgnoreUnknownService) {
Bus::Options options;
scoped_refptr<Bus> bus = new Bus(options);
ObjectProxy* object_proxy1 =
bus->GetObjectProxyWithOptions(
"org.chromium.TestService",
ObjectPath("/org/chromium/TestObject"),
ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
ASSERT_TRUE(object_proxy1);
ObjectProxy* object_proxy2 =
bus->GetObjectProxyWithOptions(
"org.chromium.TestService",
ObjectPath("/org/chromium/TestObject"),
ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
ASSERT_TRUE(object_proxy2);
EXPECT_EQ(object_proxy1, object_proxy2);
ObjectProxy* object_proxy3 =
bus->GetObjectProxyWithOptions(
"org.chromium.TestService",
ObjectPath("/org/chromium/DifferentTestObject"),
ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
ASSERT_TRUE(object_proxy3);
EXPECT_NE(object_proxy1, object_proxy3);
bus->ShutdownAndBlock();
}
TEST(BusTest, RemoveObjectProxy) {
base::MessageLoop message_loop;
base::Thread::Options thread_options;
thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
base::Thread dbus_thread("D-Bus thread");
dbus_thread.StartWithOptions(thread_options);
Bus::Options options;
options.dbus_task_runner = dbus_thread.message_loop_proxy();
scoped_refptr<Bus> bus = new Bus(options);
ASSERT_FALSE(bus->shutdown_completed());
ASSERT_FALSE(
bus->RemoveObjectProxy("org.chromium.TestService",
ObjectPath("/org/chromium/TestObject"),
base::Bind(&base::DoNothing)));
ObjectProxy* object_proxy1 =
bus->GetObjectProxy("org.chromium.TestService",
ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy1);
object_proxy1->AddRef();
ASSERT_TRUE(
bus->RemoveObjectProxy("org.chromium.TestService",
ObjectPath("/org/chromium/TestObject"),
base::Bind(&base::DoNothing)));
ObjectProxy* object_proxy2 =
bus->GetObjectProxy("org.chromium.TestService",
ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy2);
EXPECT_NE(object_proxy1, object_proxy2);
object_proxy1->Release();
bus->ShutdownOnDBusThreadAndBlock();
EXPECT_TRUE(bus->shutdown_completed());
dbus_thread.Stop();
}
TEST(BusTest, GetExportedObject) {
Bus::Options options;
scoped_refptr<Bus> bus = new Bus(options);
ExportedObject* object_proxy1 =
bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy1);
ExportedObject* object_proxy2 =
bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy2);
EXPECT_EQ(object_proxy1, object_proxy2);
ExportedObject* object_proxy3 =
bus->GetExportedObject(
ObjectPath("/org/chromium/DifferentTestObject"));
ASSERT_TRUE(object_proxy3);
EXPECT_NE(object_proxy1, object_proxy3);
bus->ShutdownAndBlock();
}
TEST(BusTest, UnregisterExportedObject) {
base::Thread::Options thread_options;
thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
base::Thread dbus_thread("D-Bus thread");
dbus_thread.StartWithOptions(thread_options);
Bus::Options options;
options.dbus_task_runner = dbus_thread.message_loop_proxy();
scoped_refptr<Bus> bus = new Bus(options);
ASSERT_FALSE(bus->shutdown_completed());
ExportedObject* object_proxy1 =
bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy1);
object_proxy1->AddRef();
bus->UnregisterExportedObject(ObjectPath("/org/chromium/TestObject"));
ExportedObject* object_proxy2 =
bus->GetExportedObject(ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy2);
EXPECT_NE(object_proxy1, object_proxy2);
object_proxy1->Release();
bus->ShutdownOnDBusThreadAndBlock();
EXPECT_TRUE(bus->shutdown_completed());
dbus_thread.Stop();
}
TEST(BusTest, ShutdownAndBlock) {
Bus::Options options;
scoped_refptr<Bus> bus = new Bus(options);
ASSERT_FALSE(bus->shutdown_completed());
bus->ShutdownAndBlock();
EXPECT_TRUE(bus->shutdown_completed());
}
TEST(BusTest, ShutdownAndBlockWithDBusThread) {
base::Thread::Options thread_options;
thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
base::Thread dbus_thread("D-Bus thread");
dbus_thread.StartWithOptions(thread_options);
Bus::Options options;
options.dbus_task_runner = dbus_thread.message_loop_proxy();
scoped_refptr<Bus> bus = new Bus(options);
ASSERT_FALSE(bus->shutdown_completed());
bus->ShutdownOnDBusThreadAndBlock();
EXPECT_TRUE(bus->shutdown_completed());
dbus_thread.Stop();
}
TEST(BusTest, AddFilterFunction) {
Bus::Options options;
scoped_refptr<Bus> bus = new Bus(options);
bus->Connect();
int data1 = 100;
int data2 = 200;
ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data1));
ASSERT_FALSE(bus->AddFilterFunction(&DummyHandler, &data1));
ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data2));
ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data1));
ASSERT_FALSE(bus->RemoveFilterFunction(&DummyHandler, &data1));
ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data2));
bus->ShutdownAndBlock();
}
TEST(BusTest, DoubleAddAndRemoveMatch) {
Bus::Options options;
scoped_refptr<Bus> bus = new Bus(options);
ScopedDBusError error;
bus->Connect();
bus->AddMatch(
"type='signal',interface='org.chromium.TestService',path='/'",
error.get());
ASSERT_FALSE(error.is_set());
bus->AddMatch(
"type='signal',interface='org.chromium.TestService',path='/'",
error.get());
ASSERT_FALSE(error.is_set());
ASSERT_TRUE(bus->RemoveMatch(
"type='signal',interface='org.chromium.TestService',path='/'",
error.get()));
ASSERT_FALSE(error.is_set());
ASSERT_TRUE(bus->RemoveMatch(
"type='signal',interface='org.chromium.TestService',path='/'",
error.get()));
ASSERT_FALSE(error.is_set());
ASSERT_FALSE(bus->RemoveMatch(
"type='signal',interface='org.chromium.TestService',path='/'",
error.get()));
bus->ShutdownAndBlock();
}
TEST(BusTest, ListenForServiceOwnerChange) {
base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
RunLoopWithExpectedCount run_loop_state;
Bus::Options bus_options;
scoped_refptr<Bus> bus = new Bus(bus_options);
std::string service_owner1;
int num_of_owner_changes1 = 0;
Bus::GetServiceOwnerCallback callback1 =
base::Bind(&OnServiceOwnerChanged,
&run_loop_state,
&service_owner1,
&num_of_owner_changes1);
bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1);
bus->ListenForServiceOwnerChange("org.chromium.TestService", callback1);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(service_owner1.empty());
EXPECT_EQ(0, num_of_owner_changes1);
ASSERT_TRUE(bus->RequestOwnershipAndBlock("org.chromium.TestService",
Bus::REQUIRE_PRIMARY));
run_loop_state.Run(1);
{
std::string current_service_owner =
bus->GetServiceOwnerAndBlock("org.chromium.TestService",
Bus::REPORT_ERRORS);
ASSERT_FALSE(current_service_owner.empty());
EXPECT_EQ(current_service_owner, service_owner1);
EXPECT_EQ(1, num_of_owner_changes1);
}
std::string service_owner2;
int num_of_owner_changes2 = 0;
Bus::GetServiceOwnerCallback callback2 =
base::Bind(&OnServiceOwnerChanged,
&run_loop_state,
&service_owner2,
&num_of_owner_changes2);
bus->ListenForServiceOwnerChange("org.chromium.TestService", callback2);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(bus->ReleaseOwnership("org.chromium.TestService"));
run_loop_state.Run(2);
EXPECT_TRUE(service_owner1.empty());
EXPECT_TRUE(service_owner2.empty());
EXPECT_EQ(2, num_of_owner_changes1);
EXPECT_EQ(1, num_of_owner_changes2);
bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback1);
bus->UnlistenForServiceOwnerChange("org.chromium.TestService", callback2);
base::RunLoop().RunUntilIdle();
bus->ShutdownAndBlock();
EXPECT_TRUE(bus->shutdown_completed());
}
}