blob: 1390b1f265b7a79d06250622406b6bb6eddba70d [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/drive/job_queue.h"
#include <stddef.h>
#include "testing/gtest/include/gtest/gtest.h"
namespace drive {
TEST(JobQueueTest, BasicJobQueueOperations) {
const size_t kNumMaxConcurrentJobs = 3;
const size_t kNumPriorityLevels = 2;
const size_t kNumMaxBatchJob = 0;
const size_t kMaxBatchSize = 0;
enum {HIGH_PRIORITY, LOW_PRIORITY};
// Create a queue. Number of jobs are initially zero.
JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob,
kMaxBatchSize);
EXPECT_EQ(0U, queue.GetNumberOfJobs());
// Push 4 jobs.
queue.Push(101, LOW_PRIORITY, false, 0);
queue.Push(102, HIGH_PRIORITY, false, 0);
queue.Push(103, LOW_PRIORITY, false, 0);
queue.Push(104, HIGH_PRIORITY, false, 0);
// High priority jobs should be popped first.
std::vector<JobID> ids;
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(102, ids[0]);
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(104, ids[0]);
// Then low priority jobs follow.
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(101, ids[0]);
// The queue allows at most 3 parallel runs. So returns false here.
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(0u, ids.size());
// No jobs finished yet, so the job count is four.
EXPECT_EQ(4U, queue.GetNumberOfJobs());
// Mark one job as finished.
queue.MarkFinished(104);
EXPECT_EQ(3U, queue.GetNumberOfJobs());
// Then the next jobs can be popped.
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(103, ids[0]);
// Push 1 more job.
queue.Push(105, LOW_PRIORITY, false, 0);
// Finish all 3 running jobs.
queue.MarkFinished(101);
queue.MarkFinished(102);
queue.MarkFinished(103);
EXPECT_EQ(1U, queue.GetNumberOfJobs());
// The remaining jobs is of low priority, so under HIGH_PRIORITY context, it
// cannot be popped for running.
queue.PopForRun(HIGH_PRIORITY, &ids);
ASSERT_EQ(0u, ids.size());
// Under the low priority context, it is fine.
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(105, ids[0]);
}
TEST(JobQueueTest, JobQueueRemove) {
const size_t kNumMaxConcurrentJobs = 3;
const size_t kNumPriorityLevels = 2;
const size_t kNumMaxBatchJob = 0;
const size_t kMaxBatchSize = 0;
enum {HIGH_PRIORITY, LOW_PRIORITY};
// Create a queue. Number of jobs are initially zero.
JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob,
kMaxBatchSize);
EXPECT_EQ(0U, queue.GetNumberOfJobs());
// Push 4 jobs.
queue.Push(101, LOW_PRIORITY, false, 0);
queue.Push(102, HIGH_PRIORITY, false, 0);
queue.Push(103, LOW_PRIORITY, false, 0);
queue.Push(104, HIGH_PRIORITY, false, 0);
EXPECT_EQ(4U, queue.GetNumberOfJobs());
// Remove 2.
queue.Remove(101);
queue.Remove(104);
EXPECT_EQ(2U, queue.GetNumberOfJobs());
// Pop the 2 jobs.
std::vector<JobID> ids;
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(102, ids[0]);
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(103, ids[0]);
queue.MarkFinished(102);
queue.MarkFinished(103);
// 0 job left.
EXPECT_EQ(0U, queue.GetNumberOfJobs());
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(0u, ids.size());
}
TEST(JobQueueTest, BatchRequest) {
const size_t kNumMaxConcurrentJobs = 1;
const size_t kNumPriorityLevels = 2;
const size_t kNumMaxBatchJob = 100;
const size_t kMaxBatchSize = 5;
enum { HIGH_PRIORITY, LOW_PRIORITY };
// Create a queue. Number of jobs are initially zero.
JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob,
kMaxBatchSize);
EXPECT_EQ(0U, queue.GetNumberOfJobs());
// Push 6 jobs.
queue.Push(101, LOW_PRIORITY, true, 1);
queue.Push(102, HIGH_PRIORITY, true, 1);
queue.Push(103, LOW_PRIORITY, false, 1);
queue.Push(104, HIGH_PRIORITY, true, 1);
queue.Push(105, LOW_PRIORITY, true, 1);
queue.Push(106, HIGH_PRIORITY, true, 10);
EXPECT_EQ(6U, queue.GetNumberOfJobs());
// Pop the 6 jobs.
std::vector<JobID> ids;
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(2u, ids.size());
EXPECT_EQ(102, ids[0]);
EXPECT_EQ(104, ids[1]);
queue.MarkFinished(102);
queue.MarkFinished(104);
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(106, ids[0]);
queue.MarkFinished(106);
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(101, ids[0]);
queue.MarkFinished(101);
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(103, ids[0]);
queue.MarkFinished(103);
queue.PopForRun(LOW_PRIORITY, &ids);
ASSERT_EQ(1u, ids.size());
EXPECT_EQ(105, ids[0]);
queue.MarkFinished(105);
queue.PopForRun(LOW_PRIORITY, &ids);
EXPECT_EQ(0u, ids.size());
}
TEST(JobQueueTest, BatchRequstNumMaxJobs) {
const size_t kNumMaxConcurrentJobs = 1;
const size_t kNumPriorityLevels = 2;
const size_t kNumMaxBatchJob = 5;
const size_t kMaxBatchSize = 100;
enum { HIGH_PRIORITY, LOW_PRIORITY };
// Create a queue. Number of jobs are initially zero.
JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob,
kMaxBatchSize);
EXPECT_EQ(0U, queue.GetNumberOfJobs());
// Push 6 jobs.
queue.Push(101, LOW_PRIORITY, true, 1);
queue.Push(102, LOW_PRIORITY, true, 1);
queue.Push(103, LOW_PRIORITY, true, 1);
queue.Push(104, LOW_PRIORITY, true, 1);
queue.Push(105, LOW_PRIORITY, true, 1);
queue.Push(106, LOW_PRIORITY, true, 1);
EXPECT_EQ(6U, queue.GetNumberOfJobs());
// Pop the 5 of 6 jobs.
std::vector<JobID> ids;
queue.PopForRun(LOW_PRIORITY, &ids);
EXPECT_EQ(5u, ids.size());
}
} // namespace drive