| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import {assertEquals} from 'chrome://webui-test/chromeos/chai_assert.js'; |
| |
| import type {ImageRequestTask} from './image_request_task.js'; |
| import {MAXIMUM_IN_PARALLEL, Scheduler} from './scheduler.js'; |
| |
| |
| /** |
| * Fake global clock used to record the "time" at which a task was run. |
| */ |
| let globalTime = 0; |
| |
| export function setUp() { |
| globalTime = 0; |
| } |
| |
| interface FakeImageRequestTask { |
| cancelCallCount: number; |
| runTime: number; |
| getId(): string; |
| getPriority(): number; |
| cancel(): void; |
| loadFromCacheAndProcess(onSuccess: VoidCallback, onFailure: VoidCallback): |
| void; |
| } |
| |
| function newTask(taskId: string, priority: number): FakeImageRequestTask { |
| return { |
| // Counts how many times cancel method was called. |
| // Used to test multiple cancellation of the same task. |
| cancelCallCount: 0, |
| |
| // Records value of globalTime variable at the time the main method, |
| // loadFromCacheAndProcess is called. Used to test if the task was |
| // executed and in what orders tasks were executed. |
| runTime: 0, |
| |
| getId(): string { |
| return taskId; |
| }, |
| |
| getPriority(): number { |
| return priority; |
| }, |
| |
| cancel() { |
| ++this.cancelCallCount; |
| }, |
| |
| loadFromCacheAndProcess(resolve: VoidCallback, _reject: VoidCallback) { |
| this.runTime = ++globalTime; |
| setTimeout(resolve); |
| }, |
| }; |
| } |
| |
| /** |
| * Checks that adding and removing tasks before the scheduler is started works. |
| */ |
| export function testIdleSchedulerAddRemove() { |
| const scheduler = new Scheduler(); |
| const fakeTask = newTask('task-1', 0); |
| scheduler.add(fakeTask as unknown as ImageRequestTask); |
| assertEquals(0, fakeTask.cancelCallCount); |
| scheduler.remove('task-1'); |
| assertEquals(1, fakeTask.cancelCallCount); |
| scheduler.remove('task-1'); |
| assertEquals(1, fakeTask.cancelCallCount); |
| } |
| |
| /** |
| * Checks that tasks that were in newTasks are correctly copied to pending |
| * tasks when scheduler is started. They also should be executed in the |
| * order of their priorities. |
| */ |
| export function testNewTasksMovedAndRunInPriorityOrder() { |
| const fakeTask1 = newTask('task-1', 1); |
| const fakeTask2 = newTask('task-2', 0); |
| |
| const scheduler = new Scheduler(); |
| scheduler.add(fakeTask1 as unknown as ImageRequestTask); |
| scheduler.add(fakeTask2 as unknown as ImageRequestTask); |
| |
| scheduler.start(); |
| assertEquals(2, fakeTask1.runTime); |
| assertEquals(1, fakeTask2.runTime); |
| } |
| |
| /** |
| * Checks that the scheduler only launches MAXIMUM_IN_PARALLEL tasks. |
| */ |
| export function testParallelTasks() { |
| const scheduler = new Scheduler(); |
| const taskList = []; |
| for (let i = 0; i <= MAXIMUM_IN_PARALLEL; ++i) { |
| taskList.push(newTask(`task-${i}`, 0)); |
| scheduler.add(taskList[i] as unknown as ImageRequestTask); |
| } |
| scheduler.start(); |
| for (let i = 0; i < MAXIMUM_IN_PARALLEL; ++i) { |
| assertEquals(i + 1, taskList[i]!.runTime, `task ${i} did not run`); |
| } |
| assertEquals(0, taskList[MAXIMUM_IN_PARALLEL]!.runTime); |
| } |