1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TASK_SCHEDULER_TEST_TASK_FACTORY_H_ 6 #define BASE_TASK_SCHEDULER_TEST_TASK_FACTORY_H_ 7 8 #include <stddef.h> 9 10 #include <unordered_set> 11 12 #include "base/callback_forward.h" 13 #include "base/macros.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/synchronization/condition_variable.h" 16 #include "base/synchronization/lock.h" 17 #include "base/task_runner.h" 18 #include "base/task_scheduler/task_traits.h" 19 #include "base/task_scheduler/test_utils.h" 20 #include "base/threading/thread_checker_impl.h" 21 22 namespace base { 23 namespace internal { 24 namespace test { 25 26 // A TestTaskFactory posts tasks to a TaskRunner and verifies that they run as 27 // expected. Generates a test failure when: 28 // - The RunsTasksInCurrentSequence() method of the TaskRunner returns false on 29 // a thread on which a Task is run. 30 // - The TaskRunnerHandles set in the context of the task don't match what's 31 // expected for the tested ExecutionMode. 32 // - The ExecutionMode of the TaskRunner is SEQUENCED or SINGLE_THREADED and 33 // Tasks don't run in posting order. 34 // - The ExecutionMode of the TaskRunner is SINGLE_THREADED and Tasks don't run 35 // on the same thread. 36 // - A Task runs more than once. 37 class TestTaskFactory { 38 public: 39 enum class PostNestedTask { 40 YES, 41 NO, 42 }; 43 44 // Constructs a TestTaskFactory that posts tasks to |task_runner|. 45 // |execution_mode| is the ExecutionMode of |task_runner|. 46 TestTaskFactory(scoped_refptr<TaskRunner> task_runner, 47 ExecutionMode execution_mode); 48 49 ~TestTaskFactory(); 50 51 // Posts a task. The posted task will: 52 // - Post a new task if |post_nested_task| is YES. The nested task won't run 53 // |after_task_closure|. 54 // - Verify conditions in which the task runs (see potential failures above). 55 // - Run |after_task_closure| if it is not null. 56 bool PostTask(PostNestedTask post_nested_task, 57 OnceClosure after_task_closure); 58 59 // Waits for all tasks posted by PostTask() to start running. It is not 60 // guaranteed that the tasks have completed their execution when this returns. 61 void WaitForAllTasksToRun() const; 62 task_runner()63 const TaskRunner* task_runner() const { return task_runner_.get(); } 64 65 private: 66 void RunTaskCallback(size_t task_index, 67 PostNestedTask post_nested_task, 68 OnceClosure after_task_closure); 69 70 // Synchronizes access to all members. 71 mutable Lock lock_; 72 73 // Condition variable signaled when a task runs. 74 mutable ConditionVariable cv_; 75 76 // Task runner through which this factory posts tasks. 77 const scoped_refptr<TaskRunner> task_runner_; 78 79 // Execution mode of |task_runner_|. 80 const ExecutionMode execution_mode_; 81 82 // Number of tasks posted by PostTask(). 83 size_t num_posted_tasks_ = 0; 84 85 // Indexes of tasks that ran. 86 std::unordered_set<size_t> ran_tasks_; 87 88 // Used to verify that all tasks run on the same thread when |execution_mode_| 89 // is SINGLE_THREADED. 90 ThreadCheckerImpl thread_checker_; 91 92 DISALLOW_COPY_AND_ASSIGN(TestTaskFactory); 93 }; 94 95 } // namespace test 96 } // namespace internal 97 } // namespace base 98 99 #endif // BASE_TASK_SCHEDULER_TEST_TASK_FACTORY_H_ 100