You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
5.0 KiB
148 lines
5.0 KiB
// 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
|