blob: 43e3b921270be31241b95bfbc0eebffdd6c6e3af [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/task/sequence_manager/test/mock_time_message_pump.h"
#include "base/message_loop/message_pump.h"
#include "base/test/simple_test_tick_clock.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace sequence_manager {
namespace {
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StrictMock;
class MockMessagePumpDelegate : public MessagePump::Delegate {
public:
MOCK_METHOD0(OnBeginWorkItem, void());
MOCK_METHOD1(OnEndWorkItem, void(int));
MOCK_METHOD0(BeforeWait, void());
MOCK_METHOD0(BeginNativeWorkBeforeDoWork, void());
MOCK_METHOD0(DoWork, NextWorkInfo());
MOCK_METHOD0(DoIdleWork, bool());
MOCK_METHOD0(RunDepth, int());
};
MessagePump::Delegate::NextWorkInfo NextWorkInfo(TimeTicks delayed_run_time) {
MessagePump::Delegate::NextWorkInfo info;
info.delayed_run_time = delayed_run_time;
return info;
}
TEST(MockMessagePumpTest, KeepsRunningIfNotAllowedToAdvanceTime) {
SimpleTestTickClock mock_clock;
mock_clock.Advance(Hours(42));
StrictMock<MockMessagePumpDelegate> delegate;
MockTimeMessagePump pump(&mock_clock);
const auto kStartTime = mock_clock.NowTicks();
const auto kFutureTime = kStartTime + Seconds(42);
EXPECT_CALL(delegate, DoWork)
.WillOnce(Return(NextWorkInfo(TimeTicks())))
.WillOnce(Return(NextWorkInfo(TimeTicks())))
.WillOnce(Return(NextWorkInfo(kFutureTime)));
EXPECT_CALL(delegate, DoIdleWork).WillOnce(Invoke([&] {
pump.Quit();
return false;
}));
pump.Run(&delegate);
EXPECT_THAT(mock_clock.NowTicks(), Eq(kStartTime));
}
TEST(MockMessagePumpTest, AdvancesTimeAsAllowed) {
SimpleTestTickClock mock_clock;
mock_clock.Advance(Hours(42));
StrictMock<MockMessagePumpDelegate> delegate;
MockTimeMessagePump pump(&mock_clock);
const auto kStartTime = mock_clock.NowTicks();
const auto kEndTime = kStartTime + Seconds(2);
pump.SetAllowTimeToAutoAdvanceUntil(kEndTime);
pump.SetStopWhenMessagePumpIsIdle(true);
EXPECT_CALL(delegate, DoWork).Times(3).WillRepeatedly(Invoke([&]() {
return NextWorkInfo(mock_clock.NowTicks() + Seconds(1));
}));
EXPECT_CALL(delegate, DoIdleWork).Times(3).WillRepeatedly(Return(false));
pump.Run(&delegate);
EXPECT_THAT(mock_clock.NowTicks(), Eq(kEndTime));
}
TEST(MockMessagePumpTest, CanQuitAfterMaybeDoWork) {
SimpleTestTickClock mock_clock;
mock_clock.Advance(Hours(42));
StrictMock<MockMessagePumpDelegate> delegate;
MockTimeMessagePump pump(&mock_clock);
pump.SetQuitAfterDoWork(true);
EXPECT_CALL(delegate, DoWork).WillOnce(Return(NextWorkInfo(TimeTicks())));
pump.Run(&delegate);
}
TEST(MockMessagePumpTest, AdvancesUntilAllowedTime) {
SimpleTestTickClock mock_clock;
mock_clock.Advance(Hours(42));
StrictMock<MockMessagePumpDelegate> delegate;
MockTimeMessagePump pump(&mock_clock);
const auto kStartTime = mock_clock.NowTicks();
const auto kEndTime = kStartTime + Seconds(2);
const auto kNextDelayedWorkTime = kEndTime + Seconds(2);
pump.SetAllowTimeToAutoAdvanceUntil(kEndTime);
pump.SetStopWhenMessagePumpIsIdle(true);
EXPECT_CALL(delegate, DoWork)
.Times(2)
.WillRepeatedly(Return(NextWorkInfo(kNextDelayedWorkTime)));
EXPECT_CALL(delegate, DoIdleWork).Times(2).WillRepeatedly(Return(false));
pump.Run(&delegate);
EXPECT_THAT(mock_clock.NowTicks(), Eq(kEndTime));
}
TEST(MockMessagePumpTest, StoresNextWakeUpTime) {
SimpleTestTickClock mock_clock;
StrictMock<MockMessagePumpDelegate> delegate;
MockTimeMessagePump pump(&mock_clock);
const auto kStartTime = mock_clock.NowTicks();
const auto kEndTime = kStartTime;
const auto kNextDelayedWorkTime = kEndTime + Seconds(2);
pump.SetAllowTimeToAutoAdvanceUntil(kEndTime);
pump.SetStopWhenMessagePumpIsIdle(true);
EXPECT_CALL(delegate, DoWork)
.WillOnce(Return(NextWorkInfo(kNextDelayedWorkTime)));
EXPECT_CALL(delegate, DoIdleWork).WillOnce(Return(false));
pump.Run(&delegate);
EXPECT_THAT(pump.next_wake_up_time(), Eq(kNextDelayedWorkTime));
}
TEST(MockMessagePumpTest, StoresNextWakeUpTimeInScheduleDelayedWork) {
SimpleTestTickClock mock_clock;
StrictMock<MockMessagePumpDelegate> delegate;
MockTimeMessagePump pump(&mock_clock);
const auto kStartTime = mock_clock.NowTicks();
const auto kNextDelayedWorkTime = kStartTime + Seconds(2);
pump.ScheduleDelayedWork(MessagePump::Delegate::NextWorkInfo{
kNextDelayedWorkTime, TimeDelta(), kStartTime});
EXPECT_THAT(pump.next_wake_up_time(), Eq(kNextDelayedWorkTime));
}
TEST(MockMessagePumpTest, NextDelayedWorkTimeInThePastKeepsRunning) {
SimpleTestTickClock mock_clock;
mock_clock.Advance(Hours(42));
StrictMock<MockMessagePumpDelegate> delegate;
MockTimeMessagePump pump(&mock_clock);
const auto kNextDelayedWorkTime = mock_clock.NowTicks();
mock_clock.Advance(Hours(2));
pump.SetStopWhenMessagePumpIsIdle(true);
EXPECT_CALL(delegate, DoWork)
.WillOnce(Return(NextWorkInfo(kNextDelayedWorkTime)))
.WillOnce(Return(NextWorkInfo(kNextDelayedWorkTime)))
.WillOnce(Return(NextWorkInfo(TimeTicks::Max())));
EXPECT_CALL(delegate, DoIdleWork).WillRepeatedly(Return(false));
pump.Run(&delegate);
}
TEST(MockMessagePumpTest,
AdvancesUntilAllowedTimeWhenNextDelayedWorkTimeIsMax) {
SimpleTestTickClock mock_clock;
mock_clock.Advance(Hours(42));
StrictMock<MockMessagePumpDelegate> delegate;
MockTimeMessagePump pump(&mock_clock);
const auto kAdvanceUntil = mock_clock.NowTicks() + Seconds(123);
pump.SetStopWhenMessagePumpIsIdle(true);
pump.SetAllowTimeToAutoAdvanceUntil(kAdvanceUntil);
EXPECT_CALL(delegate, DoWork)
.WillRepeatedly(Return(NextWorkInfo(TimeTicks::Max())));
EXPECT_CALL(delegate, DoIdleWork).WillRepeatedly(Return(false));
pump.Run(&delegate);
EXPECT_THAT(mock_clock.NowTicks(), Eq(kAdvanceUntil));
}
} // namespace
} // namespace sequence_manager
} // namespace base