1 // Copyright 2019 The Chromium Authors
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 "base/task/sequence_manager/work_deduplicator.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7
8 namespace base {
9 namespace sequence_manager {
10 namespace internal {
11
12 using NextTask = WorkDeduplicator::NextTask;
13 using ShouldScheduleWork = WorkDeduplicator::ShouldScheduleWork;
14
TEST(WorkDeduplicatorTest,BindToCurrentThreadWithoutPriorOnWorkRequested)15 TEST(WorkDeduplicatorTest, BindToCurrentThreadWithoutPriorOnWorkRequested) {
16 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
17
18 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
19 work_deduplicator.BindToCurrentThread());
20 }
21
TEST(WorkDeduplicatorTest,OnWorkRequestedUnBound)22 TEST(WorkDeduplicatorTest, OnWorkRequestedUnBound) {
23 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
24
25 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
26 work_deduplicator.OnWorkRequested());
27 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
28 work_deduplicator.BindToCurrentThread());
29 }
30
TEST(WorkDeduplicatorTest,OnWorkRequestedOnWorkStarted)31 TEST(WorkDeduplicatorTest, OnWorkRequestedOnWorkStarted) {
32 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
33 work_deduplicator.BindToCurrentThread();
34
35 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
36 work_deduplicator.OnWorkRequested());
37 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
38 work_deduplicator.OnWorkRequested());
39 }
40
TEST(WorkDeduplicatorTest,TaskRequestedWorkButDidCheckForMoreWorkDelayed)41 TEST(WorkDeduplicatorTest, TaskRequestedWorkButDidCheckForMoreWorkDelayed) {
42 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
43 work_deduplicator.BindToCurrentThread();
44
45 work_deduplicator.OnWorkStarted();
46 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
47 work_deduplicator.OnWorkRequested());
48 work_deduplicator.WillCheckForMoreWork();
49 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
50 work_deduplicator.DidCheckForMoreWork(NextTask::kIsDelayed));
51 }
52
TEST(WorkDeduplicatorTest,TaskRequestedWorkButDidCheckForMoreWorkDelayedAndCrossThreadWorkRequested)53 TEST(
54 WorkDeduplicatorTest,
55 TaskRequestedWorkButDidCheckForMoreWorkDelayedAndCrossThreadWorkRequested) {
56 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
57 work_deduplicator.BindToCurrentThread();
58
59 work_deduplicator.OnWorkStarted();
60 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
61 work_deduplicator.OnWorkRequested());
62 work_deduplicator.WillCheckForMoreWork();
63 // Simulate cross-thread PostTask while checking for more work.
64 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
65 work_deduplicator.OnWorkRequested());
66 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
67 work_deduplicator.DidCheckForMoreWork(NextTask::kIsDelayed));
68 }
69
TEST(WorkDeduplicatorTest,TaskRequestedWorkAndDidCheckForMoreWorkImmediate)70 TEST(WorkDeduplicatorTest, TaskRequestedWorkAndDidCheckForMoreWorkImmediate) {
71 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
72 work_deduplicator.BindToCurrentThread();
73
74 work_deduplicator.OnWorkStarted();
75 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
76 work_deduplicator.OnWorkRequested());
77 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
78 work_deduplicator.OnWorkRequested());
79 work_deduplicator.WillCheckForMoreWork();
80 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
81 work_deduplicator.DidCheckForMoreWork(NextTask::kIsImmediate));
82 }
83
TEST(WorkDeduplicatorTest,TaskRequestedWorkAndDidCheckForMoreWorkImmediateCrossThreadWorkRequested)84 TEST(WorkDeduplicatorTest,
85 TaskRequestedWorkAndDidCheckForMoreWorkImmediateCrossThreadWorkRequested) {
86 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
87 work_deduplicator.BindToCurrentThread();
88
89 work_deduplicator.OnWorkStarted();
90 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
91 work_deduplicator.OnWorkRequested());
92 work_deduplicator.WillCheckForMoreWork();
93 // Simulate cross-thread PostTask while checking for more work.
94 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
95 work_deduplicator.OnWorkRequested());
96 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
97 work_deduplicator.DidCheckForMoreWork(NextTask::kIsImmediate));
98 }
99
TEST(WorkDeduplicatorTest,DidCheckForMoreWorkDelayed)100 TEST(WorkDeduplicatorTest, DidCheckForMoreWorkDelayed) {
101 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
102 work_deduplicator.BindToCurrentThread();
103
104 work_deduplicator.OnWorkStarted();
105 work_deduplicator.WillCheckForMoreWork();
106 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
107 work_deduplicator.DidCheckForMoreWork(NextTask::kIsDelayed));
108 }
109
TEST(WorkDeduplicatorTest,DidCheckForMoreWorkDelayedAndCrossThreadWorkRequested)110 TEST(WorkDeduplicatorTest,
111 DidCheckForMoreWorkDelayedAndCrossThreadWorkRequested) {
112 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
113 work_deduplicator.BindToCurrentThread();
114
115 work_deduplicator.OnWorkStarted();
116 work_deduplicator.WillCheckForMoreWork();
117 // Simulate cross-thread PostTask while checking for more work.
118 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
119 work_deduplicator.OnWorkRequested());
120 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
121 work_deduplicator.DidCheckForMoreWork(NextTask::kIsDelayed));
122 }
123
TEST(WorkDeduplicatorTest,DidCheckForMoreWorkImmediate)124 TEST(WorkDeduplicatorTest, DidCheckForMoreWorkImmediate) {
125 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
126 work_deduplicator.BindToCurrentThread();
127
128 work_deduplicator.OnWorkStarted();
129 work_deduplicator.WillCheckForMoreWork();
130 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
131 work_deduplicator.DidCheckForMoreWork(NextTask::kIsImmediate));
132 }
133
TEST(WorkDeduplicatorTest,DidCheckForMoreWorkImmediateCrossThreadWorkRequested)134 TEST(WorkDeduplicatorTest,
135 DidCheckForMoreWorkImmediateCrossThreadWorkRequested) {
136 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
137 work_deduplicator.BindToCurrentThread();
138
139 work_deduplicator.OnWorkStarted();
140 work_deduplicator.WillCheckForMoreWork();
141 // Simulate cross-thread PostTask while checking for more work.
142 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
143 work_deduplicator.OnWorkRequested());
144 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
145 work_deduplicator.DidCheckForMoreWork(NextTask::kIsImmediate));
146 }
147
TEST(WorkDeduplicatorTest,OnDelayedWorkRequestedUnbound)148 TEST(WorkDeduplicatorTest, OnDelayedWorkRequestedUnbound) {
149 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
150
151 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
152 work_deduplicator.OnDelayedWorkRequested());
153 }
154
TEST(WorkDeduplicatorTest,OnDelayedWorkRequestedBound)155 TEST(WorkDeduplicatorTest, OnDelayedWorkRequestedBound) {
156 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
157 work_deduplicator.BindToCurrentThread();
158
159 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
160 work_deduplicator.OnDelayedWorkRequested());
161
162 // Unlike OnWorkRequested, calling this again doesn't change the result,
163 // because we assume a different delay is being requested.
164 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
165 work_deduplicator.OnDelayedWorkRequested());
166 }
167
TEST(WorkDeduplicatorTest,OnDelayedWorkRequestedInDoWork)168 TEST(WorkDeduplicatorTest, OnDelayedWorkRequestedInDoWork) {
169 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
170 work_deduplicator.BindToCurrentThread();
171
172 work_deduplicator.OnWorkStarted();
173 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
174 work_deduplicator.OnDelayedWorkRequested());
175 work_deduplicator.WillCheckForMoreWork();
176 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
177 work_deduplicator.OnDelayedWorkRequested());
178 work_deduplicator.DidCheckForMoreWork(NextTask::kIsImmediate);
179 }
180
TEST(WorkDeduplicatorTest,OnDelayedWorkRequestedDidCheckForMoreWorkWithMoreWork)181 TEST(WorkDeduplicatorTest,
182 OnDelayedWorkRequestedDidCheckForMoreWorkWithMoreWork) {
183 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
184 work_deduplicator.BindToCurrentThread();
185
186 work_deduplicator.OnWorkStarted();
187 work_deduplicator.WillCheckForMoreWork();
188 work_deduplicator.DidCheckForMoreWork(NextTask::kIsImmediate);
189
190 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
191 work_deduplicator.OnDelayedWorkRequested());
192 }
193
TEST(WorkDeduplicatorTest,OnDelayedWorkRequestedDidCheckForMoreWorkWithNoMoreWork)194 TEST(WorkDeduplicatorTest,
195 OnDelayedWorkRequestedDidCheckForMoreWorkWithNoMoreWork) {
196 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
197 work_deduplicator.BindToCurrentThread();
198
199 work_deduplicator.OnWorkStarted();
200 work_deduplicator.WillCheckForMoreWork();
201 work_deduplicator.DidCheckForMoreWork(NextTask::kIsDelayed);
202
203 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
204 work_deduplicator.OnDelayedWorkRequested());
205 }
206
TEST(WorkDeduplicatorTest,OnDelayedWorkRequestedWithDoWorkPending)207 TEST(WorkDeduplicatorTest, OnDelayedWorkRequestedWithDoWorkPending) {
208 WorkDeduplicator work_deduplicator(AssociatedThreadId::CreateBound());
209 work_deduplicator.BindToCurrentThread();
210
211 EXPECT_EQ(ShouldScheduleWork::kScheduleImmediate,
212 work_deduplicator.OnWorkRequested());
213 EXPECT_EQ(ShouldScheduleWork::kNotNeeded,
214 work_deduplicator.OnDelayedWorkRequested());
215 }
216
217 } // namespace internal
218 } // namespace sequence_manager
219 } // namespace base
220