Home | History | Annotate | Download | only in utility
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "mojo/public/utility/run_loop.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/compiler_specific.h"
      9 #include "mojo/public/system/core_cpp.h"
     10 #include "mojo/public/tests/test_support.h"
     11 #include "mojo/public/utility/run_loop_handler.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace mojo {
     15 namespace utility {
     16 namespace {
     17 
     18 class TestRunLoopHandler : public RunLoopHandler {
     19  public:
     20   TestRunLoopHandler()
     21       : ready_count_(0),
     22         error_count_(0),
     23         last_error_result_(MOJO_RESULT_OK) {
     24   }
     25   virtual ~TestRunLoopHandler() {}
     26 
     27   void clear_ready_count() { ready_count_ = 0; }
     28   int ready_count() const { return ready_count_; }
     29 
     30   void clear_error_count() { error_count_ = 0; }
     31   int error_count() const { return error_count_; }
     32 
     33   MojoResult last_error_result() const { return last_error_result_; }
     34 
     35   // RunLoopHandler:
     36   virtual void OnHandleReady(const Handle& handle) OVERRIDE {
     37     ready_count_++;
     38   }
     39   virtual void OnHandleError(const Handle& handle, MojoResult result) OVERRIDE {
     40     error_count_++;
     41     last_error_result_ = result;
     42   }
     43 
     44  private:
     45   int ready_count_;
     46   int error_count_;
     47   MojoResult last_error_result_;
     48 
     49   DISALLOW_COPY_AND_ASSIGN(TestRunLoopHandler);
     50 };
     51 
     52 class RunLoopTest : public testing::Test {
     53  public:
     54   RunLoopTest() {}
     55 
     56   virtual void SetUp() OVERRIDE {
     57     Test::SetUp();
     58     RunLoop::SetUp();
     59   }
     60   virtual void TearDown() OVERRIDE {
     61     RunLoop::TearDown();
     62     Test::TearDown();
     63   }
     64 
     65  private:
     66   DISALLOW_COPY_AND_ASSIGN(RunLoopTest);
     67 };
     68 
     69 // Trivial test to verify Run() with no added handles returns.
     70 TEST_F(RunLoopTest, ExitsWithNoHandles) {
     71   RunLoop run_loop;
     72   run_loop.Run();
     73 }
     74 
     75 class RemoveOnReadyRunLoopHandler : public TestRunLoopHandler {
     76  public:
     77   RemoveOnReadyRunLoopHandler() : run_loop_(NULL) {
     78   }
     79   virtual ~RemoveOnReadyRunLoopHandler() {}
     80 
     81   void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
     82 
     83   // RunLoopHandler:
     84   virtual void OnHandleReady(const Handle& handle) OVERRIDE {
     85     run_loop_->RemoveHandler(handle);
     86     TestRunLoopHandler::OnHandleReady(handle);
     87   }
     88 
     89  private:
     90   RunLoop* run_loop_;
     91 
     92   DISALLOW_COPY_AND_ASSIGN(RemoveOnReadyRunLoopHandler);
     93 };
     94 
     95 // Verifies RunLoop quits when no more handles (handle is removed when ready).
     96 TEST_F(RunLoopTest, HandleReady) {
     97   RemoveOnReadyRunLoopHandler handler;
     98   test::MessagePipe test_pipe;
     99   EXPECT_EQ(MOJO_RESULT_OK, test::WriteEmptyMessage(test_pipe.handle_1.get()));
    100 
    101   RunLoop run_loop;
    102   handler.set_run_loop(&run_loop);
    103   run_loop.AddHandler(&handler, test_pipe.handle_0.get(),
    104                       MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE);
    105   run_loop.Run();
    106   EXPECT_EQ(1, handler.ready_count());
    107   EXPECT_EQ(0, handler.error_count());
    108 }
    109 
    110 class QuitOnReadyRunLoopHandler : public TestRunLoopHandler {
    111  public:
    112   QuitOnReadyRunLoopHandler() : run_loop_(NULL) {
    113   }
    114   virtual ~QuitOnReadyRunLoopHandler() {}
    115 
    116   void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
    117 
    118   // RunLoopHandler:
    119   virtual void OnHandleReady(const Handle& handle) OVERRIDE {
    120     run_loop_->Quit();
    121     TestRunLoopHandler::OnHandleReady(handle);
    122   }
    123 
    124  private:
    125   RunLoop* run_loop_;
    126 
    127   DISALLOW_COPY_AND_ASSIGN(QuitOnReadyRunLoopHandler);
    128 };
    129 
    130 // Verifies Quit() from OnHandleReady() quits the loop.
    131 TEST_F(RunLoopTest, QuitFromReady) {
    132   QuitOnReadyRunLoopHandler handler;
    133   test::MessagePipe test_pipe;
    134   EXPECT_EQ(MOJO_RESULT_OK, test::WriteEmptyMessage(test_pipe.handle_1.get()));
    135 
    136   RunLoop run_loop;
    137   handler.set_run_loop(&run_loop);
    138   run_loop.AddHandler(&handler, test_pipe.handle_0.get(),
    139                       MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE);
    140   run_loop.Run();
    141   EXPECT_EQ(1, handler.ready_count());
    142   EXPECT_EQ(0, handler.error_count());
    143 }
    144 
    145 class QuitOnErrorRunLoopHandler : public TestRunLoopHandler {
    146  public:
    147   QuitOnErrorRunLoopHandler() : run_loop_(NULL) {
    148   }
    149   virtual ~QuitOnErrorRunLoopHandler() {}
    150 
    151   void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
    152 
    153   // RunLoopHandler:
    154   virtual void OnHandleError(const Handle& handle, MojoResult result) OVERRIDE {
    155     run_loop_->Quit();
    156     TestRunLoopHandler::OnHandleError(handle, result);
    157   }
    158 
    159  private:
    160   RunLoop* run_loop_;
    161 
    162   DISALLOW_COPY_AND_ASSIGN(QuitOnErrorRunLoopHandler);
    163 };
    164 
    165 // Verifies Quit() when the deadline is reached works.
    166 TEST_F(RunLoopTest, QuitWhenDeadlineExpired) {
    167   QuitOnErrorRunLoopHandler handler;
    168   test::MessagePipe test_pipe;
    169   RunLoop run_loop;
    170   handler.set_run_loop(&run_loop);
    171   run_loop.AddHandler(&handler, test_pipe.handle_0.get(),
    172                       MOJO_WAIT_FLAG_READABLE,
    173                       static_cast<MojoDeadline>(10000));
    174   run_loop.Run();
    175   EXPECT_EQ(0, handler.ready_count());
    176   EXPECT_EQ(1, handler.error_count());
    177   EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, handler.last_error_result());
    178 }
    179 
    180 TEST_F(RunLoopTest, Current) {
    181   EXPECT_TRUE(RunLoop::current() == NULL);
    182   {
    183     RunLoop run_loop;
    184     EXPECT_EQ(&run_loop, RunLoop::current());
    185   }
    186   EXPECT_TRUE(RunLoop::current() == NULL);
    187 }
    188 
    189 }  // namespace
    190 }  // namespace utility
    191 }  // namespace mojo
    192