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 void OnGetOriginUsageComplete(int64 usage) { |
| 135 ++num_get_origin_usage_completions_; |
| 136 usage_ = usage; |
| 137 } |
| 138 |
| 139 void OnGetOriginsComplete(const std::set<GURL>& origins) { |
| 140 ++num_get_origins_completions_; |
| 141 origins_ = origins; |
| 142 } |
| 143 |
| 144 void OnDeleteOriginDataComplete(quota::QuotaStatusCode status) { |
| 145 ++num_delete_origins_completions_; |
| 146 delete_status_ = status; |
| 147 } |
| 148 |
| 149 int64 usage_; |
| 150 std::set<GURL> origins_; |
| 151 quota::QuotaStatusCode delete_status_; |
| 152 int num_get_origin_usage_completions_; |
| 153 int num_get_origins_completions_; |
| 154 int num_delete_origins_completions_; |
| 155 MockAppCacheService mock_service_; |
| 156 base::ScopedCallbackFactory<AppCacheQuotaClientTest> callback_factory_; |
| 157 }; |
| 158 |
| 159 |
| 160 TEST_F(AppCacheQuotaClientTest, BasicCreateDestroy) { |
| 161 AppCacheQuotaClient* client = CreateClient(); |
| 162 Call_NotifyAppCacheReady(client); |
| 163 Call_OnQuotaManagerDestroyed(client); |
| 164 Call_NotifyAppCacheDestroyed(client); |
| 165 } |
| 166 |
| 167 TEST_F(AppCacheQuotaClientTest, EmptyService) { |
| 168 AppCacheQuotaClient* client = CreateClient(); |
| 169 Call_NotifyAppCacheReady(client); |
| 170 |
| 171 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kTemp)); |
| 172 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); |
| 173 EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); |
| 174 EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); |
| 175 EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty()); |
| 176 EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty()); |
| 177 EXPECT_EQ(quota::kQuotaStatusOk, DeleteOriginData(client, kTemp, kOriginA)); |
| 178 EXPECT_EQ(quota::kQuotaStatusOk, DeleteOriginData(client, kPerm, kOriginA)); |
| 179 |
| 180 Call_NotifyAppCacheDestroyed(client); |
| 181 Call_OnQuotaManagerDestroyed(client); |
| 182 } |
| 183 |
| 184 TEST_F(AppCacheQuotaClientTest, NoService) { |
| 185 AppCacheQuotaClient* client = CreateClient(); |
| 186 Call_NotifyAppCacheReady(client); |
| 187 Call_NotifyAppCacheDestroyed(client); |
| 188 |
| 189 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kTemp)); |
| 190 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); |
| 191 EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); |
| 192 EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); |
| 193 EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty()); |
| 194 EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty()); |
| 195 EXPECT_EQ(quota::kQuotaErrorAbort, |
| 196 DeleteOriginData(client, kTemp, kOriginA)); |
| 197 EXPECT_EQ(quota::kQuotaErrorAbort, |
| 198 DeleteOriginData(client, kPerm, kOriginA)); |
| 199 |
| 200 Call_OnQuotaManagerDestroyed(client); |
| 201 } |
| 202 |
| 203 TEST_F(AppCacheQuotaClientTest, GetOriginUsage) { |
| 204 AppCacheQuotaClient* client = CreateClient(); |
| 205 Call_NotifyAppCacheReady(client); |
| 206 |
| 207 SetUsageMapEntry(kOriginA, 1000); |
| 208 EXPECT_EQ(1000, GetOriginUsage(client, kOriginA, kTemp)); |
| 209 EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); |
| 210 |
| 211 Call_NotifyAppCacheDestroyed(client); |
| 212 Call_OnQuotaManagerDestroyed(client); |
| 213 } |
| 214 |
| 215 TEST_F(AppCacheQuotaClientTest, GetOriginsForHost) { |
| 216 AppCacheQuotaClient* client = CreateClient(); |
| 217 Call_NotifyAppCacheReady(client); |
| 218 |
| 219 EXPECT_EQ(kOriginA.host(), kOriginB.host()); |
| 220 EXPECT_NE(kOriginA.host(), kOriginOther.host()); |
| 221 |
| 222 std::set<GURL> origins = GetOriginsForHost(client, kTemp, kOriginA.host()); |
| 223 EXPECT_TRUE(origins.empty()); |
| 224 |
| 225 SetUsageMapEntry(kOriginA, 1000); |
| 226 SetUsageMapEntry(kOriginB, 10); |
| 227 SetUsageMapEntry(kOriginOther, 500); |
| 228 |
| 229 origins = GetOriginsForHost(client, kTemp, kOriginA.host()); |
| 230 EXPECT_EQ(2ul, origins.size()); |
| 231 EXPECT_TRUE(origins.find(kOriginA) != origins.end()); |
| 232 EXPECT_TRUE(origins.find(kOriginB) != origins.end()); |
| 233 |
| 234 origins = GetOriginsForHost(client, kTemp, kOriginOther.host()); |
| 235 EXPECT_EQ(1ul, origins.size()); |
| 236 EXPECT_TRUE(origins.find(kOriginOther) != origins.end()); |
| 237 |
| 238 origins = GetOriginsForHost(client, kPerm, kOriginA.host()); |
| 239 EXPECT_TRUE(origins.empty()); |
| 240 |
| 241 Call_NotifyAppCacheDestroyed(client); |
| 242 Call_OnQuotaManagerDestroyed(client); |
| 243 } |
| 244 |
| 245 TEST_F(AppCacheQuotaClientTest, GetOriginsForType) { |
| 246 AppCacheQuotaClient* client = CreateClient(); |
| 247 Call_NotifyAppCacheReady(client); |
| 248 |
| 249 EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); |
| 250 EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); |
| 251 |
| 252 SetUsageMapEntry(kOriginA, 1000); |
| 253 SetUsageMapEntry(kOriginB, 10); |
| 254 |
| 255 std::set<GURL> origins = GetOriginsForType(client, kTemp); |
| 256 EXPECT_EQ(2ul, origins.size()); |
| 257 EXPECT_TRUE(origins.find(kOriginA) != origins.end()); |
| 258 EXPECT_TRUE(origins.find(kOriginB) != origins.end()); |
| 259 |
| 260 EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); |
| 261 |
| 262 Call_NotifyAppCacheDestroyed(client); |
| 263 Call_OnQuotaManagerDestroyed(client); |
| 264 } |
| 265 |
| 266 TEST_F(AppCacheQuotaClientTest, DeleteOriginData) { |
| 267 AppCacheQuotaClient* client = CreateClient(); |
| 268 Call_NotifyAppCacheReady(client); |
| 269 |
| 270 // Perm deletions are short circuited in the Client and |
| 271 // should not reach the AppCacheService. |
| 272 EXPECT_EQ(quota::kQuotaStatusOk, |
| 273 DeleteOriginData(client, kPerm, kOriginA)); |
| 274 EXPECT_EQ(0, mock_service_.delete_called_count()); |
| 275 |
| 276 EXPECT_EQ(quota::kQuotaStatusOk, |
| 277 DeleteOriginData(client, kTemp, kOriginA)); |
| 278 EXPECT_EQ(1, mock_service_.delete_called_count()); |
| 279 |
| 280 mock_service_.set_mock_delete_appcaches_for_origin_result( |
| 281 net::ERR_ABORTED); |
| 282 EXPECT_EQ(quota::kQuotaErrorAbort, |
| 283 DeleteOriginData(client, kTemp, kOriginA)); |
| 284 EXPECT_EQ(2, mock_service_.delete_called_count()); |
| 285 |
| 286 Call_OnQuotaManagerDestroyed(client); |
| 287 Call_NotifyAppCacheDestroyed(client); |
| 288 } |
| 289 |
| 290 TEST_F(AppCacheQuotaClientTest, PendingRequests) { |
| 291 AppCacheQuotaClient* client = CreateClient(); |
| 292 |
| 293 SetUsageMapEntry(kOriginA, 1000); |
| 294 SetUsageMapEntry(kOriginB, 10); |
| 295 SetUsageMapEntry(kOriginOther, 500); |
| 296 |
| 297 // Queue up some reqeusts. |
| 298 AsyncGetOriginUsage(client, kOriginA, kPerm); |
| 299 AsyncGetOriginUsage(client, kOriginB, kTemp); |
| 300 AsyncGetOriginsForType(client, kPerm); |
| 301 AsyncGetOriginsForType(client, kTemp); |
| 302 AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); |
| 303 AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); |
| 304 AsyncDeleteOriginData(client, kTemp, kOriginA); |
| 305 AsyncDeleteOriginData(client, kPerm, kOriginA); |
| 306 AsyncDeleteOriginData(client, kTemp, kOriginB); |
| 307 |
| 308 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 309 EXPECT_EQ(0, num_get_origins_completions_); |
| 310 EXPECT_EQ(0, num_delete_origins_completions_); |
| 311 MessageLoop::current()->RunAllPending(); |
| 312 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 313 EXPECT_EQ(0, num_get_origins_completions_); |
| 314 EXPECT_EQ(0, num_delete_origins_completions_); |
| 315 |
| 316 // Pending requests should get serviced when the appcache is ready. |
| 317 Call_NotifyAppCacheReady(client); |
| 318 EXPECT_EQ(2, num_get_origin_usage_completions_); |
| 319 EXPECT_EQ(4, num_get_origins_completions_); |
| 320 EXPECT_EQ(0, num_delete_origins_completions_); |
| 321 MessageLoop::current()->RunAllPending(); |
| 322 EXPECT_EQ(3, num_delete_origins_completions_); // deletes are really async |
| 323 |
| 324 // They should be serviced in order requested. |
| 325 EXPECT_EQ(10, usage_); |
| 326 EXPECT_EQ(1ul, origins_.size()); |
| 327 EXPECT_TRUE(origins_.find(kOriginOther) != origins_.end()); |
| 328 |
| 329 Call_NotifyAppCacheDestroyed(client); |
| 330 Call_OnQuotaManagerDestroyed(client); |
| 331 } |
| 332 |
| 333 TEST_F(AppCacheQuotaClientTest, DestroyServiceWithPending) { |
| 334 AppCacheQuotaClient* client = CreateClient(); |
| 335 |
| 336 SetUsageMapEntry(kOriginA, 1000); |
| 337 SetUsageMapEntry(kOriginB, 10); |
| 338 SetUsageMapEntry(kOriginOther, 500); |
| 339 |
| 340 // Queue up some reqeusts prior to being ready. |
| 341 AsyncGetOriginUsage(client, kOriginA, kPerm); |
| 342 AsyncGetOriginUsage(client, kOriginB, kTemp); |
| 343 AsyncGetOriginsForType(client, kPerm); |
| 344 AsyncGetOriginsForType(client, kTemp); |
| 345 AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); |
| 346 AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); |
| 347 AsyncDeleteOriginData(client, kTemp, kOriginA); |
| 348 AsyncDeleteOriginData(client, kPerm, kOriginA); |
| 349 AsyncDeleteOriginData(client, kTemp, kOriginB); |
| 350 MessageLoop::current()->RunAllPending(); |
| 351 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 352 EXPECT_EQ(0, num_get_origins_completions_); |
| 353 EXPECT_EQ(0, num_delete_origins_completions_); |
| 354 |
| 355 // Kill the service. |
| 356 Call_NotifyAppCacheDestroyed(client); |
| 357 |
| 358 // All should have been aborted and called completion. |
| 359 EXPECT_EQ(2, num_get_origin_usage_completions_); |
| 360 EXPECT_EQ(4, num_get_origins_completions_); |
| 361 EXPECT_EQ(3, num_delete_origins_completions_); |
| 362 EXPECT_EQ(0, usage_); |
| 363 EXPECT_TRUE(origins_.empty()); |
| 364 EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); |
| 365 |
| 366 Call_OnQuotaManagerDestroyed(client); |
| 367 } |
| 368 |
| 369 TEST_F(AppCacheQuotaClientTest, DestroyQuotaManagerWithPending) { |
| 370 AppCacheQuotaClient* client = CreateClient(); |
| 371 |
| 372 SetUsageMapEntry(kOriginA, 1000); |
| 373 SetUsageMapEntry(kOriginB, 10); |
| 374 SetUsageMapEntry(kOriginOther, 500); |
| 375 |
| 376 // Queue up some reqeusts prior to being ready. |
| 377 AsyncGetOriginUsage(client, kOriginA, kPerm); |
| 378 AsyncGetOriginUsage(client, kOriginB, kTemp); |
| 379 AsyncGetOriginsForType(client, kPerm); |
| 380 AsyncGetOriginsForType(client, kTemp); |
| 381 AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); |
| 382 AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); |
| 383 AsyncDeleteOriginData(client, kTemp, kOriginA); |
| 384 AsyncDeleteOriginData(client, kPerm, kOriginA); |
| 385 AsyncDeleteOriginData(client, kTemp, kOriginB); |
| 386 MessageLoop::current()->RunAllPending(); |
| 387 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 388 EXPECT_EQ(0, num_get_origins_completions_); |
| 389 EXPECT_EQ(0, num_delete_origins_completions_); |
| 390 |
| 391 // Kill the quota manager. |
| 392 Call_OnQuotaManagerDestroyed(client); |
| 393 Call_NotifyAppCacheReady(client); |
| 394 |
| 395 // Callbacks should be deleted and not called. |
| 396 MessageLoop::current()->RunAllPending(); |
| 397 EXPECT_EQ(0, num_get_origin_usage_completions_); |
| 398 EXPECT_EQ(0, num_get_origins_completions_); |
| 399 EXPECT_EQ(0, num_delete_origins_completions_); |
| 400 |
| 401 Call_NotifyAppCacheDestroyed(client); |
| 402 } |
| 403 |
| 404 TEST_F(AppCacheQuotaClientTest, DestroyWithDeleteInProgress) { |
| 405 AppCacheQuotaClient* client = CreateClient(); |
| 406 Call_NotifyAppCacheReady(client); |
| 407 |
| 408 // Start an async delete. |
| 409 AsyncDeleteOriginData(client, kTemp, kOriginB); |
| 410 EXPECT_EQ(0, num_delete_origins_completions_); |
| 411 |
| 412 // Kill the service. |
| 413 Call_NotifyAppCacheDestroyed(client); |
| 414 |
| 415 // Should have been aborted. |
| 416 EXPECT_EQ(1, num_delete_origins_completions_); |
| 417 EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); |
| 418 |
| 419 // A real completion callback from the service should |
| 420 // be dropped if it comes in after NotifyAppCacheDestroyed. |
| 421 MessageLoop::current()->RunAllPending(); |
| 422 EXPECT_EQ(1, num_delete_origins_completions_); |
| 423 EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); |
| 424 } |
| 425 |
| 426 } // namespace appcache |
OLD | NEW |