1 // Copyright 2015 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.
5 #include "chrome/browser/chromeos/file_system_provider/queue.h"
9 #include "base/files/file.h"
10 #include "base/run_loop.h"
11 #include "content/public/test/test_browser_thread_bundle.h"
12 #include "testing/gtest/include/gtest/gtest.h"
15 namespace file_system_provider
{
18 void OnAbort(int* abort_counter
) {
22 AbortCallback
OnRun(int* run_counter
, int* abort_counter
) {
24 return base::Bind(&OnAbort
, abort_counter
);
27 #if !defined(NDEBUG) && defined(GTEST_HAS_DEATH_TEST)
29 AbortCallback
OnRunNonAbortable(int* run_counter
, int* abort_counter
) {
31 return AbortCallback();
38 class FileSystemProviderQueueTest
: public testing::Test
{
40 FileSystemProviderQueueTest() {}
41 ~FileSystemProviderQueueTest() override
{}
43 content::TestBrowserThreadBundle thread_bundle_
;
46 TEST_F(FileSystemProviderQueueTest
, NewToken
) {
48 EXPECT_EQ(1u, queue
.NewToken());
49 EXPECT_EQ(2u, queue
.NewToken());
50 EXPECT_EQ(3u, queue
.NewToken());
53 TEST_F(FileSystemProviderQueueTest
, Enqueue_OneAtOnce
) {
55 const size_t first_token
= queue
.NewToken();
56 int first_counter
= 0;
57 int first_abort_counter
= 0;
58 queue
.Enqueue(first_token
,
59 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
61 const size_t second_token
= queue
.NewToken();
62 int second_counter
= 0;
63 int second_abort_counter
= 0;
64 queue
.Enqueue(second_token
,
65 base::Bind(&OnRun
, &second_counter
, &second_abort_counter
));
67 base::RunLoop().RunUntilIdle();
68 EXPECT_EQ(1, first_counter
);
69 EXPECT_EQ(0, first_abort_counter
);
70 EXPECT_EQ(0, second_counter
);
71 EXPECT_EQ(0, second_abort_counter
);
73 // Complete the first task from the queue should run the second task.
74 queue
.Complete(first_token
);
75 base::RunLoop().RunUntilIdle();
76 EXPECT_EQ(1, first_counter
);
77 EXPECT_EQ(0, first_abort_counter
);
78 EXPECT_EQ(1, second_counter
);
79 EXPECT_EQ(0, second_abort_counter
);
81 const size_t third_token
= queue
.NewToken();
82 int third_counter
= 0;
83 int third_abort_counter
= 0;
84 queue
.Enqueue(third_token
,
85 base::Bind(&OnRun
, &third_counter
, &third_abort_counter
));
87 // The second task is still running, so the third one is blocked.
88 base::RunLoop().RunUntilIdle();
89 EXPECT_EQ(1, first_counter
);
90 EXPECT_EQ(0, first_abort_counter
);
91 EXPECT_EQ(1, second_counter
);
92 EXPECT_EQ(0, second_abort_counter
);
93 EXPECT_EQ(0, third_counter
);
94 EXPECT_EQ(0, third_abort_counter
);
96 // After aborting the second task, the third should run.
97 queue
.Abort(second_token
);
98 queue
.Complete(second_token
);
99 base::RunLoop().RunUntilIdle();
100 EXPECT_EQ(1, first_counter
);
101 EXPECT_EQ(0, first_abort_counter
);
102 EXPECT_EQ(1, second_counter
);
103 EXPECT_EQ(1, second_abort_counter
);
104 EXPECT_EQ(1, third_counter
);
105 EXPECT_EQ(0, third_abort_counter
);
108 TEST_F(FileSystemProviderQueueTest
, Enqueue_MultipleAtOnce
) {
110 const size_t first_token
= queue
.NewToken();
111 int first_counter
= 0;
112 int first_abort_counter
= 0;
113 queue
.Enqueue(first_token
,
114 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
116 const size_t second_token
= queue
.NewToken();
117 int second_counter
= 0;
118 int second_abort_counter
= 0;
119 queue
.Enqueue(second_token
,
120 base::Bind(&OnRun
, &second_counter
, &second_abort_counter
));
122 const size_t third_token
= queue
.NewToken();
123 int third_counter
= 0;
124 int third_abort_counter
= 0;
125 queue
.Enqueue(third_token
,
126 base::Bind(&OnRun
, &third_counter
, &third_abort_counter
));
128 base::RunLoop().RunUntilIdle();
129 EXPECT_EQ(1, first_counter
);
130 EXPECT_EQ(0, first_abort_counter
);
131 EXPECT_EQ(1, second_counter
);
132 EXPECT_EQ(0, second_abort_counter
);
133 EXPECT_EQ(0, third_counter
);
134 EXPECT_EQ(0, third_abort_counter
);
136 // Completing and removing the second task, should start the last one.
137 queue
.Complete(second_token
);
138 base::RunLoop().RunUntilIdle();
139 EXPECT_EQ(1, first_counter
);
140 EXPECT_EQ(0, first_abort_counter
);
141 EXPECT_EQ(1, second_counter
);
142 EXPECT_EQ(0, second_abort_counter
);
143 EXPECT_EQ(1, third_counter
);
144 EXPECT_EQ(0, third_abort_counter
);
147 #if !defined(NDEBUG) && defined(GTEST_HAS_DEATH_TEST)
149 TEST_F(FileSystemProviderQueueTest
, InvalidUsage_DuplicatedTokens
) {
151 const size_t first_token
= queue
.NewToken();
152 int first_counter
= 0;
153 int first_abort_counter
= 0;
154 queue
.Enqueue(first_token
,
155 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
157 // Use the first token on purpose.
158 int second_counter
= 0;
159 int second_abort_counter
= 0;
160 EXPECT_DEATH(queue
.Enqueue(first_token
, base::Bind(&OnRun
, &second_counter
,
161 &second_abort_counter
)),
165 TEST_F(FileSystemProviderQueueTest
, InvalidUsage_CompleteNotStarted
) {
167 const size_t first_token
= queue
.NewToken();
168 int first_counter
= 0;
169 int first_abort_counter
= 0;
170 queue
.Enqueue(first_token
,
171 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
173 // Completing and removing the first task, which however hasn't started.
174 // That should not invoke the second task.
175 EXPECT_DEATH(queue
.Complete(first_token
), "");
178 TEST_F(FileSystemProviderQueueTest
,
179 InvalidUsage_CompleteAfterAbortingNonExecutedTask
) {
181 const size_t first_token
= queue
.NewToken();
182 int first_counter
= 0;
183 int first_abort_counter
= 0;
184 queue
.Enqueue(first_token
,
185 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
187 std::vector
<base::File::Error
> first_abort_callback_log
;
188 queue
.Abort(first_token
);
190 EXPECT_DEATH(queue
.Complete(first_token
), "");
193 TEST_F(FileSystemProviderQueueTest
, InvalidUsage_AbortAfterCompleting
) {
195 const size_t first_token
= queue
.NewToken();
196 int first_counter
= 0;
197 int first_abort_counter
= 0;
198 queue
.Enqueue(first_token
,
199 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
201 base::RunLoop().RunUntilIdle();
203 queue
.Complete(first_token
);
204 EXPECT_DEATH(queue
.Abort(first_token
), "");
207 TEST_F(FileSystemProviderQueueTest
, InvalidUsage_CompleteTwice
) {
209 const size_t first_token
= queue
.NewToken();
210 int first_counter
= 0;
211 int first_abort_counter
= 0;
212 queue
.Enqueue(first_token
,
213 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
215 base::RunLoop().RunUntilIdle();
217 queue
.Complete(first_token
);
218 EXPECT_DEATH(queue
.Complete(first_token
), "");
221 TEST_F(FileSystemProviderQueueTest
, InvalidUsage_AbortTwice
) {
223 const size_t first_token
= queue
.NewToken();
224 int first_counter
= 0;
225 int first_abort_counter
= 0;
226 queue
.Enqueue(first_token
,
227 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
229 base::RunLoop().RunUntilIdle();
231 queue
.Abort(first_token
);
232 EXPECT_DEATH(queue
.Abort(first_token
), "");
235 TEST_F(FileSystemProviderQueueTest
, InvalidUsage_AbortNonAbortable
) {
237 const size_t first_token
= queue
.NewToken();
238 int first_counter
= 0;
239 int first_abort_counter
= 0;
240 queue
.Enqueue(first_token
, base::Bind(&OnRunNonAbortable
, &first_counter
,
241 &first_abort_counter
));
243 base::RunLoop().RunUntilIdle();
245 EXPECT_DEATH(queue
.Abort(first_token
), "");
250 TEST_F(FileSystemProviderQueueTest
, Enqueue_Abort
) {
252 const size_t first_token
= queue
.NewToken();
253 int first_counter
= 0;
254 int first_abort_counter
= 0;
255 queue
.Enqueue(first_token
,
256 base::Bind(&OnRun
, &first_counter
, &first_abort_counter
));
258 const size_t second_token
= queue
.NewToken();
259 int second_counter
= 0;
260 int second_abort_counter
= 0;
261 queue
.Enqueue(second_token
,
262 base::Bind(&OnRun
, &second_counter
, &second_abort_counter
));
264 base::RunLoop().RunUntilIdle();
265 EXPECT_EQ(1, first_counter
);
266 EXPECT_EQ(0, first_abort_counter
);
267 EXPECT_EQ(0, second_counter
);
268 EXPECT_EQ(0, second_abort_counter
);
270 // Abort the first task while it's being executed.
271 queue
.Abort(first_token
);
272 queue
.Complete(first_token
);
274 // Abort the second task, before it's started.
275 EXPECT_EQ(0, second_counter
);
276 queue
.Abort(second_token
);
278 base::RunLoop().RunUntilIdle();
279 EXPECT_EQ(1, first_counter
);
280 EXPECT_EQ(1, first_abort_counter
);
281 EXPECT_EQ(0, second_counter
);
282 EXPECT_EQ(0, second_abort_counter
);
285 } // namespace file_system_provider
286 } // namespace chromeos