1 // Copyright 2019 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 #include "content/public/test/test_utils.h"
6 
7 #include "base/run_loop.h"
8 #include "base/task/thread_pool.h"
9 #include "base/test/bind.h"
10 #include "base/test/task_environment.h"
11 #include "base/threading/platform_thread.h"
12 #include "content/public/browser/browser_task_traits.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/test/browser_task_environment.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 // Regression test for crbug.com/1035189.
TEST(ContentTestUtils,NestedRunAllTasksUntilIdleWithPendingThreadPoolWork)18 TEST(ContentTestUtils, NestedRunAllTasksUntilIdleWithPendingThreadPoolWork) {
19   base::test::TaskEnvironment task_environment;
20 
21   bool thread_pool_task_completed = false;
22   base::ThreadPool::PostTask(
23       FROM_HERE, {}, base::BindLambdaForTesting([&]() {
24         base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
25         thread_pool_task_completed = true;
26       }));
27 
28   base::RunLoop run_loop;
29 
30   base::ThreadTaskRunnerHandle::Get()->PostTask(
31       FROM_HERE, base::BindLambdaForTesting([&]() {
32         // Nested RunAllTasksUntilIdle() (i.e. crbug.com/1035189).
33         content::RunAllTasksUntilIdle();
34         EXPECT_TRUE(thread_pool_task_completed);
35         run_loop.Quit();
36       }));
37 
38   run_loop.Run();
39   EXPECT_TRUE(thread_pool_task_completed);
40 }
41 
42 // Regression test for crbug.com/1035604.
TEST(ContentTestUtils,FlushRealIOThread)43 TEST(ContentTestUtils, FlushRealIOThread) {
44   content::BrowserTaskEnvironment task_environment{
45       content::BrowserTaskEnvironment::REAL_IO_THREAD};
46 
47   bool io_task_completed = false;
48   content::GetIOThreadTaskRunner({})->PostTask(
49       FROM_HERE, base::BindLambdaForTesting([&]() {
50         base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
51         io_task_completed = true;
52       }));
53 
54   content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
55   EXPECT_TRUE(io_task_completed);
56 }
57 
TEST(ContentTestUtils,NestedFlushRealIOThread)58 TEST(ContentTestUtils, NestedFlushRealIOThread) {
59   content::BrowserTaskEnvironment task_environment{
60       content::BrowserTaskEnvironment::REAL_IO_THREAD};
61 
62   bool io_task_completed = false;
63   content::GetIOThreadTaskRunner({})->PostTask(
64       FROM_HERE, base::BindLambdaForTesting([&]() {
65         base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
66         io_task_completed = true;
67       }));
68 
69   base::RunLoop run_loop;
70 
71   base::ThreadTaskRunnerHandle::Get()->PostTask(
72       FROM_HERE, base::BindLambdaForTesting([&]() {
73         content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
74         EXPECT_TRUE(io_task_completed);
75         run_loop.Quit();
76       }));
77 
78   run_loop.Run();
79   EXPECT_TRUE(io_task_completed);
80 }
81 
TEST(ContentTestUtils,FlushRealIOThreadWithPendingBestEffortTask)82 TEST(ContentTestUtils, FlushRealIOThreadWithPendingBestEffortTask) {
83   content::BrowserTaskEnvironment task_environment{
84       content::BrowserTaskEnvironment::REAL_IO_THREAD};
85 
86   bool io_task_completed = false;
87   content::GetIOThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
88       ->PostTask(
89           FROM_HERE, base::BindLambdaForTesting([&]() {
90             base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
91             io_task_completed = true;
92           }));
93 
94   content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
95   EXPECT_TRUE(io_task_completed);
96 }
97 
98 // Same as FlushRealIOThreadWithPendingBestEffortTask but when BrowserThread::IO
99 // is multiplexed with BrowserThread::UI on the main thread (i.e. the default
100 // under BrowserTaskEnvironment).
TEST(ContentTestUtils,FlushFakeIOThread)101 TEST(ContentTestUtils, FlushFakeIOThread) {
102   content::BrowserTaskEnvironment task_environment;
103 
104   bool io_task_completed = false;
105   content::GetIOThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
106       ->PostTask(
107           FROM_HERE, base::BindLambdaForTesting([&]() {
108             base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
109             io_task_completed = true;
110           }));
111 
112   content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
113   EXPECT_TRUE(io_task_completed);
114 }
115 
TEST(ContentTestUtils,FlushUIThread)116 TEST(ContentTestUtils, FlushUIThread) {
117   content::BrowserTaskEnvironment task_environment;
118 
119   bool ui_task_completed = false;
120   content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
121       ->PostTask(
122           FROM_HERE, base::BindLambdaForTesting([&]() {
123             base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
124             ui_task_completed = true;
125           }));
126 
127   content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
128   EXPECT_TRUE(ui_task_completed);
129 }
130