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)
70f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/auto_reset.h"
80f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/bind.h"
90f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/run_loop.h"
100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/test/simple_test_tick_clock.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "mojo/public/system/core_cpp.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "mojo/public/tests/test_support.h"
130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace mojo {
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace common {
170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace test {
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void RunUntilIdle() {
200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::RunLoop run_loop;
210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  run_loop.RunUntilIdle();
220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DeleteWatcherAndForwardResult(
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HandleWatcher* watcher,
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::Callback<void(MojoResult)> next_callback,
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MojoResult result) {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delete watcher;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  next_callback.Run(result);
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Helper class to manage the callback and running the message loop waiting for
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// message to be received. Typical usage is something like:
340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   Schedule callback returned from GetCallback().
350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   RunUntilGotCallback();
360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   EXPECT_TRUE(got_callback());
370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   clear_callback();
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class CallbackHelper {
390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper()
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      : got_callback_(false),
420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        run_loop_(NULL),
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        weak_factory_(this) {}
440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ~CallbackHelper() {}
450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // See description above |got_callback_|.
470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool got_callback() const { return got_callback_; }
480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void clear_callback() { got_callback_ = false; }
490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Runs the current MessageLoop until the callback returned from GetCallback()
510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // is notified.
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void RunUntilGotCallback() {
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ASSERT_TRUE(run_loop_ == NULL);
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::RunLoop run_loop;
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop);
560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    run_loop.Run();
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::Callback<void(MojoResult)> GetCallback() {
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr());
610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) {
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    StartWithCallback(watcher, handle, GetCallback());
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void StartWithCallback(HandleWatcher* watcher,
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const MessagePipeHandle& handle,
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const base::Callback<void(MojoResult)>& callback) {
700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    watcher->Start(handle, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE,
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   callback);
720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnCallback(MojoResult result) {
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    got_callback_ = true;
770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (run_loop_)
780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      run_loop_->Quit();
790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Set to true when the callback is called.
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool got_callback_;
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If non-NULL we're in RunUntilGotCallback().
850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::RunLoop* run_loop_;
860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::WeakPtrFactory<CallbackHelper> weak_factory_;
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class HandleWatcherTest : public testing::Test {
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcherTest() {}
960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual ~HandleWatcherTest() {
970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    HandleWatcher::tick_clock_ = NULL;
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) protected:
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void InstallTickClock() {
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    HandleWatcher::tick_clock_ = &tick_clock_;
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::SimpleTestTickClock tick_clock_;
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoop message_loop_;
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest);
1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Trivial test case with a single handle to watch.
1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, SingleHandler) {
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe;
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe.handle_0.is_valid());
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper;
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher;
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper.Start(&watcher, test_pipe.handle_0.get());
1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper.got_callback());
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe.handle_1.get()));
1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper.RunUntilGotCallback();
1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper.got_callback());
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Creates three handles and notfies them in reverse order ensuring each one is
1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// notified appropriately.
1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, ThreeHandles) {
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe1;
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe2;
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe3;
1340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper3;
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle_0.is_valid());
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle_0.is_valid());
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe3.handle_0.is_valid());
1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle_0.get());
1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper2.Start(&watcher2, test_pipe2.handle_0.get());
1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher3;
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper3.Start(&watcher3, test_pipe3.handle_0.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)  // Write to 3 and make sure it's notified.
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe3.handle_1.get()));
1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper3.RunUntilGotCallback();
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper3.got_callback());
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper3.clear_callback();
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // running.
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe1.handle_1.get()));
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe3.handle_1.get()));
1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
1790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.clear_callback();
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe1.handle_1.get()));
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe2.handle_1.get()));
1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies Start() invoked a second time works.
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, Restart) {
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe1;
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe2;
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle_0.is_valid());
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle_0.is_valid());
2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle_0.get());
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper2.Start(&watcher2, test_pipe2.handle_0.get());
2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and make sure it's notified.
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe1.handle_1.get()));
2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.clear_callback();
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::ReadEmptyMessage(test_pipe1.handle_0.get()));
2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 2 and make sure it's notified.
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe2.handle_1.get()));
2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.clear_callback();
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Listen on 1 again.
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle_0.get());
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and make sure it's notified.
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_OK,
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            mojo::test::WriteEmptyMessage(test_pipe1.handle_1.get()));
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies deadline is honored.
2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, Deadline) {
2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InstallTickClock();
2500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe1;
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe2;
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe3;
2540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper3;
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle_0.is_valid());
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle_0.is_valid());
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(test_pipe3.handle_0.is_valid());
2600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add a watcher with an infinite timeout.
2620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle_0.get());
2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add another watcher wth a timeout of 500 microseconds.
2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  watcher2.Start(test_pipe2.handle_0.get(), MOJO_WAIT_FLAG_READABLE, 500,
2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                 callback_helper2.GetCallback());
2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Advance the clock passed the deadline. We also have to start another
2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // watcher to wake up the background thread.
2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501));
2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher3;
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper3.Start(&watcher3, test_pipe3.handle_0.get());
2840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(HandleWatcherTest, DeleteInCallback) {
292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::MessagePipe test_pipe;
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackHelper callback_helper;
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleWatcher* watcher = new HandleWatcher();
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback_helper.StartWithCallback(watcher, test_pipe.handle_1.get(),
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    base::Bind(&DeleteWatcherAndForwardResult,
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               watcher,
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               callback_helper.GetCallback()));
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  mojo::test::WriteEmptyMessage(test_pipe.handle_0.get());
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  callback_helper.RunUntilGotCallback();
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(callback_helper.got_callback());
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace test
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace common
3070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace mojo
308