Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: chrome/service/service_ipc_server_unittest.cc

Issue 2139643003: Use ChannelMojo between browser and service processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/service/service_ipc_server.cc ('k') | chrome/service/service_process.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/service/service_ipc_server.h" 5 #include "chrome/service/service_ipc_server.h"
6 6
7 #include <utility>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
9 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
10 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h" 13 #include "base/run_loop.h"
12 #include "base/single_thread_task_runner.h" 14 #include "base/single_thread_task_runner.h"
13 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
14 #include "base/threading/thread.h" 16 #include "base/threading/thread.h"
15 #include "build/build_config.h" 17 #include "build/build_config.h"
16 #include "chrome/common/service_messages.h" 18 #include "chrome/common/service_messages.h"
17 #include "ipc/ipc_channel.h" 19 #include "ipc/ipc_channel.h"
18 #include "ipc/ipc_channel_handle.h" 20 #include "ipc/ipc_channel_handle.h"
21 #include "ipc/ipc_channel_mojo.h"
22 #include "mojo/public/cpp/system/message_pipe.h"
19 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
20 24
21 namespace { 25 namespace {
22 26
23 void PumpCurrentLoop() { 27 void PumpCurrentLoop() {
24 base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower( 28 base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower(
25 base::MessageLoop::current()); 29 base::MessageLoop::current());
26 base::RunLoop().RunUntilIdle(); 30 base::RunLoop().RunUntilIdle();
27 } 31 }
28 32
29 class FakeServiceIPCServerClient : public ServiceIPCServer::Client { 33 class FakeServiceIPCServerClient : public ServiceIPCServer::Client {
30 public: 34 public:
31 FakeServiceIPCServerClient() {} 35 FakeServiceIPCServerClient() {}
32 ~FakeServiceIPCServerClient() override {} 36 ~FakeServiceIPCServerClient() override {}
33 void OnShutdown() override; 37 void OnShutdown() override;
34 void OnUpdateAvailable() override; 38 void OnUpdateAvailable() override;
35 bool OnIPCClientDisconnect() override; 39 bool OnIPCClientDisconnect() override;
40 mojo::ScopedMessagePipeHandle CreateChannelMessagePipe() override;
36 41
37 int shutdown_calls = 0; 42 int shutdown_calls_ = 0;
38 int update_available_calls = 0; 43 int update_available_calls_ = 0;
39 int ipc_client_disconnect_calls = 0; 44 int ipc_client_disconnect_calls_ = 0;
45 mojo::ScopedMessagePipeHandle channel_handle_;
40 }; 46 };
41 47
42 void FakeServiceIPCServerClient::OnShutdown() { 48 void FakeServiceIPCServerClient::OnShutdown() {
43 shutdown_calls++; 49 shutdown_calls_++;
44 } 50 }
45 51
46 void FakeServiceIPCServerClient::OnUpdateAvailable() { 52 void FakeServiceIPCServerClient::OnUpdateAvailable() {
47 update_available_calls++; 53 update_available_calls_++;
48 } 54 }
49 55
50 bool FakeServiceIPCServerClient::OnIPCClientDisconnect() { 56 bool FakeServiceIPCServerClient::OnIPCClientDisconnect() {
51 ipc_client_disconnect_calls++; 57 ipc_client_disconnect_calls_++;
52 58
53 // Always return true to indicate the server must continue listening for new 59 // Always return true to indicate the server must continue listening for new
54 // connections. 60 // connections.
55 return true; 61 return true;
56 } 62 }
57 63
64 mojo::ScopedMessagePipeHandle
65 FakeServiceIPCServerClient::CreateChannelMessagePipe() {
66 mojo::MessagePipe channel;
67 channel_handle_ = std::move(channel.handle0);
68 return std::move(channel.handle1);
69 }
70
58 class FakeChannelListener : public IPC::Listener { 71 class FakeChannelListener : public IPC::Listener {
59 public: 72 public:
60 FakeChannelListener() {} 73 FakeChannelListener() {}
61 ~FakeChannelListener() override {} 74 ~FakeChannelListener() override {}
62 bool OnMessageReceived(const IPC::Message& message) override { return true; } 75 bool OnMessageReceived(const IPC::Message& message) override { return true; }
63 }; 76 };
64 77
65 class FakeMessageHandler : public ServiceIPCServer::MessageHandler { 78 class FakeMessageHandler : public ServiceIPCServer::MessageHandler {
66 public: 79 public:
67 explicit FakeMessageHandler(bool should_handle); 80 explicit FakeMessageHandler(bool should_handle);
(...skipping 29 matching lines...) Expand all
97 110
98 // Sends |message| to the ServiceIPCServer. 111 // Sends |message| to the ServiceIPCServer.
99 void SendToServiceProcess(IPC::Message* message); 112 void SendToServiceProcess(IPC::Message* message);
100 113
101 IPC::SyncChannel* GetServerChannel() { 114 IPC::SyncChannel* GetServerChannel() {
102 return server_->channel_.get(); 115 return server_->channel_.get();
103 } 116 }
104 117
105 protected: 118 protected:
106 FakeServiceIPCServerClient service_process_client_; 119 FakeServiceIPCServerClient service_process_client_;
107 IPC::ChannelHandle channel_handle_;
108 base::MessageLoopForUI main_message_loop_; 120 base::MessageLoopForUI main_message_loop_;
109 base::Thread io_thread_; 121 base::Thread io_thread_;
110 base::WaitableEvent shutdown_event_; 122 base::WaitableEvent shutdown_event_;
111 std::unique_ptr<ServiceIPCServer> server_; 123 std::unique_ptr<ServiceIPCServer> server_;
112 FakeChannelListener client_process_channel_listener_; 124 FakeChannelListener client_process_channel_listener_;
113 std::unique_ptr<IPC::SyncChannel> client_process_channel_; 125 std::unique_ptr<IPC::SyncChannel> client_process_channel_;
114 }; 126 };
115 127
116 ServiceIPCServerTest::ServiceIPCServerTest() 128 ServiceIPCServerTest::ServiceIPCServerTest()
117 : channel_handle_(IPC::Channel::GenerateUniqueRandomChannelID()), 129 : io_thread_("ServiceIPCServerTest IO"),
118 io_thread_("ServiceIPCServerTest IO"),
119 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, 130 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL,
120 base::WaitableEvent::InitialState::NOT_SIGNALED) {} 131 base::WaitableEvent::InitialState::NOT_SIGNALED) {}
121 132
122 void ServiceIPCServerTest::SetUp() { 133 void ServiceIPCServerTest::SetUp() {
123 base::Thread::Options options; 134 base::Thread::Options options;
135 mojo::MessagePipe channel;
124 options.message_loop_type = base::MessageLoop::TYPE_IO; 136 options.message_loop_type = base::MessageLoop::TYPE_IO;
125 ASSERT_TRUE(io_thread_.StartWithOptions(options)); 137 ASSERT_TRUE(io_thread_.StartWithOptions(options));
126 138
127 server_.reset(new ServiceIPCServer(&service_process_client_, 139 server_.reset(new ServiceIPCServer(&service_process_client_,
128 io_thread_.task_runner(), 140 io_thread_.task_runner(),
129 channel_handle_,
130 &shutdown_event_)); 141 &shutdown_event_));
131 server_->Init(); 142 server_->Init();
132 } 143 }
133 144
134 void ServiceIPCServerTest::TearDown() { 145 void ServiceIPCServerTest::TearDown() {
135 // Close the ipc channels to prevent memory leaks. 146 // Close the ipc channels to prevent memory leaks.
136 if (client_process_channel_) { 147 if (client_process_channel_) {
137 client_process_channel_->Close(); 148 client_process_channel_->Close();
138 PumpLoops(); 149 PumpLoops();
139 } 150 }
140 if (GetServerChannel()) { 151 if (GetServerChannel()) {
141 GetServerChannel()->Close(); 152 GetServerChannel()->Close();
142 PumpLoops(); 153 PumpLoops();
143 } 154 }
144 io_thread_.Stop(); 155 io_thread_.Stop();
145 } 156 }
146 157
147 void ServiceIPCServerTest::PumpLoops() { 158 void ServiceIPCServerTest::PumpLoops() {
148 base::RunLoop run_loop; 159 base::RunLoop run_loop;
149 io_thread_.task_runner()->PostTaskAndReply(FROM_HERE, 160 io_thread_.task_runner()->PostTaskAndReply(FROM_HERE,
150 base::Bind(&PumpCurrentLoop), 161 base::Bind(&PumpCurrentLoop),
151 run_loop.QuitClosure()); 162 run_loop.QuitClosure());
152 run_loop.Run(); 163 run_loop.Run();
153 PumpCurrentLoop(); 164 PumpCurrentLoop();
154 } 165 }
155 166
156 void ServiceIPCServerTest::ConnectClientChannel() { 167 void ServiceIPCServerTest::ConnectClientChannel() {
157 client_process_channel_ = IPC::SyncChannel::Create( 168 client_process_channel_ = IPC::SyncChannel::Create(
158 channel_handle_, 169 IPC::ChannelMojo::CreateClientFactory(
159 IPC::Channel::MODE_NAMED_CLIENT, 170 std::move(service_process_client_.channel_handle_),
160 &client_process_channel_listener_, 171 io_thread_.task_runner()),
161 io_thread_.task_runner(), 172 &client_process_channel_listener_, io_thread_.task_runner(),
162 true /* create_pipe_now */, 173 true /* create_pipe_now */, &shutdown_event_);
163 &shutdown_event_);
164 PumpLoops(); 174 PumpLoops();
165 } 175 }
166 176
167 void ServiceIPCServerTest::DestroyClientChannel() { 177 void ServiceIPCServerTest::DestroyClientChannel() {
168 client_process_channel_.reset(); 178 client_process_channel_.reset();
169 PumpLoops(); 179 PumpLoops();
170 } 180 }
171 181
172 void ServiceIPCServerTest::SendToServiceProcess(IPC::Message* message) { 182 void ServiceIPCServerTest::SendToServiceProcess(IPC::Message* message) {
173 client_process_channel_->Send(message); 183 client_process_channel_->Send(message);
174 PumpLoops(); 184 PumpLoops();
175 } 185 }
176 186
177 TEST_F(ServiceIPCServerTest, ConnectDisconnectReconnect) { 187 TEST_F(ServiceIPCServerTest, ConnectDisconnectReconnect) {
178 // Initially there is no ipc client connected. 188 // Initially there is no ipc client connected.
179 ASSERT_FALSE(server_->is_ipc_client_connected()); 189 ASSERT_FALSE(server_->is_ipc_client_connected());
180 190
181 // When a channel is connected the server is notified via OnChannelConnected. 191 // When a channel is connected the server is notified via OnChannelConnected.
182 ConnectClientChannel(); 192 ConnectClientChannel();
183 ASSERT_TRUE(server_->is_ipc_client_connected()); 193 ASSERT_TRUE(server_->is_ipc_client_connected());
184 194
185 // When the channel is destroyed the server is notified via OnChannelError. 195 // When the channel is destroyed the server is notified via OnChannelError.
186 // In turn, the server notifies its service process client. 196 // In turn, the server notifies its service process client.
187 DestroyClientChannel(); 197 DestroyClientChannel();
188 ASSERT_FALSE(server_->is_ipc_client_connected()); 198 ASSERT_FALSE(server_->is_ipc_client_connected());
189 ASSERT_EQ(1, service_process_client_.ipc_client_disconnect_calls); 199 ASSERT_EQ(1, service_process_client_.ipc_client_disconnect_calls_);
190 200
191 // On Windows only, the server recreates its channel in OnChannelError, if the
192 // service process client tells it to continue listening. On other platforms
193 // the channel is reused for subsequent reconnects by the client process. This
194 // means however that OnChannelConnected is not called again and the server is
195 // only aware of being connected once an IPC message is received.
196 ConnectClientChannel(); 201 ConnectClientChannel();
197 #if defined(OS_WIN)
198 ASSERT_TRUE(server_->is_ipc_client_connected()); 202 ASSERT_TRUE(server_->is_ipc_client_connected());
199 #else
200 ASSERT_FALSE(server_->is_ipc_client_connected());
201 #endif
202 SendToServiceProcess(new ServiceMsg_UpdateAvailable()); 203 SendToServiceProcess(new ServiceMsg_UpdateAvailable());
203 ASSERT_TRUE(server_->is_ipc_client_connected()); 204 ASSERT_TRUE(server_->is_ipc_client_connected());
204 205
205 // Destroy the client process channel again to verify the 206 // Destroy the client process channel again to verify the
206 // ServiceIPCServer::Client is notified again. This means that unlike 207 // ServiceIPCServer::Client is notified again. This means that unlike
207 // OnChannelConnected, OnChannelError is called more than once. 208 // OnChannelConnected, OnChannelError is called more than once.
208 DestroyClientChannel(); 209 DestroyClientChannel();
209 ASSERT_FALSE(server_->is_ipc_client_connected()); 210 ASSERT_FALSE(server_->is_ipc_client_connected());
210 ASSERT_EQ(2, service_process_client_.ipc_client_disconnect_calls); 211 ASSERT_EQ(2, service_process_client_.ipc_client_disconnect_calls_);
211 } 212 }
212 213
213 TEST_F(ServiceIPCServerTest, Shutdown) { 214 TEST_F(ServiceIPCServerTest, Shutdown) {
214 ConnectClientChannel(); 215 ConnectClientChannel();
215 ASSERT_TRUE(server_->is_ipc_client_connected()); 216 ASSERT_TRUE(server_->is_ipc_client_connected());
216 217
217 // When a shutdown message is received, the ServiceIPCServer::Client is 218 // When a shutdown message is received, the ServiceIPCServer::Client is
218 // notified. 219 // notified.
219 SendToServiceProcess(new ServiceMsg_Shutdown()); 220 SendToServiceProcess(new ServiceMsg_Shutdown());
220 ASSERT_EQ(1, service_process_client_.shutdown_calls); 221 ASSERT_EQ(1, service_process_client_.shutdown_calls_);
221 } 222 }
222 223
223 TEST_F(ServiceIPCServerTest, UpdateAvailable) { 224 TEST_F(ServiceIPCServerTest, UpdateAvailable) {
224 ConnectClientChannel(); 225 ConnectClientChannel();
225 ASSERT_TRUE(server_->is_ipc_client_connected()); 226 ASSERT_TRUE(server_->is_ipc_client_connected());
226 227
227 // When a product update message is received, the ServiceIPCServer::Client is 228 // When a product update message is received, the ServiceIPCServer::Client is
228 // notified. 229 // notified.
229 SendToServiceProcess(new ServiceMsg_UpdateAvailable()); 230 SendToServiceProcess(new ServiceMsg_UpdateAvailable());
230 ASSERT_EQ(1, service_process_client_.update_available_calls); 231 ASSERT_EQ(1, service_process_client_.update_available_calls_);
231 } 232 }
232 233
233 TEST_F(ServiceIPCServerTest, SingleMessageHandler) { 234 TEST_F(ServiceIPCServerTest, SingleMessageHandler) {
234 ConnectClientChannel(); 235 ConnectClientChannel();
235 ASSERT_TRUE(server_->is_ipc_client_connected()); 236 ASSERT_TRUE(server_->is_ipc_client_connected());
236 237
237 // Verify that a message handler is offered messages not handled by the server 238 // Verify that a message handler is offered messages not handled by the server
238 // itself. 239 // itself.
239 FakeMessageHandler* handler = 240 FakeMessageHandler* handler =
240 new FakeMessageHandler(true /* should_handle */); 241 new FakeMessageHandler(true /* should_handle */);
(...skipping 15 matching lines...) Expand all
256 new FakeMessageHandler(true /* should_handle */); 257 new FakeMessageHandler(true /* should_handle */);
257 server_->AddMessageHandler(base::WrapUnique(handler2)); 258 server_->AddMessageHandler(base::WrapUnique(handler2));
258 FakeMessageHandler* handler3 = 259 FakeMessageHandler* handler3 =
259 new FakeMessageHandler(true /* should_handle */); 260 new FakeMessageHandler(true /* should_handle */);
260 server_->AddMessageHandler(base::WrapUnique(handler3)); 261 server_->AddMessageHandler(base::WrapUnique(handler3));
261 SendToServiceProcess(new ServiceMsg_DisableCloudPrintProxy()); 262 SendToServiceProcess(new ServiceMsg_DisableCloudPrintProxy());
262 ASSERT_EQ(1, handler1->handle_message_calls_); 263 ASSERT_EQ(1, handler1->handle_message_calls_);
263 ASSERT_EQ(1, handler2->handle_message_calls_); 264 ASSERT_EQ(1, handler2->handle_message_calls_);
264 ASSERT_EQ(0, handler3->handle_message_calls_); 265 ASSERT_EQ(0, handler3->handle_message_calls_);
265 } 266 }
OLDNEW
« no previous file with comments | « chrome/service/service_ipc_server.cc ('k') | chrome/service/service_process.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698