summaryrefslogtreecommitdiff
path: root/dbus/object_proxy_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dbus/object_proxy_unittest.cc')
-rw-r--r--dbus/object_proxy_unittest.cc147
1 files changed, 147 insertions, 0 deletions
diff --git a/dbus/object_proxy_unittest.cc b/dbus/object_proxy_unittest.cc
new file mode 100644
index 0000000000..1f5746faa4
--- /dev/null
+++ b/dbus/object_proxy_unittest.cc
@@ -0,0 +1,147 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "dbus/object_proxy.h"
+#include "base/bind.h"
+#include "base/files/file_descriptor_watcher_posix.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "dbus/bus.h"
+#include "dbus/test_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace dbus {
+namespace {
+
+class ObjectProxyTest : public testing::Test {
+ protected:
+ ObjectProxyTest() : file_descriptor_watcher_(&message_loop_) {}
+
+ void SetUp() override {
+ Bus::Options bus_options;
+ bus_options.bus_type = Bus::SESSION;
+ bus_options.connection_type = Bus::PRIVATE;
+ bus_ = new Bus(bus_options);
+ }
+
+ void TearDown() override { bus_->ShutdownAndBlock(); }
+
+ base::MessageLoopForIO message_loop_;
+
+ // This enables FileDescriptorWatcher, which is required by dbus::Watch.
+ base::FileDescriptorWatcher file_descriptor_watcher_;
+
+ scoped_refptr<Bus> bus_;
+};
+
+// Used as a WaitForServiceToBeAvailableCallback.
+void OnServiceIsAvailable(bool* dest_service_is_available,
+ int* num_calls,
+ bool src_service_is_available) {
+ *dest_service_is_available = src_service_is_available;
+ (*num_calls)++;
+}
+
+// Used as a callback for TestService::RequestOwnership().
+void OnOwnershipRequestDone(bool success) {
+ ASSERT_TRUE(success);
+}
+
+// Used as a callback for TestService::ReleaseOwnership().
+void OnOwnershipReleased() {}
+
+TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableRunOnce) {
+ TestService::Options options;
+ TestService test_service(options);
+ ObjectProxy* object_proxy = bus_->GetObjectProxy(
+ test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
+
+ // The callback is not yet called because the service is not available.
+ int num_calls = 0;
+ bool service_is_available = false;
+ object_proxy->WaitForServiceToBeAvailable(
+ base::Bind(&OnServiceIsAvailable, &service_is_available, &num_calls));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, num_calls);
+
+ // Start the service. The callback should be called asynchronously.
+ ASSERT_TRUE(test_service.StartService());
+ ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
+ ASSERT_TRUE(test_service.has_ownership());
+ num_calls = 0;
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, num_calls);
+ EXPECT_TRUE(service_is_available);
+
+ // Release the service's ownership of its name. The callback should not be
+ // invoked again.
+ test_service.ReleaseOwnership(base::Bind(&OnOwnershipReleased));
+ num_calls = 0;
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, num_calls);
+
+ // Take ownership of the name and check that the callback is not called.
+ test_service.RequestOwnership(base::Bind(&OnOwnershipRequestDone));
+ num_calls = 0;
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, num_calls);
+}
+
+TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableAlreadyRunning) {
+ TestService::Options options;
+ TestService test_service(options);
+ ObjectProxy* object_proxy = bus_->GetObjectProxy(
+ test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
+
+ ASSERT_TRUE(test_service.StartService());
+ ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
+ ASSERT_TRUE(test_service.has_ownership());
+
+ // Since the service is already running, the callback should be invoked
+ // immediately (but asynchronously, rather than the callback being invoked
+ // directly within WaitForServiceToBeAvailable()).
+ int num_calls = 0;
+ bool service_is_available = false;
+ object_proxy->WaitForServiceToBeAvailable(
+ base::Bind(&OnServiceIsAvailable, &service_is_available, &num_calls));
+ EXPECT_EQ(0, num_calls);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, num_calls);
+ EXPECT_TRUE(service_is_available);
+}
+
+TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableMultipleCallbacks) {
+ TestService::Options options;
+ TestService test_service(options);
+ ObjectProxy* object_proxy = bus_->GetObjectProxy(
+ test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
+
+ // Register two callbacks.
+ int num_calls_1 = 0, num_calls_2 = 0;
+ bool service_is_available_1 = false, service_is_available_2 = false;
+ object_proxy->WaitForServiceToBeAvailable(
+ base::Bind(&OnServiceIsAvailable, &service_is_available_1, &num_calls_1));
+ object_proxy->WaitForServiceToBeAvailable(
+ base::Bind(&OnServiceIsAvailable, &service_is_available_2, &num_calls_2));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, num_calls_1);
+ EXPECT_EQ(0, num_calls_2);
+
+ // Start the service and confirm that both callbacks are invoked.
+ ASSERT_TRUE(test_service.StartService());
+ ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
+ ASSERT_TRUE(test_service.has_ownership());
+ num_calls_1 = 0;
+ num_calls_2 = 0;
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, num_calls_1);
+ EXPECT_EQ(1, num_calls_2);
+ EXPECT_TRUE(service_is_available_1);
+ EXPECT_TRUE(service_is_available_2);
+}
+
+} // namespace
+} // namespace dbus