1 // Copyright 2014 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.
8 #include "base/callback.h"
9 #include "base/files/file.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/run_loop.h"
15 #include "chrome/browser/chromeos/file_system_provider/request_manager.h"
16 #include "chrome/browser/chromeos/file_system_provider/request_value.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "testing/gtest/include/gtest/gtest.h"
21 namespace file_system_provider
{
24 // Logs calls of the success and error callbacks on requests.
29 explicit ExecuteEvent(int request_id
) : request_id_(request_id
) {}
30 virtual ~ExecuteEvent() {}
32 int request_id() { return request_id_
; }
40 SuccessEvent(int request_id
, scoped_ptr
<RequestValue
> result
, bool has_next
)
41 : request_id_(request_id
),
42 result_(result
.Pass()),
43 has_next_(has_next
) {}
44 virtual ~SuccessEvent() {}
46 int request_id() { return request_id_
; }
47 RequestValue
* result() { return result_
.get(); }
48 bool has_next() { return has_next_
; }
52 scoped_ptr
<RequestValue
> result_
;
58 ErrorEvent(int request_id
, base::File::Error error
)
59 : request_id_(request_id
), error_(error
) {}
60 virtual ~ErrorEvent() {}
62 int request_id() { return request_id_
; }
63 base::File::Error
error() { return error_
; }
67 base::File::Error error_
;
70 EventLogger() : weak_ptr_factory_(this) {}
71 virtual ~EventLogger() {}
73 void OnExecute(int request_id
) {
74 execute_events_
.push_back(new ExecuteEvent(request_id
));
77 void OnSuccess(int request_id
,
78 scoped_ptr
<RequestValue
> result
,
80 success_events_
.push_back(
81 new SuccessEvent(request_id
, result
.Pass(), has_next
));
84 void OnError(int request_id
, base::File::Error error
) {
85 error_events_
.push_back(new ErrorEvent(request_id
, error
));
88 ScopedVector
<ExecuteEvent
>& execute_events() { return execute_events_
; }
89 ScopedVector
<SuccessEvent
>& success_events() { return success_events_
; }
90 ScopedVector
<ErrorEvent
>& error_events() { return error_events_
; }
92 base::WeakPtr
<EventLogger
> GetWeakPtr() {
93 return weak_ptr_factory_
.GetWeakPtr();
97 ScopedVector
<ExecuteEvent
> execute_events_
;
98 ScopedVector
<SuccessEvent
> success_events_
;
99 ScopedVector
<ErrorEvent
> error_events_
;
100 base::WeakPtrFactory
<EventLogger
> weak_ptr_factory_
;
102 DISALLOW_COPY_AND_ASSIGN(EventLogger
);
105 // Fake handler, which forwards callbacks to the logger. The handler is owned
106 // by a request manager, however the logger is owned by tests.
107 class FakeHandler
: public RequestManager::HandlerInterface
{
109 // The handler can outlive the passed logger, so using a weak pointer. The
110 // |execute_reply| value will be returned for the Execute() call.
111 FakeHandler(base::WeakPtr
<EventLogger
> logger
, bool execute_reply
)
112 : logger_(logger
), execute_reply_(execute_reply
) {}
114 // RequestManager::Handler overrides.
115 virtual bool Execute(int request_id
) OVERRIDE
{
117 logger_
->OnExecute(request_id
);
119 return execute_reply_
;
122 // RequestManager::Handler overrides.
123 virtual void OnSuccess(int request_id
,
124 scoped_ptr
<RequestValue
> result
,
125 bool has_next
) OVERRIDE
{
127 logger_
->OnSuccess(request_id
, result
.Pass(), has_next
);
130 // RequestManager::Handler overrides.
131 virtual void OnError(int request_id
, base::File::Error error
) OVERRIDE
{
133 logger_
->OnError(request_id
, error
);
136 virtual ~FakeHandler() {}
139 base::WeakPtr
<EventLogger
> logger_
;
141 DISALLOW_COPY_AND_ASSIGN(FakeHandler
);
146 class FileSystemProviderRequestManagerTest
: public testing::Test
{
148 FileSystemProviderRequestManagerTest() {}
149 virtual ~FileSystemProviderRequestManagerTest() {}
151 virtual void SetUp() OVERRIDE
{
152 request_manager_
.reset(new RequestManager());
155 content::TestBrowserThreadBundle thread_bundle_
;
156 scoped_ptr
<RequestManager
> request_manager_
;
159 TEST_F(FileSystemProviderRequestManagerTest
, CreateAndFulFill
) {
162 const int request_id
= request_manager_
->CreateRequest(
163 make_scoped_ptr
<RequestManager::HandlerInterface
>(
164 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
166 EXPECT_EQ(1, request_id
);
167 EXPECT_EQ(0u, logger
.success_events().size());
168 EXPECT_EQ(0u, logger
.error_events().size());
170 scoped_ptr
<RequestValue
> response(
171 RequestValue::CreateForTesting("i-like-vanilla"));
172 const bool has_next
= false;
175 request_manager_
->FulfillRequest(request_id
, response
.Pass(), has_next
);
178 // Validate if the callback has correct arguments.
179 ASSERT_EQ(1u, logger
.success_events().size());
180 EXPECT_EQ(0u, logger
.error_events().size());
181 EventLogger::SuccessEvent
* event
= logger
.success_events()[0];
182 ASSERT_TRUE(event
->result());
183 const std::string
* response_test_string
= event
->result()->testing_params();
184 ASSERT_TRUE(response_test_string
);
185 EXPECT_EQ("i-like-vanilla", *response_test_string
);
186 EXPECT_FALSE(event
->has_next());
188 // Confirm, that the request is removed. Basically, fulfilling again for the
189 // same request, should fail.
191 scoped_ptr
<RequestValue
> response
;
193 request_manager_
->FulfillRequest(request_id
, response
.Pass(), has_next
);
197 // Rejecting should also fail.
199 bool retry
= request_manager_
->RejectRequest(request_id
,
200 base::File::FILE_ERROR_FAILED
);
205 TEST_F(FileSystemProviderRequestManagerTest
, CreateAndFulFill_WithHasNext
) {
208 const int request_id
= request_manager_
->CreateRequest(
209 make_scoped_ptr
<RequestManager::HandlerInterface
>(
210 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
212 EXPECT_EQ(1, request_id
);
213 EXPECT_EQ(0u, logger
.success_events().size());
214 EXPECT_EQ(0u, logger
.error_events().size());
216 scoped_ptr
<RequestValue
> response
;
217 const bool has_next
= true;
220 request_manager_
->FulfillRequest(request_id
, response
.Pass(), has_next
);
223 // Validate if the callback has correct arguments.
224 ASSERT_EQ(1u, logger
.success_events().size());
225 EXPECT_EQ(0u, logger
.error_events().size());
226 EventLogger::SuccessEvent
* event
= logger
.success_events()[0];
227 EXPECT_FALSE(event
->result());
228 EXPECT_TRUE(event
->has_next());
230 // Confirm, that the request is not removed (since it has has_next == true).
231 // Basically, fulfilling again for the same request, should not fail.
233 bool new_has_next
= false;
234 bool retry
= request_manager_
->FulfillRequest(
235 request_id
, response
.Pass(), new_has_next
);
239 // Since |new_has_next| is false, then the request should be removed. To check
240 // it, try to fulfill again, what should fail.
242 bool new_has_next
= false;
243 bool retry
= request_manager_
->FulfillRequest(
244 request_id
, response
.Pass(), new_has_next
);
249 TEST_F(FileSystemProviderRequestManagerTest
, CreateAndReject
) {
252 const int request_id
= request_manager_
->CreateRequest(
253 make_scoped_ptr
<RequestManager::HandlerInterface
>(
254 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
256 EXPECT_EQ(1, request_id
);
257 EXPECT_EQ(0u, logger
.success_events().size());
258 EXPECT_EQ(0u, logger
.error_events().size());
260 base::File::Error error
= base::File::FILE_ERROR_NO_MEMORY
;
261 bool result
= request_manager_
->RejectRequest(request_id
, error
);
264 // Validate if the callback has correct arguments.
265 ASSERT_EQ(1u, logger
.error_events().size());
266 EXPECT_EQ(0u, logger
.success_events().size());
267 EventLogger::ErrorEvent
* event
= logger
.error_events()[0];
268 EXPECT_EQ(error
, event
->error());
270 // Confirm, that the request is removed. Basically, fulfilling again for the
271 // same request, should fail.
273 scoped_ptr
<RequestValue
> response
;
274 bool has_next
= false;
276 request_manager_
->FulfillRequest(request_id
, response
.Pass(), has_next
);
280 // Rejecting should also fail.
282 bool retry
= request_manager_
->RejectRequest(request_id
, error
);
287 TEST_F(FileSystemProviderRequestManagerTest
,
288 CreateAndFulfillWithWrongRequestId
) {
291 const int request_id
= request_manager_
->CreateRequest(
292 make_scoped_ptr
<RequestManager::HandlerInterface
>(
293 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
295 EXPECT_EQ(1, request_id
);
296 EXPECT_EQ(0u, logger
.success_events().size());
297 EXPECT_EQ(0u, logger
.error_events().size());
299 base::File::Error error
= base::File::FILE_ERROR_NO_MEMORY
;
300 bool result
= request_manager_
->RejectRequest(request_id
+ 1, error
);
301 EXPECT_FALSE(result
);
303 // Callbacks should not be called.
304 EXPECT_EQ(0u, logger
.error_events().size());
305 EXPECT_EQ(0u, logger
.success_events().size());
307 // Confirm, that the request hasn't been removed, by rejecting it correctly.
309 bool retry
= request_manager_
->RejectRequest(request_id
, error
);
314 TEST_F(FileSystemProviderRequestManagerTest
,
315 CreateAndRejectWithWrongRequestId
) {
318 const int request_id
= request_manager_
->CreateRequest(
319 make_scoped_ptr
<RequestManager::HandlerInterface
>(
320 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
322 EXPECT_EQ(1, request_id
);
323 EXPECT_EQ(0u, logger
.success_events().size());
324 EXPECT_EQ(0u, logger
.error_events().size());
326 base::File::Error error
= base::File::FILE_ERROR_NO_MEMORY
;
327 bool result
= request_manager_
->RejectRequest(request_id
+ 1, error
);
328 EXPECT_FALSE(result
);
330 // Callbacks should not be called.
331 EXPECT_EQ(0u, logger
.error_events().size());
332 EXPECT_EQ(0u, logger
.success_events().size());
334 // Confirm, that the request hasn't been removed, by rejecting it correctly.
336 bool retry
= request_manager_
->RejectRequest(request_id
, error
);
341 TEST_F(FileSystemProviderRequestManagerTest
, UniqueIds
) {
344 const int first_request_id
= request_manager_
->CreateRequest(
345 make_scoped_ptr
<RequestManager::HandlerInterface
>(
346 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
348 const int second_request_id
= request_manager_
->CreateRequest(
349 make_scoped_ptr
<RequestManager::HandlerInterface
>(
350 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
352 EXPECT_EQ(1, first_request_id
);
353 EXPECT_EQ(2, second_request_id
);
356 TEST_F(FileSystemProviderRequestManagerTest
, AbortOnDestroy
) {
360 RequestManager request_manager
;
361 const int request_id
= request_manager
.CreateRequest(
362 make_scoped_ptr
<RequestManager::HandlerInterface
>(
363 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
365 EXPECT_EQ(1, request_id
);
366 EXPECT_EQ(0u, logger
.success_events().size());
367 EXPECT_EQ(0u, logger
.error_events().size());
370 // All active requests should be aborted in the destructor of RequestManager.
371 ASSERT_EQ(1u, logger
.error_events().size());
372 EventLogger::ErrorEvent
* event
= logger
.error_events()[0];
373 EXPECT_EQ(base::File::FILE_ERROR_ABORT
, event
->error());
375 EXPECT_EQ(0u, logger
.success_events().size());
378 TEST_F(FileSystemProviderRequestManagerTest
, AbortOnTimeout
) {
380 base::RunLoop run_loop
;
382 request_manager_
->SetTimeoutForTests(base::TimeDelta::FromSeconds(0));
383 const int request_id
= request_manager_
->CreateRequest(
384 make_scoped_ptr
<RequestManager::HandlerInterface
>(
385 new FakeHandler(logger
.GetWeakPtr(), true /* execute_reply */)));
386 EXPECT_LT(0, request_id
);
388 // Wait until the request is timeouted.
389 run_loop
.RunUntilIdle();
391 ASSERT_EQ(1u, logger
.error_events().size());
392 EventLogger::ErrorEvent
* event
= logger
.error_events()[0];
393 EXPECT_EQ(base::File::FILE_ERROR_ABORT
, event
->error());
396 } // namespace file_system_provider
397 } // namespace chromeos