[go: nahoru, domu]

blob: df38b51d0ff27f357e4ba9d2ea72318c65cbaa51 [file] [log] [blame]
Avi Drissman4e1b7bc2022-09-15 14:03:501// Copyright 2015 The Chromium Authors
jkarlind1292e442015-02-06 13:54:432// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
jsbell279efb42015-03-31 17:02:465#include "content/browser/cache_storage/cache_storage_scheduler.h"
jkarlind1292e442015-02-06 13:54:436
Avi Drissmanadac21992023-01-11 23:46:397#include "base/functional/bind.h"
8#include "base/functional/callback.h"
Keishi Hattori0e45c022021-11-27 09:25:529#include "base/memory/raw_ptr.h"
jkarlind1292e442015-02-06 13:54:4310#include "base/run_loop.h"
Sean Maher5b9af51f2022-11-21 15:32:4711#include "base/task/single_thread_task_runner.h"
Ben Kellya9846422019-08-06 15:57:5012#include "base/test/scoped_feature_list.h"
Gabriel Charettec7108742019-08-23 03:31:4013#include "content/public/test/browser_task_environment.h"
jkarlind1292e442015-02-06 13:54:4314#include "testing/gtest/include/gtest/gtest.h"
15
16namespace content {
Daniel Bratell238244e2017-12-15 01:06:0617namespace cache_storage_scheduler_unittest {
jkarlind1292e442015-02-06 13:54:4318
jkarlin90593042015-04-03 16:46:4419class TestTask {
jkarlind1292e442015-02-06 13:54:4320 public:
jkarlin90593042015-04-03 16:46:4421 TestTask(CacheStorageScheduler* scheduler)
Ben Kellya9846422019-08-06 15:57:5022 : scheduler_(scheduler),
23 id_(scheduler_->CreateId()),
24 callback_count_(0) {}
jkarlind1292e442015-02-06 13:54:4325
Ben Kellya9846422019-08-06 15:57:5026 virtual void Run() {
27 callback_count_++;
28 run_loop_.Quit();
29 }
30 void Done() { scheduler_->CompleteOperationAndRunNext(id_); }
jkarlind1292e442015-02-06 13:54:4331
32 int callback_count() const { return callback_count_; }
Ben Kellya9846422019-08-06 15:57:5033 CacheStorageSchedulerId id() const { return id_; }
34 base::RunLoop& run_loop() { return run_loop_; }
jkarlind1292e442015-02-06 13:54:4335
36 protected:
Keishi Hattori0e45c022021-11-27 09:25:5237 raw_ptr<CacheStorageScheduler> scheduler_;
Ben Kellya9846422019-08-06 15:57:5038 const CacheStorageSchedulerId id_;
39 base::RunLoop run_loop_;
jkarlind1292e442015-02-06 13:54:4340 int callback_count_;
41};
42
Ben Kellya9846422019-08-06 15:57:5043class TestScheduler : public CacheStorageScheduler {
44 public:
45 TestScheduler()
Sean Maher5b9af51f2022-11-21 15:32:4746 : CacheStorageScheduler(
47 CacheStorageSchedulerClient::kStorage,
48 base::SingleThreadTaskRunner::GetCurrentDefault()) {}
Ben Kellya9846422019-08-06 15:57:5049
50 void SetDoneStartingClosure(base::OnceClosure done_closure) {
51 CHECK(!done_closure_);
52 done_closure_ = std::move(done_closure);
53 }
54
55 protected:
56 void DoneStartingAvailableOperations() override {
57 if (done_closure_) {
Sean Maher5b9af51f2022-11-21 15:32:4758 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
59 FROM_HERE, std::move(done_closure_));
Ben Kellya9846422019-08-06 15:57:5060 }
61 CacheStorageScheduler::DoneStartingAvailableOperations();
62 }
63
64 base::OnceClosure done_closure_;
65};
66
jsbell279efb42015-03-31 17:02:4667class CacheStorageSchedulerTest : public testing::Test {
jkarlind1292e442015-02-06 13:54:4368 protected:
jsbell279efb42015-03-31 17:02:4669 CacheStorageSchedulerTest()
Gabriel Charette798fde72019-08-20 22:24:0470 : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP),
Ben Kellya9846422019-08-06 15:57:5071 task1_(&scheduler_),
72 task2_(&scheduler_),
73 task3_(&scheduler_) {}
jkarlind1292e442015-02-06 13:54:4374
Gabriel Charette798fde72019-08-20 22:24:0475 BrowserTaskEnvironment task_environment_;
Ben Kellya9846422019-08-06 15:57:5076 TestScheduler scheduler_;
jkarlin90593042015-04-03 16:46:4477 TestTask task1_;
78 TestTask task2_;
Ben Kellya9846422019-08-06 15:57:5079 TestTask task3_;
jkarlind1292e442015-02-06 13:54:4380};
81
jsbell279efb42015-03-31 17:02:4682TEST_F(CacheStorageSchedulerTest, ScheduleOne) {
Ben Kellya9846422019-08-06 15:57:5083 base::RunLoop done_loop;
84 scheduler_.SetDoneStartingClosure(done_loop.QuitClosure());
jkarlind1292e442015-02-06 13:54:4385 scheduler_.ScheduleOperation(
Ben Kellya9846422019-08-06 15:57:5086 task1_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:4187 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
jsbellf43e59e2017-06-21 21:12:2588 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
Ben Kellya9846422019-08-06 15:57:5089 task1_.run_loop().Run();
90 done_loop.Run();
jkarlin90593042015-04-03 16:46:4491 EXPECT_EQ(1, task1_.callback_count());
jkarlind1292e442015-02-06 13:54:4392}
93
Ben Kellya9846422019-08-06 15:57:5094TEST_F(CacheStorageSchedulerTest, ScheduledOperations) {
95 base::RunLoop done_loop;
96 scheduler_.SetDoneStartingClosure(done_loop.QuitClosure());
Balazs Engedyda579412019-08-06 14:16:5697 scheduler_.ScheduleOperation(
Ben Kellya9846422019-08-06 15:57:5098 task1_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:4199 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Balazs Engedyda579412019-08-06 14:16:56100 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
Ben Kellya9846422019-08-06 15:57:50101 EXPECT_TRUE(scheduler_.ScheduledOperations());
102 task1_.run_loop().Run();
103 done_loop.Run();
104 EXPECT_EQ(1, task1_.callback_count());
105 EXPECT_TRUE(scheduler_.ScheduledOperations());
106 EXPECT_TRUE(scheduler_.IsRunningExclusiveOperation());
107 task1_.Done();
108 EXPECT_FALSE(scheduler_.ScheduledOperations());
109 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
110}
111
112TEST_F(CacheStorageSchedulerTest, ScheduleTwoExclusive) {
113 base::test::ScopedFeatureList scoped_feature_list;
114 scoped_feature_list.InitAndEnableFeatureWithParameters(
Adrienne Walker12b76122021-01-28 02:49:57115 kCacheStorageParallelOps, {{"max_shared_ops", "3"}});
Ben Kellya9846422019-08-06 15:57:50116
Balazs Engedyda579412019-08-06 14:16:56117 scheduler_.ScheduleOperation(
Ben Kellya9846422019-08-06 15:57:50118 task1_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:41119 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50120 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
121 base::RunLoop done_loop1;
122 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
123 scheduler_.ScheduleOperation(
124 task2_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:41125 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Balazs Engedyda579412019-08-06 14:16:56126 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
Ben Kellya9846422019-08-06 15:57:50127
128 // Should only run the first exclusive op.
129 task1_.run_loop().Run();
130 done_loop1.Run();
Balazs Engedyda579412019-08-06 14:16:56131 EXPECT_EQ(1, task1_.callback_count());
132 EXPECT_EQ(0, task2_.callback_count());
Ben Kellya9846422019-08-06 15:57:50133 EXPECT_TRUE(scheduler_.IsRunningExclusiveOperation());
Balazs Engedyda579412019-08-06 14:16:56134
Ben Kellya9846422019-08-06 15:57:50135 base::RunLoop done_loop2;
136 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
137
138 // Should run the second exclusive op after the first completes.
Balazs Engedyda579412019-08-06 14:16:56139 task1_.Done();
140 EXPECT_TRUE(scheduler_.ScheduledOperations());
Ben Kellya9846422019-08-06 15:57:50141 task2_.run_loop().Run();
142 done_loop2.Run();
143 EXPECT_EQ(1, task1_.callback_count());
144 EXPECT_EQ(1, task2_.callback_count());
145 EXPECT_TRUE(scheduler_.IsRunningExclusiveOperation());
146}
147
148TEST_F(CacheStorageSchedulerTest, ScheduleTwoShared) {
149 base::test::ScopedFeatureList scoped_feature_list;
150 scoped_feature_list.InitAndEnableFeatureWithParameters(
Adrienne Walker12b76122021-01-28 02:49:57151 kCacheStorageParallelOps, {{"max_shared_ops", "3"}});
Ben Kellya9846422019-08-06 15:57:50152
153 scheduler_.ScheduleOperation(
154 task1_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41155 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50156 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
157 base::RunLoop done_loop1;
158 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
159 scheduler_.ScheduleOperation(
160 task2_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41161 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50162 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
163
164 // Should run both shared ops in paralle.
165 task1_.run_loop().Run();
166 task2_.run_loop().Run();
167 done_loop1.Run();
168 EXPECT_EQ(1, task1_.callback_count());
169 EXPECT_EQ(1, task2_.callback_count());
170 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
171
172 base::RunLoop done_loop2;
173 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
174
175 // Completing the first op should trigger a check for new ops
176 // which will not be present here.
177 task1_.Done();
178 EXPECT_TRUE(scheduler_.ScheduledOperations());
179 done_loop2.Run();
180 EXPECT_EQ(1, task1_.callback_count());
181 EXPECT_EQ(1, task2_.callback_count());
182 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
183
184 base::RunLoop done_loop3;
185 scheduler_.SetDoneStartingClosure(done_loop3.QuitClosure());
186
187 // Completing the second op should result in the scheduler
188 // becoming idle.
189 task2_.Done();
190 EXPECT_FALSE(scheduler_.ScheduledOperations());
191 done_loop3.Run();
Balazs Engedyda579412019-08-06 14:16:56192 EXPECT_EQ(1, task1_.callback_count());
193 EXPECT_EQ(1, task2_.callback_count());
194}
195
Ben Kellya9846422019-08-06 15:57:50196TEST_F(CacheStorageSchedulerTest, ScheduleOneExclusiveOneShared) {
197 base::test::ScopedFeatureList scoped_feature_list;
198 scoped_feature_list.InitAndEnableFeatureWithParameters(
Adrienne Walker12b76122021-01-28 02:49:57199 kCacheStorageParallelOps, {{"max_shared_ops", "3"}});
Ben Kellya9846422019-08-06 15:57:50200
Wez582821162019-07-31 18:36:03201 scheduler_.ScheduleOperation(
Ben Kellya9846422019-08-06 15:57:50202 task1_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:41203 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Wez582821162019-07-31 18:36:03204 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
Ben Kellya9846422019-08-06 15:57:50205 base::RunLoop done_loop1;
206 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
207 scheduler_.ScheduleOperation(
208 task2_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41209 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50210 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
211
212 // Should only run the first exclusive op.
213 task1_.run_loop().Run();
214 done_loop1.Run();
Ben Kelly1d544252019-08-05 18:33:44215 EXPECT_EQ(1, task1_.callback_count());
Ben Kellya9846422019-08-06 15:57:50216 EXPECT_EQ(0, task2_.callback_count());
217 EXPECT_TRUE(scheduler_.IsRunningExclusiveOperation());
218
219 base::RunLoop done_loop2;
220 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
221
222 // Should run the second shared op after the first is completed.
Ben Kelly1d544252019-08-05 18:33:44223 task1_.Done();
Ben Kellya9846422019-08-06 15:57:50224 EXPECT_TRUE(scheduler_.ScheduledOperations());
225 task2_.run_loop().Run();
226 done_loop2.Run();
227 EXPECT_EQ(1, task1_.callback_count());
228 EXPECT_EQ(1, task2_.callback_count());
229 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
230
231 task2_.Done();
Ben Kelly1d544252019-08-05 18:33:44232 EXPECT_FALSE(scheduler_.ScheduledOperations());
Ben Kelly1d544252019-08-05 18:33:44233}
234
Ben Kellya9846422019-08-06 15:57:50235TEST_F(CacheStorageSchedulerTest, ScheduleOneSharedOneExclusive) {
236 base::test::ScopedFeatureList scoped_feature_list;
237 scoped_feature_list.InitAndEnableFeatureWithParameters(
Adrienne Walker12b76122021-01-28 02:49:57238 kCacheStorageParallelOps, {{"max_shared_ops", "3"}});
Ben Kellya9846422019-08-06 15:57:50239
240 scheduler_.ScheduleOperation(
241 task1_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41242 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50243 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
244 base::RunLoop done_loop1;
245 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
246 scheduler_.ScheduleOperation(
247 task2_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:41248 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50249 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
250
251 // Should only run the first shared op.
252 task1_.run_loop().Run();
253 done_loop1.Run();
254 EXPECT_EQ(1, task1_.callback_count());
255 EXPECT_EQ(0, task2_.callback_count());
256 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
257
258 base::RunLoop done_loop2;
259 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
260
261 // Should run the second exclusive op after the first completes.
262 task1_.Done();
263 EXPECT_TRUE(scheduler_.ScheduledOperations());
264 task2_.run_loop().Run();
265 done_loop2.Run();
266 EXPECT_EQ(1, task1_.callback_count());
267 EXPECT_EQ(1, task2_.callback_count());
268 EXPECT_TRUE(scheduler_.IsRunningExclusiveOperation());
269
270 task2_.Done();
271 EXPECT_FALSE(scheduler_.ScheduledOperations());
272}
273
274TEST_F(CacheStorageSchedulerTest, ScheduleTwoSharedOneExclusive) {
275 base::test::ScopedFeatureList scoped_feature_list;
276 scoped_feature_list.InitAndEnableFeatureWithParameters(
Adrienne Walker12b76122021-01-28 02:49:57277 kCacheStorageParallelOps, {{"max_shared_ops", "3"}});
Ben Kellya9846422019-08-06 15:57:50278
279 scheduler_.ScheduleOperation(
280 task1_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41281 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50282 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
283 scheduler_.ScheduleOperation(
284 task2_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41285 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50286 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
287 base::RunLoop done_loop1;
288 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
289 scheduler_.ScheduleOperation(
290 task3_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:41291 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50292 base::BindOnce(&TestTask::Run, base::Unretained(&task3_)));
293
294 // Should run the two shared ops in parallel.
295 task1_.run_loop().Run();
296 task2_.run_loop().Run();
297 done_loop1.Run();
298 EXPECT_EQ(1, task1_.callback_count());
299 EXPECT_EQ(1, task2_.callback_count());
300 EXPECT_EQ(0, task3_.callback_count());
301 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
302
303 base::RunLoop done_loop2;
304 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
305
306 // Completing the first shared op should not allow the exclusive op
307 // to run yet.
308 task1_.Done();
309 EXPECT_TRUE(scheduler_.ScheduledOperations());
310 done_loop2.Run();
311 EXPECT_EQ(1, task1_.callback_count());
312 EXPECT_EQ(1, task2_.callback_count());
313 EXPECT_EQ(0, task3_.callback_count());
314 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
315
316 base::RunLoop done_loop3;
317 scheduler_.SetDoneStartingClosure(done_loop3.QuitClosure());
318
319 // The third exclusive op should run after both the preceding shared ops
320 // complete.
321 task2_.Done();
322 EXPECT_TRUE(scheduler_.ScheduledOperations());
323 task3_.run_loop().Run();
324 done_loop3.Run();
325 EXPECT_EQ(1, task1_.callback_count());
326 EXPECT_EQ(1, task2_.callback_count());
327 EXPECT_EQ(1, task3_.callback_count());
328 EXPECT_TRUE(scheduler_.IsRunningExclusiveOperation());
329
330 task3_.Done();
331 EXPECT_FALSE(scheduler_.ScheduledOperations());
332}
333
334TEST_F(CacheStorageSchedulerTest, ScheduleOneExclusiveTwoShared) {
335 base::test::ScopedFeatureList scoped_feature_list;
336 scoped_feature_list.InitAndEnableFeatureWithParameters(
Adrienne Walker12b76122021-01-28 02:49:57337 kCacheStorageParallelOps, {{"max_shared_ops", "3"}});
Ben Kellya9846422019-08-06 15:57:50338
339 scheduler_.ScheduleOperation(
340 task1_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:41341 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50342 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
343 scheduler_.ScheduleOperation(
344 task2_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41345 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50346 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
347 base::RunLoop done_loop1;
348 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
349 scheduler_.ScheduleOperation(
350 task3_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41351 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50352 base::BindOnce(&TestTask::Run, base::Unretained(&task3_)));
353
354 // Should only run the first exclusive op.
355 task1_.run_loop().Run();
356 done_loop1.Run();
357 EXPECT_EQ(1, task1_.callback_count());
358 EXPECT_EQ(0, task2_.callback_count());
359 EXPECT_EQ(0, task3_.callback_count());
360 EXPECT_TRUE(scheduler_.IsRunningExclusiveOperation());
361
362 base::RunLoop done_loop2;
363 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
364
365 // Should run both the shared ops in parallel after the first exclusive
366 // op is completed.
367 task1_.Done();
368 EXPECT_TRUE(scheduler_.ScheduledOperations());
369 task2_.run_loop().Run();
370 task3_.run_loop().Run();
371 done_loop2.Run();
372 EXPECT_EQ(1, task1_.callback_count());
373 EXPECT_EQ(1, task2_.callback_count());
374 EXPECT_EQ(1, task3_.callback_count());
375 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
376
377 base::RunLoop done_loop3;
378 scheduler_.SetDoneStartingClosure(done_loop3.QuitClosure());
379
380 task2_.Done();
381 EXPECT_TRUE(scheduler_.ScheduledOperations());
382 done_loop3.Run();
383 EXPECT_EQ(1, task1_.callback_count());
384 EXPECT_EQ(1, task2_.callback_count());
385 EXPECT_EQ(1, task3_.callback_count());
386 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
387
388 task3_.Done();
389 EXPECT_FALSE(scheduler_.ScheduledOperations());
390}
391
392TEST_F(CacheStorageSchedulerTest, ScheduleOneSharedOneExclusiveOneShared) {
393 base::test::ScopedFeatureList scoped_feature_list;
394 scoped_feature_list.InitAndEnableFeatureWithParameters(
Adrienne Walker12b76122021-01-28 02:49:57395 kCacheStorageParallelOps, {{"max_shared_ops", "3"}});
Ben Kellya9846422019-08-06 15:57:50396
397 scheduler_.ScheduleOperation(
398 task1_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41399 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50400 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
401 scheduler_.ScheduleOperation(
402 task2_.id(), CacheStorageSchedulerMode::kExclusive,
Ben Kellyab28fec62019-11-04 16:21:41403 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50404 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
405 base::RunLoop done_loop1;
406 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
407 scheduler_.ScheduleOperation(
408 task3_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41409 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50410 base::BindOnce(&TestTask::Run, base::Unretained(&task3_)));
411
412 // Should only run the first shared op.
413 task1_.run_loop().Run();
414 done_loop1.Run();
415 EXPECT_EQ(1, task1_.callback_count());
416 EXPECT_EQ(0, task2_.callback_count());
417 EXPECT_EQ(0, task3_.callback_count());
418 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
419
420 base::RunLoop done_loop2;
421 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
422
423 // Should run the exclusive op after the first op is completed.
424 task1_.Done();
425 EXPECT_TRUE(scheduler_.ScheduledOperations());
426 task2_.run_loop().Run();
427 done_loop2.Run();
428 EXPECT_EQ(1, task1_.callback_count());
429 EXPECT_EQ(1, task2_.callback_count());
430 EXPECT_EQ(0, task3_.callback_count());
431 EXPECT_TRUE(scheduler_.IsRunningExclusiveOperation());
432
433 base::RunLoop done_loop3;
434 scheduler_.SetDoneStartingClosure(done_loop3.QuitClosure());
435
436 // Should run the last shared op after the preceding exclusive op
437 // is completed.
438 task2_.Done();
439 EXPECT_TRUE(scheduler_.ScheduledOperations());
440 task3_.run_loop().Run();
441 done_loop3.Run();
442 EXPECT_EQ(1, task1_.callback_count());
443 EXPECT_EQ(1, task2_.callback_count());
444 EXPECT_EQ(1, task3_.callback_count());
445 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
446
447 task3_.Done();
448 EXPECT_FALSE(scheduler_.ScheduledOperations());
449}
450
451TEST_F(CacheStorageSchedulerTest, ScheduleTwoSharedNotParallel) {
452 // Disable parallelism
453 base::test::ScopedFeatureList scoped_feature_list;
454 scoped_feature_list.InitAndEnableFeatureWithParameters(
Adrienne Walker12b76122021-01-28 02:49:57455 kCacheStorageParallelOps, {{"max_shared_ops", "1"}});
Ben Kellya9846422019-08-06 15:57:50456
457 scheduler_.ScheduleOperation(
458 task1_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41459 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50460 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
461 base::RunLoop done_loop1;
462 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
463 scheduler_.ScheduleOperation(
464 task2_.id(), CacheStorageSchedulerMode::kShared,
Ben Kellyab28fec62019-11-04 16:21:41465 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
Ben Kellya9846422019-08-06 15:57:50466 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
467
468 // Should only run one shared op since the max shared is set to 1.
469 task1_.run_loop().Run();
470 done_loop1.Run();
471 EXPECT_EQ(1, task1_.callback_count());
472 EXPECT_EQ(0, task2_.callback_count());
473 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
474
475 base::RunLoop done_loop2;
476 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
477
478 // Should run the next shared op after the first completes.
479 task1_.Done();
480 EXPECT_TRUE(scheduler_.ScheduledOperations());
481 task2_.run_loop().Run();
482 done_loop2.Run();
483 EXPECT_EQ(1, task1_.callback_count());
484 EXPECT_EQ(1, task2_.callback_count());
485 EXPECT_FALSE(scheduler_.IsRunningExclusiveOperation());
486}
487
Ben Kellyab28fec62019-11-04 16:21:41488TEST_F(CacheStorageSchedulerTest, ScheduleByPriorityTwoNormalOneHigh) {
489 scheduler_.ScheduleOperation(
490 task1_.id(), CacheStorageSchedulerMode::kExclusive,
491 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
492 base::BindOnce(&TestTask::Run, base::Unretained(&task1_)));
493 base::RunLoop done_loop1;
494 scheduler_.SetDoneStartingClosure(done_loop1.QuitClosure());
495 scheduler_.ScheduleOperation(
496 task2_.id(), CacheStorageSchedulerMode::kExclusive,
497 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kNormal,
498 base::BindOnce(&TestTask::Run, base::Unretained(&task2_)));
499 scheduler_.ScheduleOperation(
500 task3_.id(), CacheStorageSchedulerMode::kExclusive,
501 CacheStorageSchedulerOp::kTest, CacheStorageSchedulerPriority::kHigh,
502 base::BindOnce(&TestTask::Run, base::Unretained(&task3_)));
503
504 // Should run the first normal priority op because the queue was empty
505 // when it was added.
506 task1_.run_loop().Run();
507 done_loop1.Run();
508 EXPECT_EQ(1, task1_.callback_count());
509 EXPECT_EQ(0, task2_.callback_count());
510 EXPECT_EQ(0, task3_.callback_count());
511
512 base::RunLoop done_loop3;
513 scheduler_.SetDoneStartingClosure(done_loop3.QuitClosure());
514
515 // Should run the high priority op next.
516 task1_.Done();
517 task3_.run_loop().Run();
518 done_loop3.Run();
519 EXPECT_EQ(1, task1_.callback_count());
520 EXPECT_EQ(0, task2_.callback_count());
521 EXPECT_EQ(1, task3_.callback_count());
522
523 base::RunLoop done_loop2;
524 scheduler_.SetDoneStartingClosure(done_loop2.QuitClosure());
525
526 // Should run the final normal priority op after the high priority op
527 // completes.
528 task3_.Done();
529 EXPECT_TRUE(scheduler_.ScheduledOperations());
530 task2_.run_loop().Run();
531 done_loop2.Run();
532 EXPECT_EQ(1, task1_.callback_count());
533 EXPECT_EQ(1, task2_.callback_count());
534 EXPECT_EQ(1, task3_.callback_count());
535}
536
Daniel Bratell238244e2017-12-15 01:06:06537} // namespace cache_storage_scheduler_unittest
jkarlind1292e442015-02-06 13:54:43538} // namespace content