handle_watcher_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/common/time_helper.h"
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/core.h"
18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/test_support/test_utils.h"
190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace mojo {
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace common {
230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace test {
240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ObserveCallback(bool* was_signaled,
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     MojoResult* result_observed,
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     MojoResult result) {
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *was_signaled = true;
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *result_observed = result;
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void RunUntilIdle() {
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::RunLoop run_loop;
340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  run_loop.RunUntilIdle();
350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DeleteWatcherAndForwardResult(
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HandleWatcher* watcher,
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::Callback<void(MojoResult)> next_callback,
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MojoResult result) {
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delete watcher;
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  next_callback.Run(result);
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Helper class to manage the callback and running the message loop waiting for
460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// message to be received. Typical usage is something like:
470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   Schedule callback returned from GetCallback().
480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   RunUntilGotCallback();
490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   EXPECT_TRUE(got_callback());
500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   clear_callback();
510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class CallbackHelper {
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper()
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      : got_callback_(false),
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        run_loop_(NULL),
560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        weak_factory_(this) {}
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ~CallbackHelper() {}
580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // See description above |got_callback_|.
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool got_callback() const { return got_callback_; }
610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void clear_callback() { got_callback_ = false; }
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Runs the current MessageLoop until the callback returned from GetCallback()
640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // is notified.
650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void RunUntilGotCallback() {
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ASSERT_TRUE(run_loop_ == NULL);
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::RunLoop run_loop;
680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop);
690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    run_loop.Run();
700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::Callback<void(MojoResult)> GetCallback() {
730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr());
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) {
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    StartWithCallback(watcher, handle, GetCallback());
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void StartWithCallback(HandleWatcher* watcher,
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const MessagePipeHandle& handle,
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const base::Callback<void(MojoResult)>& callback) {
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    watcher->Start(handle, MOJO_HANDLE_SIGNAL_READABLE,
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   MOJO_DEADLINE_INDEFINITE, callback);
850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnCallback(MojoResult result) {
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    got_callback_ = true;
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (run_loop_)
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      run_loop_->Quit();
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Set to true when the callback is called.
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool got_callback_;
960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If non-NULL we're in RunUntilGotCallback().
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::RunLoop* run_loop_;
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::WeakPtrFactory<CallbackHelper> weak_factory_;
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class HandleWatcherTest : public testing::Test {
1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcherTest() {}
1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual ~HandleWatcherTest() {
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test::SetTickClockForTest(NULL);
1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) protected:
1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void InstallTickClock() {
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test::SetTickClockForTest(&tick_clock_);
1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::SimpleTestTickClock tick_clock_;
1190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ShadowingAtExitManager at_exit_;
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoop message_loop_;
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest);
1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Trivial test case with a single handle to watch.
1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, SingleHandler) {
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe;
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe.handle0.is_valid());
1310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper;
1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper.Start(&watcher, test_pipe.handle0.get());
1340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper.got_callback());
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper.RunUntilGotCallback();
1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper.got_callback());
1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Creates three handles and notfies them in reverse order ensuring each one is
1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// notified appropriately.
1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, ThreeHandles) {
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe3;
1480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
1490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper3;
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe3.handle0.is_valid());
1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
1640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher3;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 3 and make sure it's notified.
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper3.RunUntilGotCallback();
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper3.got_callback());
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper3.clear_callback();
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // running.
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.clear_callback();
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies Start() invoked a second time works.
2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, Restart) {
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and make sure it's notified.
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.clear_callback();
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1.handle0.get()));
2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 2 and make sure it's notified.
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.clear_callback();
2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Listen on 1 again.
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.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)}
2590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies deadline is honored.
2610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, Deadline) {
2620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InstallTickClock();
2630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe3;
2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
2680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper3;
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe3.handle0.is_valid());
2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add a watcher with an infinite timeout.
2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add another watcher wth a timeout of 500 microseconds.
2830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  watcher2.Start(test_pipe2.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, 500,
2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                 callback_helper2.GetCallback());
2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Advance the clock passed the deadline. We also have to start another
2920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // watcher to wake up the background thread.
2930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501));
2940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher3;
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
3000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
3020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(HandleWatcherTest, DeleteInCallback) {
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe;
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackHelper callback_helper;
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleWatcher* watcher = new HandleWatcher();
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(),
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    base::Bind(&DeleteWatcherAndForwardResult,
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               watcher,
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               callback_helper.GetCallback()));
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(),
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  callback_helper.RunUntilGotCallback();
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(callback_helper.got_callback());
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(HandleWatcherCleanEnvironmentTest, AbortedOnMessageLoopDestruction) {
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool was_signaled = false;
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MojoResult result = MOJO_RESULT_OK;
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ShadowingAtExitManager at_exit;
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MessagePipe pipe;
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  HandleWatcher watcher;
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoop loop;
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    watcher.Start(pipe.handle0.get(),
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  MOJO_HANDLE_SIGNAL_READABLE,
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  MOJO_DEADLINE_INDEFINITE,
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  base::Bind(&ObserveCallback, &was_signaled, &result));
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Now, let the MessageLoop get torn down. We expect our callback to run.
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(was_signaled);
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_ABORTED, result);
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void NeverReached(MojoResult result) {
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FAIL() << "Callback should never be invoked " << result;
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Called on the main thread when a thread is done. Decrements |active_count|
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// and if |active_count| is zero quits |run_loop|.
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void StressThreadDone(base::RunLoop* run_loop, int* active_count) {
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  (*active_count)--;
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_GE(*active_count, 0);
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (*active_count == 0)
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    run_loop->Quit();
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// See description of StressTest. This is called on the background thread.
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |count| is the number of HandleWatchers to create. |active_count| is the
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// number of outstanding threads, |task_runner| the task runner for the main
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// thread and |run_loop| the run loop that should be quit when there are no more
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// threads running. When done StressThreadDone() is invoked on the main thread.
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |active_count| and |run_loop| should only be used on the main thread.
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RunStressTest(int count,
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   scoped_refptr<base::TaskRunner> task_runner,
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   base::RunLoop* run_loop,
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   int* active_count) {
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  struct TestData {
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MessagePipe pipe;
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    HandleWatcher watcher;
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ScopedVector<TestData> data_vector;
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (int i = 0; i < count; ++i) {
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (i % 20 == 0) {
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // Every so often we wait. This results in some level of thread balancing
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // as well as making sure HandleWatcher has time to actually start some
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // watches.
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      MessagePipe test_pipe;
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ASSERT_TRUE(test_pipe.handle0.is_valid());
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      CallbackHelper callback_helper;
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      HandleWatcher watcher;
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      callback_helper.Start(&watcher, test_pipe.handle0.get());
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      RunUntilIdle();
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      EXPECT_FALSE(callback_helper.got_callback());
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               std::string()));
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::MessageLoop::ScopedNestableTaskAllower scoper(
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::MessageLoop::current());
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      callback_helper.RunUntilGotCallback();
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      EXPECT_TRUE(callback_helper.got_callback());
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else {
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      scoped_ptr<TestData> test_data(new TestData);
3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ASSERT_TRUE(test_data->pipe.handle0.is_valid());
3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      test_data->watcher.Start(test_data->pipe.handle0.get(),
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    MOJO_HANDLE_SIGNAL_READABLE,
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    MOJO_DEADLINE_INDEFINITE,
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    base::Bind(&NeverReached));
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      data_vector.push_back(test_data.release());
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (i % 15 == 0)
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      data_vector.clear();
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  task_runner->PostTask(FROM_HERE,
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        base::Bind(&StressThreadDone, run_loop,
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   active_count));
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// This test is meant to stress HandleWatcher. It uses from various threads
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// repeatedly starting and stopping watches. It spins up kThreadCount
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// threads. Each thread creates kWatchCount watches. Every so often each thread
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// writes to a pipe and waits for the response.
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(HandleWatcherCleanEnvironmentTest, StressTest) {
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(NDEBUG)
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kThreadCount = 15;
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kWatchCount = 400;
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kThreadCount = 10;
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kWatchCount = 250;
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::ShadowingAtExitManager at_exit;
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::MessageLoop message_loop;
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop run_loop;
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ScopedVector<base::Thread> threads;
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int threads_active_counter = kThreadCount;
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Starts the threads first and then post the task in hopes of having more
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // threads running at once.
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (int i = 0; i < kThreadCount; ++i) {
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<base::Thread> thread(new base::Thread("test thread"));
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    thread->Start();
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    threads.push_back(thread.release());
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (int i = 0; i < kThreadCount; ++i) {
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    threads[i]->task_runner()->PostTask(
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        FROM_HERE, base::Bind(&RunStressTest, kWatchCount,
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              message_loop.task_runner(),
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &run_loop, &threads_active_counter));
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  run_loop.Run();
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(0, threads_active_counter);
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace test
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace common
4410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace mojo
442