Home | History | Annotate | Download | only in message_loops
      1 // Copyright 2015 The Chromium OS 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 <brillo/message_loops/fake_message_loop.h>
      6 
      7 #include <memory>
      8 #include <vector>
      9 
     10 #include <base/bind.h>
     11 #include <base/location.h>
     12 #include <base/test/simple_test_clock.h>
     13 #include <gtest/gtest.h>
     14 
     15 #include <brillo/bind_lambda.h>
     16 #include <brillo/message_loops/message_loop.h>
     17 
     18 using base::Bind;
     19 using base::Time;
     20 using base::TimeDelta;
     21 using std::vector;
     22 
     23 namespace brillo {
     24 
     25 using TaskId = MessageLoop::TaskId;
     26 
     27 class FakeMessageLoopTest : public ::testing::Test {
     28  protected:
     29   void SetUp() override {
     30     loop_.reset(new FakeMessageLoop(nullptr));
     31     EXPECT_TRUE(loop_.get());
     32   }
     33   void TearDown() override {
     34     EXPECT_FALSE(loop_->PendingTasks());
     35   }
     36 
     37   base::SimpleTestClock clock_;
     38   std::unique_ptr<FakeMessageLoop> loop_;
     39 };
     40 
     41 TEST_F(FakeMessageLoopTest, CancelTaskInvalidValuesTest) {
     42   EXPECT_FALSE(loop_->CancelTask(MessageLoop::kTaskIdNull));
     43   EXPECT_FALSE(loop_->CancelTask(1234));
     44 }
     45 
     46 TEST_F(FakeMessageLoopTest, PostDelayedTaskRunsInOrder) {
     47   vector<int> order;
     48   loop_->PostDelayedTask(Bind([&order]() { order.push_back(1); }),
     49                          TimeDelta::FromSeconds(1));
     50   loop_->PostDelayedTask(Bind([&order]() { order.push_back(4); }),
     51                          TimeDelta::FromSeconds(4));
     52   loop_->PostDelayedTask(Bind([&order]() { order.push_back(3); }),
     53                          TimeDelta::FromSeconds(3));
     54   loop_->PostDelayedTask(Bind([&order]() { order.push_back(2); }),
     55                          TimeDelta::FromSeconds(2));
     56   // Run until all the tasks are run.
     57   loop_->Run();
     58   EXPECT_EQ((vector<int>{1, 2, 3, 4}), order);
     59 }
     60 
     61 TEST_F(FakeMessageLoopTest, PostDelayedTaskAdvancesTheTime) {
     62   Time start = Time::FromInternalValue(1000000);
     63   clock_.SetNow(start);
     64   loop_.reset(new FakeMessageLoop(&clock_));
     65   loop_->PostDelayedTask(Bind(&base::DoNothing), TimeDelta::FromSeconds(1));
     66   loop_->PostDelayedTask(Bind(&base::DoNothing), TimeDelta::FromSeconds(2));
     67   EXPECT_FALSE(loop_->RunOnce(false));
     68   // If the callback didn't run, the time shouldn't change.
     69   EXPECT_EQ(start, clock_.Now());
     70 
     71   // If we run only one callback, the time should be set to the time that
     72   // callack ran.
     73   EXPECT_TRUE(loop_->RunOnce(true));
     74   EXPECT_EQ(start + TimeDelta::FromSeconds(1), clock_.Now());
     75 
     76   // If the clock is advanced manually, we should be able to run the
     77   // callback without blocking, since the firing time is in the past.
     78   clock_.SetNow(start + TimeDelta::FromSeconds(3));
     79   EXPECT_TRUE(loop_->RunOnce(false));
     80   // The time should not change even if the callback is due in the past.
     81   EXPECT_EQ(start + TimeDelta::FromSeconds(3), clock_.Now());
     82 }
     83 
     84 TEST_F(FakeMessageLoopTest, WatchFileDescriptorWaits) {
     85   int fd = 1234;
     86   // We will simulate this situation. At the beginning, we will watch for a
     87   // file descriptor that won't trigger for 10s. Then we will pretend it is
     88   // ready after 10s and expect its callback to run just once.
     89   int called = 0;
     90   TaskId task_id = loop_->WatchFileDescriptor(
     91       FROM_HERE, fd, MessageLoop::kWatchRead, false,
     92       Bind([&called] { called++; }));
     93   EXPECT_NE(MessageLoop::kTaskIdNull, task_id);
     94 
     95   EXPECT_NE(MessageLoop::kTaskIdNull,
     96             loop_->PostDelayedTask(Bind([this] { this->loop_->BreakLoop(); }),
     97                                    TimeDelta::FromSeconds(10)));
     98   EXPECT_NE(MessageLoop::kTaskIdNull,
     99             loop_->PostDelayedTask(Bind([this] { this->loop_->BreakLoop(); }),
    100                                    TimeDelta::FromSeconds(20)));
    101   loop_->Run();
    102   EXPECT_EQ(0, called);
    103 
    104   loop_->SetFileDescriptorReadiness(fd, MessageLoop::kWatchRead, true);
    105   loop_->Run();
    106   EXPECT_EQ(1, called);
    107   EXPECT_FALSE(loop_->CancelTask(task_id));
    108 }
    109 
    110 TEST_F(FakeMessageLoopTest, PendingTasksTest) {
    111   loop_->PostDelayedTask(Bind(&base::DoNothing), TimeDelta::FromSeconds(1));
    112   EXPECT_TRUE(loop_->PendingTasks());
    113   loop_->Run();
    114 }
    115 
    116 }  // namespace brillo
    117