blob: 5b7c8d602441b8c6c39802ac86d956048ea4e904 [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"
Robert Liao0bde45e2017-06-22 21:16:0388#include "build/build_config.h"
[email protected]ec04d3f2013-06-06 21:31:3989
90namespace base {
fdorayad58f832016-12-19 18:06:4691namespace test {
Francois Doray69f889f2017-08-02 15:42:1292class ScopedTaskEnvironment;
fdorayad58f832016-12-19 18:06:4693} // namespace test
Robert Liao0bde45e2017-06-22 21:16:0394#if defined(OS_WIN)
95namespace win {
96class ScopedCOMInitializer;
97} // namespace win
98#endif
[email protected]ec04d3f2013-06-06 21:31:3999} // namespace base
100
101namespace content {
102
103class TestBrowserThread;
104
Gabriel Charettecc8362b2017-09-20 21:59:40105// Note: to drive these threads (e.g. run all tasks until idle), see
106// content/public/test/test_utils.h.
[email protected]ec04d3f2013-06-06 21:31:39107class TestBrowserThreadBundle {
108 public:
109 // Used to specify the type of MessageLoop that backs the UI thread, and
110 // which of the named BrowserThreads should be backed by a real
111 // threads. The UI thread is always the main thread in a unit test.
112 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,
118 DONT_CREATE_BROWSER_THREADS = 1 << 2,
[email protected]ec04d3f2013-06-06 21:31:39119 };
120
121 TestBrowserThreadBundle();
122 explicit TestBrowserThreadBundle(int options);
123
Francois Doray69f889f2017-08-02 15:42:12124 // Creates browser threads; should only be called from other classes if the
125 // DONT_CREATE_BROWSER_THREADS option was used when the bundle was created.
126 void CreateBrowserThreads();
aberent8f1ce402016-01-13 12:01:38127
Gabriel Charette147335ea2018-03-22 15:59:19128 // Runs all tasks posted to TaskScheduler and main thread until idle.
129 // Note: At the moment, this will not process BrowserThread::IO if this
130 // TestBrowserThreadBundle is using a REAL_IO_THREAD.
131 // TODO(robliao): fix this by making TaskScheduler aware of all MessageLoops.
132 //
133 // Note that this is not the cleanest way to run until idle as it will return
134 // early if it depends on an async condition that isn't guaranteed to have
135 // occurred yet. The best way to run until a condition is met is with RunLoop:
136 //
137 // void KickoffAsyncFoo(base::OnceClosure on_done);
138 //
139 // base::RunLoop run_loop;
140 // KickoffAsyncFoo(run_loop.QuitClosure());
141 // run_loop.Run();
142 //
Gabriel Charetted4c59d02018-03-21 20:12:26143 void RunUntilIdle();
144
Gabriel Charette147335ea2018-03-22 15:59:19145 // Flush the IO thread. Replacement for RunLoop::RunUntilIdle() for tests that
146 // have a REAL_IO_THREAD. As with RunUntilIdle() above, prefer using
147 // RunLoop+QuitClosure() to await an async condition.
148 void RunIOThreadUntilIdle();
149
[email protected]ec04d3f2013-06-06 21:31:39150 ~TestBrowserThreadBundle();
151
152 private:
aberent8f1ce402016-01-13 12:01:38153 void Init();
[email protected]ec04d3f2013-06-06 21:31:39154
Francois Doray69f889f2017-08-02 15:42:12155 std::unique_ptr<base::test::ScopedTaskEnvironment> scoped_task_environment_;
dcheng6003e0b2016-04-09 18:42:34156 std::unique_ptr<TestBrowserThread> ui_thread_;
dcheng6003e0b2016-04-09 18:42:34157 std::unique_ptr<TestBrowserThread> io_thread_;
[email protected]ec04d3f2013-06-06 21:31:39158
aberent8f1ce402016-01-13 12:01:38159 int options_;
fdoray93605d22017-01-13 12:17:25160 bool threads_created_;
aberent8f1ce402016-01-13 12:01:38161
Robert Liao0bde45e2017-06-22 21:16:03162#if defined(OS_WIN)
163 std::unique_ptr<base::win::ScopedCOMInitializer> com_initializer_;
164#endif
165
[email protected]ec04d3f2013-06-06 21:31:39166 DISALLOW_COPY_AND_ASSIGN(TestBrowserThreadBundle);
167};
168
169} // namespace content
170
sdefresne634eec92014-12-18 13:02:54171#endif // CONTENT_PUBLIC_TEST_TEST_BROWSER_THREAD_BUNDLE_H_