10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
20f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
30f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// found in the LICENSE file.
40f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "mojo/common/handle_watcher.h"
60f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/at_exit.h"
100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/auto_reset.h"
110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/bind.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_vector.h"
130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/run_loop.h"
140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/test/simple_test_tick_clock.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/threading/thread.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/common/message_pump_mojo.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/common/time_helper.h"
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/core.h"
19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/test_support/test_utils.h"
200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace mojo {
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace common {
240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace test {
250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccienum MessageLoopConfig {
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MESSAGE_LOOP_CONFIG_DEFAULT = 0,
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MESSAGE_LOOP_CONFIG_MOJO = 1
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ObserveCallback(bool* was_signaled,
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     MojoResult* result_observed,
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     MojoResult result) {
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *was_signaled = true;
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *result_observed = result;
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void RunUntilIdle() {
390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::RunLoop run_loop;
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  run_loop.RunUntilIdle();
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DeleteWatcherAndForwardResult(
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HandleWatcher* watcher,
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::Callback<void(MojoResult)> next_callback,
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MojoResult result) {
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delete watcher;
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  next_callback.Run(result);
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<base::MessageLoop> CreateMessageLoop(MessageLoopConfig config) {
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::MessageLoop> loop;
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (config == MESSAGE_LOOP_CONFIG_DEFAULT)
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    loop.reset(new base::MessageLoop());
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  else
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    loop.reset(new base::MessageLoop(MessagePumpMojo::Create()));
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return loop.Pass();
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Helper class to manage the callback and running the message loop waiting for
610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// message to be received. Typical usage is something like:
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   Schedule callback returned from GetCallback().
630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   RunUntilGotCallback();
640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   EXPECT_TRUE(got_callback());
650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   clear_callback();
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class CallbackHelper {
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper()
690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      : got_callback_(false),
700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        run_loop_(NULL),
710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        weak_factory_(this) {}
720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ~CallbackHelper() {}
730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // See description above |got_callback_|.
750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool got_callback() const { return got_callback_; }
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void clear_callback() { got_callback_ = false; }
770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Runs the current MessageLoop until the callback returned from GetCallback()
790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // is notified.
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void RunUntilGotCallback() {
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ASSERT_TRUE(run_loop_ == NULL);
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::RunLoop run_loop;
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop);
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    run_loop.Run();
850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::Callback<void(MojoResult)> GetCallback() {
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr());
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) {
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    StartWithCallback(watcher, handle, GetCallback());
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void StartWithCallback(HandleWatcher* watcher,
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const MessagePipeHandle& handle,
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const base::Callback<void(MojoResult)>& callback) {
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    watcher->Start(handle, MOJO_HANDLE_SIGNAL_READABLE,
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   MOJO_DEADLINE_INDEFINITE, callback);
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnCallback(MojoResult result) {
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    got_callback_ = true;
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (run_loop_)
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      run_loop_->Quit();
1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Set to true when the callback is called.
1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool got_callback_;
1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If non-NULL we're in RunUntilGotCallback().
1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::RunLoop* run_loop_;
1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::WeakPtrFactory<CallbackHelper> weak_factory_;
1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
1190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass HandleWatcherTest : public testing::TestWithParam<MessageLoopConfig> {
1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HandleWatcherTest() : message_loop_(CreateMessageLoop(GetParam())) {}
1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual ~HandleWatcherTest() {
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test::SetTickClockForTest(NULL);
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) protected:
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void TearDownMessageLoop() {
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    message_loop_.reset();
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void InstallTickClock() {
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test::SetTickClockForTest(&tick_clock_);
1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::SimpleTestTickClock tick_clock_;
1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ShadowingAtExitManager at_exit_;
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::MessageLoop> message_loop_;
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest);
1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciINSTANTIATE_TEST_CASE_P(
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MultipleMessageLoopConfigs, HandleWatcherTest,
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    testing::Values(MESSAGE_LOOP_CONFIG_DEFAULT, MESSAGE_LOOP_CONFIG_MOJO));
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Trivial test case with a single handle to watch.
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, SingleHandler) {
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe;
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe.handle0.is_valid());
1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper;
1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher;
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper.Start(&watcher, test_pipe.handle0.get());
1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper.got_callback());
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper.RunUntilGotCallback();
1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper.got_callback());
1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Creates three handles and notfies them in reverse order ensuring each one is
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// notified appropriately.
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, ThreeHandles) {
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe3;
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper3;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe3.handle0.is_valid());
1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
1870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher3;
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 3 and make sure it's notified.
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper3.RunUntilGotCallback();
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper3.got_callback());
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper3.clear_callback();
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // running.
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.clear_callback();
2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies Start() invoked a second time works.
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, Restart) {
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and make sure it's notified.
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
2570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.clear_callback();
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1.handle0.get()));
2600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 2 and make sure it's notified.
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.clear_callback();
2680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Listen on 1 again.
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
2710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and make sure it's notified.
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies deadline is honored.
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, Deadline) {
2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InstallTickClock();
2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe3;
2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
2910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
2920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper3;
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe3.handle0.is_valid());
2960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add a watcher with an infinite timeout.
2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
3000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
3020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add another watcher wth a timeout of 500 microseconds.
3060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  watcher2.Start(test_pipe2.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, 500,
3080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                 callback_helper2.GetCallback());
3090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
3100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
3110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
3120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Advance the clock passed the deadline. We also have to start another
3150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // watcher to wake up the background thread.
3160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501));
3170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher3;
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
3200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
3220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
3230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
3240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
3250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, DeleteInCallback) {
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe;
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackHelper callback_helper;
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleWatcher* watcher = new HandleWatcher();
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(),
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    base::Bind(&DeleteWatcherAndForwardResult,
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               watcher,
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               callback_helper.GetCallback()));
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(),
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  callback_helper.RunUntilGotCallback();
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(callback_helper.got_callback());
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_P(HandleWatcherTest, AbortedOnMessageLoopDestruction) {
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool was_signaled = false;
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MojoResult result = MOJO_RESULT_OK;
345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MessagePipe pipe;
347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  HandleWatcher watcher;
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  watcher.Start(pipe.handle0.get(),
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                MOJO_HANDLE_SIGNAL_READABLE,
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                MOJO_DEADLINE_INDEFINITE,
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                base::Bind(&ObserveCallback, &was_signaled, &result));
352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now, let the MessageLoop get torn down. We expect our callback to run.
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TearDownMessageLoop();
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(was_signaled);
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_ABORTED, result);
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void NeverReached(MojoResult result) {
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FAIL() << "Callback should never be invoked " << result;
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Called on the main thread when a thread is done. Decrements |active_count|
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// and if |active_count| is zero quits |run_loop|.
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void StressThreadDone(base::RunLoop* run_loop, int* active_count) {
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  (*active_count)--;
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_GE(*active_count, 0);
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (*active_count == 0)
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    run_loop->Quit();
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// See description of StressTest. This is called on the background thread.
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |count| is the number of HandleWatchers to create. |active_count| is the
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// number of outstanding threads, |task_runner| the task runner for the main
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// thread and |run_loop| the run loop that should be quit when there are no more
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// threads running. When done StressThreadDone() is invoked on the main thread.
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |active_count| and |run_loop| should only be used on the main thread.
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RunStressTest(int count,
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   scoped_refptr<base::TaskRunner> task_runner,
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   base::RunLoop* run_loop,
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   int* active_count) {
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  struct TestData {
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MessagePipe pipe;
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    HandleWatcher watcher;
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ScopedVector<TestData> data_vector;
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (int i = 0; i < count; ++i) {
3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (i % 20 == 0) {
3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // Every so often we wait. This results in some level of thread balancing
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // as well as making sure HandleWatcher has time to actually start some
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // watches.
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      MessagePipe test_pipe;
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ASSERT_TRUE(test_pipe.handle0.is_valid());
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      CallbackHelper callback_helper;
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      HandleWatcher watcher;
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      callback_helper.Start(&watcher, test_pipe.handle0.get());
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      RunUntilIdle();
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      EXPECT_FALSE(callback_helper.got_callback());
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               std::string()));
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::MessageLoop::ScopedNestableTaskAllower scoper(
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::MessageLoop::current());
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      callback_helper.RunUntilGotCallback();
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      EXPECT_TRUE(callback_helper.got_callback());
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else {
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      scoped_ptr<TestData> test_data(new TestData);
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ASSERT_TRUE(test_data->pipe.handle0.is_valid());
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      test_data->watcher.Start(test_data->pipe.handle0.get(),
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    MOJO_HANDLE_SIGNAL_READABLE,
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    MOJO_DEADLINE_INDEFINITE,
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    base::Bind(&NeverReached));
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      data_vector.push_back(test_data.release());
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (i % 15 == 0)
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      data_vector.clear();
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  task_runner->PostTask(FROM_HERE,
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        base::Bind(&StressThreadDone, run_loop,
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   active_count));
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// This test is meant to stress HandleWatcher. It uses from various threads
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// repeatedly starting and stopping watches. It spins up kThreadCount
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// threads. Each thread creates kWatchCount watches. Every so often each thread
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// writes to a pipe and waits for the response.
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(HandleWatcherCleanEnvironmentTest, StressTest) {
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(NDEBUG)
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kThreadCount = 15;
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kWatchCount = 400;
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kThreadCount = 10;
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kWatchCount = 250;
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::ShadowingAtExitManager at_exit;
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::MessageLoop message_loop;
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop run_loop;
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ScopedVector<base::Thread> threads;
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int threads_active_counter = kThreadCount;
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Starts the threads first and then post the task in hopes of having more
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // threads running at once.
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (int i = 0; i < kThreadCount; ++i) {
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<base::Thread> thread(new base::Thread("test thread"));
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (i % 2) {
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Thread::Options thread_options;
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      thread_options.message_pump_factory =
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::Bind(&MessagePumpMojo::Create);
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      thread->StartWithOptions(thread_options);
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      thread->Start();
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    threads.push_back(thread.release());
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (int i = 0; i < kThreadCount; ++i) {
4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    threads[i]->task_runner()->PostTask(
4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        FROM_HERE, base::Bind(&RunStressTest, kWatchCount,
4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              message_loop.task_runner(),
4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &run_loop, &threads_active_counter));
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  run_loop.Run();
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(0, threads_active_counter);
4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace test
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace common
4670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace mojo
468