handle_watcher_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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)
90f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/auto_reset.h"
100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/bind.h"
110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/run_loop.h"
120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/test/simple_test_tick_clock.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/common/time_helper.h"
14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/environment/environment.h"
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/core.h"
16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/test_support/test_utils.h"
170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace mojo {
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace common {
210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace test {
220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ObserveCallback(bool* was_signaled,
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     MojoResult* result_observed,
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     MojoResult result) {
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *was_signaled = true;
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *result_observed = result;
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void RunUntilIdle() {
310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::RunLoop run_loop;
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  run_loop.RunUntilIdle();
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DeleteWatcherAndForwardResult(
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HandleWatcher* watcher,
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::Callback<void(MojoResult)> next_callback,
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MojoResult result) {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delete watcher;
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  next_callback.Run(result);
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Helper class to manage the callback and running the message loop waiting for
440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// message to be received. Typical usage is something like:
450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   Schedule callback returned from GetCallback().
460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   RunUntilGotCallback();
470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   EXPECT_TRUE(got_callback());
480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//   clear_callback();
490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class CallbackHelper {
500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper()
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      : got_callback_(false),
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        run_loop_(NULL),
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        weak_factory_(this) {}
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ~CallbackHelper() {}
560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // See description above |got_callback_|.
580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool got_callback() const { return got_callback_; }
590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void clear_callback() { got_callback_ = false; }
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Runs the current MessageLoop until the callback returned from GetCallback()
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // is notified.
630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void RunUntilGotCallback() {
640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ASSERT_TRUE(run_loop_ == NULL);
650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::RunLoop run_loop;
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop);
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    run_loop.Run();
680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::Callback<void(MojoResult)> GetCallback() {
710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr());
720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) {
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    StartWithCallback(watcher, handle, GetCallback());
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void StartWithCallback(HandleWatcher* watcher,
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const MessagePipeHandle& handle,
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const base::Callback<void(MojoResult)>& callback) {
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    watcher->Start(handle, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE,
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   callback);
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnCallback(MojoResult result) {
870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    got_callback_ = true;
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (run_loop_)
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      run_loop_->Quit();
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Set to true when the callback is called.
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool got_callback_;
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If non-NULL we're in RunUntilGotCallback().
960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::RunLoop* run_loop_;
970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::WeakPtrFactory<CallbackHelper> weak_factory_;
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class HandleWatcherTest : public testing::Test {
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcherTest() {}
1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual ~HandleWatcherTest() {
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test::SetTickClockForTest(NULL);
1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) protected:
1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void InstallTickClock() {
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test::SetTickClockForTest(&tick_clock_);
1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::SimpleTestTickClock tick_clock_;
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Environment environment_;
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoop message_loop_;
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest);
1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Trivial test case with a single handle to watch.
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, SingleHandler) {
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe;
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe.handle0.is_valid());
1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper;
1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher;
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper.Start(&watcher, test_pipe.handle0.get());
1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper.got_callback());
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper.RunUntilGotCallback();
1370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper.got_callback());
1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Creates three handles and notfies them in reverse order ensuring each one is
1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// notified appropriately.
1420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, ThreeHandles) {
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe3;
1460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
1470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
1480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper3;
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe3.handle0.is_valid());
1520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher3;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 3 and make sure it's notified.
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper3.RunUntilGotCallback();
1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
1790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper3.got_callback());
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper3.clear_callback();
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // running.
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.clear_callback();
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies Start() invoked a second time works.
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, Restart) {
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
2100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
2230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and make sure it's notified.
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.clear_callback();
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1.handle0.get()));
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 2 and make sure it's notified.
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.clear_callback();
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Listen on 1 again.
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Write to 1 and make sure it's notified.
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
2530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper1.RunUntilGotCallback();
2540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper1.got_callback());
2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Verifies deadline is honored.
2590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(HandleWatcherTest, Deadline) {
2600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  InstallTickClock();
2610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe1;
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe2;
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe3;
2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper1;
2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper2;
2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CallbackHelper callback_helper3;
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe1.handle0.is_valid());
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe2.handle0.is_valid());
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_pipe3.handle0.is_valid());
2710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add a watcher with an infinite timeout.
2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher1;
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Add another watcher wth a timeout of 500 microseconds.
2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher2;
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  watcher2.Start(test_pipe2.handle0.get(), MOJO_WAIT_FLAG_READABLE, 500,
2830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                 callback_helper2.GetCallback());
2840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RunUntilIdle();
2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper2.got_callback());
2870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
2880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Advance the clock passed the deadline. We also have to start another
2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // watcher to wake up the background thread.
2910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501));
2920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  HandleWatcher watcher3;
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
2950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  callback_helper2.RunUntilGotCallback();
2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper1.got_callback());
2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(callback_helper2.got_callback());
2990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(callback_helper3.got_callback());
3000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(HandleWatcherTest, DeleteInCallback) {
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MessagePipe test_pipe;
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CallbackHelper callback_helper;
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HandleWatcher* watcher = new HandleWatcher();
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(),
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    base::Bind(&DeleteWatcherAndForwardResult,
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               watcher,
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                               callback_helper.GetCallback()));
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(),
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string()));
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  callback_helper.RunUntilGotCallback();
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(callback_helper.got_callback());
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(HandleWatcherCleanEnvironmentTest, AbortedOnMessageLoopDestruction) {
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool was_signaled = false;
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MojoResult result = MOJO_RESULT_OK;
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Environment env;
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MessagePipe pipe;
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  HandleWatcher watcher;
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoop loop;
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    watcher.Start(pipe.handle0.get(),
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  MOJO_WAIT_FLAG_READABLE,
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  MOJO_DEADLINE_INDEFINITE,
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  base::Bind(&ObserveCallback, &was_signaled, &result));
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Now, let the MessageLoop get torn down. We expect our callback to run.
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(was_signaled);
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_ABORTED, result);
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace test
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace common
3420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace mojo
343