request_manager_unittest.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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. 4 5#include <string> 6 7#include "base/bind.h" 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 "base/values.h" 16#include "chrome/browser/chromeos/file_system_provider/request_manager.h" 17#include "content/public/test/test_browser_thread_bundle.h" 18#include "testing/gtest/include/gtest/gtest.h" 19 20namespace chromeos { 21namespace file_system_provider { 22namespace { 23 24// Logs calls of the success and error callbacks on requests. 25class EventLogger { 26 public: 27 class SuccessEvent { 28 public: 29 SuccessEvent(scoped_ptr<base::DictionaryValue> result, bool has_next) 30 : result_(result.Pass()), has_next_(has_next) {} 31 ~SuccessEvent() {} 32 33 base::DictionaryValue* result() { return result_.get(); } 34 bool has_next() { return has_next_; } 35 36 private: 37 scoped_ptr<base::DictionaryValue> result_; 38 bool has_next_; 39 }; 40 41 class ErrorEvent { 42 public: 43 explicit ErrorEvent(base::File::Error error) : error_(error) {} 44 ~ErrorEvent() {} 45 46 base::File::Error error() { return error_; } 47 48 private: 49 base::File::Error error_; 50 }; 51 52 EventLogger() : weak_ptr_factory_(this) {} 53 virtual ~EventLogger() {} 54 55 void OnSuccess(scoped_ptr<base::DictionaryValue> result, bool has_next) { 56 success_events_.push_back(new SuccessEvent(result.Pass(), has_next)); 57 } 58 59 void OnError(base::File::Error error) { 60 error_events_.push_back(new ErrorEvent(error)); 61 } 62 63 ScopedVector<SuccessEvent>& success_events() { return success_events_; } 64 ScopedVector<ErrorEvent>& error_events() { return error_events_; } 65 66 base::WeakPtr<EventLogger> GetWeakPtr() { 67 return weak_ptr_factory_.GetWeakPtr(); 68 } 69 70 private: 71 ScopedVector<SuccessEvent> success_events_; 72 ScopedVector<ErrorEvent> error_events_; 73 base::WeakPtrFactory<EventLogger> weak_ptr_factory_; 74}; 75 76} // namespace 77 78class FileSystemProviderRequestManagerTest : public testing::Test { 79 protected: 80 FileSystemProviderRequestManagerTest() {} 81 virtual ~FileSystemProviderRequestManagerTest() {} 82 83 virtual void SetUp() OVERRIDE { 84 request_manager_.reset(new RequestManager()); 85 } 86 87 content::TestBrowserThreadBundle thread_bundle_; 88 scoped_ptr<RequestManager> request_manager_; 89}; 90 91TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill) { 92 EventLogger logger; 93 94 int request_id = request_manager_->CreateRequest( 95 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 96 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 97 98 EXPECT_EQ(1, request_id); 99 EXPECT_EQ(0u, logger.success_events().size()); 100 EXPECT_EQ(0u, logger.error_events().size()); 101 102 scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue()); 103 const bool has_next = false; 104 response->SetString("path", "i-like-vanilla"); 105 106 bool result = 107 request_manager_->FulfillRequest(request_id, response.Pass(), has_next); 108 EXPECT_TRUE(result); 109 110 // Validate if the callback has correct arguments. 111 ASSERT_EQ(1u, logger.success_events().size()); 112 EXPECT_EQ(0u, logger.error_events().size()); 113 EventLogger::SuccessEvent* event = logger.success_events()[0]; 114 ASSERT_TRUE(event->result()); 115 std::string response_test_string; 116 EXPECT_TRUE(event->result()->GetString("path", &response_test_string)); 117 EXPECT_EQ("i-like-vanilla", response_test_string); 118 EXPECT_FALSE(event->has_next()); 119 120 // Confirm, that the request is removed. Basically, fulfilling again for the 121 // same request, should fail. 122 { 123 scoped_ptr<base::DictionaryValue> response; 124 bool retry = 125 request_manager_->FulfillRequest(request_id, response.Pass(), has_next); 126 EXPECT_FALSE(retry); 127 } 128 129 // Rejecting should also fail. 130 { 131 bool retry = request_manager_->RejectRequest(request_id, 132 base::File::FILE_ERROR_FAILED); 133 EXPECT_FALSE(retry); 134 } 135} 136 137TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill_WithHasNext) { 138 EventLogger logger; 139 140 int request_id = request_manager_->CreateRequest( 141 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 142 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 143 144 EXPECT_EQ(1, request_id); 145 EXPECT_EQ(0u, logger.success_events().size()); 146 EXPECT_EQ(0u, logger.error_events().size()); 147 148 scoped_ptr<base::DictionaryValue> response; 149 const bool has_next = true; 150 151 bool result = 152 request_manager_->FulfillRequest(request_id, response.Pass(), has_next); 153 EXPECT_TRUE(result); 154 155 // Validate if the callback has correct arguments. 156 ASSERT_EQ(1u, logger.success_events().size()); 157 EXPECT_EQ(0u, logger.error_events().size()); 158 EventLogger::SuccessEvent* event = logger.success_events()[0]; 159 EXPECT_FALSE(event->result()); 160 EXPECT_TRUE(event->has_next()); 161 162 // Confirm, that the request is not removed (since it has has_next == true). 163 // Basically, fulfilling again for the same request, should not fail. 164 { 165 bool new_has_next = false; 166 bool retry = request_manager_->FulfillRequest( 167 request_id, response.Pass(), new_has_next); 168 EXPECT_TRUE(retry); 169 } 170 171 // Since |new_has_next| is false, then the request should be removed. To check 172 // it, try to fulfill again, what should fail. 173 { 174 bool new_has_next = false; 175 bool retry = request_manager_->FulfillRequest( 176 request_id, response.Pass(), new_has_next); 177 EXPECT_FALSE(retry); 178 } 179} 180 181TEST_F(FileSystemProviderRequestManagerTest, CreateAndReject) { 182 EventLogger logger; 183 184 int request_id = request_manager_->CreateRequest( 185 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 186 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 187 188 EXPECT_EQ(1, request_id); 189 EXPECT_EQ(0u, logger.success_events().size()); 190 EXPECT_EQ(0u, logger.error_events().size()); 191 192 base::File::Error error = base::File::FILE_ERROR_NO_MEMORY; 193 bool result = request_manager_->RejectRequest(request_id, error); 194 EXPECT_TRUE(result); 195 196 // Validate if the callback has correct arguments. 197 ASSERT_EQ(1u, logger.error_events().size()); 198 EXPECT_EQ(0u, logger.success_events().size()); 199 EventLogger::ErrorEvent* event = logger.error_events()[0]; 200 EXPECT_EQ(error, event->error()); 201 202 // Confirm, that the request is removed. Basically, fulfilling again for the 203 // same request, should fail. 204 { 205 scoped_ptr<base::DictionaryValue> response; 206 bool has_next = false; 207 bool retry = 208 request_manager_->FulfillRequest(request_id, response.Pass(), has_next); 209 EXPECT_FALSE(retry); 210 } 211 212 // Rejecting should also fail. 213 { 214 bool retry = request_manager_->RejectRequest(request_id, error); 215 EXPECT_FALSE(retry); 216 } 217} 218 219TEST_F(FileSystemProviderRequestManagerTest, 220 CreateAndFulfillWithWrongRequestId) { 221 EventLogger logger; 222 223 int request_id = request_manager_->CreateRequest( 224 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 225 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 226 227 EXPECT_EQ(1, request_id); 228 EXPECT_EQ(0u, logger.success_events().size()); 229 EXPECT_EQ(0u, logger.error_events().size()); 230 231 base::File::Error error = base::File::FILE_ERROR_NO_MEMORY; 232 bool result = request_manager_->RejectRequest(request_id + 1, error); 233 EXPECT_FALSE(result); 234 235 // Callbacks should not be called. 236 EXPECT_EQ(0u, logger.error_events().size()); 237 EXPECT_EQ(0u, logger.success_events().size()); 238 239 // Confirm, that the request hasn't been removed, by rejecting it correctly. 240 { 241 bool retry = request_manager_->RejectRequest(request_id, error); 242 EXPECT_TRUE(retry); 243 } 244} 245 246TEST_F(FileSystemProviderRequestManagerTest, 247 CreateAndRejectWithWrongRequestId) { 248 EventLogger logger; 249 250 int request_id = request_manager_->CreateRequest( 251 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 252 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 253 254 EXPECT_EQ(1, request_id); 255 EXPECT_EQ(0u, logger.success_events().size()); 256 EXPECT_EQ(0u, logger.error_events().size()); 257 258 base::File::Error error = base::File::FILE_ERROR_NO_MEMORY; 259 bool result = request_manager_->RejectRequest(request_id + 1, error); 260 EXPECT_FALSE(result); 261 262 // Callbacks should not be called. 263 EXPECT_EQ(0u, logger.error_events().size()); 264 EXPECT_EQ(0u, logger.success_events().size()); 265 266 // Confirm, that the request hasn't been removed, by rejecting it correctly. 267 { 268 bool retry = request_manager_->RejectRequest(request_id, error); 269 EXPECT_TRUE(retry); 270 } 271} 272 273TEST_F(FileSystemProviderRequestManagerTest, UniqueIds) { 274 EventLogger logger; 275 276 int first_request_id = request_manager_->CreateRequest( 277 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 278 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 279 280 int second_request_id = request_manager_->CreateRequest( 281 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 282 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 283 284 EXPECT_EQ(1, first_request_id); 285 EXPECT_EQ(2, second_request_id); 286} 287 288TEST_F(FileSystemProviderRequestManagerTest, AbortOnDestroy) { 289 EventLogger logger; 290 291 { 292 RequestManager request_manager; 293 int request_id = request_manager.CreateRequest( 294 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 295 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 296 297 EXPECT_EQ(1, request_id); 298 EXPECT_EQ(0u, logger.success_events().size()); 299 EXPECT_EQ(0u, logger.error_events().size()); 300 } 301 302 // All active requests should be aborted in the destructor of RequestManager. 303 EventLogger::ErrorEvent* event = logger.error_events()[0]; 304 ASSERT_EQ(1u, logger.error_events().size()); 305 EXPECT_EQ(base::File::FILE_ERROR_ABORT, event->error()); 306 307 EXPECT_EQ(0u, logger.success_events().size()); 308} 309 310TEST_F(FileSystemProviderRequestManagerTest, AbortOnTimeout) { 311 EventLogger logger; 312 base::RunLoop run_loop; 313 314 request_manager_->SetTimeoutForTests(base::TimeDelta::FromSeconds(0)); 315 int request_id = request_manager_->CreateRequest( 316 base::Bind(&EventLogger::OnSuccess, logger.GetWeakPtr()), 317 base::Bind(&EventLogger::OnError, logger.GetWeakPtr())); 318 EXPECT_LT(0, request_id); 319 320 // Wait until the request is timeouted. 321 run_loop.RunUntilIdle(); 322 323 ASSERT_EQ(1u, logger.error_events().size()); 324 EventLogger::ErrorEvent* event = logger.error_events()[0]; 325 EXPECT_EQ(base::File::FILE_ERROR_ABORT, event->error()); 326} 327 328} // namespace file_system_provider 329} // namespace chromeos 330