1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/background_sync/background_sync_op_scheduler.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/scoped_feature_list.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace background_sync_op_scheduler_unittest {
class TestTask {
public:
explicit TestTask(BackgroundSyncOpScheduler* scheduler)
: scheduler_(scheduler), callback_count_(0) {}
virtual void Run() {
callback_count_++;
run_loop_.Quit();
}
void Done() { scheduler_->CompleteOperationAndRunNext(); }
int callback_count() const { return callback_count_; }
base::RunLoop& run_loop() { return run_loop_; }
protected:
raw_ptr<BackgroundSyncOpScheduler> scheduler_;
base::RunLoop run_loop_;
int callback_count_;
};
class TestScheduler : public BackgroundSyncOpScheduler {
public:
TestScheduler()
: BackgroundSyncOpScheduler(
base::SingleThreadTaskRunner::GetCurrentDefault()) {}
void SetDoneStartingClosure(base::OnceClosure done_closure) {
CHECK(!done_closure_);
done_closure_ = std::move(done_closure);
}
protected:
void DoneStartingAvailableOperations() override {
if (done_closure_) {
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, std::move(done_closure_));
}
BackgroundSyncOpScheduler::DoneStartingAvailableOperations();
}
base::OnceClosure done_closure_;
};
class BackgroundSyncOpSchedulerTest : public testing::Test {
protected:
BackgroundSyncOpSchedulerTest()
: task_environment_(BrowserTaskEnvironment::IO_MAINLOOP),
task1_(&scheduler_),
task2_(&scheduler_),
task3_(&scheduler_) {}
BrowserTaskEnvironment task_environment_;
TestScheduler scheduler_;
TestTask task1_;
TestTask task2_;
TestTask task3_;
};
TEST_F(BackgroundSyncOpSchedulerTest, ScheduleOne) {
base::RunLoop done_loop;
scheduler_.SetDoneStartingClosure(done_loop.QuitClosure());
scheduler_.ScheduleOperation(
base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
task1_.run_loop().Run();
done_loop.Run();
EXPECT_EQ(1, task1_.callback_count());
}
TEST_F(BackgroundSyncOpSchedulerTest, ScheduledOperations) {
base::RunLoop done_loop;
scheduler_.SetDoneStartingClosure(done_loop.QuitClosure());
scheduler_.ScheduleOperation(
base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
EXPECT_TRUE(scheduler_.ScheduledOperations());
task1_.run_loop().Run();
done_loop.Run();
EXPECT_EQ(1, task1_.callback_count());
EXPECT_TRUE(scheduler_.ScheduledOperations());
task1_.Done();
EXPECT_FALSE(scheduler_.ScheduledOperations());
}
TEST_F(BackgroundSyncOpSchedulerTest, ScheduleTwoExclusive) {
scheduler_.ScheduleOperation(
base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
base::RunLoop done_loop1;
scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
scheduler_.ScheduleOperation(
base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
// Should only run the first exclusive op.
task1_.run_loop().Run();
done_loop1.Run();
EXPECT_EQ(1, task1_.callback_count());
EXPECT_EQ(0, task2_.callback_count());
base::RunLoop done_loop2;
scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
// Should run the second exclusive op after the first completes.
task1_.Done();
EXPECT_TRUE(scheduler_.ScheduledOperations());
task2_.run_loop().Run();
done_loop2.Run();
EXPECT_EQ(1, task1_.callback_count());
EXPECT_EQ(1, task2_.callback_count());
}
} // namespace background_sync_op_scheduler_unittest
} // namespace content
|