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