blob: 189ef9074a02da81e727aefae08b4458e44200ab [file] [log] [blame]
hashimoto@chromium.orged268092013-10-02 16:53:09 +09001// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/bind.h"
6#include "base/memory/ref_counted.h"
7#include "base/run_loop.h"
8#include "dbus/bus.h"
9#include "dbus/object_proxy.h"
10#include "dbus/test_service.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace dbus {
14namespace {
15
16class ObjectProxyTest : public testing::Test {
17 protected:
dcheng7f5750d2014-12-30 03:30:17 +090018 void SetUp() override {
hashimoto@chromium.orged268092013-10-02 16:53:09 +090019 Bus::Options bus_options;
20 bus_options.bus_type = Bus::SESSION;
21 bus_options.connection_type = Bus::PRIVATE;
22 bus_ = new Bus(bus_options);
hashimoto@chromium.orged268092013-10-02 16:53:09 +090023 }
24
dcheng7f5750d2014-12-30 03:30:17 +090025 void TearDown() override { bus_->ShutdownAndBlock(); }
hashimoto@chromium.orged268092013-10-02 16:53:09 +090026
27 base::MessageLoopForIO message_loop_;
28 scoped_refptr<Bus> bus_;
hashimoto@chromium.orged268092013-10-02 16:53:09 +090029};
30
31// Used as a WaitForServiceToBeAvailableCallback.
derat05e85b32016-08-12 10:41:06 +090032void OnServiceIsAvailable(bool* dest_service_is_available,
33 int* num_calls,
34 bool src_service_is_available) {
35 *dest_service_is_available = src_service_is_available;
36 (*num_calls)++;
hashimoto@chromium.orged268092013-10-02 16:53:09 +090037}
38
derat05e85b32016-08-12 10:41:06 +090039// Used as a callback for TestService::RequestOwnership().
40void OnOwnershipRequestDone(bool success) {
41 ASSERT_TRUE(success);
42}
hashimoto@chromium.orged268092013-10-02 16:53:09 +090043
derat05e85b32016-08-12 10:41:06 +090044// Used as a callback for TestService::ReleaseOwnership().
45void OnOwnershipReleased() {}
46
47TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableRunOnce) {
hashimotof4a4c0d2016-01-05 17:48:03 +090048 TestService::Options options;
49 TestService test_service(options);
hashimotof4a4c0d2016-01-05 17:48:03 +090050 ObjectProxy* object_proxy = bus_->GetObjectProxy(
51 test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
hashimoto@chromium.orged268092013-10-02 16:53:09 +090052
derat05e85b32016-08-12 10:41:06 +090053 // The callback is not yet called because the service is not available.
54 int num_calls = 0;
55 bool service_is_available = false;
56 object_proxy->WaitForServiceToBeAvailable(
57 base::Bind(&OnServiceIsAvailable, &service_is_available, &num_calls));
58 base::RunLoop().RunUntilIdle();
59 EXPECT_EQ(0, num_calls);
60
61 // Start the service. The callback should be called asynchronously.
62 ASSERT_TRUE(test_service.StartService());
63 ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
64 ASSERT_TRUE(test_service.has_ownership());
65 num_calls = 0;
66 base::RunLoop().RunUntilIdle();
67 EXPECT_EQ(1, num_calls);
68 EXPECT_TRUE(service_is_available);
69
70 // Release the service's ownership of its name. The callback should not be
71 // invoked again.
72 test_service.ReleaseOwnership(base::Bind(&OnOwnershipReleased));
73 num_calls = 0;
74 base::RunLoop().RunUntilIdle();
75 EXPECT_EQ(0, num_calls);
76
77 // Take ownership of the name and check that the callback is not called.
78 test_service.RequestOwnership(base::Bind(&OnOwnershipRequestDone));
79 num_calls = 0;
80 base::RunLoop().RunUntilIdle();
81 EXPECT_EQ(0, num_calls);
82}
83
84TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableAlreadyRunning) {
85 TestService::Options options;
86 TestService test_service(options);
87 ObjectProxy* object_proxy = bus_->GetObjectProxy(
88 test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
89
hashimoto@chromium.orged268092013-10-02 16:53:09 +090090 ASSERT_TRUE(test_service.StartService());
91 ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
92 ASSERT_TRUE(test_service.has_ownership());
93
derat05e85b32016-08-12 10:41:06 +090094 // Since the service is already running, the callback should be invoked
95 // immediately (but asynchronously, rather than the callback being invoked
96 // directly within WaitForServiceToBeAvailable()).
97 int num_calls = 0;
98 bool service_is_available = false;
hashimotof4a4c0d2016-01-05 17:48:03 +090099 object_proxy->WaitForServiceToBeAvailable(
derat05e85b32016-08-12 10:41:06 +0900100 base::Bind(&OnServiceIsAvailable, &service_is_available, &num_calls));
101 EXPECT_EQ(0, num_calls);
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900102
derat05e85b32016-08-12 10:41:06 +0900103 base::RunLoop().RunUntilIdle();
104 EXPECT_EQ(1, num_calls);
105 EXPECT_TRUE(service_is_available);
106}
107
108TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableMultipleCallbacks) {
109 TestService::Options options;
110 TestService test_service(options);
111 ObjectProxy* object_proxy = bus_->GetObjectProxy(
112 test_service.service_name(), ObjectPath("/org/chromium/TestObject"));
113
114 // Register two callbacks.
115 int num_calls_1 = 0, num_calls_2 = 0;
116 bool service_is_available_1 = false, service_is_available_2 = false;
117 object_proxy->WaitForServiceToBeAvailable(
118 base::Bind(&OnServiceIsAvailable, &service_is_available_1, &num_calls_1));
119 object_proxy->WaitForServiceToBeAvailable(
120 base::Bind(&OnServiceIsAvailable, &service_is_available_2, &num_calls_2));
121 base::RunLoop().RunUntilIdle();
122 EXPECT_EQ(0, num_calls_1);
123 EXPECT_EQ(0, num_calls_2);
124
125 // Start the service and confirm that both callbacks are invoked.
126 ASSERT_TRUE(test_service.StartService());
127 ASSERT_TRUE(test_service.WaitUntilServiceIsStarted());
128 ASSERT_TRUE(test_service.has_ownership());
129 num_calls_1 = 0;
130 num_calls_2 = 0;
131 base::RunLoop().RunUntilIdle();
132 EXPECT_EQ(1, num_calls_1);
133 EXPECT_EQ(1, num_calls_2);
134 EXPECT_TRUE(service_is_available_1);
135 EXPECT_TRUE(service_is_available_2);
hashimoto@chromium.orged268092013-10-02 16:53:09 +0900136}
137
138} // namespace
139} // namespace dbus