1 // Copyright 2019 The Chromium Authors
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 "base/task/sequence_manager/test/mock_time_message_pump.h"
6
7 #include "base/message_loop/message_pump.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace base {
13 namespace sequence_manager {
14 namespace {
15
16 using ::testing::DoAll;
17 using ::testing::Eq;
18 using ::testing::Invoke;
19 using ::testing::Return;
20 using ::testing::SetArgPointee;
21 using ::testing::StrictMock;
22
23 class MockMessagePumpDelegate : public MessagePump::Delegate {
24 public:
25 MOCK_METHOD0(OnBeginWorkItem, void());
26 MOCK_METHOD1(OnEndWorkItem, void(int));
27 MOCK_METHOD0(BeforeWait, void());
28 MOCK_METHOD0(BeginNativeWorkBeforeDoWork, void());
29 MOCK_METHOD0(DoWork, NextWorkInfo());
30 MOCK_METHOD0(DoIdleWork, bool());
31 MOCK_METHOD0(RunDepth, int());
32 };
33
NextWorkInfo(TimeTicks delayed_run_time)34 MessagePump::Delegate::NextWorkInfo NextWorkInfo(TimeTicks delayed_run_time) {
35 MessagePump::Delegate::NextWorkInfo info;
36 info.delayed_run_time = delayed_run_time;
37 return info;
38 }
39
TEST(MockMessagePumpTest,KeepsRunningIfNotAllowedToAdvanceTime)40 TEST(MockMessagePumpTest, KeepsRunningIfNotAllowedToAdvanceTime) {
41 SimpleTestTickClock mock_clock;
42 mock_clock.Advance(Hours(42));
43 StrictMock<MockMessagePumpDelegate> delegate;
44 MockTimeMessagePump pump(&mock_clock);
45 const auto kStartTime = mock_clock.NowTicks();
46 const auto kFutureTime = kStartTime + Seconds(42);
47
48 EXPECT_CALL(delegate, DoWork)
49 .WillOnce(Return(NextWorkInfo(TimeTicks())))
50 .WillOnce(Return(NextWorkInfo(TimeTicks())))
51 .WillOnce(Return(NextWorkInfo(kFutureTime)));
52 EXPECT_CALL(delegate, DoIdleWork).WillOnce(Invoke([&] {
53 pump.Quit();
54 return false;
55 }));
56
57 pump.Run(&delegate);
58
59 EXPECT_THAT(mock_clock.NowTicks(), Eq(kStartTime));
60 }
61
TEST(MockMessagePumpTest,AdvancesTimeAsAllowed)62 TEST(MockMessagePumpTest, AdvancesTimeAsAllowed) {
63 SimpleTestTickClock mock_clock;
64 mock_clock.Advance(Hours(42));
65 StrictMock<MockMessagePumpDelegate> delegate;
66 MockTimeMessagePump pump(&mock_clock);
67 const auto kStartTime = mock_clock.NowTicks();
68 const auto kEndTime = kStartTime + Seconds(2);
69
70 pump.SetAllowTimeToAutoAdvanceUntil(kEndTime);
71 pump.SetStopWhenMessagePumpIsIdle(true);
72 EXPECT_CALL(delegate, DoWork).Times(3).WillRepeatedly(Invoke([&]() {
73 return NextWorkInfo(mock_clock.NowTicks() + Seconds(1));
74 }));
75 EXPECT_CALL(delegate, DoIdleWork).Times(3).WillRepeatedly(Return(false));
76
77 pump.Run(&delegate);
78
79 EXPECT_THAT(mock_clock.NowTicks(), Eq(kEndTime));
80 }
81
TEST(MockMessagePumpTest,CanQuitAfterMaybeDoWork)82 TEST(MockMessagePumpTest, CanQuitAfterMaybeDoWork) {
83 SimpleTestTickClock mock_clock;
84 mock_clock.Advance(Hours(42));
85 StrictMock<MockMessagePumpDelegate> delegate;
86 MockTimeMessagePump pump(&mock_clock);
87
88 pump.SetQuitAfterDoWork(true);
89 EXPECT_CALL(delegate, DoWork).WillOnce(Return(NextWorkInfo(TimeTicks())));
90
91 pump.Run(&delegate);
92 }
93
TEST(MockMessagePumpTest,AdvancesUntilAllowedTime)94 TEST(MockMessagePumpTest, AdvancesUntilAllowedTime) {
95 SimpleTestTickClock mock_clock;
96 mock_clock.Advance(Hours(42));
97 StrictMock<MockMessagePumpDelegate> delegate;
98 MockTimeMessagePump pump(&mock_clock);
99 const auto kStartTime = mock_clock.NowTicks();
100 const auto kEndTime = kStartTime + Seconds(2);
101 const auto kNextDelayedWorkTime = kEndTime + Seconds(2);
102
103 pump.SetAllowTimeToAutoAdvanceUntil(kEndTime);
104 pump.SetStopWhenMessagePumpIsIdle(true);
105 EXPECT_CALL(delegate, DoWork)
106 .Times(2)
107 .WillRepeatedly(Return(NextWorkInfo(kNextDelayedWorkTime)));
108 EXPECT_CALL(delegate, DoIdleWork).Times(2).WillRepeatedly(Return(false));
109
110 pump.Run(&delegate);
111
112 EXPECT_THAT(mock_clock.NowTicks(), Eq(kEndTime));
113 }
114
TEST(MockMessagePumpTest,StoresNextWakeUpTime)115 TEST(MockMessagePumpTest, StoresNextWakeUpTime) {
116 SimpleTestTickClock mock_clock;
117 StrictMock<MockMessagePumpDelegate> delegate;
118 MockTimeMessagePump pump(&mock_clock);
119 const auto kStartTime = mock_clock.NowTicks();
120 const auto kEndTime = kStartTime;
121 const auto kNextDelayedWorkTime = kEndTime + Seconds(2);
122
123 pump.SetAllowTimeToAutoAdvanceUntil(kEndTime);
124 pump.SetStopWhenMessagePumpIsIdle(true);
125 EXPECT_CALL(delegate, DoWork)
126 .WillOnce(Return(NextWorkInfo(kNextDelayedWorkTime)));
127 EXPECT_CALL(delegate, DoIdleWork).WillOnce(Return(false));
128
129 pump.Run(&delegate);
130
131 EXPECT_THAT(pump.next_wake_up_time(), Eq(kNextDelayedWorkTime));
132 }
133
TEST(MockMessagePumpTest,StoresNextWakeUpTimeInScheduleDelayedWork)134 TEST(MockMessagePumpTest, StoresNextWakeUpTimeInScheduleDelayedWork) {
135 SimpleTestTickClock mock_clock;
136 StrictMock<MockMessagePumpDelegate> delegate;
137 MockTimeMessagePump pump(&mock_clock);
138 const auto kStartTime = mock_clock.NowTicks();
139 const auto kNextDelayedWorkTime = kStartTime + Seconds(2);
140
141 pump.ScheduleDelayedWork(MessagePump::Delegate::NextWorkInfo{
142 kNextDelayedWorkTime, TimeDelta(), kStartTime});
143
144 EXPECT_THAT(pump.next_wake_up_time(), Eq(kNextDelayedWorkTime));
145 }
146
TEST(MockMessagePumpTest,NextDelayedWorkTimeInThePastKeepsRunning)147 TEST(MockMessagePumpTest, NextDelayedWorkTimeInThePastKeepsRunning) {
148 SimpleTestTickClock mock_clock;
149 mock_clock.Advance(Hours(42));
150 StrictMock<MockMessagePumpDelegate> delegate;
151 MockTimeMessagePump pump(&mock_clock);
152 const auto kNextDelayedWorkTime = mock_clock.NowTicks();
153 mock_clock.Advance(Hours(2));
154
155 pump.SetStopWhenMessagePumpIsIdle(true);
156
157 EXPECT_CALL(delegate, DoWork)
158 .WillOnce(Return(NextWorkInfo(kNextDelayedWorkTime)))
159 .WillOnce(Return(NextWorkInfo(kNextDelayedWorkTime)))
160 .WillOnce(Return(NextWorkInfo(TimeTicks::Max())));
161 EXPECT_CALL(delegate, DoIdleWork).WillRepeatedly(Return(false));
162
163 pump.Run(&delegate);
164 }
165
TEST(MockMessagePumpTest,AdvancesUntilAllowedTimeWhenNextDelayedWorkTimeIsMax)166 TEST(MockMessagePumpTest,
167 AdvancesUntilAllowedTimeWhenNextDelayedWorkTimeIsMax) {
168 SimpleTestTickClock mock_clock;
169 mock_clock.Advance(Hours(42));
170 StrictMock<MockMessagePumpDelegate> delegate;
171 MockTimeMessagePump pump(&mock_clock);
172 const auto kAdvanceUntil = mock_clock.NowTicks() + Seconds(123);
173
174 pump.SetStopWhenMessagePumpIsIdle(true);
175 pump.SetAllowTimeToAutoAdvanceUntil(kAdvanceUntil);
176 EXPECT_CALL(delegate, DoWork)
177 .WillRepeatedly(Return(NextWorkInfo(TimeTicks::Max())));
178 EXPECT_CALL(delegate, DoIdleWork).WillRepeatedly(Return(false));
179
180 pump.Run(&delegate);
181
182 EXPECT_THAT(mock_clock.NowTicks(), Eq(kAdvanceUntil));
183 }
184
185 } // namespace
186 } // namespace sequence_manager
187 } // namespace base
188