xref: /aosp_15_r20/external/cronet/base/task/thread_pool/test_task_factory.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/task/thread_pool/test_task_factory.h"
6 
7 #include "base/check_op.h"
8 #include "base/functional/bind.h"
9 #include "base/functional/callback.h"
10 #include "base/functional/callback_helpers.h"
11 #include "base/location.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/task/sequenced_task_runner.h"
14 #include "base/task/single_thread_task_runner.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 namespace base {
18 namespace internal {
19 namespace test {
20 
TestTaskFactory(scoped_refptr<TaskRunner> task_runner,TaskSourceExecutionMode execution_mode)21 TestTaskFactory::TestTaskFactory(scoped_refptr<TaskRunner> task_runner,
22                                  TaskSourceExecutionMode execution_mode)
23     : cv_(&lock_),
24       task_runner_(std::move(task_runner)),
25       execution_mode_(execution_mode) {
26   // Detach |thread_checker_| from the current thread. It will be attached to
27   // the first thread that calls ThreadCheckerImpl::CalledOnValidThread().
28   thread_checker_.DetachFromThread();
29 }
30 
~TestTaskFactory()31 TestTaskFactory::~TestTaskFactory() {
32   WaitForAllTasksToRun();
33 }
34 
PostTask(PostNestedTask post_nested_task,OnceClosure after_task_closure)35 bool TestTaskFactory::PostTask(PostNestedTask post_nested_task,
36                                OnceClosure after_task_closure) {
37   AutoLock auto_lock(lock_);
38   return task_runner_->PostTask(
39       FROM_HERE, BindOnce(&TestTaskFactory::RunTaskCallback, Unretained(this),
40                           num_posted_tasks_++, post_nested_task,
41                           std::move(after_task_closure)));
42 }
43 
WaitForAllTasksToRun() const44 void TestTaskFactory::WaitForAllTasksToRun() const {
45   AutoLock auto_lock(lock_);
46   while (ran_tasks_.size() < num_posted_tasks_)
47     cv_.Wait();
48 }
49 
RunTaskCallback(size_t task_index,PostNestedTask post_nested_task,OnceClosure after_task_closure)50 void TestTaskFactory::RunTaskCallback(size_t task_index,
51                                       PostNestedTask post_nested_task,
52                                       OnceClosure after_task_closure) {
53   if (post_nested_task == PostNestedTask::YES)
54     PostTask(PostNestedTask::NO, OnceClosure());
55 
56   if (execution_mode_ == TaskSourceExecutionMode::kSingleThread ||
57       execution_mode_ == TaskSourceExecutionMode::kSequenced) {
58     EXPECT_TRUE(static_cast<SequencedTaskRunner*>(task_runner_.get())
59                     ->RunsTasksInCurrentSequence());
60   }
61 
62   // Verify task runner CurrentDefaultHandles are set as expected in the task's
63   // scope.
64   switch (execution_mode_) {
65     case TaskSourceExecutionMode::kJob:
66     case TaskSourceExecutionMode::kParallel:
67       EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
68       EXPECT_FALSE(SequencedTaskRunner::HasCurrentDefault());
69       break;
70     case TaskSourceExecutionMode::kSequenced:
71       EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
72       EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
73       EXPECT_EQ(task_runner_, SequencedTaskRunner::GetCurrentDefault());
74       break;
75     case TaskSourceExecutionMode::kSingleThread:
76       // SequencedTaskRunner::CurrentDefaultHandle inherits from
77       // SingleThreadTaskRunner::CurrentDefaultHandle so both are expected to be
78       // "set" in the kSingleThread case.
79       EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
80       EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
81       EXPECT_EQ(task_runner_, SingleThreadTaskRunner::GetCurrentDefault());
82       EXPECT_EQ(task_runner_, SequencedTaskRunner::GetCurrentDefault());
83       break;
84   }
85 
86   {
87     AutoLock auto_lock(lock_);
88 
89     DCHECK_LE(task_index, num_posted_tasks_);
90 
91     if ((execution_mode_ == TaskSourceExecutionMode::kSingleThread ||
92          execution_mode_ == TaskSourceExecutionMode::kSequenced) &&
93         task_index != ran_tasks_.size()) {
94       ADD_FAILURE() << "A task didn't run in the expected order.";
95     }
96 
97     if (execution_mode_ == TaskSourceExecutionMode::kSingleThread)
98       EXPECT_TRUE(thread_checker_.CalledOnValidThread());
99 
100     if (ran_tasks_.find(task_index) != ran_tasks_.end())
101       ADD_FAILURE() << "A task ran more than once.";
102     ran_tasks_.insert(task_index);
103 
104     cv_.Signal();
105   }
106 
107   if (!after_task_closure.is_null())
108     std::move(after_task_closure).Run();
109 }
110 
111 }  // namespace test
112 }  // namespace internal
113 }  // namespace base
114