1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#ifndef CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <limits>
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <set>
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector>
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/basictypes.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/compiler_specific.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/trace_event.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/logging.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/test/test_simple_task_runner.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cc/test/test_now_source.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace cc {
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Subclass of TestPendingTask which has a unique ID for every task, supports
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// being used inside a std::set and has debug tracing support.
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TestOrderablePendingTask : public base::TestPendingTask {
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestOrderablePendingTask();
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestOrderablePendingTask(const tracked_objects::Location& location,
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           const base::Closure& task,
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           base::TimeTicks post_time,
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           base::TimeDelta delay,
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           TestNestability nestability);
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ~TestOrderablePendingTask();
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // operators needed by std::set and comparison
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool operator==(const TestOrderablePendingTask& other) const;
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool operator<(const TestOrderablePendingTask& other) const;
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // debug tracing functions
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<base::debug::ConvertableToTraceFormat> AsValue() const;
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void AsValueInto(base::debug::TracedValue* state) const;
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static size_t task_id_counter;
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t task_id_;
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This runs pending tasks based on task's post_time + delay.
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// We should not execute a delayed task sooner than some of the queued tasks
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// which don't have a delay even though it is queued early.
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass OrderedSimpleTaskRunner : public base::SingleThreadTaskRunner {
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  OrderedSimpleTaskRunner();
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OrderedSimpleTaskRunner(scoped_refptr<TestNowSource> now_src,
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          bool advance_now);
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // base::TestSimpleTaskRunner implementation:
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               const base::Closure& task,
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               base::TimeDelta delay) OVERRIDE;
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool PostNonNestableDelayedTask(
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const tracked_objects::Location& from_here,
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const base::Closure& task,
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::TimeDelta delay) OVERRIDE;
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Set a maximum number of tasks to run at once. Useful as a timeout to
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // prevent infinite task loops.
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static const size_t kAbsoluteMaxTasks;
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetRunTaskLimit(size_t max_tasks) { max_tasks_ = max_tasks; }
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void ClearRunTaskLimit() { max_tasks_ = kAbsoluteMaxTasks; }
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Allow task runner to advance now when running tasks.
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetAutoAdvanceNowToPendingTasks(bool advance_now) {
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    advance_now_ = advance_now;
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks NextTaskTime();
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta DelayToNextTaskTime();
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Run tasks while the callback returns true or too many tasks have been run.
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns true if there are still pending tasks left.
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool RunTasksWhile(base::Callback<bool(void)> condition);
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Run tasks while *all* of the callbacks return true or too many tasks have
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // been run. Exits on the *first* condition which returns false, skipping
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // calling all remaining conditions. Conditions can have side effects,
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // including modifying the task queue.
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns true if there are still pending tasks left.
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool RunTasksWhile(
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const std::vector<base::Callback<bool(void)> >& conditions);
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Convenience functions to run tasks with common conditions.
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Run tasks which existed at the start of this call.
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return code indicates tasks still exist to run.
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool RunPendingTasks();
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Keep running tasks until no tasks are left.
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return code indicates tasks still exist to run which also indicates if
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // runner reached idle.
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool RunUntilIdle();
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Keep running tasks until given time period.
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Return code indicates tasks still exist to run.
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool RunUntilTime(base::TimeTicks time);
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool RunForPeriod(base::TimeDelta period);
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // base::debug tracing functionality
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<base::debug::ConvertableToTraceFormat> AsValue() const;
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void AsValueInto(base::debug::TracedValue* state) const;
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Common conditions to run for, exposed publicly to allow external users to
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // use their own combinations.
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // -------------------------------------------------------------------------
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Keep running until the given number of tasks have run.
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // You generally shouldn't use this check as it will cause your tests to fail
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // when code is changed adding a new task. It is useful as a "timeout" type
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // solution.
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Callback<bool(void)> TaskRunCountBelow(size_t max_tasks);
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Keep running until a task which didn't exist initially would run.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Callback<bool(void)> TaskExistedInitially();
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Stop running tasks when NextTaskTime() >= stop_at
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Callback<bool(void)> NowBefore(base::TimeTicks stop_at);
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Advance Now() to the next task to run.
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Callback<bool(void)> AdvanceNow();
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) protected:
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static bool TaskRunCountBelowCallback(size_t max_tasks, size_t* task_run);
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool TaskExistedInitiallyCallback(
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const std::set<TestOrderablePendingTask>& existing_tasks);
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool NowBeforeCallback(base::TimeTicks stop_at);
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool AdvanceNowCallback();
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~OrderedSimpleTaskRunner();
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ThreadChecker thread_checker_;
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool advance_now_;
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<TestNowSource> now_src_;
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t max_tasks_;
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool inside_run_tasks_until_;
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::set<TestOrderablePendingTask> pending_tasks_;
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OrderedSimpleTaskRunner);
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace cc
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_
155