• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SetUp()29   void SetUp() override {
30     loop_.reset(new FakeMessageLoop(nullptr));
31     EXPECT_TRUE(loop_.get());
32   }
TearDown()33   void TearDown() override {
34     EXPECT_FALSE(loop_->PendingTasks());
35   }
36 
37   base::SimpleTestClock clock_;
38   std::unique_ptr<FakeMessageLoop> loop_;
39 };
40 
TEST_F(FakeMessageLoopTest,CancelTaskInvalidValuesTest)41 TEST_F(FakeMessageLoopTest, CancelTaskInvalidValuesTest) {
42   EXPECT_FALSE(loop_->CancelTask(MessageLoop::kTaskIdNull));
43   EXPECT_FALSE(loop_->CancelTask(1234));
44 }
45 
TEST_F(FakeMessageLoopTest,PostDelayedTaskRunsInOrder)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 
TEST_F(FakeMessageLoopTest,PostDelayedTaskAdvancesTheTime)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 
TEST_F(FakeMessageLoopTest,WatchFileDescriptorWaits)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 
TEST_F(FakeMessageLoopTest,PendingTasksTest)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