diff options
Diffstat (limited to 'dbus/object_proxy_unittest.cc')
-rw-r--r-- | dbus/object_proxy_unittest.cc | 147 |
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 |