blob: 218bdd56abec386239c2e9566bdbace70eb933b4 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
initial.commit09911bf2008-07-26 23:55:294//
5// Unit test for SyncChannel.
6
initial.commit09911bf2008-07-26 23:55:297#include <string>
8#include <vector>
9
10#include "base/basictypes.h"
11#include "base/logging.h"
12#include "base/message_loop.h"
[email protected]aa96ae772009-01-20 22:08:1513#include "base/platform_thread.h"
[email protected]807204142009-05-05 03:31:4414#include "base/stl_util-inl.h"
initial.commit09911bf2008-07-26 23:55:2915#include "base/string_util.h"
16#include "base/thread.h"
[email protected]aa96ae772009-01-20 22:08:1517#include "base/waitable_event.h"
[email protected]82e5ee82009-04-03 02:29:4518#include "chrome/common/ipc_message.h"
19#include "chrome/common/ipc_sync_channel.h"
initial.commit09911bf2008-07-26 23:55:2920#include "testing/gtest/include/gtest/gtest.h"
21
[email protected]82e5ee82009-04-03 02:29:4522
23#define MESSAGES_INTERNAL_FILE "chrome/common/ipc_sync_message_unittest.h"
24#include "chrome/common/ipc_message_macros.h"
initial.commit09911bf2008-07-26 23:55:2925
26using namespace IPC;
[email protected]aa96ae772009-01-20 22:08:1527using base::WaitableEvent;
initial.commit09911bf2008-07-26 23:55:2928
[email protected]dd3eac22008-08-26 07:28:3429namespace {
30
initial.commit09911bf2008-07-26 23:55:2931// Base class for a "process" with listener and IPC threads.
32class Worker : public Channel::Listener, public Message::Sender {
33 public:
34 // Will create a channel without a name.
35 Worker(Channel::Mode mode, const std::string& thread_name)
[email protected]aa96ae772009-01-20 22:08:1536 : done_(new WaitableEvent(false, false)),
37 channel_created_(new WaitableEvent(false, false)),
initial.commit09911bf2008-07-26 23:55:2938 mode_(mode),
39 ipc_thread_((thread_name + "_ipc").c_str()),
40 listener_thread_((thread_name + "_listener").c_str()),
[email protected]8930d472009-02-21 08:05:2841 overrided_thread_(NULL),
42 shutdown_event_(true, false) { }
initial.commit09911bf2008-07-26 23:55:2943
44 // Will create a named channel and use this name for the threads' name.
45 Worker(const std::wstring& channel_name, Channel::Mode mode)
[email protected]aa96ae772009-01-20 22:08:1546 : done_(new WaitableEvent(false, false)),
47 channel_created_(new WaitableEvent(false, false)),
48 channel_name_(channel_name),
initial.commit09911bf2008-07-26 23:55:2949 mode_(mode),
50 ipc_thread_((WideToUTF8(channel_name) + "_ipc").c_str()),
51 listener_thread_((WideToUTF8(channel_name) + "_listener").c_str()),
[email protected]8930d472009-02-21 08:05:2852 overrided_thread_(NULL),
53 shutdown_event_(true, false) { }
initial.commit09911bf2008-07-26 23:55:2954
55 // The IPC thread needs to outlive SyncChannel, so force the correct order of
56 // destruction.
57 virtual ~Worker() {
[email protected]aa96ae772009-01-20 22:08:1558 WaitableEvent listener_done(false, false), ipc_done(false, false);
[email protected]3cdb7af812008-10-24 19:21:1359 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
[email protected]9d4ff5ed2009-03-03 00:21:5660 this, &Worker::OnListenerThreadShutdown1, &listener_done,
[email protected]aa96ae772009-01-20 22:08:1561 &ipc_done));
62 listener_done.Wait();
63 ipc_done.Wait();
initial.commit09911bf2008-07-26 23:55:2964 ipc_thread_.Stop();
65 listener_thread_.Stop();
initial.commit09911bf2008-07-26 23:55:2966 }
67 void AddRef() { }
68 void Release() { }
69 bool Send(Message* msg) { return channel_->Send(msg); }
[email protected]d65cab7a2008-08-12 01:25:4170 bool SendWithTimeout(Message* msg, int timeout_ms) {
71 return channel_->SendWithTimeout(msg, timeout_ms);
72 }
[email protected]aa96ae772009-01-20 22:08:1573 void WaitForChannelCreation() { channel_created_->Wait(); }
[email protected]3cdb7af812008-10-24 19:21:1374 void CloseChannel() {
75 DCHECK(MessageLoop::current() == ListenerThread()->message_loop());
76 channel_->Close();
77 }
initial.commit09911bf2008-07-26 23:55:2978 void Start() {
[email protected]17b89142008-11-07 21:52:1579 StartThread(&listener_thread_, MessageLoop::TYPE_DEFAULT);
[email protected]3cdb7af812008-10-24 19:21:1380 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
initial.commit09911bf2008-07-26 23:55:2981 this, &Worker::OnStart));
82 }
[email protected]ab820df2008-08-26 05:55:1083 void OverrideThread(base::Thread* overrided_thread) {
initial.commit09911bf2008-07-26 23:55:2984 DCHECK(overrided_thread_ == NULL);
85 overrided_thread_ = overrided_thread;
86 }
[email protected]4df10d612008-11-12 00:38:2687 bool SendAnswerToLife(bool pump, int timeout, bool succeed) {
88 int answer = 0;
89 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
90 if (pump)
91 msg->EnableMessagePumping();
92 bool result = SendWithTimeout(msg, timeout);
93 DCHECK(result == succeed);
94 DCHECK(answer == (succeed ? 42 : 0));
95 return result;
96 }
97 bool SendDouble(bool pump, bool succeed) {
98 int answer = 0;
99 SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer);
100 if (pump)
101 msg->EnableMessagePumping();
102 bool result = Send(msg);
103 DCHECK(result == succeed);
104 DCHECK(answer == (succeed ? 10 : 0));
105 return result;
106 }
initial.commit09911bf2008-07-26 23:55:29107 Channel::Mode mode() { return mode_; }
[email protected]aa96ae772009-01-20 22:08:15108 WaitableEvent* done_event() { return done_.get(); }
initial.commit09911bf2008-07-26 23:55:29109
110 protected:
111 // Derived classes need to call this when they've completed their part of
112 // the test.
[email protected]aa96ae772009-01-20 22:08:15113 void Done() { done_->Signal(); }
initial.commit09911bf2008-07-26 23:55:29114 // Functions for dervied classes to implement if they wish.
115 virtual void Run() { }
initial.commit09911bf2008-07-26 23:55:29116 virtual void OnAnswer(int* answer) { NOTREACHED(); }
117 virtual void OnAnswerDelay(Message* reply_msg) {
118 // The message handler map below can only take one entry for
119 // SyncChannelTestMsg_AnswerToLife, so since some classes want
120 // the normal version while other want the delayed reply, we
121 // call the normal version if the derived class didn't override
122 // this function.
123 int answer;
124 OnAnswer(&answer);
125 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, answer);
126 Send(reply_msg);
127 }
[email protected]3cdb7af812008-10-24 19:21:13128 virtual void OnDouble(int in, int* out) { NOTREACHED(); }
129 virtual void OnDoubleDelay(int in, Message* reply_msg) {
130 int result;
131 OnDouble(in, &result);
132 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, result);
133 Send(reply_msg);
134 }
initial.commit09911bf2008-07-26 23:55:29135
136 private:
[email protected]3cdb7af812008-10-24 19:21:13137 base::Thread* ListenerThread() {
138 return overrided_thread_ ? overrided_thread_ : &listener_thread_;
139 }
initial.commit09911bf2008-07-26 23:55:29140 // Called on the listener thread to create the sync channel.
141 void OnStart() {
initial.commit09911bf2008-07-26 23:55:29142 // Link ipc_thread_, listener_thread_ and channel_ altogether.
[email protected]17b89142008-11-07 21:52:15143 StartThread(&ipc_thread_, MessageLoop::TYPE_IO);
initial.commit09911bf2008-07-26 23:55:29144 channel_.reset(new SyncChannel(
[email protected]d65cab7a2008-08-12 01:25:41145 channel_name_, mode_, this, NULL, ipc_thread_.message_loop(), true,
[email protected]8930d472009-02-21 08:05:28146 &shutdown_event_));
[email protected]aa96ae772009-01-20 22:08:15147 channel_created_->Signal();
initial.commit09911bf2008-07-26 23:55:29148 Run();
149 }
150
[email protected]9d4ff5ed2009-03-03 00:21:56151 void OnListenerThreadShutdown1(WaitableEvent* listener_event,
152 WaitableEvent* ipc_event) {
[email protected]3cdb7af812008-10-24 19:21:13153 // SyncChannel needs to be destructed on the thread that it was created on.
154 channel_.reset();
[email protected]9d4ff5ed2009-03-03 00:21:56155
156 MessageLoop::current()->RunAllPending();
[email protected]aa96ae772009-01-20 22:08:15157
[email protected]3cdb7af812008-10-24 19:21:13158 ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
[email protected]9d4ff5ed2009-03-03 00:21:56159 this, &Worker::OnIPCThreadShutdown, listener_event, ipc_event));
[email protected]3cdb7af812008-10-24 19:21:13160 }
161
[email protected]9d4ff5ed2009-03-03 00:21:56162 void OnIPCThreadShutdown(WaitableEvent* listener_event,
163 WaitableEvent* ipc_event) {
164 MessageLoop::current()->RunAllPending();
[email protected]aa96ae772009-01-20 22:08:15165 ipc_event->Signal();
[email protected]9d4ff5ed2009-03-03 00:21:56166
167 listener_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
168 this, &Worker::OnListenerThreadShutdown2, listener_event));
169 }
170
171 void OnListenerThreadShutdown2(WaitableEvent* listener_event) {
172 MessageLoop::current()->RunAllPending();
173 listener_event->Signal();
[email protected]3cdb7af812008-10-24 19:21:13174 }
175
initial.commit09911bf2008-07-26 23:55:29176 void OnMessageReceived(const Message& message) {
177 IPC_BEGIN_MESSAGE_MAP(Worker, message)
[email protected]3cdb7af812008-10-24 19:21:13178 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay)
initial.commit09911bf2008-07-26 23:55:29179 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife,
180 OnAnswerDelay)
181 IPC_END_MESSAGE_MAP()
182 }
183
[email protected]17b89142008-11-07 21:52:15184 void StartThread(base::Thread* thread, MessageLoop::Type type) {
[email protected]ab820df2008-08-26 05:55:10185 base::Thread::Options options;
[email protected]17b89142008-11-07 21:52:15186 options.message_loop_type = type;
[email protected]ab820df2008-08-26 05:55:10187 thread->StartWithOptions(options);
188 }
189
[email protected]aa96ae772009-01-20 22:08:15190 scoped_ptr<WaitableEvent> done_;
191 scoped_ptr<WaitableEvent> channel_created_;
initial.commit09911bf2008-07-26 23:55:29192 std::wstring channel_name_;
193 Channel::Mode mode_;
194 scoped_ptr<SyncChannel> channel_;
[email protected]ab820df2008-08-26 05:55:10195 base::Thread ipc_thread_;
196 base::Thread listener_thread_;
197 base::Thread* overrided_thread_;
initial.commit09911bf2008-07-26 23:55:29198
[email protected]8930d472009-02-21 08:05:28199 base::WaitableEvent shutdown_event_;
200
initial.commit09911bf2008-07-26 23:55:29201 DISALLOW_EVIL_CONSTRUCTORS(Worker);
202};
203
204
205// Starts the test with the given workers. This function deletes the workers
206// when it's done.
207void RunTest(std::vector<Worker*> workers) {
initial.commit09911bf2008-07-26 23:55:29208 // First we create the workers that are channel servers, or else the other
209 // workers' channel initialization might fail because the pipe isn't created..
210 for (size_t i = 0; i < workers.size(); ++i) {
211 if (workers[i]->mode() == Channel::MODE_SERVER) {
212 workers[i]->Start();
213 workers[i]->WaitForChannelCreation();
214 }
215 }
216
217 // now create the clients
218 for (size_t i = 0; i < workers.size(); ++i) {
219 if (workers[i]->mode() == Channel::MODE_CLIENT)
220 workers[i]->Start();
221 }
222
223 // wait for all the workers to finish
initial.commit09911bf2008-07-26 23:55:29224 for (size_t i = 0; i < workers.size(); ++i)
[email protected]aa96ae772009-01-20 22:08:15225 workers[i]->done_event()->Wait();
initial.commit09911bf2008-07-26 23:55:29226
[email protected]82e5ee82009-04-03 02:29:45227 STLDeleteContainerPointers(workers.begin(), workers.end());
initial.commit09911bf2008-07-26 23:55:29228}
229
[email protected]dd3eac22008-08-26 07:28:34230} // namespace
231
[email protected]9629c0e2009-02-04 23:16:29232class IPCSyncChannelTest : public testing::Test {
233 private:
234 MessageLoop message_loop_;
235};
236
initial.commit09911bf2008-07-26 23:55:29237//-----------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34238
239namespace {
240
initial.commit09911bf2008-07-26 23:55:29241class SimpleServer : public Worker {
242 public:
[email protected]3cdb7af812008-10-24 19:21:13243 SimpleServer(bool pump_during_send)
244 : Worker(Channel::MODE_SERVER, "simpler_server"),
245 pump_during_send_(pump_during_send) { }
initial.commit09911bf2008-07-26 23:55:29246 void Run() {
[email protected]aa96ae772009-01-20 22:08:15247 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
initial.commit09911bf2008-07-26 23:55:29248 Done();
249 }
[email protected]3cdb7af812008-10-24 19:21:13250
251 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29252};
253
254class SimpleClient : public Worker {
255 public:
256 SimpleClient() : Worker(Channel::MODE_CLIENT, "simple_client") { }
257
258 void OnAnswer(int* answer) {
259 *answer = 42;
260 Done();
261 }
262};
263
[email protected]3cdb7af812008-10-24 19:21:13264void Simple(bool pump_during_send) {
initial.commit09911bf2008-07-26 23:55:29265 std::vector<Worker*> workers;
[email protected]3cdb7af812008-10-24 19:21:13266 workers.push_back(new SimpleServer(pump_during_send));
initial.commit09911bf2008-07-26 23:55:29267 workers.push_back(new SimpleClient());
268 RunTest(workers);
269}
270
[email protected]3cdb7af812008-10-24 19:21:13271} // namespace
272
273// Tests basic synchronous call
274TEST_F(IPCSyncChannelTest, Simple) {
275 Simple(false);
276 Simple(true);
277}
initial.commit09911bf2008-07-26 23:55:29278
279//-----------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34280
281namespace {
282
initial.commit09911bf2008-07-26 23:55:29283class DelayClient : public Worker {
284 public:
285 DelayClient() : Worker(Channel::MODE_CLIENT, "delay_client") { }
286
287 void OnAnswerDelay(Message* reply_msg) {
288 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
289 Send(reply_msg);
290 Done();
291 }
292};
293
[email protected]3cdb7af812008-10-24 19:21:13294void DelayReply(bool pump_during_send) {
initial.commit09911bf2008-07-26 23:55:29295 std::vector<Worker*> workers;
[email protected]3cdb7af812008-10-24 19:21:13296 workers.push_back(new SimpleServer(pump_during_send));
initial.commit09911bf2008-07-26 23:55:29297 workers.push_back(new DelayClient());
298 RunTest(workers);
299}
300
[email protected]3cdb7af812008-10-24 19:21:13301} // namespace
302
303// Tests that asynchronous replies work
304TEST_F(IPCSyncChannelTest, DelayReply) {
305 DelayReply(false);
306 DelayReply(true);
307}
initial.commit09911bf2008-07-26 23:55:29308
309//-----------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34310
311namespace {
312
initial.commit09911bf2008-07-26 23:55:29313class NoHangServer : public Worker {
314 public:
[email protected]aa96ae772009-01-20 22:08:15315 explicit NoHangServer(WaitableEvent* got_first_reply, bool pump_during_send)
[email protected]3cdb7af812008-10-24 19:21:13316 : Worker(Channel::MODE_SERVER, "no_hang_server"),
317 got_first_reply_(got_first_reply),
318 pump_during_send_(pump_during_send) { }
initial.commit09911bf2008-07-26 23:55:29319 void Run() {
[email protected]aa96ae772009-01-20 22:08:15320 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
321 got_first_reply_->Signal();
initial.commit09911bf2008-07-26 23:55:29322
[email protected]aa96ae772009-01-20 22:08:15323 SendAnswerToLife(pump_during_send_, base::kNoTimeout, false);
initial.commit09911bf2008-07-26 23:55:29324 Done();
325 }
326
[email protected]aa96ae772009-01-20 22:08:15327 WaitableEvent* got_first_reply_;
[email protected]3cdb7af812008-10-24 19:21:13328 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29329};
330
331class NoHangClient : public Worker {
332 public:
[email protected]aa96ae772009-01-20 22:08:15333 explicit NoHangClient(WaitableEvent* got_first_reply)
initial.commit09911bf2008-07-26 23:55:29334 : Worker(Channel::MODE_CLIENT, "no_hang_client"),
335 got_first_reply_(got_first_reply) { }
336
337 virtual void OnAnswerDelay(Message* reply_msg) {
338 // Use the DELAY_REPLY macro so that we can force the reply to be sent
339 // before this function returns (when the channel will be reset).
340 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
341 Send(reply_msg);
342 got_first_reply_->Wait();
343 CloseChannel();
344 Done();
345 }
346
[email protected]aa96ae772009-01-20 22:08:15347 WaitableEvent* got_first_reply_;
initial.commit09911bf2008-07-26 23:55:29348};
349
[email protected]3cdb7af812008-10-24 19:21:13350void NoHang(bool pump_during_send) {
[email protected]aa96ae772009-01-20 22:08:15351 WaitableEvent got_first_reply(false, false);
initial.commit09911bf2008-07-26 23:55:29352 std::vector<Worker*> workers;
[email protected]3cdb7af812008-10-24 19:21:13353 workers.push_back(new NoHangServer(&got_first_reply, pump_during_send));
initial.commit09911bf2008-07-26 23:55:29354 workers.push_back(new NoHangClient(&got_first_reply));
355 RunTest(workers);
356}
357
[email protected]3cdb7af812008-10-24 19:21:13358} // namespace
359
360// Tests that caller doesn't hang if receiver dies
361TEST_F(IPCSyncChannelTest, NoHang) {
362 NoHang(false);
363 NoHang(true);
364}
initial.commit09911bf2008-07-26 23:55:29365
366//-----------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34367
368namespace {
369
[email protected]3cdb7af812008-10-24 19:21:13370class UnblockServer : public Worker {
initial.commit09911bf2008-07-26 23:55:29371 public:
[email protected]3cdb7af812008-10-24 19:21:13372 UnblockServer(bool pump_during_send)
373 : Worker(Channel::MODE_SERVER, "unblock_server"),
374 pump_during_send_(pump_during_send) { }
initial.commit09911bf2008-07-26 23:55:29375 void Run() {
[email protected]aa96ae772009-01-20 22:08:15376 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
initial.commit09911bf2008-07-26 23:55:29377 Done();
378 }
379
380 void OnDouble(int in, int* out) {
381 *out = in * 2;
382 }
[email protected]3cdb7af812008-10-24 19:21:13383
384 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29385};
386
[email protected]3cdb7af812008-10-24 19:21:13387class UnblockClient : public Worker {
initial.commit09911bf2008-07-26 23:55:29388 public:
[email protected]3cdb7af812008-10-24 19:21:13389 UnblockClient(bool pump_during_send)
390 : Worker(Channel::MODE_CLIENT, "unblock_client"),
391 pump_during_send_(pump_during_send) { }
initial.commit09911bf2008-07-26 23:55:29392
393 void OnAnswer(int* answer) {
[email protected]4df10d612008-11-12 00:38:26394 SendDouble(pump_during_send_, true);
395 *answer = 42;
initial.commit09911bf2008-07-26 23:55:29396 Done();
397 }
[email protected]3cdb7af812008-10-24 19:21:13398
399 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29400};
401
[email protected]3cdb7af812008-10-24 19:21:13402void Unblock(bool server_pump, bool client_pump) {
403 std::vector<Worker*> workers;
404 workers.push_back(new UnblockServer(server_pump));
405 workers.push_back(new UnblockClient(client_pump));
406 RunTest(workers);
407}
408
[email protected]dd3eac22008-08-26 07:28:34409} // namespace
410
initial.commit09911bf2008-07-26 23:55:29411// Tests that the caller unblocks to answer a sync message from the receiver.
[email protected]3cdb7af812008-10-24 19:21:13412TEST_F(IPCSyncChannelTest, Unblock) {
413 Unblock(false, false);
414 Unblock(false, true);
415 Unblock(true, false);
416 Unblock(true, true);
417}
418
419//-----------------------------------------------------------------------------
420
421namespace {
422
423class RecursiveServer : public Worker {
424 public:
425 explicit RecursiveServer(
426 bool expected_send_result, bool pump_first, bool pump_second)
427 : Worker(Channel::MODE_SERVER, "recursive_server"),
428 expected_send_result_(expected_send_result),
429 pump_first_(pump_first), pump_second_(pump_second) { }
430 void Run() {
[email protected]4df10d612008-11-12 00:38:26431 SendDouble(pump_first_, expected_send_result_);
[email protected]3cdb7af812008-10-24 19:21:13432 Done();
433 }
434
435 void OnDouble(int in, int* out) {
[email protected]4df10d612008-11-12 00:38:26436 *out = in * 2;
[email protected]aa96ae772009-01-20 22:08:15437 SendAnswerToLife(pump_second_, base::kNoTimeout, expected_send_result_);
[email protected]3cdb7af812008-10-24 19:21:13438 }
439
440 bool expected_send_result_, pump_first_, pump_second_;
441};
442
443class RecursiveClient : public Worker {
444 public:
445 explicit RecursiveClient(bool pump_during_send, bool close_channel)
446 : Worker(Channel::MODE_CLIENT, "recursive_client"),
447 pump_during_send_(pump_during_send), close_channel_(close_channel) { }
448
449 void OnDoubleDelay(int in, Message* reply_msg) {
[email protected]4df10d612008-11-12 00:38:26450 SendDouble(pump_during_send_, !close_channel_);
[email protected]c690a182008-10-24 23:10:32451 if (close_channel_) {
452 delete reply_msg;
453 } else {
[email protected]3cdb7af812008-10-24 19:21:13454 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2);
455 Send(reply_msg);
456 }
457 Done();
458 }
459
460 void OnAnswerDelay(Message* reply_msg) {
461 if (close_channel_) {
[email protected]c690a182008-10-24 23:10:32462 delete reply_msg;
[email protected]3cdb7af812008-10-24 19:21:13463 CloseChannel();
464 } else {
465 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
466 Send(reply_msg);
467 }
468 }
469
470 bool pump_during_send_, close_channel_;
471};
472
473void Recursive(
474 bool server_pump_first, bool server_pump_second, bool client_pump) {
initial.commit09911bf2008-07-26 23:55:29475 std::vector<Worker*> workers;
[email protected]3cdb7af812008-10-24 19:21:13476 workers.push_back(
477 new RecursiveServer(true, server_pump_first, server_pump_second));
478 workers.push_back(new RecursiveClient(client_pump, false));
initial.commit09911bf2008-07-26 23:55:29479 RunTest(workers);
480}
481
[email protected]3cdb7af812008-10-24 19:21:13482} // namespace
483
484// Tests a server calling Send while another Send is pending.
485TEST_F(IPCSyncChannelTest, Recursive) {
486 Recursive(false, false, false);
487 Recursive(false, false, true);
488 Recursive(false, true, false);
489 Recursive(false, true, true);
490 Recursive(true, false, false);
491 Recursive(true, false, true);
492 Recursive(true, true, false);
493 Recursive(true, true, true);
494}
495
496//-----------------------------------------------------------------------------
497
498namespace {
499
500void RecursiveNoHang(
501 bool server_pump_first, bool server_pump_second, bool client_pump) {
502 std::vector<Worker*> workers;
503 workers.push_back(
504 new RecursiveServer(false, server_pump_first, server_pump_second));
505 workers.push_back(new RecursiveClient(client_pump, true));
506 RunTest(workers);
507}
508
509} // namespace
510
511// Tests that if a caller makes a sync call during an existing sync call and
512// the receiver dies, neither of the Send() calls hang.
513TEST_F(IPCSyncChannelTest, RecursiveNoHang) {
514 RecursiveNoHang(false, false, false);
515 RecursiveNoHang(false, false, true);
516 RecursiveNoHang(false, true, false);
517 RecursiveNoHang(false, true, true);
518 RecursiveNoHang(true, false, false);
519 RecursiveNoHang(true, false, true);
520 RecursiveNoHang(true, true, false);
521 RecursiveNoHang(true, true, true);
522}
initial.commit09911bf2008-07-26 23:55:29523
524//-----------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34525
526namespace {
527
initial.commit09911bf2008-07-26 23:55:29528class MultipleServer1 : public Worker {
529 public:
[email protected]3cdb7af812008-10-24 19:21:13530 MultipleServer1(bool pump_during_send)
531 : Worker(L"test_channel1", Channel::MODE_SERVER),
532 pump_during_send_(pump_during_send) { }
533
initial.commit09911bf2008-07-26 23:55:29534 void Run() {
[email protected]4df10d612008-11-12 00:38:26535 SendDouble(pump_during_send_, true);
initial.commit09911bf2008-07-26 23:55:29536 Done();
537 }
[email protected]3cdb7af812008-10-24 19:21:13538
539 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29540};
541
542class MultipleClient1 : public Worker {
543 public:
[email protected]aa96ae772009-01-20 22:08:15544 MultipleClient1(WaitableEvent* client1_msg_received,
545 WaitableEvent* client1_can_reply) :
initial.commit09911bf2008-07-26 23:55:29546 Worker(L"test_channel1", Channel::MODE_CLIENT),
547 client1_msg_received_(client1_msg_received),
548 client1_can_reply_(client1_can_reply) { }
549
550 void OnDouble(int in, int* out) {
[email protected]aa96ae772009-01-20 22:08:15551 client1_msg_received_->Signal();
initial.commit09911bf2008-07-26 23:55:29552 *out = in * 2;
553 client1_can_reply_->Wait();
554 Done();
555 }
556
557 private:
[email protected]aa96ae772009-01-20 22:08:15558 WaitableEvent *client1_msg_received_, *client1_can_reply_;
initial.commit09911bf2008-07-26 23:55:29559};
560
561class MultipleServer2 : public Worker {
562 public:
563 MultipleServer2() : Worker(L"test_channel2", Channel::MODE_SERVER) { }
564
565 void OnAnswer(int* result) {
566 *result = 42;
567 Done();
568 }
569};
570
571class MultipleClient2 : public Worker {
572 public:
[email protected]3cdb7af812008-10-24 19:21:13573 MultipleClient2(
[email protected]aa96ae772009-01-20 22:08:15574 WaitableEvent* client1_msg_received, WaitableEvent* client1_can_reply,
[email protected]3cdb7af812008-10-24 19:21:13575 bool pump_during_send)
576 : Worker(L"test_channel2", Channel::MODE_CLIENT),
initial.commit09911bf2008-07-26 23:55:29577 client1_msg_received_(client1_msg_received),
[email protected]3cdb7af812008-10-24 19:21:13578 client1_can_reply_(client1_can_reply),
579 pump_during_send_(pump_during_send) { }
initial.commit09911bf2008-07-26 23:55:29580
581 void Run() {
initial.commit09911bf2008-07-26 23:55:29582 client1_msg_received_->Wait();
[email protected]aa96ae772009-01-20 22:08:15583 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
584 client1_can_reply_->Signal();
initial.commit09911bf2008-07-26 23:55:29585 Done();
586 }
587
588 private:
[email protected]aa96ae772009-01-20 22:08:15589 WaitableEvent *client1_msg_received_, *client1_can_reply_;
[email protected]3cdb7af812008-10-24 19:21:13590 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29591};
592
[email protected]3cdb7af812008-10-24 19:21:13593void Multiple(bool server_pump, bool client_pump) {
initial.commit09911bf2008-07-26 23:55:29594 std::vector<Worker*> workers;
595
596 // A shared worker thread so that server1 and server2 run on one thread.
[email protected]ab820df2008-08-26 05:55:10597 base::Thread worker_thread("Multiple");
initial.commit09911bf2008-07-26 23:55:29598 worker_thread.Start();
599
600 // Server1 sends a sync msg to client1, which blocks the reply until
601 // server2 (which runs on the same worker thread as server1) responds
602 // to a sync msg from client2.
[email protected]aa96ae772009-01-20 22:08:15603 WaitableEvent client1_msg_received(false, false);
604 WaitableEvent client1_can_reply(false, false);
initial.commit09911bf2008-07-26 23:55:29605
606 Worker* worker;
607
608 worker = new MultipleServer2();
609 worker->OverrideThread(&worker_thread);
610 workers.push_back(worker);
611
612 worker = new MultipleClient2(
[email protected]3cdb7af812008-10-24 19:21:13613 &client1_msg_received, &client1_can_reply, client_pump);
initial.commit09911bf2008-07-26 23:55:29614 workers.push_back(worker);
615
[email protected]3cdb7af812008-10-24 19:21:13616 worker = new MultipleServer1(server_pump);
initial.commit09911bf2008-07-26 23:55:29617 worker->OverrideThread(&worker_thread);
618 workers.push_back(worker);
619
620 worker = new MultipleClient1(
621 &client1_msg_received, &client1_can_reply);
622 workers.push_back(worker);
623
624 RunTest(workers);
625}
626
[email protected]3cdb7af812008-10-24 19:21:13627} // namespace
628
629// Tests that multiple SyncObjects on the same listener thread can unblock each
630// other.
631TEST_F(IPCSyncChannelTest, Multiple) {
632 Multiple(false, false);
633 Multiple(false, true);
634 Multiple(true, false);
635 Multiple(true, true);
636}
initial.commit09911bf2008-07-26 23:55:29637
638//-----------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34639
640namespace {
641
initial.commit09911bf2008-07-26 23:55:29642class QueuedReplyServer1 : public Worker {
643 public:
[email protected]3cdb7af812008-10-24 19:21:13644 QueuedReplyServer1(bool pump_during_send)
645 : Worker(L"test_channel1", Channel::MODE_SERVER),
646 pump_during_send_(pump_during_send) { }
initial.commit09911bf2008-07-26 23:55:29647 void Run() {
[email protected]4df10d612008-11-12 00:38:26648 SendDouble(pump_during_send_, true);
initial.commit09911bf2008-07-26 23:55:29649 Done();
650 }
[email protected]3cdb7af812008-10-24 19:21:13651
652 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29653};
654
655class QueuedReplyClient1 : public Worker {
656 public:
[email protected]aa96ae772009-01-20 22:08:15657 QueuedReplyClient1(WaitableEvent* client1_msg_received,
658 WaitableEvent* server2_can_reply) :
initial.commit09911bf2008-07-26 23:55:29659 Worker(L"test_channel1", Channel::MODE_CLIENT),
660 client1_msg_received_(client1_msg_received),
661 server2_can_reply_(server2_can_reply) { }
662
663 void OnDouble(int in, int* out) {
[email protected]aa96ae772009-01-20 22:08:15664 client1_msg_received_->Signal();
initial.commit09911bf2008-07-26 23:55:29665 *out = in * 2;
666 server2_can_reply_->Wait();
667 Done();
668 }
669
670 private:
[email protected]aa96ae772009-01-20 22:08:15671 WaitableEvent *client1_msg_received_, *server2_can_reply_;
initial.commit09911bf2008-07-26 23:55:29672};
673
674class QueuedReplyServer2 : public Worker {
675 public:
[email protected]aa96ae772009-01-20 22:08:15676 explicit QueuedReplyServer2(WaitableEvent* server2_can_reply) :
initial.commit09911bf2008-07-26 23:55:29677 Worker(L"test_channel2", Channel::MODE_SERVER),
678 server2_can_reply_(server2_can_reply) { }
679
680 void OnAnswer(int* result) {
[email protected]aa96ae772009-01-20 22:08:15681 server2_can_reply_->Signal();
initial.commit09911bf2008-07-26 23:55:29682
683 // give client1's reply time to reach the server listener thread
[email protected]aa96ae772009-01-20 22:08:15684 PlatformThread::Sleep(200);
initial.commit09911bf2008-07-26 23:55:29685
686 *result = 42;
687 Done();
688 }
689
[email protected]aa96ae772009-01-20 22:08:15690 WaitableEvent *server2_can_reply_;
initial.commit09911bf2008-07-26 23:55:29691};
692
693class QueuedReplyClient2 : public Worker {
694 public:
[email protected]3cdb7af812008-10-24 19:21:13695 explicit QueuedReplyClient2(
[email protected]aa96ae772009-01-20 22:08:15696 WaitableEvent* client1_msg_received, bool pump_during_send)
[email protected]3cdb7af812008-10-24 19:21:13697 : Worker(L"test_channel2", Channel::MODE_CLIENT),
698 client1_msg_received_(client1_msg_received),
699 pump_during_send_(pump_during_send){ }
initial.commit09911bf2008-07-26 23:55:29700
701 void Run() {
initial.commit09911bf2008-07-26 23:55:29702 client1_msg_received_->Wait();
[email protected]aa96ae772009-01-20 22:08:15703 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
initial.commit09911bf2008-07-26 23:55:29704 Done();
705 }
706
[email protected]aa96ae772009-01-20 22:08:15707 WaitableEvent *client1_msg_received_;
[email protected]3cdb7af812008-10-24 19:21:13708 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29709};
710
[email protected]3cdb7af812008-10-24 19:21:13711void QueuedReply(bool server_pump, bool client_pump) {
initial.commit09911bf2008-07-26 23:55:29712 std::vector<Worker*> workers;
713
714 // A shared worker thread so that server1 and server2 run on one thread.
[email protected]ab820df2008-08-26 05:55:10715 base::Thread worker_thread("QueuedReply");
initial.commit09911bf2008-07-26 23:55:29716 worker_thread.Start();
717
[email protected]aa96ae772009-01-20 22:08:15718 WaitableEvent client1_msg_received(false, false);
719 WaitableEvent server2_can_reply(false, false);
initial.commit09911bf2008-07-26 23:55:29720
721 Worker* worker;
722
723 worker = new QueuedReplyServer2(&server2_can_reply);
724 worker->OverrideThread(&worker_thread);
725 workers.push_back(worker);
726
[email protected]3cdb7af812008-10-24 19:21:13727 worker = new QueuedReplyClient2(&client1_msg_received, client_pump);
initial.commit09911bf2008-07-26 23:55:29728 workers.push_back(worker);
729
[email protected]3cdb7af812008-10-24 19:21:13730 worker = new QueuedReplyServer1(server_pump);
initial.commit09911bf2008-07-26 23:55:29731 worker->OverrideThread(&worker_thread);
732 workers.push_back(worker);
733
734 worker = new QueuedReplyClient1(
735 &client1_msg_received, &server2_can_reply);
736 workers.push_back(worker);
737
738 RunTest(workers);
739}
740
[email protected]3cdb7af812008-10-24 19:21:13741} // namespace
742
743// While a blocking send is in progress, the listener thread might answer other
744// synchronous messages. This tests that if during the response to another
745// message the reply to the original messages comes, it is queued up correctly
746// and the original Send is unblocked later.
747TEST_F(IPCSyncChannelTest, QueuedReply) {
748 QueuedReply(false, false);
749 QueuedReply(false, true);
750 QueuedReply(true, false);
751 QueuedReply(true, true);
752}
initial.commit09911bf2008-07-26 23:55:29753
754//-----------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34755
756namespace {
757
initial.commit09911bf2008-07-26 23:55:29758class BadServer : public Worker {
759 public:
[email protected]3cdb7af812008-10-24 19:21:13760 BadServer(bool pump_during_send)
761 : Worker(Channel::MODE_SERVER, "simpler_server"),
762 pump_during_send_(pump_during_send) { }
initial.commit09911bf2008-07-26 23:55:29763 void Run() {
764 int answer = 0;
765
[email protected]4df10d612008-11-12 00:38:26766 SyncMessage* msg = new SyncMessage(
[email protected]3cdb7af812008-10-24 19:21:13767 MSG_ROUTING_CONTROL, SyncChannelTestMsg_Double::ID,
768 Message::PRIORITY_NORMAL, NULL);
769 if (pump_during_send_)
770 msg->EnableMessagePumping();
771
initial.commit09911bf2008-07-26 23:55:29772 // Temporarily set the minimum logging very high so that the assertion
773 // in ipc_message_utils doesn't fire.
774 int log_level = logging::GetMinLogLevel();
775 logging::SetMinLogLevel(kint32max);
776 bool result = Send(msg);
777 logging::SetMinLogLevel(log_level);
778 DCHECK(!result);
779
780 // Need to send another message to get the client to call Done().
781 result = Send(new SyncChannelTestMsg_AnswerToLife(&answer));
782 DCHECK(result);
783 DCHECK(answer == 42);
784
785 Done();
786 }
[email protected]3cdb7af812008-10-24 19:21:13787
788 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29789};
790
[email protected]3cdb7af812008-10-24 19:21:13791void BadMessage(bool pump_during_send) {
792 std::vector<Worker*> workers;
793 workers.push_back(new BadServer(pump_during_send));
794 workers.push_back(new SimpleClient());
795 RunTest(workers);
796}
797
[email protected]dd3eac22008-08-26 07:28:34798} // namespace
799
initial.commit09911bf2008-07-26 23:55:29800// Tests that if a message is not serialized correctly, the Send() will fail.
[email protected]dd3eac22008-08-26 07:28:34801TEST_F(IPCSyncChannelTest, BadMessage) {
[email protected]3cdb7af812008-10-24 19:21:13802 BadMessage(false);
803 BadMessage(true);
initial.commit09911bf2008-07-26 23:55:29804}
805
initial.commit09911bf2008-07-26 23:55:29806//-----------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34807
808namespace {
809
[email protected]3cdb7af812008-10-24 19:21:13810class ChattyClient : public Worker {
initial.commit09911bf2008-07-26 23:55:29811 public:
[email protected]3cdb7af812008-10-24 19:21:13812 ChattyClient() :
813 Worker(Channel::MODE_CLIENT, "chatty_client") { }
initial.commit09911bf2008-07-26 23:55:29814
815 void OnAnswer(int* answer) {
816 // The PostMessage limit is 10k. Send 20% more than that.
817 const int kMessageLimit = 10000;
818 const int kMessagesToSend = kMessageLimit * 120 / 100;
819 for (int i = 0; i < kMessagesToSend; ++i) {
[email protected]4df10d612008-11-12 00:38:26820 if (!SendDouble(false, true))
initial.commit09911bf2008-07-26 23:55:29821 break;
822 }
[email protected]4df10d612008-11-12 00:38:26823 *answer = 42;
initial.commit09911bf2008-07-26 23:55:29824 Done();
825 }
826};
827
[email protected]3cdb7af812008-10-24 19:21:13828void ChattyServer(bool pump_during_send) {
829 std::vector<Worker*> workers;
830 workers.push_back(new UnblockServer(pump_during_send));
831 workers.push_back(new ChattyClient());
832 RunTest(workers);
833}
834
[email protected]dd3eac22008-08-26 07:28:34835} // namespace
836
[email protected]4df10d612008-11-12 00:38:26837// Tests http://b/1093251 - that sending lots of sync messages while
initial.commit09911bf2008-07-26 23:55:29838// the receiver is waiting for a sync reply does not overflow the PostMessage
839// queue.
[email protected]dd3eac22008-08-26 07:28:34840TEST_F(IPCSyncChannelTest, ChattyServer) {
[email protected]3cdb7af812008-10-24 19:21:13841 ChattyServer(false);
842 ChattyServer(true);
initial.commit09911bf2008-07-26 23:55:29843}
[email protected]d65cab7a2008-08-12 01:25:41844
[email protected]d65cab7a2008-08-12 01:25:41845//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34846
847namespace {
848
[email protected]d65cab7a2008-08-12 01:25:41849class TimeoutServer : public Worker {
850 public:
851 TimeoutServer(int timeout_ms,
[email protected]3cdb7af812008-10-24 19:21:13852 std::vector<bool> timeout_seq,
853 bool pump_during_send)
[email protected]d65cab7a2008-08-12 01:25:41854 : Worker(Channel::MODE_SERVER, "timeout_server"),
855 timeout_ms_(timeout_ms),
[email protected]3cdb7af812008-10-24 19:21:13856 timeout_seq_(timeout_seq),
857 pump_during_send_(pump_during_send) {
[email protected]d65cab7a2008-08-12 01:25:41858 }
859
860 void Run() {
861 for (std::vector<bool>::const_iterator iter = timeout_seq_.begin();
862 iter != timeout_seq_.end(); ++iter) {
[email protected]4df10d612008-11-12 00:38:26863 SendAnswerToLife(pump_during_send_, timeout_ms_, !*iter);
[email protected]d65cab7a2008-08-12 01:25:41864 }
865 Done();
866 }
867
868 private:
869 int timeout_ms_;
870 std::vector<bool> timeout_seq_;
[email protected]3cdb7af812008-10-24 19:21:13871 bool pump_during_send_;
[email protected]d65cab7a2008-08-12 01:25:41872};
873
874class UnresponsiveClient : public Worker {
875 public:
876 UnresponsiveClient(std::vector<bool> timeout_seq)
877 : Worker(Channel::MODE_CLIENT, "unresponsive_client"),
878 timeout_seq_(timeout_seq) {
879 }
880
881 void OnAnswerDelay(Message* reply_msg) {
882 DCHECK(!timeout_seq_.empty());
883 if (!timeout_seq_[0]) {
884 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
885 Send(reply_msg);
886 } else {
887 // Don't reply.
[email protected]463667372008-08-20 20:20:52888 delete reply_msg;
[email protected]d65cab7a2008-08-12 01:25:41889 }
890 timeout_seq_.erase(timeout_seq_.begin());
891 if (timeout_seq_.empty())
892 Done();
893 }
894
895 private:
896 // Whether we should time-out or respond to the various messages we receive.
897 std::vector<bool> timeout_seq_;
898};
899
[email protected]3cdb7af812008-10-24 19:21:13900void SendWithTimeoutOK(bool pump_during_send) {
901 std::vector<Worker*> workers;
902 std::vector<bool> timeout_seq;
903 timeout_seq.push_back(false);
904 timeout_seq.push_back(false);
905 timeout_seq.push_back(false);
906 workers.push_back(new TimeoutServer(5000, timeout_seq, pump_during_send));
907 workers.push_back(new SimpleClient());
908 RunTest(workers);
909}
910
911void SendWithTimeoutTimeout(bool pump_during_send) {
912 std::vector<Worker*> workers;
913 std::vector<bool> timeout_seq;
914 timeout_seq.push_back(true);
915 timeout_seq.push_back(false);
916 timeout_seq.push_back(false);
917 workers.push_back(new TimeoutServer(100, timeout_seq, pump_during_send));
918 workers.push_back(new UnresponsiveClient(timeout_seq));
919 RunTest(workers);
920}
921
922void SendWithTimeoutMixedOKAndTimeout(bool pump_during_send) {
923 std::vector<Worker*> workers;
924 std::vector<bool> timeout_seq;
925 timeout_seq.push_back(true);
926 timeout_seq.push_back(false);
927 timeout_seq.push_back(false);
928 timeout_seq.push_back(true);
929 timeout_seq.push_back(false);
930 workers.push_back(new TimeoutServer(100, timeout_seq, pump_during_send));
931 workers.push_back(new UnresponsiveClient(timeout_seq));
932 RunTest(workers);
933}
934
[email protected]dd3eac22008-08-26 07:28:34935} // namespace
936
[email protected]d65cab7a2008-08-12 01:25:41937// Tests that SendWithTimeout does not time-out if the response comes back fast
938// enough.
[email protected]dd3eac22008-08-26 07:28:34939TEST_F(IPCSyncChannelTest, SendWithTimeoutOK) {
[email protected]3cdb7af812008-10-24 19:21:13940 SendWithTimeoutOK(false);
941 SendWithTimeoutOK(true);
[email protected]d65cab7a2008-08-12 01:25:41942}
943
944// Tests that SendWithTimeout does time-out.
[email protected]dd3eac22008-08-26 07:28:34945TEST_F(IPCSyncChannelTest, SendWithTimeoutTimeout) {
[email protected]3cdb7af812008-10-24 19:21:13946 SendWithTimeoutTimeout(false);
947 SendWithTimeoutTimeout(true);
[email protected]d65cab7a2008-08-12 01:25:41948}
949
950// Sends some message that time-out and some that succeed.
[email protected]dd3eac22008-08-26 07:28:34951TEST_F(IPCSyncChannelTest, SendWithTimeoutMixedOKAndTimeout) {
[email protected]3cdb7af812008-10-24 19:21:13952 SendWithTimeoutMixedOKAndTimeout(false);
953 SendWithTimeoutMixedOKAndTimeout(true);
954}
[email protected]4df10d612008-11-12 00:38:26955
956//------------------------------------------------------------------------------
957
958namespace {
959
960class NestedTask : public Task {
961 public:
962 NestedTask(Worker* server) : server_(server) { }
963 void Run() {
964 // Sleep a bit so that we wake up after the reply has been received.
[email protected]aa96ae772009-01-20 22:08:15965 PlatformThread::Sleep(250);
966 server_->SendAnswerToLife(true, base::kNoTimeout, true);
[email protected]4df10d612008-11-12 00:38:26967 }
968
969 Worker* server_;
970};
971
972static bool timeout_occured = false;
973
974class TimeoutTask : public Task {
975 public:
976 void Run() {
977 timeout_occured = true;
978 }
979};
980
981class DoneEventRaceServer : public Worker {
982 public:
983 DoneEventRaceServer()
984 : Worker(Channel::MODE_SERVER, "done_event_race_server") { }
985
986 void Run() {
987 MessageLoop::current()->PostTask(FROM_HERE, new NestedTask(this));
988 MessageLoop::current()->PostDelayedTask(FROM_HERE, new TimeoutTask(), 9000);
989 // Even though we have a timeout on the Send, it will succeed since for this
990 // bug, the reply message comes back and is deserialized, however the done
991 // event wasn't set. So we indirectly use the timeout task to notice if a
992 // timeout occurred.
993 SendAnswerToLife(true, 10000, true);
994 DCHECK(!timeout_occured);
995 Done();
996 }
997};
998
999} // namespace
1000
1001// Tests http://b/1474092 - that if after the done_event is set but before
1002// OnObjectSignaled is called another message is sent out, then after its
1003// reply comes back OnObjectSignaled will be called for the first message.
1004TEST_F(IPCSyncChannelTest, DoneEventRace) {
1005 std::vector<Worker*> workers;
1006 workers.push_back(new DoneEventRaceServer());
1007 workers.push_back(new SimpleClient());
1008 RunTest(workers);
1009}