#include "base/task/sequence_manager/task_queue.h"
#include "base/message_loop/message_pump.h"
#include "base/message_loop/message_pump_type.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_features.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base::sequence_manager::internal::task_queue_unittest {
namespace {
TEST(TaskQueueTest, TaskQueueVoters) {
auto sequence_manager = CreateSequenceManagerOnCurrentThreadWithPump(
MessagePump::Create(MessagePumpType::DEFAULT));
auto queue =
sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ));
EXPECT_TRUE(queue->IsQueueEnabled());
std::unique_ptr<TaskQueue::QueueEnabledVoter> voter1 =
queue->CreateQueueEnabledVoter();
std::unique_ptr<TaskQueue::QueueEnabledVoter> voter2 =
queue->CreateQueueEnabledVoter();
std::unique_ptr<TaskQueue::QueueEnabledVoter> voter3 =
queue->CreateQueueEnabledVoter();
std::unique_ptr<TaskQueue::QueueEnabledVoter> voter4 =
queue->CreateQueueEnabledVoter();
EXPECT_TRUE(queue->IsQueueEnabled());
voter1->SetVoteToEnable(false);
EXPECT_FALSE(queue->IsQueueEnabled());
voter1.reset();
EXPECT_TRUE(queue->IsQueueEnabled());
voter2->SetVoteToEnable(false);
EXPECT_FALSE(queue->IsQueueEnabled());
voter3->SetVoteToEnable(false);
EXPECT_FALSE(queue->IsQueueEnabled());
voter2->SetVoteToEnable(true);
EXPECT_FALSE(queue->IsQueueEnabled());
voter3->SetVoteToEnable(true);
EXPECT_TRUE(queue->IsQueueEnabled());
}
TEST(TaskQueueTest, ShutdownQueueBeforeEnabledVoterDeleted) {
auto sequence_manager = CreateSequenceManagerOnCurrentThreadWithPump(
MessagePump::Create(MessagePumpType::DEFAULT));
auto queue =
sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ));
std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
queue->CreateQueueEnabledVoter();
voter->SetVoteToEnable(true);
queue.reset();
voter.reset();
}
TEST(TaskQueueTest, ShutdownQueueBeforeDisabledVoterDeleted) {
auto sequence_manager = CreateSequenceManagerOnCurrentThreadWithPump(
MessagePump::Create(MessagePumpType::DEFAULT));
auto queue =
sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ));
std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
queue->CreateQueueEnabledVoter();
voter->SetVoteToEnable(false);
queue.reset();
voter.reset();
}
TEST(TaskQueueTest, CanceledTaskRemoved) {
auto sequence_manager = CreateSequenceManagerOnCurrentThreadWithPump(
MessagePump::Create(MessagePumpType::DEFAULT));
auto queue =
sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ));
auto task_runner = queue->task_runner();
EXPECT_EQ(queue->GetNumberOfPendingTasks(), 0u);
bool task_ran = false;
DelayedTaskHandle delayed_task_handle =
task_runner->PostCancelableDelayedTask(
subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
BindLambdaForTesting([&task_ran] { task_ran = true; }), Seconds(20));
EXPECT_EQ(queue->GetNumberOfPendingTasks(), 1u);
delayed_task_handle.CancelTask();
EXPECT_EQ(queue->GetNumberOfPendingTasks(), 0u);
EXPECT_FALSE(task_ran);
}
TEST(TaskQueueTest, ValidCancelableTaskIsNotCanceled) {
auto sequence_manager = CreateSequenceManagerOnCurrentThreadWithPump(
MessagePump::Create(MessagePumpType::DEFAULT));
auto queue =
sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ));
auto task_runner = queue->task_runner();
EXPECT_EQ(queue->GetNumberOfPendingTasks(), 0u);
SingleThreadTaskRunner::CurrentDefaultHandle
single_thread_task_runner_current_default_handle(task_runner);
RunLoop run_loop;
constexpr TimeDelta kTestDelay = Microseconds(1);
task_runner->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), kTestDelay);
DelayedTaskHandle delayed_task_handle =
task_runner->PostCancelableDelayedTask(
subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE, DoNothing(),
kTestDelay);
run_loop.Run();
EXPECT_EQ(queue->GetNumberOfPendingTasks(), 1u);
sequence_manager->ReclaimMemory();
EXPECT_EQ(queue->GetNumberOfPendingTasks(), 1u);
delayed_task_handle.CancelTask();
}
}
}