blob: 710832041d9c5460afe149113b7c0a05974b21fa [file] [log] [blame]
[email protected]ec04d3f2013-06-06 21:31:391// Copyright 2013 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
Francois Doray9f68b1a2017-12-25 13:41:585// TestBrowserThreadBundle is a convenience class which allows usage of these
6// APIs within its scope:
7// - Same APIs as base::test::ScopedTaskEnvironment.
8// - content::BrowserThread.
[email protected]ec04d3f2013-06-06 21:31:399//
Francois Doray9f68b1a2017-12-25 13:41:5810// Only tests that need the BrowserThread API should instantiate a
11// TestBrowserThreadBundle. Use base::test::ScopedTaskEnvironment otherwise.
12//
13// By default, BrowserThread::UI/IO are backed by a single shared MessageLoop on
14// the main thread. If a test truly needs BrowserThread::IO tasks to run on a
15// separate thread, it can pass the REAL_IO_THREAD option to the constructor.
16// TaskScheduler tasks always run on dedicated threads.
[email protected]ec04d3f2013-06-06 21:31:3917//
fdoray575c4b22017-04-05 19:25:5118// To synchronously run tasks from the shared MessageLoop:
19//
20// ... until there are no undelayed tasks in the shared MessageLoop:
21// base::RunLoop::RunUntilIdle();
22//
23// ... until there are no undelayed tasks in the shared MessageLoop, in
Gabriel Charettea1e0a372017-09-14 18:48:2124// TaskScheduler (excluding tasks not posted from the shared MessageLoop's
25// thread or TaskScheduler):
Gabriel Charette01507a22017-09-27 21:30:0826// content::RunAllTasksUntilIdle();
fdoray575c4b22017-04-05 19:25:5127//
28// ... until a condition is met:
29// base::RunLoop run_loop;
30// // Runs until a task running in the shared MessageLoop calls
31// // run_loop.Quit() or runs run_loop.QuitClosure() (&run_loop or
32// // run_loop.QuitClosure() must be kept somewhere accessible by that task).
33// run_loop.Run();
34//
Gabriel Charettea1e0a372017-09-14 18:48:2135// To wait until there are no pending undelayed tasks in TaskScheduler, without
36// running tasks from the shared MessageLoop:
fdoray575c4b22017-04-05 19:25:5137// base::TaskScheduler::GetInstance()->FlushForTesting();
fdoray575c4b22017-04-05 19:25:5138//
Francois Doray9f68b1a2017-12-25 13:41:5839// The destructor of TestBrowserThreadBundle runs remaining UI/IO tasks and
40// remaining task scheduler tasks.
[email protected]ec04d3f2013-06-06 21:31:3941//
Francois Doray9f68b1a2017-12-25 13:41:5842// If a test needs to pump IO messages on the main thread, it should use the
fdoray575c4b22017-04-05 19:25:5143// IO_MAINLOOP option. Most of the time, IO_MAINLOOP avoids needing to use a
fdorayad58f832016-12-19 18:06:4644// REAL_IO_THREAD.
aberent8f1ce402016-01-13 12:01:3845//
46// For some tests it is important to emulate real browser startup. During real
Francois Doray69f889f2017-08-02 15:42:1247// browser startup, the main MessageLoop and the TaskScheduler are created
48// before browser threads. Passing DONT_CREATE_BROWSER_THREADS to constructor
49// will delay creating browser threads until the test explicitly calls
50// CreateBrowserThreads().
aberent8f1ce402016-01-13 12:01:3851//
Francois Doray69f889f2017-08-02 15:42:1252// DONT_CREATE_BROWSER_THREADS should only be used when the options specify at
53// least one real thread other than the main thread.
gab1f58e952017-05-04 23:28:5154//
fdoray8c580522017-05-08 16:59:4155// TestBrowserThreadBundle may be instantiated in a scope where there is already
56// a base::test::ScopedTaskEnvironment. In that case, it will use the
57// MessageLoop and the TaskScheduler provided by this
58// base::test::ScopedTaskEnvironment instead of creating its own. The ability to
59// have a base::test::ScopedTaskEnvironment and a TestBrowserThreadBundle in the
60// same scope is useful when a fixture that inherits from a fixture that
61// provides a base::test::ScopedTaskEnvironment needs to add support for browser
62// threads.
63//
gab1f58e952017-05-04 23:28:5164// Basic usage:
65//
66// class MyTestFixture : public testing::Test {
67// public:
68// (...)
69//
70// protected:
71// // Must be the first member (or at least before any member that cares
72// // about tasks) to be initialized first and destroyed last. protected
73// // instead of private visibility will allow controlling the task
74// // environment (e.g. clock) once such features are added (see
75// // base::test::ScopedTaskEnvironment for details), until then it at least
76// // doesn't hurt :).
77// content::TestBrowserThreadBundle test_browser_thread_bundle_;
78//
79// // Other members go here (or further below in private section.)
80// };
[email protected]ec04d3f2013-06-06 21:31:3981
sdefresne634eec92014-12-18 13:02:5482#ifndef CONTENT_PUBLIC_TEST_TEST_BROWSER_THREAD_BUNDLE_H_
83#define CONTENT_PUBLIC_TEST_TEST_BROWSER_THREAD_BUNDLE_H_
[email protected]ec04d3f2013-06-06 21:31:3984
dcheng6003e0b2016-04-09 18:42:3485#include <memory>
86
avi652869c2015-12-25 01:48:4587#include "base/macros.h"
Alex Clarke1052bb02018-12-14 09:44:1688#include "base/test/scoped_task_environment.h"
Robert Liao0bde45e2017-06-22 21:16:0389#include "build/build_config.h"
[email protected]ec04d3f2013-06-06 21:31:3990
91namespace base {
Robert Liao0bde45e2017-06-22 21:16:0392#if defined(OS_WIN)
93namespace win {
94class ScopedCOMInitializer;
95} // namespace win
96#endif
[email protected]ec04d3f2013-06-06 21:31:3997} // namespace base
98
99namespace content {
100
101class TestBrowserThread;
102
Gabriel Charettecc8362b2017-09-20 21:59:40103// Note: to drive these threads (e.g. run all tasks until idle), see
104// content/public/test/test_utils.h.
Alex Clarke1052bb02018-12-14 09:44:16105class TestBrowserThreadBundle : public base::test::ScopedTaskEnvironment {
[email protected]ec04d3f2013-06-06 21:31:39106 public:
107 // Used to specify the type of MessageLoop that backs the UI thread, and
108 // which of the named BrowserThreads should be backed by a real
109 // threads. The UI thread is always the main thread in a unit test.
Robbie McElrath57129d72018-09-05 22:58:26110 // TODO(https://crbug.com/881041): The mainloop types are mutually exclusive,
111 // and can be removed from here and given as a separate constructor argument.
[email protected]ec04d3f2013-06-06 21:31:39112 enum Options {
fdorayaedd3c2c2017-01-14 00:09:32113 DEFAULT = 0,
Gabriel Charette9d8482ea2018-04-11 11:35:07114 // The main thread will use a MessageLoopForIO (and support the
115 // base::FileDescriptorWatcher API on POSIX).
fdorayaedd3c2c2017-01-14 00:09:32116 IO_MAINLOOP = 1 << 0,
Gabriel Charettee9748f272017-10-25 19:31:15117 REAL_IO_THREAD = 1 << 1,
Robbie McElrath57129d72018-09-05 22:58:26118 // The main thread will use a plain main loop instead of a MessageLoopForUI.
119 // (i.e. will support ThreadTaskRunnerHandle::Get() and RunLoop only).
Gabriel Charette468e2302018-12-20 19:24:37120 PLAIN_MAINLOOP = 1 << 2,
[email protected]ec04d3f2013-06-06 21:31:39121 };
122
Alex Clarke1052bb02018-12-14 09:44:16123 // Deprecated.
[email protected]ec04d3f2013-06-06 21:31:39124 explicit TestBrowserThreadBundle(int options);
125
Alex Clarke1052bb02018-12-14 09:44:16126 TestBrowserThreadBundle(
127 base::test::ScopedTaskEnvironment::MainThreadType main_thread_type =
128 base::test::ScopedTaskEnvironment::MainThreadType::UI,
129 base::test::ScopedTaskEnvironment::ExecutionMode execution_control_mode =
130 base::test::ScopedTaskEnvironment::ExecutionMode::ASYNC,
131 int options = DEFAULT);
132
Gabriel Charette147335ea2018-03-22 15:59:19133 // Runs all tasks posted to TaskScheduler and main thread until idle.
134 // Note: At the moment, this will not process BrowserThread::IO if this
135 // TestBrowserThreadBundle is using a REAL_IO_THREAD.
136 // TODO(robliao): fix this by making TaskScheduler aware of all MessageLoops.
137 //
138 // Note that this is not the cleanest way to run until idle as it will return
139 // early if it depends on an async condition that isn't guaranteed to have
140 // occurred yet. The best way to run until a condition is met is with RunLoop:
141 //
142 // void KickoffAsyncFoo(base::OnceClosure on_done);
143 //
144 // base::RunLoop run_loop;
145 // KickoffAsyncFoo(run_loop.QuitClosure());
146 // run_loop.Run();
147 //
Gabriel Charetted4c59d02018-03-21 20:12:26148
Gabriel Charette147335ea2018-03-22 15:59:19149 // Flush the IO thread. Replacement for RunLoop::RunUntilIdle() for tests that
150 // have a REAL_IO_THREAD. As with RunUntilIdle() above, prefer using
151 // RunLoop+QuitClosure() to await an async condition.
152 void RunIOThreadUntilIdle();
153
Alex Clarke1052bb02018-12-14 09:44:16154 ~TestBrowserThreadBundle() override;
[email protected]ec04d3f2013-06-06 21:31:39155
156 private:
aberent8f1ce402016-01-13 12:01:38157 void Init();
[email protected]ec04d3f2013-06-06 21:31:39158
dcheng6003e0b2016-04-09 18:42:34159 std::unique_ptr<TestBrowserThread> ui_thread_;
dcheng6003e0b2016-04-09 18:42:34160 std::unique_ptr<TestBrowserThread> io_thread_;
[email protected]ec04d3f2013-06-06 21:31:39161
aberent8f1ce402016-01-13 12:01:38162 int options_;
aberent8f1ce402016-01-13 12:01:38163
Robert Liao0bde45e2017-06-22 21:16:03164#if defined(OS_WIN)
165 std::unique_ptr<base::win::ScopedCOMInitializer> com_initializer_;
166#endif
167
[email protected]ec04d3f2013-06-06 21:31:39168 DISALLOW_COPY_AND_ASSIGN(TestBrowserThreadBundle);
169};
170
171} // namespace content
172
sdefresne634eec92014-12-18 13:02:54173#endif // CONTENT_PUBLIC_TEST_TEST_BROWSER_THREAD_BUNDLE_H_