Commit 8df5663a authored by Farah Charab's avatar Farah Charab Committed by Commit Bot

Scheduler: Fuzzer for TaskQueueManager V3.

Provides support for fencing and throttling.

Change-Id: I44d9e027fbf7e78deef1b8205c918a0eebfab503
Reviewed-on: https://chromium-review.googlesource.com/1146802Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Commit-Queue: Farah Charab <farahcharab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577880}
parent f10092d4
......@@ -21,7 +21,7 @@ message SequenceManagerTestDescription {
}
message Action {
// NEXT ID = 9
// NEXT ID = 11
optional uint64 action_id = 1;
......@@ -33,6 +33,8 @@ message SequenceManagerTestDescription {
ShutdownTaskQueueAction shutdown_task_queue = 6;
CancelTaskAction cancel_task = 7;
CreateQueueVoterAction create_queue_voter = 8;
InsertFenceAction insert_fence = 9;
RemoveFenceAction remove_fence = 10;
}
}
......@@ -121,5 +123,27 @@ message SequenceManagerTestDescription {
optional uint64 task_id = 1;
}
message InsertFenceAction {
// NEXT ID = 3
enum FencePosition {
NOW = 0;
BEGINNING_OF_TIME = 1;
}
optional FencePosition position = 1 [default = NOW];
// Used to identify the |task_queue_id|'s oldest available queue to
// insert the fence to (modulo the number of available queues).
optional uint64 task_queue_id = 2;
}
message RemoveFenceAction {
// NEXT ID = 2
// Used to identify the |task_queue_id|'s oldest available queue to remove a
// fence from, if one exists (modulo the number of available queues).
optional uint64 task_queue_id = 2;
}
repeated Action initial_actions = 1;
}
......@@ -89,6 +89,10 @@ void SequenceManagerFuzzerProcessor::RunAction(
action.shutdown_task_queue());
} else if (action.has_cancel_task()) {
ExecuteCancelTaskAction(action.action_id(), action.cancel_task());
} else if (action.has_insert_fence()) {
ExecuteInsertFenceAction(action.action_id(), action.insert_fence());
} else if (action.has_remove_fence()) {
ExecuteRemoveFenceAction(action.action_id(), action.remove_fence());
} else {
ExecutePostDelayedTaskAction(action.action_id(),
action.post_delayed_task());
......@@ -202,17 +206,45 @@ void SequenceManagerFuzzerProcessor::ExecuteCancelTaskAction(
test_task_runner_->GetMockTickClock()->NowTicks());
if (!pending_tasks_.empty()) {
size_t queue_index = action.task_id() % pending_tasks_.size();
pending_tasks_[queue_index]->weak_ptr_factory_.InvalidateWeakPtrs();
size_t task_index = action.task_id() % pending_tasks_.size();
pending_tasks_[task_index]->weak_ptr_factory_.InvalidateWeakPtrs();
// If it is already running, it is a parent task and will be deleted when
// it is done.
if (!pending_tasks_[queue_index]->is_running) {
pending_tasks_.erase(pending_tasks_.begin() + queue_index);
if (!pending_tasks_[task_index]->is_running) {
pending_tasks_.erase(pending_tasks_.begin() + task_index);
}
}
}
void SequenceManagerFuzzerProcessor::ExecuteInsertFenceAction(
uint64_t action_id,
const SequenceManagerTestDescription::InsertFenceAction& action) {
LogActionForTesting(action_id, ActionForTest::ActionType::kInsertFence,
test_task_runner_->GetMockTickClock()->NowTicks());
size_t queue_index = action.task_queue_id() % task_queues_.size();
if (action.position() ==
SequenceManagerTestDescription::InsertFenceAction::NOW) {
task_queues_[queue_index].queue.get()->InsertFence(
TaskQueue::InsertFencePosition::kNow);
} else {
task_queues_[queue_index].queue.get()->InsertFence(
TaskQueue::InsertFencePosition::kBeginningOfTime);
}
}
void SequenceManagerFuzzerProcessor::ExecuteRemoveFenceAction(
uint64_t action_id,
const SequenceManagerTestDescription::RemoveFenceAction& action) {
LogActionForTesting(action_id, ActionForTest::ActionType::kRemoveFence,
test_task_runner_->GetMockTickClock()->NowTicks());
size_t queue_index = action.task_queue_id() % task_queues_.size();
task_queues_[queue_index].queue.get()->RemoveFence();
}
void SequenceManagerFuzzerProcessor::ExecuteTask(
const SequenceManagerTestDescription::Task& task) {
TimeTicks start_time = test_task_runner_->GetMockTickClock()->NowTicks();
......
......@@ -47,6 +47,8 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor {
kCreateQueueVoter,
kCancelTask,
kShutdownTaskQueue,
kInsertFence,
kRemoveFence
};
ActionForTest(uint64_t id, ActionType type, uint64_t start);
......@@ -110,6 +112,12 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor {
void ExecuteCancelTaskAction(
uint64_t action_id,
const SequenceManagerTestDescription::CancelTaskAction& action);
void ExecuteInsertFenceAction(
uint64_t action_id,
const SequenceManagerTestDescription::InsertFenceAction& action);
void ExecuteRemoveFenceAction(
uint64_t action_id,
const SequenceManagerTestDescription::RemoveFenceAction& action);
void ExecuteTask(const SequenceManagerTestDescription::Task& task);
......
......@@ -944,5 +944,125 @@ TEST(SequenceManagerFuzzerProcessorTest, OrderOfSimpleUnnestedExecutedActions) {
EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
}
TEST(SequenceManagerFuzzerProcessorTest, InsertAndRemoveFence) {
std::vector<ActionForTest> executed_actions;
std::vector<TaskForTest> executed_tasks;
// Describes a test that inserts a fence to a task queue after a delay of
// 20ms, posts a task to it after a delay of 25ms, and removes the fence after
// a delay of 30ms.
SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"(
initial_actions {
action_id : 1
create_task_queue{
}
}
initial_actions {
action_id : 2
post_delayed_task {
delay_ms : 20
task_queue_id : 2
task {
task_id : 1
actions {
action_id : 3
insert_fence {
position: NOW
task_queue_id: 1
}
}
}
}
}
initial_actions {
action_id : 4
post_delayed_task {
delay_ms : 30
task_queue_id : 2
task {
task_id : 2
actions {
action_id : 5
remove_fence {
task_queue_id: 1
}
}
}
}
}
initial_actions {
action_id: 6
post_delayed_task {
delay_ms: 25
task_queue_id: 1
task {
task_id: 3
}
}
})",
&executed_tasks,
&executed_actions);
std::vector<ActionForTest> expected_actions;
expected_actions.emplace_back(1, ActionForTest::ActionType::kCreateTaskQueue,
0);
expected_actions.emplace_back(2, ActionForTest::ActionType::kPostDelayedTask,
0);
expected_actions.emplace_back(4, ActionForTest::ActionType::kPostDelayedTask,
0);
expected_actions.emplace_back(6, ActionForTest::ActionType::kPostDelayedTask,
0);
expected_actions.emplace_back(3, ActionForTest::ActionType::kInsertFence, 20);
expected_actions.emplace_back(5, ActionForTest::ActionType::kRemoveFence, 30);
EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
std::vector<TaskForTest> expected_tasks;
expected_tasks.emplace_back(1, 20, 20);
expected_tasks.emplace_back(2, 30, 30);
// Task with id 3 will not execute until the fence is removed from the task
// queue it was posted to.
expected_tasks.emplace_back(3, 30, 30);
EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks));
}
TEST(SequenceManagerFuzzerProcessorTest, ThrottleTaskQueue) {
std::vector<ActionForTest> executed_actions;
std::vector<TaskForTest> executed_tasks;
// Describes a test that throttles a task queue, and posts a task to it.
SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"(
initial_actions {
action_id : 1
insert_fence {
position: BEGINNING_OF_TIME
task_queue_id: 1
}
}
initial_actions {
action_id: 2
post_delayed_task {
task_queue_id: 1
task {
task_id: 3
}
}
})",
&executed_tasks,
&executed_actions);
std::vector<ActionForTest> expected_actions;
expected_actions.emplace_back(1, ActionForTest::ActionType::kInsertFence, 0);
expected_actions.emplace_back(2, ActionForTest::ActionType::kPostDelayedTask,
0);
EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
// Task queue with id 1 is throttled, so posted tasks will not get executed.
EXPECT_THAT(executed_tasks, IsEmpty());
}
} // namespace sequence_manager
} // namespace base
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment