[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 1 | // 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 | |
| 5 | // TestBrowserThreadBundle is a convenience class for creating a set of |
fdoray | ad58f83 | 2016-12-19 18:06:46 | [diff] [blame] | 6 | // TestBrowserThreads, a blocking pool, and a task scheduler in unit tests. For |
| 7 | // most tests, it is sufficient to just instantiate the TestBrowserThreadBundle |
| 8 | // as a member variable. It is a good idea to put the TestBrowserThreadBundle as |
| 9 | // the first member variable in test classes, so it is destroyed last, and the |
| 10 | // test threads always exist from the perspective of other classes. |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 11 | // |
fdoray | 575c4b2 | 2017-04-05 19:25:51 | [diff] [blame] | 12 | // By default, all of the created TestBrowserThreads will be backed by a single |
| 13 | // shared MessageLoop. If a test truly needs separate threads, it can do so by |
| 14 | // passing the appropriate combination of option values during the |
| 15 | // TestBrowserThreadBundle construction. TaskScheduler and blocking pool tasks |
| 16 | // always run on dedicated threads. |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 17 | // |
fdoray | 575c4b2 | 2017-04-05 19:25:51 | [diff] [blame] | 18 | // 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 |
| 24 | // TaskScheduler or in the blocking pool (excluding tasks not posted from the |
| 25 | // shared MessageLoop's thread, TaskScheduler or the blocking pool): |
| 26 | // content::RunAllBlockingPoolTasksUntilIdle(); |
| 27 | // |
| 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 | // |
| 35 | // To wait until there are no pending undelayed tasks in TaskScheduler or in the |
| 36 | // blocking pool, without running tasks from the shared MessageLoop: |
| 37 | // base::TaskScheduler::GetInstance()->FlushForTesting(); |
| 38 | // // Note: content::BrowserThread::GetBlockingPool()->FlushForTesting() is |
| 39 | // // equivalent but deprecated. |
| 40 | // |
| 41 | // The destructor of TestBrowserThreadBundle runs remaining TestBrowserThreads |
| 42 | // tasks, remaining blocking pool tasks, and remaining BLOCK_SHUTDOWN task |
| 43 | // scheduler tasks. |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 44 | // |
fdoray | ad58f83 | 2016-12-19 18:06:46 | [diff] [blame] | 45 | // If a test needs a MessageLoopForIO on the main thread, it should use the |
fdoray | 575c4b2 | 2017-04-05 19:25:51 | [diff] [blame] | 46 | // IO_MAINLOOP option. Most of the time, IO_MAINLOOP avoids needing to use a |
fdoray | ad58f83 | 2016-12-19 18:06:46 | [diff] [blame] | 47 | // REAL_IO_THREAD. |
aberent | 8f1ce40 | 2016-01-13 12:01:38 | [diff] [blame] | 48 | // |
| 49 | // For some tests it is important to emulate real browser startup. During real |
fdoray | 93605d2 | 2017-01-13 12:17:25 | [diff] [blame] | 50 | // browser startup, the main MessageLoop is created before other threads. |
| 51 | // Passing DONT_CREATE_THREADS to constructor will delay creating other threads |
| 52 | // until the test explicitly calls CreateThreads(). |
aberent | 8f1ce40 | 2016-01-13 12:01:38 | [diff] [blame] | 53 | // |
fdoray | 93605d2 | 2017-01-13 12:17:25 | [diff] [blame] | 54 | // DONT_CREATE_THREADS should only be used when the options specify at least |
aberent | 8f1ce40 | 2016-01-13 12:01:38 | [diff] [blame] | 55 | // one real thread other than the main thread. |
gab | 1f58e95 | 2017-05-04 23:28:51 | [diff] [blame^] | 56 | // |
| 57 | // Basic usage: |
| 58 | // |
| 59 | // class MyTestFixture : public testing::Test { |
| 60 | // public: |
| 61 | // (...) |
| 62 | // |
| 63 | // protected: |
| 64 | // // Must be the first member (or at least before any member that cares |
| 65 | // // about tasks) to be initialized first and destroyed last. protected |
| 66 | // // instead of private visibility will allow controlling the task |
| 67 | // // environment (e.g. clock) once such features are added (see |
| 68 | // // base::test::ScopedTaskEnvironment for details), until then it at least |
| 69 | // // doesn't hurt :). |
| 70 | // content::TestBrowserThreadBundle test_browser_thread_bundle_; |
| 71 | // |
| 72 | // // Other members go here (or further below in private section.) |
| 73 | // }; |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 74 | |
sdefresne | 634eec9 | 2014-12-18 13:02:54 | [diff] [blame] | 75 | #ifndef CONTENT_PUBLIC_TEST_TEST_BROWSER_THREAD_BUNDLE_H_ |
| 76 | #define CONTENT_PUBLIC_TEST_TEST_BROWSER_THREAD_BUNDLE_H_ |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 77 | |
dcheng | 6003e0b | 2016-04-09 18:42:34 | [diff] [blame] | 78 | #include <memory> |
| 79 | |
avi | 652869c | 2015-12-25 01:48:45 | [diff] [blame] | 80 | #include "base/macros.h" |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 81 | |
| 82 | namespace base { |
| 83 | class MessageLoop; |
fdoray | ad58f83 | 2016-12-19 18:06:46 | [diff] [blame] | 84 | namespace test { |
fdoray | aedd3c2c | 2017-01-14 00:09:32 | [diff] [blame] | 85 | class ScopedAsyncTaskScheduler; |
fdoray | ad58f83 | 2016-12-19 18:06:46 | [diff] [blame] | 86 | } // namespace test |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 87 | } // namespace base |
| 88 | |
| 89 | namespace content { |
| 90 | |
| 91 | class TestBrowserThread; |
| 92 | |
| 93 | class TestBrowserThreadBundle { |
| 94 | public: |
| 95 | // Used to specify the type of MessageLoop that backs the UI thread, and |
| 96 | // which of the named BrowserThreads should be backed by a real |
| 97 | // threads. The UI thread is always the main thread in a unit test. |
| 98 | enum Options { |
fdoray | aedd3c2c | 2017-01-14 00:09:32 | [diff] [blame] | 99 | DEFAULT = 0, |
| 100 | IO_MAINLOOP = 1 << 0, |
| 101 | REAL_DB_THREAD = 1 << 1, |
| 102 | REAL_FILE_THREAD = 1 << 2, |
| 103 | REAL_IO_THREAD = 1 << 3, |
fdoray | 575c4b2 | 2017-04-05 19:25:51 | [diff] [blame] | 104 | DONT_CREATE_THREADS = 1 << 4, |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 105 | }; |
| 106 | |
| 107 | TestBrowserThreadBundle(); |
| 108 | explicit TestBrowserThreadBundle(int options); |
| 109 | |
fdoray | 93605d2 | 2017-01-13 12:17:25 | [diff] [blame] | 110 | // Creates threads; should only be called from other classes if the |
| 111 | // DONT_CREATE_THREADS option was used when the bundle was created. |
| 112 | void CreateThreads(); |
aberent | 8f1ce40 | 2016-01-13 12:01:38 | [diff] [blame] | 113 | |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 114 | ~TestBrowserThreadBundle(); |
| 115 | |
| 116 | private: |
aberent | 8f1ce40 | 2016-01-13 12:01:38 | [diff] [blame] | 117 | void Init(); |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 118 | |
dcheng | 6003e0b | 2016-04-09 18:42:34 | [diff] [blame] | 119 | std::unique_ptr<base::MessageLoop> message_loop_; |
fdoray | aedd3c2c | 2017-01-14 00:09:32 | [diff] [blame] | 120 | std::unique_ptr<base::test::ScopedAsyncTaskScheduler> |
| 121 | scoped_async_task_scheduler_; |
dcheng | 6003e0b | 2016-04-09 18:42:34 | [diff] [blame] | 122 | std::unique_ptr<TestBrowserThread> ui_thread_; |
| 123 | std::unique_ptr<TestBrowserThread> db_thread_; |
| 124 | std::unique_ptr<TestBrowserThread> file_thread_; |
| 125 | std::unique_ptr<TestBrowserThread> file_user_blocking_thread_; |
| 126 | std::unique_ptr<TestBrowserThread> process_launcher_thread_; |
| 127 | std::unique_ptr<TestBrowserThread> cache_thread_; |
| 128 | std::unique_ptr<TestBrowserThread> io_thread_; |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 129 | |
aberent | 8f1ce40 | 2016-01-13 12:01:38 | [diff] [blame] | 130 | int options_; |
fdoray | 93605d2 | 2017-01-13 12:17:25 | [diff] [blame] | 131 | bool threads_created_; |
aberent | 8f1ce40 | 2016-01-13 12:01:38 | [diff] [blame] | 132 | |
[email protected] | ec04d3f | 2013-06-06 21:31:39 | [diff] [blame] | 133 | DISALLOW_COPY_AND_ASSIGN(TestBrowserThreadBundle); |
| 134 | }; |
| 135 | |
| 136 | } // namespace content |
| 137 | |
sdefresne | 634eec9 | 2014-12-18 13:02:54 | [diff] [blame] | 138 | #endif // CONTENT_PUBLIC_TEST_TEST_BROWSER_THREAD_BUNDLE_H_ |