X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmojo%2Fpublic%2Fcpp%2Futility%2Ftests%2Frun_loop_unittest.cc;h=5f59aa2b830cf9bd47b175ecad8be04c6423092c;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=ba17fe856a5711b244d1b00c82ac24caa5f54b2e;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/mojo/public/cpp/utility/tests/run_loop_unittest.cc b/src/mojo/public/cpp/utility/tests/run_loop_unittest.cc index ba17fe8..5f59aa2 100644 --- a/src/mojo/public/cpp/utility/tests/run_loop_unittest.cc +++ b/src/mojo/public/cpp/utility/tests/run_loop_unittest.cc @@ -190,7 +190,122 @@ TEST_F(RunLoopTest, Current) { EXPECT_TRUE(RunLoop::current() == NULL); } -// TODO(darin): Add tests for nested calls to RunLoop::Run(). See crbug/384633. +class NestingRunLoopHandler : public TestRunLoopHandler { + public: + static const size_t kDepthLimit; + static const char kSignalMagic; + + NestingRunLoopHandler() + : run_loop_(NULL), + pipe_(NULL), + depth_(0), + reached_depth_limit_(false) {} + + virtual ~NestingRunLoopHandler() {} + + void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } + void set_pipe(MessagePipe* pipe) { pipe_ = pipe; } + bool reached_depth_limit() const { return reached_depth_limit_; } + + // RunLoopHandler: + virtual void OnHandleReady(const Handle& handle) MOJO_OVERRIDE { + TestRunLoopHandler::OnHandleReady(handle); + EXPECT_EQ(handle.value(), pipe_->handle0.get().value()); + + ReadSignal(); + size_t current_depth = ++depth_; + if (current_depth < kDepthLimit) { + WriteSignal(); + run_loop_->Run(); + if (current_depth == kDepthLimit - 1) { + // The topmost loop Quit()-ed, so its parent takes back the + // control without exeeding deadline. + EXPECT_EQ(error_count(), 0); + } else { + EXPECT_EQ(error_count(), 1); + } + + } else { + EXPECT_EQ(current_depth, kDepthLimit); + reached_depth_limit_ = true; + run_loop_->Quit(); + } + --depth_; + } + + void WriteSignal() { + char write_byte = kSignalMagic; + MojoResult write_result = WriteMessageRaw( + pipe_->handle1.get(), + &write_byte, 1, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE); + EXPECT_EQ(write_result, MOJO_RESULT_OK); + } + + void ReadSignal() { + char read_byte = 0; + uint32_t bytes_read = 1; + uint32_t handles_read = 0; + MojoResult read_result = ReadMessageRaw( + pipe_->handle0.get(), + &read_byte, &bytes_read, NULL, &handles_read, + MOJO_READ_MESSAGE_FLAG_NONE); + EXPECT_EQ(read_result, MOJO_RESULT_OK); + EXPECT_EQ(read_byte, kSignalMagic); + } + + private: + RunLoop* run_loop_; + MessagePipe* pipe_; + size_t depth_; + bool reached_depth_limit_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(NestingRunLoopHandler); +}; + +const size_t NestingRunLoopHandler::kDepthLimit = 10; +const char NestingRunLoopHandler::kSignalMagic = 'X'; + +TEST_F(RunLoopTest, NestedRun) { + NestingRunLoopHandler handler; + MessagePipe test_pipe; + RunLoop run_loop; + handler.set_run_loop(&run_loop); + handler.set_pipe(&test_pipe); + run_loop.AddHandler(&handler, test_pipe.handle0.get(), + MOJO_HANDLE_SIGNAL_READABLE, + static_cast(10000)); + handler.WriteSignal(); + run_loop.Run(); + + EXPECT_TRUE(handler.reached_depth_limit()); + // Got MOJO_RESULT_DEADLINE_EXCEEDED once then removed from the + // RunLoop's handler list. + EXPECT_EQ(handler.error_count(), 1); + EXPECT_EQ(handler.last_error_result(), MOJO_RESULT_DEADLINE_EXCEEDED); +} + +struct Task { + Task(int num, std::vector* sequence) : num(num), sequence(sequence) {} + + void Run() const { sequence->push_back(num); } + + int num; + std::vector* sequence; +}; + +TEST_F(RunLoopTest, DelayedTaskOrder) { + std::vector sequence; + RunLoop run_loop; + run_loop.PostDelayedTask(Closure(Task(1, &sequence)), 0); + run_loop.PostDelayedTask(Closure(Task(2, &sequence)), 0); + run_loop.PostDelayedTask(Closure(Task(3, &sequence)), 0); + run_loop.RunUntilIdle(); + + ASSERT_EQ(3u, sequence.size()); + EXPECT_EQ(1, sequence[0]); + EXPECT_EQ(2, sequence[1]); + EXPECT_EQ(3, sequence[2]); +} } // namespace } // namespace mojo