• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TestRunLoopHandler()20   TestRunLoopHandler()
21       : ready_count_(0),
22         error_count_(0),
23         last_error_result_(MOJO_RESULT_OK) {
24   }
~TestRunLoopHandler()25   virtual ~TestRunLoopHandler() {}
26 
clear_ready_count()27   void clear_ready_count() { ready_count_ = 0; }
ready_count() const28   int ready_count() const { return ready_count_; }
29 
clear_error_count()30   void clear_error_count() { error_count_ = 0; }
error_count() const31   int error_count() const { return error_count_; }
32 
last_error_result() const33   MojoResult last_error_result() const { return last_error_result_; }
34 
35   // RunLoopHandler:
OnHandleReady(const Handle & handle)36   virtual void OnHandleReady(const Handle& handle) OVERRIDE {
37     ready_count_++;
38   }
OnHandleError(const Handle & handle,MojoResult result)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:
RunLoopTest()54   RunLoopTest() {}
55 
SetUp()56   virtual void SetUp() OVERRIDE {
57     Test::SetUp();
58     RunLoop::SetUp();
59   }
TearDown()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.
TEST_F(RunLoopTest,ExitsWithNoHandles)70 TEST_F(RunLoopTest, ExitsWithNoHandles) {
71   RunLoop run_loop;
72   run_loop.Run();
73 }
74 
75 class RemoveOnReadyRunLoopHandler : public TestRunLoopHandler {
76  public:
RemoveOnReadyRunLoopHandler()77   RemoveOnReadyRunLoopHandler() : run_loop_(NULL) {
78   }
~RemoveOnReadyRunLoopHandler()79   virtual ~RemoveOnReadyRunLoopHandler() {}
80 
set_run_loop(RunLoop * run_loop)81   void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
82 
83   // RunLoopHandler:
OnHandleReady(const Handle & handle)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).
TEST_F(RunLoopTest,HandleReady)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:
QuitOnReadyRunLoopHandler()112   QuitOnReadyRunLoopHandler() : run_loop_(NULL) {
113   }
~QuitOnReadyRunLoopHandler()114   virtual ~QuitOnReadyRunLoopHandler() {}
115 
set_run_loop(RunLoop * run_loop)116   void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
117 
118   // RunLoopHandler:
OnHandleReady(const Handle & handle)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.
TEST_F(RunLoopTest,QuitFromReady)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:
QuitOnErrorRunLoopHandler()147   QuitOnErrorRunLoopHandler() : run_loop_(NULL) {
148   }
~QuitOnErrorRunLoopHandler()149   virtual ~QuitOnErrorRunLoopHandler() {}
150 
set_run_loop(RunLoop * run_loop)151   void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
152 
153   // RunLoopHandler:
OnHandleError(const Handle & handle,MojoResult result)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.
TEST_F(RunLoopTest,QuitWhenDeadlineExpired)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 
TEST_F(RunLoopTest,Current)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