OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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 <map> |
| 6 |
| 7 #include "base/memory/scoped_callback_factory.h" |
| 8 #include "base/message_loop.h" |
| 9 #include "base/message_loop_proxy.h" |
| 10 #include "net/base/net_errors.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 #include "webkit/appcache/appcache_quota_client.h" |
| 13 #include "webkit/appcache/mock_appcache_service.h" |
| 14 |
| 15 namespace appcache { |
| 16 |
| 17 // Declared to shorten the line lengths. |
| 18 static const quota::StorageType kTemp = quota::kStorageTypeTemporary; |
| 19 static const quota::StorageType kPerm = quota::kStorageTypePersistent; |
| 20 |
| 21 // Base class for our test fixtures. |
| 22 class AppCacheQuotaClientTest : public testing::Test { |
| 23 public: |
| 24 const GURL kOriginA; |
| 25 const GURL kOriginB; |
| 26 const GURL kOriginOther; |
| 27 |
| 28 AppCacheQuotaClientTest() |
| 29 : kOriginA("http://host"), |
| 30 kOriginB("http://host:8000"), |
| 31 kOriginOther("http://other"), |
| 32 usage_(0), |
| 33 delete_status_(quota::kQuotaStatusUnknown), |
| 34 num_get_origin_usage_completions_(0), |
| 35 num_get_origins_completions_(0), |
| 36 num_delete_origins_completions_(0), |
| 37 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 38 } |
| 39 |
| 40 int64 GetOriginUsage( |
| 41 quota::QuotaClient* client, |
| 42 const GURL& origin, |
| 43 quota::StorageType type) { |
| 44 usage_ = -1; |
| 45 AsyncGetOriginUsage(client, origin, type); |
| 46 MessageLoop::current()->RunAllPending(); |
| 47 return usage_; |
| 48 } |
| 49 |
| 50 const std::set<GURL>& GetOriginsForType( |
| 51 quota::QuotaClient* client, |
| 52 quota::StorageType type) { |
| 53 origins_.clear(); |
| 54 AsyncGetOriginsForType(client, type); |
| 55 MessageLoop::current()->RunAllPending(); |
| 56 return origins_; |
| 57 } |
| 58 |
| 59 const std::set<GURL>& GetOriginsForHost( |
| 60 quota::QuotaClient* client, |
| 61 quota::StorageType type, |
| 62 const std::string& host) { |
| 63 origins_.clear(); |
| 64 AsyncGetOriginsForHost(client, type, host); |
| 65 MessageLoop::current()->RunAllPending(); |
| 66 return origins_; |
| 67 } |
| 68 |
| 69 quota::QuotaStatusCode DeleteOriginData( |
| 70 quota::QuotaClient* client, |
| 71 quota::StorageType type, |
| 72 const GURL& origin) { |
| 73 delete_status_ = quota::kQuotaStatusUnknown; |
| 74 AsyncDeleteOriginData(client, type, origin); |
| 75 MessageLoop::current()->RunAllPending(); |
| 76 return delete_status_; |
| 77 } |
| 78 |
| 79 void AsyncGetOriginUsage( |
| 80 quota::QuotaClient* client, |
| 81 const GURL& origin, |
| 82 quota::StorageType type) { |
| 83 client->GetOriginUsage(origin, type, |
| 84 callback_factory_.NewCallback( |
| 85 &AppCacheQuotaClientTest::OnGetOriginUsageComplete)); |
| 86 } |
| 87 |
| 88 void AsyncGetOriginsForType( |
| 89 quota::QuotaClient* client, |
| 90 quota::StorageType type) { |
| 91 client->GetOriginsForType(type, |
| 92 callback_factory_.NewCallback( |
| 93 &AppCacheQuotaClientTest::OnGetOriginsComplete)); |
| 94 } |
| 95 |
| 96 void AsyncGetOriginsForHost( |
| 97 quota::QuotaClient* client, |
| 98 quota::StorageType type, |
| 99 const std::string& host) { |
| 100 client->GetOriginsForHost(type, host, |
| 101 callback_factory_.NewCallback( |
| 102 &AppCacheQuotaClientTest::OnGetOriginsComplete)); |
| 103 } |
| 104 |
| 105 void AsyncDeleteOriginData( |
| 106 quota::QuotaClient* client, |
| 107 quota::StorageType type, |
| 108 const GURL& origin) { |
| 109 client->DeleteOriginData(origin, type, |
| 110 callback_factory_.NewCallback( |
| 111 &AppCacheQuotaClientTest::OnDeleteOriginDataComplete)); |
| 112 } |
| 113 |
| 114 void SetUsageMapEntry(const GURL& origin, int64 usage) { |
| 115 mock_service_.storage()->usage_map_[origin] = usage; |
| 116 } |
| 117 |
| 118 AppCacheQuotaClient* CreateClient() { |
| 119 return new AppCacheQuotaClient(&mock_service_); |
| 120 } |
| 121 |
| 122 void Call_NotifyAppCacheReady(AppCacheQuotaClient* client) { |
| 123 client->NotifyAppCacheReady(); |
| 124 } |
| 125 |
| 126 void Call_NotifyAppCacheDestroyed(AppCacheQuotaClient* client) { |
| 127 client->NotifyAppCacheDestroyed(); |
| 128 } |
| 129 |
| 130 void Call_OnQuotaManagerDestroyed(AppCacheQuotaClient* client) { |
| 131 client->OnQuotaManagerDestroyed(); |
| 132 } |
| 133 |
| 134 protected: |
| 135 void OnGetOriginUsageComplete(int64 usage) { |
| 136 ++num_get_origin_usage_completions_; |
| 137 usage_ = usage; |
| 138 } |
| 139 |
| 140 void OnGetOriginsComplete(const std::set<GURL>& origins) { |
| 141 ++num_get_origins_completions_; |
| 142 origins_ = origins; |
| 143 } |
| 144 |
| 145 void OnDeleteOriginDataComplete(quota::QuotaStatusCode status) { |
| 146 ++num_delete_origins_completions_; |
| 147 delete_status_ = status; |
| 148 } |
| 149 |
| 150 int64 usage_; |
| 151 std::set<GURL> origins_; |
| 152 quota::QuotaStatusCode delete_status_; |
| 153 int num_get_origin_usage_completions_; |
| 154 int num_get_origins_completions_; |
| 155 int num_delete_origins_completions_; |
| 156 MockAppCacheService mock_service_; |
| 157 base::ScopedCallbackFactory<AppCacheQuotaClientTest> callback_factory_; |
| 158 }; |
| 159 |
| 160 |
| 161 TEST_F(AppCacheQuotaClientTest, BasicCreateDestroy) { |
| 162 AppCacheQuotaClient* client = CreateClient(); |
| 163 Call_NotifyAppCacheReady(client); |
| 164 Call_OnQuotaManagerDestroyed(client); |
| 165 Call_NotifyAppCacheDestroyed(client); |
| 166 } |
| 167 |
| 168 TEST_F(AppCacheQuotaClientTest, EmptyService) { |
| 169 AppCacheQuotaClient* client = CreateClient(); |
| 170 Call_NotifyAppCacheReady(client); |
| 171 |
| 172 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kTemp)); |
| 173 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); |
| 174 EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); |
| 175 EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); |
| 176 EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty()); |
| 177 EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty()); |
| 178 EXPECT_EQ(quota::kQuotaStatusOk, DeleteOriginData(client, kTemp, kOriginA)); |
| 179 EXPECT_EQ(quota::kQuotaStatusOk, DeleteOriginData(client, kPerm, kOriginA)); |
| 180 |
| 181 Call_NotifyAppCacheDestroyed(client); |
| 182 Call_OnQuotaManagerDestroyed(client); |
| 183 } |
| 184 |
| 185 TEST_F(AppCacheQuotaClientTest, NoService) { |
| 186 AppCacheQuotaClient* client = CreateClient(); |
| 187 Call_NotifyAppCacheReady(client); |
| 188 Call_NotifyAppCacheDestroyed(client); |
| 189 |
| 190 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kTemp)); |
| 191 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); |
| 192 EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); |
| 193 EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); |
| 194 EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty()); |
| 195 EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty()); |
| 196 EXPECT_EQ(quota::kQuotaErrorAbort, |
| 197 DeleteOriginData(client, kTemp, kOriginA)); |
| 198 EXPECT_EQ(quota::kQuotaErrorAbort, |
| 199 DeleteOriginData(client, kPerm, kOriginA)); |
| 200 |
| 201 Call_OnQuotaManagerDestroyed(client); |
| 202 } |
| 203 |
| 204 TEST_F(AppCacheQuotaClientTest, GetOriginUsage) { |
| 205 AppCacheQuotaClient* client = CreateClient(); |
| 206 Call_NotifyAppCacheReady(client); |
| 207 |
| 208 SetUsageMapEntry(kOriginA, 1000); |
| 209 EXPECT_EQ(1000, GetOriginUsage(client, kOriginA, kTemp)); |
| 210 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); |
| 211 |
| 212 Call_NotifyAppCacheDestroyed(client); |
| 213 Call_OnQuotaManagerDestroyed(client); |
| 214 } |
| 215 |
| 216 TEST_F(AppCacheQuotaClientTest, GetOriginsForHost) { |
| 217 AppCacheQuotaClient* client = CreateClient(); |
| 218 Call_NotifyAppCacheReady(client); |
| 219 |
| 220 EXPECT_EQ(kOriginA.host(), kOriginB.host()); |
| 221 EXPECT_NE(kOriginA.host(), kOriginOther.host()); |
| 222 |
| 223 std::set<GURL> origins = GetOriginsForHost(client, kTemp, kOriginA.host()); |
| 224 EXPECT_TRUE(origins.empty()); |
| 225 |
| 226 SetUsageMapEntry(kOriginA, 1000); |
| 227 SetUsageMapEntry(kOriginB, 10); |
| 228 SetUsageMapEntry(kOriginOther, 500); |
| 229 |
| 230 origins = GetOriginsForHost(client, kTemp, kOriginA.host()); |
| 231 EXPECT_EQ(2ul, origins.size()); |
| 232 EXPECT_TRUE(origins.find(kOriginA) != origins.end()); |
| 233 EXPECT_TRUE(origins.find(kOriginB) != origins.end()); |
| 234 |
| 235 origins = GetOriginsForHost(client, kTemp, kOriginOther.host()); |
| 236 EXPECT_EQ(1ul, origins.size()); |
| 237 EXPECT_TRUE(origins.find(kOriginOther) != origins.end()); |
| 238 |
| 239 origins = GetOriginsForHost(client, kPerm, kOriginA.host()); |
| 240 EXPECT_TRUE(origins.empty()); |
| 241 |
| 242 Call_NotifyAppCacheDestroyed(client); |
| 243 Call_OnQuotaManagerDestroyed(client); |
| 244 } |
| 245 |
| 246 TEST_F(AppCacheQuotaClientTest, GetOriginsForType) { |
| 247 AppCacheQuotaClient* client = CreateClient(); |
| 248 Call_NotifyAppCacheReady(client); |
| 249 |
| 250 EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); |
| 251 EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); |
| 252 |
| 253 SetUsageMapEntry(kOriginA, 1000); |
| 254 SetUsageMapEntry(kOriginB, 10); |
| 255 |
| 256 std::set<GURL> origins = GetOriginsForType(client, kTemp); |
| 257 EXPECT_EQ(2ul, origins.size()); |
| 258 EXPECT_TRUE(origins.find(kOriginA) != origins.end()); |
| 259 EXPECT_TRUE(origins.find(kOriginB) != origins.end()); |
| 260 |
| 261 EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); |
| 262 |
| 263 Call_NotifyAppCacheDestroyed(client); |
| 264 Call_OnQuotaManagerDestroyed(client); |
| 265 } |
| 266 |
| 267 TEST_F(AppCacheQuotaClientTest, DeleteOriginData) { |
| 268 AppCacheQuotaClient* client = CreateClient(); |
| 269 Call_NotifyAppCacheReady(client); |
| 270 |
| 271 // Perm deletions are short circuited in the Client and |
| 272 // should not reach the AppCacheService. |
| 273 EXPECT_EQ(quota::kQuotaStatusOk, |
| 274 DeleteOriginData(client, kPerm, kOriginA)); |
| 275 EXPECT_EQ(0, mock_service_.delete_called_count()); |
| 276 |
| 277 EXPECT_EQ(quota::kQuotaStatusOk, |
| 278 DeleteOriginData(client, kTemp, kOriginA)); |
| 279 EXPECT_EQ(1, mock_service_.delete_called_count()); |
| 280 |
| 281 mock_service_.set_mock_delete_appcaches_for_origin_result( |
| 282 net::ERR_ABORTED); |
| 283 EXPECT_EQ(quota::kQuotaErrorAbort, |
| 284 DeleteOriginData(client, kTemp, kOriginA)); |
| 285 EXPECT_EQ(2, mock_service_.delete_called_count()); |
| 286 |
| 287 Call_OnQuotaManagerDestroyed(client); |
| 288 Call_NotifyAppCacheDestroyed(client); |
| 289 } |
| 290 |
| 291 TEST_F(AppCacheQuotaClientTest, PendingRequests) { |
| 292 AppCacheQuotaClient* client = CreateClient(); |
| 293 |
| 294 SetUsageMapEntry(kOriginA, 1000); |
| 295 SetUsageMapEntry(kOriginB, 10); |
| 296 SetUsageMapEntry(kOriginOther, 500); |
| 297 |
| 298 // Queue up some reqeusts. |
| 299 AsyncGetOriginUsage(client, kOriginA, kPerm); |
| 300 AsyncGetOriginUsage(client, kOriginB, kTemp); |
| 301 AsyncGetOriginsForType(client, kPerm); |
| 302 AsyncGetOriginsForType(client, kTemp); |
| 303 AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); |
| 304 AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); |
| 305 AsyncDeleteOriginData(client, kTemp, kOriginA); |
| 306 AsyncDeleteOriginData(client, kPerm, kOriginA); |
| 307 AsyncDeleteOriginData(client, kTemp, kOriginB); |
| 308 |
| 309 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 310 EXPECT_EQ(0, num_get_origins_completions_); |
| 311 EXPECT_EQ(0, num_delete_origins_completions_); |
| 312 MessageLoop::current()->RunAllPending(); |
| 313 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 314 EXPECT_EQ(0, num_get_origins_completions_); |
| 315 EXPECT_EQ(0, num_delete_origins_completions_); |
| 316 |
| 317 // Pending requests should get serviced when the appcache is ready. |
| 318 Call_NotifyAppCacheReady(client); |
| 319 EXPECT_EQ(2, num_get_origin_usage_completions_); |
| 320 EXPECT_EQ(4, num_get_origins_completions_); |
| 321 EXPECT_EQ(0, num_delete_origins_completions_); |
| 322 MessageLoop::current()->RunAllPending(); |
| 323 EXPECT_EQ(3, num_delete_origins_completions_); // deletes are really async |
| 324 |
| 325 // They should be serviced in order requested. |
| 326 EXPECT_EQ(10, usage_); |
| 327 EXPECT_EQ(1ul, origins_.size()); |
| 328 EXPECT_TRUE(origins_.find(kOriginOther) != origins_.end()); |
| 329 |
| 330 Call_NotifyAppCacheDestroyed(client); |
| 331 Call_OnQuotaManagerDestroyed(client); |
| 332 } |
| 333 |
| 334 TEST_F(AppCacheQuotaClientTest, DestroyServiceWithPending) { |
| 335 AppCacheQuotaClient* client = CreateClient(); |
| 336 |
| 337 SetUsageMapEntry(kOriginA, 1000); |
| 338 SetUsageMapEntry(kOriginB, 10); |
| 339 SetUsageMapEntry(kOriginOther, 500); |
| 340 |
| 341 // Queue up some reqeusts prior to being ready. |
| 342 AsyncGetOriginUsage(client, kOriginA, kPerm); |
| 343 AsyncGetOriginUsage(client, kOriginB, kTemp); |
| 344 AsyncGetOriginsForType(client, kPerm); |
| 345 AsyncGetOriginsForType(client, kTemp); |
| 346 AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); |
| 347 AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); |
| 348 AsyncDeleteOriginData(client, kTemp, kOriginA); |
| 349 AsyncDeleteOriginData(client, kPerm, kOriginA); |
| 350 AsyncDeleteOriginData(client, kTemp, kOriginB); |
| 351 MessageLoop::current()->RunAllPending(); |
| 352 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 353 EXPECT_EQ(0, num_get_origins_completions_); |
| 354 EXPECT_EQ(0, num_delete_origins_completions_); |
| 355 |
| 356 // Kill the service. |
| 357 Call_NotifyAppCacheDestroyed(client); |
| 358 |
| 359 // All should have been aborted and called completion. |
| 360 EXPECT_EQ(2, num_get_origin_usage_completions_); |
| 361 EXPECT_EQ(4, num_get_origins_completions_); |
| 362 EXPECT_EQ(3, num_delete_origins_completions_); |
| 363 EXPECT_EQ(0, usage_); |
| 364 EXPECT_TRUE(origins_.empty()); |
| 365 EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); |
| 366 |
| 367 Call_OnQuotaManagerDestroyed(client); |
| 368 } |
| 369 |
| 370 TEST_F(AppCacheQuotaClientTest, DestroyQuotaManagerWithPending) { |
| 371 AppCacheQuotaClient* client = CreateClient(); |
| 372 |
| 373 SetUsageMapEntry(kOriginA, 1000); |
| 374 SetUsageMapEntry(kOriginB, 10); |
| 375 SetUsageMapEntry(kOriginOther, 500); |
| 376 |
| 377 // Queue up some reqeusts prior to being ready. |
| 378 AsyncGetOriginUsage(client, kOriginA, kPerm); |
| 379 AsyncGetOriginUsage(client, kOriginB, kTemp); |
| 380 AsyncGetOriginsForType(client, kPerm); |
| 381 AsyncGetOriginsForType(client, kTemp); |
| 382 AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); |
| 383 AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); |
| 384 AsyncDeleteOriginData(client, kTemp, kOriginA); |
| 385 AsyncDeleteOriginData(client, kPerm, kOriginA); |
| 386 AsyncDeleteOriginData(client, kTemp, kOriginB); |
| 387 MessageLoop::current()->RunAllPending(); |
| 388 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 389 EXPECT_EQ(0, num_get_origins_completions_); |
| 390 EXPECT_EQ(0, num_delete_origins_completions_); |
| 391 |
| 392 // Kill the quota manager. |
| 393 Call_OnQuotaManagerDestroyed(client); |
| 394 Call_NotifyAppCacheReady(client); |
| 395 |
| 396 // Callbacks should be deleted and not called. |
| 397 MessageLoop::current()->RunAllPending(); |
| 398 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 399 EXPECT_EQ(0, num_get_origins_completions_); |
| 400 EXPECT_EQ(0, num_delete_origins_completions_); |
| 401 |
| 402 Call_NotifyAppCacheDestroyed(client); |
| 403 } |
| 404 |
| 405 TEST_F(AppCacheQuotaClientTest, DestroyWithDeleteInProgress) { |
| 406 AppCacheQuotaClient* client = CreateClient(); |
| 407 Call_NotifyAppCacheReady(client); |
| 408 |
| 409 // Start an async delete. |
| 410 AsyncDeleteOriginData(client, kTemp, kOriginB); |
| 411 EXPECT_EQ(0, num_delete_origins_completions_); |
| 412 |
| 413 // Kill the service. |
| 414 Call_NotifyAppCacheDestroyed(client); |
| 415 |
| 416 // Should have been aborted. |
| 417 EXPECT_EQ(1, num_delete_origins_completions_); |
| 418 EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); |
| 419 |
| 420 // A real completion callback from the service should |
| 421 // be dropped if it comes in after NotifyAppCacheDestroyed. |
| 422 MessageLoop::current()->RunAllPending(); |
| 423 EXPECT_EQ(1, num_delete_origins_completions_); |
| 424 EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); |
| 425 |
| 426 Call_OnQuotaManagerDestroyed(client); |
| 427 } |
| 428 |
| 429 } // namespace appcache |
OLD | NEW |