| Index: base/message_loop_unittest.cc
|
| ===================================================================
|
| --- base/message_loop_unittest.cc (revision 1824)
|
| +++ base/message_loop_unittest.cc (working copy)
|
| @@ -137,6 +137,159 @@
|
| EXPECT_EQ(foo->result(), "abacad");
|
| }
|
|
|
| +// This class runs slowly to simulate a large amount of work being done.
|
| +class SlowTask : public Task {
|
| + public:
|
| + SlowTask(int pause_ms, int* quit_counter)
|
| + : pause_ms_(pause_ms), quit_counter_(quit_counter) {
|
| + }
|
| + virtual void Run() {
|
| + PlatformThread::Sleep(pause_ms_);
|
| + if (--(*quit_counter_) == 0)
|
| + MessageLoop::current()->Quit();
|
| + }
|
| + private:
|
| + int pause_ms_;
|
| + int* quit_counter_;
|
| +};
|
| +
|
| +// This class records the time when Run was called in a Time object, which is
|
| +// useful for building a variety of MessageLoop tests.
|
| +class RecordRunTimeTask : public SlowTask {
|
| + public:
|
| + RecordRunTimeTask(Time* run_time, int* quit_counter)
|
| + : SlowTask(10, quit_counter), run_time_(run_time) {
|
| + }
|
| + virtual void Run() {
|
| + *run_time_ = Time::Now();
|
| + // Cause our Run function to take some time to execute. As a result we can
|
| + // count on subsequent RecordRunTimeTask objects running at a future time,
|
| + // without worry about the resolution of our system clock being an issue.
|
| + SlowTask::Run();
|
| + }
|
| + private:
|
| + Time* run_time_;
|
| +};
|
| +
|
| +void RunTest_PostDelayedTask_Basic(MessageLoop::Type message_loop_type) {
|
| + MessageLoop loop(message_loop_type);
|
| +
|
| + // Test that PostDelayedTask results in a delayed task.
|
| +
|
| + const int kDelayMS = 100;
|
| +
|
| + int num_tasks = 1;
|
| + Time run_time;
|
| +
|
| + loop.PostDelayedTask(
|
| + FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), kDelayMS);
|
| +
|
| + Time time_before_run = Time::Now();
|
| + loop.Run();
|
| + Time time_after_run = Time::Now();
|
| +
|
| + EXPECT_EQ(0, num_tasks);
|
| + EXPECT_LT(kDelayMS, (time_after_run - time_before_run).InMilliseconds());
|
| +}
|
| +
|
| +void RunTest_PostDelayedTask_InDelayOrder(MessageLoop::Type message_loop_type) {
|
| + MessageLoop loop(message_loop_type);
|
| +
|
| + // Test that two tasks with different delays run in the right order.
|
| +
|
| + int num_tasks = 2;
|
| + Time run_time1, run_time2;
|
| +
|
| + loop.PostDelayedTask(
|
| + FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), 200);
|
| + // If we get a large pause in execution (due to a context switch) here, this
|
| + // test could fail.
|
| + loop.PostDelayedTask(
|
| + FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 10);
|
| +
|
| + loop.Run();
|
| + EXPECT_EQ(0, num_tasks);
|
| +
|
| + EXPECT_TRUE(run_time2 < run_time1);
|
| +}
|
| +
|
| +void RunTest_PostDelayedTask_InPostOrder(MessageLoop::Type message_loop_type) {
|
| + MessageLoop loop(message_loop_type);
|
| +
|
| + // Test that two tasks with the same delay run in the order in which they
|
| + // were posted.
|
| + //
|
| + // NOTE: This is actually an approximate test since the API only takes a
|
| + // "delay" parameter, so we are not exactly simulating two tasks that get
|
| + // posted at the exact same time. It would be nice if the API allowed us to
|
| + // specify the desired run time.
|
| +
|
| + const int kDelayMS = 100;
|
| +
|
| + int num_tasks = 2;
|
| + Time run_time1, run_time2;
|
| +
|
| + loop.PostDelayedTask(
|
| + FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), kDelayMS);
|
| + loop.PostDelayedTask(
|
| + FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), kDelayMS);
|
| +
|
| + loop.Run();
|
| + EXPECT_EQ(0, num_tasks);
|
| +
|
| + EXPECT_TRUE(run_time1 < run_time2);
|
| +}
|
| +
|
| +void RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::Type message_loop_type) {
|
| + MessageLoop loop(message_loop_type);
|
| +
|
| + // Test that a delayed task still runs after a normal tasks even if the
|
| + // normal tasks take a long time to run.
|
| +
|
| + const int kPauseMS = 50;
|
| +
|
| + int num_tasks = 2;
|
| + Time run_time;
|
| +
|
| + loop.PostTask(
|
| + FROM_HERE, new SlowTask(kPauseMS, &num_tasks));
|
| + loop.PostDelayedTask(
|
| + FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), 10);
|
| +
|
| + Time time_before_run = Time::Now();
|
| + loop.Run();
|
| + Time time_after_run = Time::Now();
|
| +
|
| + EXPECT_EQ(0, num_tasks);
|
| +
|
| + EXPECT_LT(kPauseMS, (time_after_run - time_before_run).InMilliseconds());
|
| +}
|
| +
|
| +void RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::Type message_loop_type) {
|
| + MessageLoop loop(message_loop_type);
|
| +
|
| + // Test that a delayed task still runs after a pile of normal tasks. The key
|
| + // difference between this test and the previous one is that here we return
|
| + // the MessageLoop a lot so we give the MessageLoop plenty of opportunities
|
| + // to maybe run the delayed task. It should know not to do so until the
|
| + // delayed task's delay has passed.
|
| +
|
| + int num_tasks = 11;
|
| + Time run_time1, run_time2;
|
| +
|
| + // Clutter the ML with tasks.
|
| + for (int i = 1; i < num_tasks; ++i)
|
| + loop.PostTask(FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks));
|
| +
|
| + loop.PostDelayedTask(
|
| + FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 1);
|
| +
|
| + loop.Run();
|
| + EXPECT_EQ(0, num_tasks);
|
| +
|
| + EXPECT_TRUE(run_time2 > run_time1);
|
| +}
|
| +
|
| class NestingTest : public Task {
|
| public:
|
| explicit NestingTest(int* depth) : depth_(depth) {
|
| @@ -705,8 +858,7 @@
|
| TaskList order;
|
|
|
| Task* task = new OrderedTasks(&order, 1);
|
| - task->set_nestable(false);
|
| - MessageLoop::current()->PostTask(FROM_HERE, task);
|
| + MessageLoop::current()->PostNonNestableTask(FROM_HERE, task);
|
| MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 2));
|
| MessageLoop::current()->PostTask(FROM_HERE, new QuitTask(&order, 3));
|
| MessageLoop::current()->Run();
|
| @@ -730,13 +882,11 @@
|
| MessageLoop::current()->PostTask(FROM_HERE,
|
| new TaskThatPumps(&order, 1));
|
| Task* task = new OrderedTasks(&order, 2);
|
| - task->set_nestable(false);
|
| - MessageLoop::current()->PostTask(FROM_HERE, task);
|
| + MessageLoop::current()->PostNonNestableTask(FROM_HERE, task);
|
| MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 3));
|
| MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 4));
|
| Task* non_nestable_quit = new QuitTask(&order, 5);
|
| - non_nestable_quit->set_nestable(false);
|
| - MessageLoop::current()->PostTask(FROM_HERE, non_nestable_quit);
|
| + MessageLoop::current()->PostNonNestableTask(FROM_HERE, non_nestable_quit);
|
|
|
| MessageLoop::current()->Run();
|
|
|
| @@ -869,6 +1019,36 @@
|
| RunTest_PostTask_SEH(MessageLoop::TYPE_IO);
|
| }
|
|
|
| +TEST(MessageLoopTest, PostDelayedTask_Basic) {
|
| + RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_DEFAULT);
|
| + RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_UI);
|
| + RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_IO);
|
| +}
|
| +
|
| +TEST(MessageLoopTest, PostDelayedTask_InDelayOrder) {
|
| + RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_DEFAULT);
|
| + RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_UI);
|
| + RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_IO);
|
| +}
|
| +
|
| +TEST(MessageLoopTest, PostDelayedTask_InPostOrder) {
|
| + RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_DEFAULT);
|
| + RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_UI);
|
| + RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_IO);
|
| +}
|
| +
|
| +TEST(MessageLoopTest, PostDelayedTask_InPostOrder_2) {
|
| + RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_DEFAULT);
|
| + RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_UI);
|
| + RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_IO);
|
| +}
|
| +
|
| +TEST(MessageLoopTest, PostDelayedTask_InPostOrder_3) {
|
| + RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_DEFAULT);
|
| + RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_UI);
|
| + RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_IO);
|
| +}
|
| +
|
| #if defined(OS_WIN)
|
| TEST(MessageLoopTest, Crasher) {
|
| RunTest_Crasher(MessageLoop::TYPE_DEFAULT);
|
|
|