Update CrOS OOBE throbber to MD throbber; delete old asset
[chromium-blink-merge.git] / chrome / service / service_ipc_server_unittest.cc
blobefeea79185875117d54a1f22cde069761100a214
1 // Copyright 2015 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.
5 #include "chrome/service/service_ipc_server.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/threading/thread.h"
14 #include "chrome/common/service_messages.h"
15 #include "ipc/ipc_channel.h"
16 #include "ipc/ipc_channel_handle.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace {
21 void PumpCurrentLoop() {
22 base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower(
23 base::MessageLoop::current());
24 base::RunLoop().RunUntilIdle();
27 class FakeServiceIPCServerClient : public ServiceIPCServer::Client {
28 public:
29 FakeServiceIPCServerClient() {}
30 ~FakeServiceIPCServerClient() override {}
31 void OnShutdown() override;
32 void OnUpdateAvailable() override;
33 bool OnIPCClientDisconnect() override;
35 int shutdown_calls = 0;
36 int update_available_calls = 0;
37 int ipc_client_disconnect_calls = 0;
40 void FakeServiceIPCServerClient::OnShutdown() {
41 shutdown_calls++;
44 void FakeServiceIPCServerClient::OnUpdateAvailable() {
45 update_available_calls++;
48 bool FakeServiceIPCServerClient::OnIPCClientDisconnect() {
49 ipc_client_disconnect_calls++;
51 // Always return true to indicate the server must continue listening for new
52 // connections.
53 return true;
56 class FakeChannelListener : public IPC::Listener {
57 public:
58 FakeChannelListener() {}
59 ~FakeChannelListener() override {}
60 bool OnMessageReceived(const IPC::Message& message) override { return true; }
63 class FakeMessageHandler : public ServiceIPCServer::MessageHandler {
64 public:
65 explicit FakeMessageHandler(bool should_handle);
66 bool HandleMessage(const IPC::Message& message) override;
67 bool should_handle_;
68 int handle_message_calls_;
71 FakeMessageHandler::FakeMessageHandler(bool should_handle)
72 : should_handle_(should_handle), handle_message_calls_(0) {
75 bool FakeMessageHandler::HandleMessage(const IPC::Message& message) {
76 handle_message_calls_++;
77 return should_handle_;
80 } // namespace
82 class ServiceIPCServerTest : public ::testing::Test {
83 public:
84 ServiceIPCServerTest();
85 ~ServiceIPCServerTest() override {}
86 void SetUp() override;
87 void TearDown() override;
88 void PumpLoops();
90 // Simulates the browser process connecting to the service process.
91 void ConnectClientChannel();
93 // Simulates the browser process shutting down.
94 void DestroyClientChannel();
96 // Sends |message| to the ServiceIPCServer.
97 void SendToServiceProcess(IPC::Message* message);
99 IPC::SyncChannel* GetServerChannel() {
100 return server_->channel_.get();
103 protected:
104 FakeServiceIPCServerClient service_process_client_;
105 IPC::ChannelHandle channel_handle_;
106 base::MessageLoopForUI main_message_loop_;
107 base::Thread io_thread_;
108 base::WaitableEvent shutdown_event_;
109 scoped_ptr<ServiceIPCServer> server_;
110 FakeChannelListener client_process_channel_listener_;
111 scoped_ptr<IPC::SyncChannel> client_process_channel_;
114 ServiceIPCServerTest::ServiceIPCServerTest()
115 : channel_handle_(IPC::Channel::GenerateUniqueRandomChannelID()),
116 io_thread_("ServiceIPCServerTest IO"),
117 shutdown_event_(true /* manual_reset */, false /* initially_signaled */) {
120 void ServiceIPCServerTest::SetUp() {
121 base::Thread::Options options;
122 options.message_loop_type = base::MessageLoop::TYPE_IO;
123 ASSERT_TRUE(io_thread_.StartWithOptions(options));
125 server_.reset(new ServiceIPCServer(&service_process_client_,
126 io_thread_.task_runner(),
127 channel_handle_,
128 &shutdown_event_));
129 server_->Init();
132 void ServiceIPCServerTest::TearDown() {
133 // Close the ipc channels to prevent memory leaks.
134 if (client_process_channel_) {
135 client_process_channel_->Close();
136 PumpLoops();
138 if (GetServerChannel()) {
139 GetServerChannel()->Close();
140 PumpLoops();
142 io_thread_.Stop();
145 void ServiceIPCServerTest::PumpLoops() {
146 base::RunLoop run_loop;
147 io_thread_.task_runner()->PostTaskAndReply(FROM_HERE,
148 base::Bind(&PumpCurrentLoop),
149 run_loop.QuitClosure());
150 run_loop.Run();
151 PumpCurrentLoop();
154 void ServiceIPCServerTest::ConnectClientChannel() {
155 client_process_channel_ = IPC::SyncChannel::Create(
156 channel_handle_,
157 IPC::Channel::MODE_NAMED_CLIENT,
158 &client_process_channel_listener_,
159 io_thread_.task_runner(),
160 true /* create_pipe_now */,
161 &shutdown_event_);
162 PumpLoops();
165 void ServiceIPCServerTest::DestroyClientChannel() {
166 client_process_channel_.reset();
167 PumpLoops();
170 void ServiceIPCServerTest::SendToServiceProcess(IPC::Message* message) {
171 client_process_channel_->Send(message);
172 PumpLoops();
175 TEST_F(ServiceIPCServerTest, ConnectDisconnectReconnect) {
176 // Initially there is no ipc client connected.
177 ASSERT_FALSE(server_->is_ipc_client_connected());
179 // When a channel is connected the server is notified via OnChannelConnected.
180 ConnectClientChannel();
181 ASSERT_TRUE(server_->is_ipc_client_connected());
183 // When the channel is destroyed the server is notified via OnChannelError.
184 // In turn, the server notifies its service process client.
185 DestroyClientChannel();
186 ASSERT_FALSE(server_->is_ipc_client_connected());
187 ASSERT_EQ(1, service_process_client_.ipc_client_disconnect_calls);
189 // On Windows only, the server recreates its channel in OnChannelError, if the
190 // service process client tells it to continue listening. On other platforms
191 // the channel is reused for subsequent reconnects by the client process. This
192 // means however that OnChannelConnected is not called again and the server is
193 // only aware of being connected once an IPC message is received.
194 ConnectClientChannel();
195 #if defined(OS_WIN)
196 ASSERT_TRUE(server_->is_ipc_client_connected());
197 #else
198 ASSERT_FALSE(server_->is_ipc_client_connected());
199 #endif
200 SendToServiceProcess(new ServiceMsg_UpdateAvailable());
201 ASSERT_TRUE(server_->is_ipc_client_connected());
203 // Destroy the client process channel again to verify the
204 // ServiceIPCServer::Client is notified again. This means that unlike
205 // OnChannelConnected, OnChannelError is called more than once.
206 DestroyClientChannel();
207 ASSERT_FALSE(server_->is_ipc_client_connected());
208 ASSERT_EQ(2, service_process_client_.ipc_client_disconnect_calls);
211 TEST_F(ServiceIPCServerTest, Shutdown) {
212 ConnectClientChannel();
213 ASSERT_TRUE(server_->is_ipc_client_connected());
215 // When a shutdown message is received, the ServiceIPCServer::Client is
216 // notified.
217 SendToServiceProcess(new ServiceMsg_Shutdown());
218 ASSERT_EQ(1, service_process_client_.shutdown_calls);
221 TEST_F(ServiceIPCServerTest, UpdateAvailable) {
222 ConnectClientChannel();
223 ASSERT_TRUE(server_->is_ipc_client_connected());
225 // When a product update message is received, the ServiceIPCServer::Client is
226 // notified.
227 SendToServiceProcess(new ServiceMsg_UpdateAvailable());
228 ASSERT_EQ(1, service_process_client_.update_available_calls);
231 TEST_F(ServiceIPCServerTest, SingleMessageHandler) {
232 ConnectClientChannel();
233 ASSERT_TRUE(server_->is_ipc_client_connected());
235 // Verify that a message handler is offered messages not handled by the server
236 // itself.
237 FakeMessageHandler* handler =
238 new FakeMessageHandler(true /* should_handle */);
239 server_->AddMessageHandler(make_scoped_ptr(handler));
240 SendToServiceProcess(new ServiceMsg_DisableCloudPrintProxy());
241 ASSERT_EQ(1, handler->handle_message_calls_);
244 TEST_F(ServiceIPCServerTest, MultipleMessageHandlers) {
245 ConnectClientChannel();
246 ASSERT_TRUE(server_->is_ipc_client_connected());
248 // If there are multiple handlers they are offered the message in order of
249 // being added until it is handled.
250 FakeMessageHandler* handler1 =
251 new FakeMessageHandler(false /* should_handle */);
252 server_->AddMessageHandler(make_scoped_ptr(handler1));
253 FakeMessageHandler* handler2 =
254 new FakeMessageHandler(true /* should_handle */);
255 server_->AddMessageHandler(make_scoped_ptr(handler2));
256 FakeMessageHandler* handler3 =
257 new FakeMessageHandler(true /* should_handle */);
258 server_->AddMessageHandler(make_scoped_ptr(handler3));
259 SendToServiceProcess(new ServiceMsg_DisableCloudPrintProxy());
260 ASSERT_EQ(1, handler1->handle_message_calls_);
261 ASSERT_EQ(1, handler2->handle_message_calls_);
262 ASSERT_EQ(0, handler3->handle_message_calls_);