TestQuotaManager.cpp (145216B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "QuotaManagerDependencyFixture.h" 8 #include "QuotaManagerTestHelpers.h" 9 #include "gtest/gtest.h" 10 #include "mozilla/BasePrincipal.h" 11 #include "mozilla/dom/quota/ClientDirectoryLock.h" 12 #include "mozilla/dom/quota/ClientDirectoryLockHandle.h" 13 #include "mozilla/dom/quota/DirectoryLock.h" 14 #include "mozilla/dom/quota/DirectoryLockInlines.h" 15 #include "mozilla/dom/quota/OriginScope.h" 16 #include "mozilla/dom/quota/PersistenceScope.h" 17 #include "mozilla/dom/quota/QuotaManager.h" 18 #include "mozilla/dom/quota/ResultExtensions.h" 19 #include "mozilla/dom/quota/UniversalDirectoryLock.h" 20 #include "mozilla/gtest/MozAssertions.h" 21 #include "mozilla/ipc/PBackgroundSharedTypes.h" 22 #include "nsFmtString.h" 23 #include "prtime.h" 24 25 namespace mozilla::dom::quota::test { 26 27 class TestQuotaManager : public QuotaManagerDependencyFixture { 28 public: 29 static void SetUpTestCase() { ASSERT_NO_FATAL_FAILURE(InitializeFixture()); } 30 31 static void TearDownTestCase() { ASSERT_NO_FATAL_FAILURE(ShutdownFixture()); } 32 33 void TearDown() override { 34 ASSERT_NO_FATAL_FAILURE(ClearStoragesForOrigin(GetTestOriginMetadata())); 35 } 36 }; 37 38 class TestQuotaManagerAndClearStorage : public TestQuotaManager { 39 public: 40 void TearDown() override { ASSERT_NO_FATAL_FAILURE(ClearStorage()); } 41 }; 42 43 using BoolPairTestParams = std::pair<bool, bool>; 44 45 class TestQuotaManagerAndClearStorageWithBoolPair 46 : public TestQuotaManagerAndClearStorage, 47 public testing::WithParamInterface<BoolPairTestParams> {}; 48 49 class TestQuotaManagerAndShutdownFixture 50 : public QuotaManagerDependencyFixture { 51 public: 52 void SetUp() override { ASSERT_NO_FATAL_FAILURE(InitializeFixture()); } 53 54 void TearDown() override { ASSERT_NO_FATAL_FAILURE(ShutdownFixture()); } 55 }; 56 57 TEST_F(TestQuotaManager, GetThumbnailPrivateIdentityId) { 58 PerformOnIOThread([]() { 59 QuotaManager* quotaManager = QuotaManager::Get(); 60 ASSERT_TRUE(quotaManager); 61 62 const bool known = quotaManager->IsThumbnailPrivateIdentityIdKnown(); 63 ASSERT_TRUE(known); 64 65 const uint32_t id = quotaManager->GetThumbnailPrivateIdentityId(); 66 ASSERT_GT(id, 4u); 67 }); 68 } 69 70 // Test OpenStorageDirectory when an opening of the storage directory is 71 // already ongoing and storage shutdown is scheduled after that. 72 TEST_F(TestQuotaManager, OpenStorageDirectory_OngoingWithScheduledShutdown) { 73 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 74 75 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 76 77 PerformOnBackgroundThread([]() { 78 QuotaManager* quotaManager = QuotaManager::Get(); 79 ASSERT_TRUE(quotaManager); 80 81 RefPtr<UniversalDirectoryLock> directoryLock; 82 83 nsTArray<RefPtr<BoolPromise>> promises; 84 85 promises.AppendElement( 86 quotaManager 87 ->OpenStorageDirectory( 88 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 89 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 90 /* aExclusive */ false) 91 ->Then(GetCurrentSerialEventTarget(), __func__, 92 [&directoryLock]( 93 UniversalDirectoryLockPromise::ResolveOrRejectValue&& 94 aValue) { 95 if (aValue.IsReject()) { 96 return BoolPromise::CreateAndReject(aValue.RejectValue(), 97 __func__); 98 } 99 100 [&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }(); 101 102 directoryLock = std::move(aValue.ResolveValue()); 103 104 return BoolPromise::CreateAndResolve(true, __func__); 105 }) 106 ->Then(quotaManager->IOThread(), __func__, 107 [](const BoolPromise::ResolveOrRejectValue& aValue) { 108 if (aValue.IsReject()) { 109 return BoolPromise::CreateAndReject(aValue.RejectValue(), 110 __func__); 111 } 112 113 []() { 114 QuotaManager* quotaManager = QuotaManager::Get(); 115 ASSERT_TRUE(quotaManager); 116 117 ASSERT_TRUE( 118 quotaManager->IsStorageInitializedInternal()); 119 }(); 120 121 return BoolPromise::CreateAndResolve(true, __func__); 122 }) 123 ->Then(GetCurrentSerialEventTarget(), __func__, 124 [&directoryLock]( 125 const BoolPromise::ResolveOrRejectValue& aValue) { 126 DropDirectoryLock(directoryLock); 127 128 if (aValue.IsReject()) { 129 return BoolPromise::CreateAndReject(aValue.RejectValue(), 130 __func__); 131 } 132 133 return BoolPromise::CreateAndResolve(true, __func__); 134 })); 135 promises.AppendElement(quotaManager->ShutdownStorage()); 136 promises.AppendElement( 137 quotaManager 138 ->OpenStorageDirectory( 139 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 140 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 141 /* aExclusive */ false) 142 ->Then(GetCurrentSerialEventTarget(), __func__, 143 [](UniversalDirectoryLockPromise::ResolveOrRejectValue&& 144 aValue) { 145 if (aValue.IsReject()) { 146 return BoolPromise::CreateAndReject(aValue.RejectValue(), 147 __func__); 148 } 149 150 RefPtr<UniversalDirectoryLock> directoryLock = 151 std::move(aValue.ResolveValue()); 152 DropDirectoryLock(directoryLock); 153 154 return BoolPromise::CreateAndResolve(true, __func__); 155 })); 156 157 { 158 auto value = 159 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 160 ASSERT_TRUE(value.IsResolve()); 161 162 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 163 } 164 }); 165 166 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 167 168 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 169 } 170 171 // Test OpenStorageDirectory when an opening of the storage directory is 172 // already ongoing and an exclusive directory lock is requested after that. 173 TEST_F(TestQuotaManager, 174 OpenStorageDirectory_OngoingWithExclusiveDirectoryLock) { 175 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 176 177 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 178 179 PerformOnBackgroundThread([]() { 180 QuotaManager* quotaManager = QuotaManager::Get(); 181 ASSERT_TRUE(quotaManager); 182 183 RefPtr<UniversalDirectoryLock> directoryLock = 184 quotaManager->CreateDirectoryLockInternal( 185 PersistenceScope::CreateFromNull(), OriginScope::FromNull(), 186 ClientStorageScope::CreateFromNull(), 187 /* aExclusive */ true); 188 189 nsTArray<RefPtr<BoolPromise>> promises; 190 191 promises.AppendElement( 192 quotaManager 193 ->OpenStorageDirectory( 194 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 195 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 196 /* aExclusive */ false) 197 ->Then(GetCurrentSerialEventTarget(), __func__, 198 [&directoryLock]( 199 UniversalDirectoryLockPromise::ResolveOrRejectValue&& 200 aValue) { 201 DropDirectoryLock(directoryLock); 202 203 if (aValue.IsReject()) { 204 return BoolPromise::CreateAndReject(aValue.RejectValue(), 205 __func__); 206 } 207 208 RefPtr<UniversalDirectoryLock> directoryLock = 209 std::move(aValue.ResolveValue()); 210 DropDirectoryLock(directoryLock); 211 212 return BoolPromise::CreateAndResolve(true, __func__); 213 })); 214 promises.AppendElement(directoryLock->Acquire()); 215 promises.AppendElement( 216 quotaManager 217 ->OpenStorageDirectory( 218 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 219 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 220 /* aExclusive */ false) 221 ->Then(GetCurrentSerialEventTarget(), __func__, 222 [](UniversalDirectoryLockPromise::ResolveOrRejectValue&& 223 aValue) { 224 if (aValue.IsReject()) { 225 return BoolPromise::CreateAndReject(aValue.RejectValue(), 226 __func__); 227 } 228 229 RefPtr<UniversalDirectoryLock> directoryLock = 230 std::move(aValue.ResolveValue()); 231 DropDirectoryLock(directoryLock); 232 233 return BoolPromise::CreateAndResolve(true, __func__); 234 })); 235 236 { 237 auto value = 238 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 239 ASSERT_TRUE(value.IsResolve()); 240 241 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 242 } 243 }); 244 245 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 246 247 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 248 } 249 250 // Test OpenStorageDirectory when an opening of the storage directory already 251 // finished. 252 TEST_F(TestQuotaManager, OpenStorageDirectory_Finished) { 253 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 254 255 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 256 257 PerformOnBackgroundThread([]() { 258 QuotaManager* quotaManager = QuotaManager::Get(); 259 ASSERT_TRUE(quotaManager); 260 261 { 262 auto value = Await(quotaManager->OpenStorageDirectory( 263 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 264 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 265 /* aExclusive */ false)); 266 ASSERT_TRUE(value.IsResolve()); 267 268 RefPtr<UniversalDirectoryLock> directoryLock = 269 std::move(value.ResolveValue()); 270 DropDirectoryLock(directoryLock); 271 272 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 273 } 274 275 { 276 auto value = Await(quotaManager->OpenStorageDirectory( 277 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 278 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 279 /* aExclusive */ false)); 280 ASSERT_TRUE(value.IsResolve()); 281 282 RefPtr<UniversalDirectoryLock> directoryLock = 283 std::move(value.ResolveValue()); 284 DropDirectoryLock(directoryLock); 285 286 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 287 } 288 }); 289 290 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 291 292 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 293 } 294 295 // Test OpenStorageDirectory when an opening of the storage directory already 296 // finished but storage shutdown has just been scheduled. 297 TEST_F(TestQuotaManager, OpenStorageDirectory_FinishedWithScheduledShutdown) { 298 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 299 300 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 301 302 PerformOnBackgroundThread([]() { 303 QuotaManager* quotaManager = QuotaManager::Get(); 304 ASSERT_TRUE(quotaManager); 305 306 { 307 auto value = Await(quotaManager->OpenStorageDirectory( 308 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 309 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 310 /* aExclusive */ false)); 311 ASSERT_TRUE(value.IsResolve()); 312 313 RefPtr<UniversalDirectoryLock> directoryLock = 314 std::move(value.ResolveValue()); 315 DropDirectoryLock(directoryLock); 316 317 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 318 } 319 320 nsTArray<RefPtr<BoolPromise>> promises; 321 322 promises.AppendElement(quotaManager->ShutdownStorage()); 323 promises.AppendElement( 324 quotaManager 325 ->OpenStorageDirectory( 326 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 327 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 328 /* aExclusive */ false) 329 ->Then(GetCurrentSerialEventTarget(), __func__, 330 [](UniversalDirectoryLockPromise::ResolveOrRejectValue&& 331 aValue) { 332 if (aValue.IsReject()) { 333 return BoolPromise::CreateAndReject(aValue.RejectValue(), 334 __func__); 335 } 336 337 RefPtr<UniversalDirectoryLock> directoryLock = 338 std::move(aValue.ResolveValue()); 339 DropDirectoryLock(directoryLock); 340 341 return BoolPromise::CreateAndResolve(true, __func__); 342 })); 343 344 { 345 auto value = 346 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 347 ASSERT_TRUE(value.IsResolve()); 348 349 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 350 } 351 }); 352 353 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 354 355 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 356 } 357 358 // Test OpenStorageDirectory when an opening of the storage directory already 359 // finished and an exclusive client directory lock for a non-overlapping 360 // origin is acquired in between. 361 TEST_F(TestQuotaManager, 362 OpenStorageDirectory_FinishedWithExclusiveClientDirectoryLock) { 363 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 364 365 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 366 367 PerformOnBackgroundThread([]() { 368 QuotaManager* quotaManager = QuotaManager::Get(); 369 ASSERT_TRUE(quotaManager); 370 371 { 372 auto value = Await(quotaManager->OpenStorageDirectory( 373 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 374 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 375 /* aExclusive */ false)); 376 ASSERT_TRUE(value.IsResolve()); 377 378 RefPtr<UniversalDirectoryLock> directoryLock = 379 std::move(value.ResolveValue()); 380 DropDirectoryLock(directoryLock); 381 382 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 383 } 384 385 RefPtr<ClientDirectoryLock> directoryLock = 386 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 387 /* aExclusive */ true); 388 389 { 390 auto value = Await(directoryLock->Acquire()); 391 ASSERT_TRUE(value.IsResolve()); 392 } 393 394 { 395 auto value = Await(quotaManager->OpenStorageDirectory( 396 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 397 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 398 /* aExclusive */ false)); 399 ASSERT_TRUE(value.IsResolve()); 400 401 RefPtr<UniversalDirectoryLock> directoryLock = 402 std::move(value.ResolveValue()); 403 DropDirectoryLock(directoryLock); 404 405 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 406 } 407 408 DropDirectoryLock(directoryLock); 409 }); 410 411 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 412 413 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 414 } 415 416 // Test simple OpenClientDirectory behavior and verify that origin access time 417 // updates are triggered as expected. 418 TEST_F(TestQuotaManager, OpenClientDirectory_Simple) { 419 auto testOriginMetadata = GetTestOriginMetadata(); 420 421 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 422 423 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 424 425 const auto saveOriginAccessTimeCountBefore = SaveOriginAccessTimeCount(); 426 const auto saveOriginAccessTimeCountInternalBefore = 427 SaveOriginAccessTimeCountInternal(); 428 429 // Can't check origin state metadata since storage is not yet initialized. 430 431 auto directoryMetadataHeaderBefore = 432 LoadDirectoryMetadataHeader(testOriginMetadata); 433 ASSERT_FALSE(directoryMetadataHeaderBefore); 434 435 PerformOnBackgroundThread([]() { 436 QuotaManager* quotaManager = QuotaManager::Get(); 437 ASSERT_TRUE(quotaManager); 438 439 { 440 auto value = 441 Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); 442 ASSERT_TRUE(value.IsResolve()); 443 444 ClientDirectoryLockHandle directoryLockHandle = 445 std::move(value.ResolveValue()); 446 447 { 448 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 449 } 450 451 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 452 } 453 }); 454 455 ProcessPendingNormalOriginOperations(); 456 457 const auto saveOriginAccessTimeCountAfter = SaveOriginAccessTimeCount(); 458 const auto saveOriginAccessTimeCountInternalAfter = 459 SaveOriginAccessTimeCountInternal(); 460 461 ASSERT_EQ(saveOriginAccessTimeCountAfter - saveOriginAccessTimeCountBefore, 462 2u); 463 ASSERT_EQ(saveOriginAccessTimeCountInternalAfter - 464 saveOriginAccessTimeCountInternalBefore, 465 2u); 466 467 auto originStateMetadataAfter = GetOriginStateMetadata(testOriginMetadata); 468 ASSERT_TRUE(originStateMetadataAfter); 469 ASSERT_TRUE(originStateMetadataAfter->mAccessed); 470 471 auto directoryMetadataHeaderAfter = 472 LoadDirectoryMetadataHeader(testOriginMetadata); 473 ASSERT_TRUE(directoryMetadataHeaderAfter); 474 ASSERT_TRUE(directoryMetadataHeaderAfter->mAccessed); 475 476 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 477 478 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 479 } 480 481 // Test simple OpenClientDirectory behavior when the origin directory exists, 482 // and verify that access time updates are triggered on first and last access. 483 TEST_F(TestQuotaManager, OpenClientDirectory_Simple_OriginDirectoryExists) { 484 auto testOriginMetadata = GetTestOriginMetadata(); 485 486 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 487 488 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 489 490 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 491 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 492 ASSERT_NO_FATAL_FAILURE( 493 InitializeTemporaryOrigin(GetTestOriginMetadata(), 494 /* aCreateIfNonExistent */ true)); 495 496 const auto saveOriginAccessTimeCountBefore = SaveOriginAccessTimeCount(); 497 const auto saveOriginAccessTimeCountInternalBefore = 498 SaveOriginAccessTimeCountInternal(); 499 500 auto originStateMetadataBefore = GetOriginStateMetadata(testOriginMetadata); 501 ASSERT_TRUE(originStateMetadataBefore); 502 ASSERT_FALSE(originStateMetadataBefore->mAccessed); 503 504 auto directoryMetadataHeaderBefore = 505 LoadDirectoryMetadataHeader(testOriginMetadata); 506 ASSERT_TRUE(directoryMetadataHeaderBefore); 507 ASSERT_FALSE(directoryMetadataHeaderBefore->mAccessed); 508 509 PerformOnBackgroundThread([]() { 510 QuotaManager* quotaManager = QuotaManager::Get(); 511 ASSERT_TRUE(quotaManager); 512 513 { 514 auto value = 515 Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); 516 ASSERT_TRUE(value.IsResolve()); 517 518 ClientDirectoryLockHandle directoryLockHandle = 519 std::move(value.ResolveValue()); 520 521 { 522 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 523 } 524 525 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 526 } 527 }); 528 529 ProcessPendingNormalOriginOperations(); 530 531 const auto saveOriginAccessTimeCountAfter = SaveOriginAccessTimeCount(); 532 const auto saveOriginAccessTimeCountInternalAfter = 533 SaveOriginAccessTimeCountInternal(); 534 535 ASSERT_EQ(saveOriginAccessTimeCountAfter - saveOriginAccessTimeCountBefore, 536 2u); 537 ASSERT_EQ(saveOriginAccessTimeCountInternalAfter - 538 saveOriginAccessTimeCountInternalBefore, 539 2u); 540 541 auto originStateMetadataAfter = GetOriginStateMetadata(testOriginMetadata); 542 ASSERT_TRUE(originStateMetadataAfter); 543 ASSERT_TRUE(originStateMetadataAfter->mAccessed); 544 545 auto directoryMetadataHeaderAfter = 546 LoadDirectoryMetadataHeader(testOriginMetadata); 547 ASSERT_TRUE(directoryMetadataHeaderAfter); 548 ASSERT_TRUE(directoryMetadataHeaderAfter->mAccessed); 549 550 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 551 552 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 553 } 554 555 // Test OpenClientDirectory when the origin directory doesn't exist, and verify 556 // that no access time update occurs. The directory should not be created 557 // solely for updating access time. 558 TEST_F(TestQuotaManager, 559 OpenClientDirectory_Simple_NonExistingOriginDirectory) { 560 auto testOriginMetadata = GetTestOriginMetadata(); 561 562 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 563 564 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 565 566 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 567 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 568 ASSERT_NO_FATAL_FAILURE( 569 InitializeTemporaryOrigin(GetTestOriginMetadata(), 570 /* aCreateIfNonExistent */ false)); 571 572 const auto saveOriginAccessTimeCountBefore = SaveOriginAccessTimeCount(); 573 const auto saveOriginAccessTimeCountInternalBefore = 574 SaveOriginAccessTimeCountInternal(); 575 576 auto originStateMetadataBefore = GetOriginStateMetadata(testOriginMetadata); 577 ASSERT_TRUE(originStateMetadataBefore); 578 ASSERT_FALSE(originStateMetadataBefore->mAccessed); 579 580 auto directoryMetadataHeaderBefore = 581 LoadDirectoryMetadataHeader(testOriginMetadata); 582 ASSERT_FALSE(directoryMetadataHeaderBefore); 583 584 PerformOnBackgroundThread([]() { 585 QuotaManager* quotaManager = QuotaManager::Get(); 586 ASSERT_TRUE(quotaManager); 587 588 { 589 auto value = Await(quotaManager->OpenClientDirectory( 590 GetTestClientMetadata(), 591 /* aInitializeOrigin */ true, /* aCreateIfNonExistent */ false)); 592 ASSERT_TRUE(value.IsResolve()); 593 594 ClientDirectoryLockHandle directoryLockHandle = 595 std::move(value.ResolveValue()); 596 597 { 598 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 599 } 600 601 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 602 } 603 }); 604 605 ProcessPendingNormalOriginOperations(); 606 607 const auto saveOriginAccessTimeCountAfter = SaveOriginAccessTimeCount(); 608 const auto saveOriginAccessTimeCountInternalAfter = 609 SaveOriginAccessTimeCountInternal(); 610 611 // This is expected to be 0, the origin directory should not be created 612 // solely to update access time when, for example, LSNG explicitly requests 613 // that it not be created if it doesn't exist. The access time will be saved 614 // later. 615 ASSERT_EQ(saveOriginAccessTimeCountAfter - saveOriginAccessTimeCountBefore, 616 0u); 617 ASSERT_EQ(saveOriginAccessTimeCountInternalAfter - 618 saveOriginAccessTimeCountInternalBefore, 619 0u); 620 621 auto originStateMetadataAfter = GetOriginStateMetadata(testOriginMetadata); 622 ASSERT_TRUE(originStateMetadataAfter); 623 ASSERT_TRUE(originStateMetadataAfter->mAccessed); 624 625 auto directoryMetadataHeaderAfter = 626 LoadDirectoryMetadataHeader(testOriginMetadata); 627 ASSERT_FALSE(directoryMetadataHeaderAfter); 628 629 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 630 631 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 632 } 633 634 // Test OpenClientDirectory when a clear operation is scheduled before 635 // releasing the directory lock. Verifies that access time updates still occur, 636 // even with the scheduled clear operation. 637 TEST_F(TestQuotaManager, 638 OpenClientDirectory_SimpleWithScheduledClearing_OriginDirectoryExists) { 639 auto testOriginMetadata = GetTestOriginMetadata(); 640 641 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 642 643 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 644 645 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 646 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 647 ASSERT_NO_FATAL_FAILURE( 648 InitializeTemporaryOrigin(testOriginMetadata, 649 /* aCreateIfNonExistent */ true)); 650 651 const auto saveOriginAccessTimeCountBefore = SaveOriginAccessTimeCount(); 652 const auto saveOriginAccessTimeCountInternalBefore = 653 SaveOriginAccessTimeCountInternal(); 654 655 auto originStateMetadataBefore = GetOriginStateMetadata(testOriginMetadata); 656 ASSERT_TRUE(originStateMetadataBefore); 657 ASSERT_FALSE(originStateMetadataBefore->mAccessed); 658 659 auto directoryMetadataHeaderBefore = 660 LoadDirectoryMetadataHeader(testOriginMetadata); 661 ASSERT_TRUE(directoryMetadataHeaderBefore); 662 ASSERT_FALSE(directoryMetadataHeaderBefore->mAccessed); 663 664 PerformOnBackgroundThread([testOriginMetadata]() { 665 QuotaManager* quotaManager = QuotaManager::Get(); 666 ASSERT_TRUE(quotaManager); 667 668 { 669 auto value = 670 Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); 671 ASSERT_TRUE(value.IsResolve()); 672 673 ClientDirectoryLockHandle directoryLockHandle = 674 std::move(value.ResolveValue()); 675 676 nsCOMPtr<nsIPrincipal> principal = 677 BasePrincipal::CreateContentPrincipal(testOriginMetadata.mOrigin); 678 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 679 680 mozilla::ipc::PrincipalInfo principalInfo; 681 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 682 QM_TEST_FAIL); 683 684 // This can't be awaited here, it would cause a hang, on the other hand, 685 // it must be scheduled before the handle is moved below. 686 quotaManager->ClearStoragesForOrigin( 687 /* aPersistenceType */ Nothing(), principalInfo); 688 689 { 690 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 691 } 692 693 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 694 } 695 }); 696 697 ProcessPendingNormalOriginOperations(); 698 699 const auto saveOriginAccessTimeCountAfter = SaveOriginAccessTimeCount(); 700 const auto saveOriginAccessTimeCountInternalAfter = 701 SaveOriginAccessTimeCountInternal(); 702 703 ASSERT_EQ(saveOriginAccessTimeCountAfter - saveOriginAccessTimeCountBefore, 704 2u); 705 ASSERT_EQ(saveOriginAccessTimeCountInternalAfter - 706 saveOriginAccessTimeCountInternalBefore, 707 2u); 708 709 auto originStateMetadataAfter = GetOriginStateMetadata(testOriginMetadata); 710 ASSERT_FALSE(originStateMetadataAfter); 711 712 auto directoryMetadataHeaderAfter = 713 LoadDirectoryMetadataHeader(testOriginMetadata); 714 ASSERT_FALSE(directoryMetadataHeaderAfter); 715 716 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 717 718 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 719 } 720 721 // Test OpenClientDirectory when a client directory opening is already ongoing 722 // and the origin directory exists. Verifies that each opening completes only 723 // after the origin access time update triggered by first access has finished, 724 // and that access time is updated only on first and last access as expected. 725 TEST_F(TestQuotaManager, OpenClientDirectory_Ongoing_OriginDirectoryExists) { 726 auto testOriginMetadata = GetTestOriginMetadata(); 727 728 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 729 730 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 731 732 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 733 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 734 ASSERT_NO_FATAL_FAILURE( 735 InitializeTemporaryOrigin(GetTestOriginMetadata(), 736 /* aCreateIfNonExistent */ true)); 737 738 const auto saveOriginAccessTimeCountBefore = SaveOriginAccessTimeCount(); 739 const auto saveOriginAccessTimeCountInternalBefore = 740 SaveOriginAccessTimeCountInternal(); 741 742 auto originStateMetadataBefore = GetOriginStateMetadata(testOriginMetadata); 743 ASSERT_TRUE(originStateMetadataBefore); 744 ASSERT_FALSE(originStateMetadataBefore->mAccessed); 745 746 auto directoryMetadataHeaderBefore = 747 LoadDirectoryMetadataHeader(testOriginMetadata); 748 ASSERT_TRUE(directoryMetadataHeaderBefore); 749 ASSERT_FALSE(directoryMetadataHeaderBefore->mAccessed); 750 751 PerformOnBackgroundThread([saveOriginAccessTimeCountBefore, 752 saveOriginAccessTimeCountInternalBefore]() { 753 auto testClientMetadata = GetTestClientMetadata(); 754 755 QuotaManager* quotaManager = QuotaManager::Get(); 756 ASSERT_TRUE(quotaManager); 757 758 ClientDirectoryLockHandle directoryLockHandle; 759 ClientDirectoryLockHandle directoryLockHandle2; 760 761 nsTArray<RefPtr<BoolPromise>> promises; 762 763 promises.AppendElement( 764 quotaManager->OpenClientDirectory(testClientMetadata) 765 ->Then(GetCurrentSerialEventTarget(), __func__, 766 [saveOriginAccessTimeCountBefore, &directoryLockHandle]( 767 QuotaManager::ClientDirectoryLockHandlePromise:: 768 ResolveOrRejectValue&& aValue) { 769 if (aValue.IsReject()) { 770 return BoolPromise::CreateAndReject(aValue.RejectValue(), 771 __func__); 772 } 773 774 QuotaManager* quotaManager = QuotaManager::Get(); 775 MOZ_RELEASE_ASSERT(quotaManager); 776 777 const auto saveOriginAccessTimeCountNow = 778 quotaManager->SaveOriginAccessTimeCount(); 779 780 EXPECT_EQ(saveOriginAccessTimeCountNow - 781 saveOriginAccessTimeCountBefore, 782 1u); 783 784 directoryLockHandle = std::move(aValue.ResolveValue()); 785 786 return BoolPromise::CreateAndResolve(true, __func__); 787 }) 788 ->Then(quotaManager->IOThread(), __func__, 789 [saveOriginAccessTimeCountInternalBefore]( 790 const BoolPromise::ResolveOrRejectValue& aValue) { 791 if (aValue.IsReject()) { 792 return BoolPromise::CreateAndReject(aValue.RejectValue(), 793 __func__); 794 } 795 796 QuotaManager* quotaManager = QuotaManager::Get(); 797 MOZ_RELEASE_ASSERT(quotaManager); 798 799 const auto saveOriginAccessTimeCountInternalNow = 800 quotaManager->SaveOriginAccessTimeCountInternal(); 801 802 EXPECT_EQ(saveOriginAccessTimeCountInternalNow - 803 saveOriginAccessTimeCountInternalBefore, 804 1u); 805 806 return BoolPromise::CreateAndResolve(true, __func__); 807 })); 808 promises.AppendElement( 809 quotaManager->OpenClientDirectory(testClientMetadata) 810 ->Then(GetCurrentSerialEventTarget(), __func__, 811 [saveOriginAccessTimeCountBefore, &directoryLockHandle2]( 812 QuotaManager::ClientDirectoryLockHandlePromise:: 813 ResolveOrRejectValue&& aValue) { 814 if (aValue.IsReject()) { 815 return BoolPromise::CreateAndReject(aValue.RejectValue(), 816 __func__); 817 } 818 819 QuotaManager* quotaManager = QuotaManager::Get(); 820 MOZ_RELEASE_ASSERT(quotaManager); 821 822 const auto saveOriginAccessTimeCountNow = 823 quotaManager->SaveOriginAccessTimeCount(); 824 825 EXPECT_EQ(saveOriginAccessTimeCountNow - 826 saveOriginAccessTimeCountBefore, 827 1u); 828 829 directoryLockHandle2 = std::move(aValue.ResolveValue()); 830 831 return BoolPromise::CreateAndResolve(true, __func__); 832 }) 833 ->Then(quotaManager->IOThread(), __func__, 834 [saveOriginAccessTimeCountInternalBefore]( 835 const BoolPromise::ResolveOrRejectValue& aValue) { 836 if (aValue.IsReject()) { 837 return BoolPromise::CreateAndReject(aValue.RejectValue(), 838 __func__); 839 } 840 841 QuotaManager* quotaManager = QuotaManager::Get(); 842 MOZ_RELEASE_ASSERT(quotaManager); 843 844 const auto saveOriginAccessTimeCountInternalNow = 845 quotaManager->SaveOriginAccessTimeCountInternal(); 846 847 EXPECT_EQ(saveOriginAccessTimeCountInternalNow - 848 saveOriginAccessTimeCountInternalBefore, 849 1u); 850 851 return BoolPromise::CreateAndResolve(true, __func__); 852 })); 853 854 { 855 auto value = 856 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 857 ASSERT_TRUE(value.IsResolve()); 858 859 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 860 } 861 862 { 863 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 864 } 865 866 { 867 auto destroyingDirectoryLockHandle2 = std::move(directoryLockHandle2); 868 } 869 }); 870 871 ProcessPendingNormalOriginOperations(); 872 873 const auto saveOriginAccessTimeCountAfter = SaveOriginAccessTimeCount(); 874 const auto saveOriginAccessTimeCountInternalAfter = 875 SaveOriginAccessTimeCountInternal(); 876 877 ASSERT_EQ(saveOriginAccessTimeCountAfter - saveOriginAccessTimeCountBefore, 878 2u); 879 ASSERT_EQ(saveOriginAccessTimeCountInternalAfter - 880 saveOriginAccessTimeCountInternalBefore, 881 2u); 882 883 auto originStateMetadataAfter = GetOriginStateMetadata(testOriginMetadata); 884 ASSERT_TRUE(originStateMetadataAfter); 885 ASSERT_TRUE(originStateMetadataAfter->mAccessed); 886 887 auto directoryMetadataHeaderAfter = 888 LoadDirectoryMetadataHeader(testOriginMetadata); 889 ASSERT_TRUE(directoryMetadataHeaderAfter); 890 ASSERT_TRUE(directoryMetadataHeaderAfter->mAccessed); 891 892 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 893 894 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 895 } 896 897 // Test OpenClientDirctory when an opening of a client directory is already 898 // ongoing and storage shutdown is scheduled after that. 899 TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) { 900 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 901 902 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 903 904 PerformOnBackgroundThread([]() { 905 QuotaManager* quotaManager = QuotaManager::Get(); 906 ASSERT_TRUE(quotaManager); 907 908 ClientDirectoryLockHandle directoryLockHandle; 909 910 nsTArray<RefPtr<BoolPromise>> promises; 911 912 promises.AppendElement( 913 quotaManager->OpenClientDirectory(GetTestClientMetadata()) 914 ->Then(GetCurrentSerialEventTarget(), __func__, 915 [&directoryLockHandle]( 916 QuotaManager::ClientDirectoryLockHandlePromise:: 917 ResolveOrRejectValue&& aValue) { 918 if (aValue.IsReject()) { 919 return BoolPromise::CreateAndReject(aValue.RejectValue(), 920 __func__); 921 } 922 923 [&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }(); 924 925 directoryLockHandle = std::move(aValue.ResolveValue()); 926 927 return BoolPromise::CreateAndResolve(true, __func__); 928 }) 929 ->Then(quotaManager->IOThread(), __func__, 930 [](const BoolPromise::ResolveOrRejectValue& aValue) { 931 if (aValue.IsReject()) { 932 return BoolPromise::CreateAndReject(aValue.RejectValue(), 933 __func__); 934 } 935 936 []() { 937 QuotaManager* quotaManager = QuotaManager::Get(); 938 ASSERT_TRUE(quotaManager); 939 940 ASSERT_TRUE( 941 quotaManager->IsStorageInitializedInternal()); 942 }(); 943 944 return BoolPromise::CreateAndResolve(true, __func__); 945 }) 946 ->Then(GetCurrentSerialEventTarget(), __func__, 947 [&directoryLockHandle]( 948 const BoolPromise::ResolveOrRejectValue& aValue) { 949 { 950 auto destroyingDirectoryLockHandle = 951 std::move(directoryLockHandle); 952 } 953 954 if (aValue.IsReject()) { 955 return BoolPromise::CreateAndReject(aValue.RejectValue(), 956 __func__); 957 } 958 959 return BoolPromise::CreateAndResolve(true, __func__); 960 })); 961 promises.AppendElement(quotaManager->ShutdownStorage()); 962 promises.AppendElement( 963 quotaManager->OpenClientDirectory(GetTestClientMetadata()) 964 ->Then(GetCurrentSerialEventTarget(), __func__, 965 [](QuotaManager::ClientDirectoryLockHandlePromise:: 966 ResolveOrRejectValue&& aValue) { 967 if (aValue.IsReject()) { 968 return BoolPromise::CreateAndReject(aValue.RejectValue(), 969 __func__); 970 } 971 972 ClientDirectoryLockHandle directoryLockHandle = 973 std::move(aValue.ResolveValue()); 974 975 { 976 auto destroyingDirectoryLockHandle = 977 std::move(directoryLockHandle); 978 } 979 980 return BoolPromise::CreateAndResolve(true, __func__); 981 })); 982 983 { 984 auto value = 985 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 986 ASSERT_TRUE(value.IsResolve()); 987 988 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 989 } 990 }); 991 992 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 993 994 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 995 } 996 997 // Test OpenClientDirectory when an opening of a client directory is already 998 // ongoing and an exclusive directory lock is requested after that. 999 TEST_F(TestQuotaManager, 1000 OpenClientDirectory_OngoingWithExclusiveDirectoryLock) { 1001 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1002 1003 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1004 1005 PerformOnBackgroundThread([]() { 1006 QuotaManager* quotaManager = QuotaManager::Get(); 1007 ASSERT_TRUE(quotaManager); 1008 1009 RefPtr<UniversalDirectoryLock> directoryLock = 1010 quotaManager->CreateDirectoryLockInternal( 1011 PersistenceScope::CreateFromNull(), OriginScope::FromNull(), 1012 ClientStorageScope::CreateFromNull(), 1013 /* aExclusive */ true); 1014 1015 nsTArray<RefPtr<BoolPromise>> promises; 1016 1017 promises.AppendElement( 1018 quotaManager->OpenClientDirectory(GetTestClientMetadata()) 1019 ->Then(GetCurrentSerialEventTarget(), __func__, 1020 [&directoryLock]( 1021 QuotaManager::ClientDirectoryLockHandlePromise:: 1022 ResolveOrRejectValue&& aValue) { 1023 DropDirectoryLock(directoryLock); 1024 1025 if (aValue.IsReject()) { 1026 return BoolPromise::CreateAndReject(aValue.RejectValue(), 1027 __func__); 1028 } 1029 1030 ClientDirectoryLockHandle directoryLockHandle = 1031 std::move(aValue.ResolveValue()); 1032 1033 { 1034 auto destroyingDirectoryLockHandle = 1035 std::move(directoryLockHandle); 1036 } 1037 1038 return BoolPromise::CreateAndResolve(true, __func__); 1039 })); 1040 promises.AppendElement(directoryLock->Acquire()); 1041 promises.AppendElement( 1042 quotaManager->OpenClientDirectory(GetTestClientMetadata()) 1043 ->Then(GetCurrentSerialEventTarget(), __func__, 1044 [](QuotaManager::ClientDirectoryLockHandlePromise:: 1045 ResolveOrRejectValue&& aValue) { 1046 if (aValue.IsReject()) { 1047 return BoolPromise::CreateAndReject(aValue.RejectValue(), 1048 __func__); 1049 } 1050 1051 ClientDirectoryLockHandle directoryLockHandle = 1052 std::move(aValue.ResolveValue()); 1053 1054 { 1055 auto destroyingDirectoryLockHandle = 1056 std::move(directoryLockHandle); 1057 } 1058 1059 return BoolPromise::CreateAndResolve(true, __func__); 1060 })); 1061 1062 { 1063 auto value = 1064 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1065 ASSERT_TRUE(value.IsResolve()); 1066 1067 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1068 } 1069 }); 1070 1071 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1072 1073 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1074 } 1075 1076 // Test OpenClientDirectory when an opening of a client directory already 1077 // finished. 1078 TEST_F(TestQuotaManager, OpenClientDirectory_Finished) { 1079 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1080 1081 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1082 1083 PerformOnBackgroundThread([]() { 1084 QuotaManager* quotaManager = QuotaManager::Get(); 1085 ASSERT_TRUE(quotaManager); 1086 1087 { 1088 auto value = 1089 Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); 1090 ASSERT_TRUE(value.IsResolve()); 1091 1092 ClientDirectoryLockHandle directoryLockHandle = 1093 std::move(value.ResolveValue()); 1094 1095 { 1096 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 1097 } 1098 1099 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1100 } 1101 1102 { 1103 auto value = 1104 Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); 1105 ASSERT_TRUE(value.IsResolve()); 1106 1107 ClientDirectoryLockHandle directoryLockHandle = 1108 std::move(value.ResolveValue()); 1109 1110 { 1111 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 1112 } 1113 1114 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1115 } 1116 }); 1117 1118 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1119 1120 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1121 } 1122 1123 // Test OpenClientDirectory when an opening of a client directory already 1124 // finished but storage shutdown has just been scheduled. 1125 TEST_F(TestQuotaManager, OpenClientDirectory_FinishedWithScheduledShutdown) { 1126 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1127 1128 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1129 1130 PerformOnBackgroundThread([]() { 1131 QuotaManager* quotaManager = QuotaManager::Get(); 1132 ASSERT_TRUE(quotaManager); 1133 1134 { 1135 auto value = 1136 Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); 1137 ASSERT_TRUE(value.IsResolve()); 1138 1139 ClientDirectoryLockHandle directoryLockHandle = 1140 std::move(value.ResolveValue()); 1141 1142 { 1143 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 1144 } 1145 1146 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1147 } 1148 1149 nsTArray<RefPtr<BoolPromise>> promises; 1150 1151 promises.AppendElement(quotaManager->ShutdownStorage()); 1152 promises.AppendElement( 1153 quotaManager->OpenClientDirectory(GetTestClientMetadata()) 1154 ->Then(GetCurrentSerialEventTarget(), __func__, 1155 [](QuotaManager::ClientDirectoryLockHandlePromise:: 1156 ResolveOrRejectValue&& aValue) { 1157 if (aValue.IsReject()) { 1158 return BoolPromise::CreateAndReject(aValue.RejectValue(), 1159 __func__); 1160 } 1161 1162 ClientDirectoryLockHandle directoryLockHandle = 1163 std::move(aValue.ResolveValue()); 1164 1165 { 1166 auto destroyingDirectoryLockHandle = 1167 std::move(directoryLockHandle); 1168 } 1169 1170 return BoolPromise::CreateAndResolve(true, __func__); 1171 })); 1172 1173 { 1174 auto value = 1175 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1176 ASSERT_TRUE(value.IsResolve()); 1177 1178 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1179 } 1180 }); 1181 1182 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1183 1184 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1185 } 1186 1187 // Test OpenClientDirectory when an opening of a client directory already 1188 // finished with an exclusive client directory lock for a different origin is 1189 // acquired in between. 1190 TEST_F(TestQuotaManager, 1191 OpenClientDirectory_FinishedWithOtherExclusiveClientDirectoryLock) { 1192 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1193 1194 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1195 1196 PerformOnBackgroundThread([]() { 1197 QuotaManager* quotaManager = QuotaManager::Get(); 1198 ASSERT_TRUE(quotaManager); 1199 1200 { 1201 auto value = 1202 Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); 1203 ASSERT_TRUE(value.IsResolve()); 1204 1205 ClientDirectoryLockHandle directoryLockHandle = 1206 std::move(value.ResolveValue()); 1207 1208 { 1209 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 1210 } 1211 1212 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1213 } 1214 1215 RefPtr<ClientDirectoryLock> directoryLock = 1216 quotaManager->CreateDirectoryLock(GetOtherTestClientMetadata(), 1217 /* aExclusive */ true); 1218 1219 { 1220 auto value = Await(directoryLock->Acquire()); 1221 ASSERT_TRUE(value.IsResolve()); 1222 } 1223 1224 { 1225 auto value = 1226 Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); 1227 ASSERT_TRUE(value.IsResolve()); 1228 1229 ClientDirectoryLockHandle directoryLockHandle = 1230 std::move(value.ResolveValue()); 1231 1232 { 1233 auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); 1234 } 1235 1236 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1237 } 1238 1239 DropDirectoryLock(directoryLock); 1240 }); 1241 1242 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1243 1244 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1245 } 1246 1247 TEST_F(TestQuotaManager, OpenClientDirectory_InitializeOrigin) { 1248 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1249 1250 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1251 1252 PerformOnBackgroundThread([]() { 1253 QuotaManager* quotaManager = QuotaManager::Get(); 1254 ASSERT_TRUE(quotaManager); 1255 1256 ClientDirectoryLockHandle directoryLockHandle; 1257 1258 RefPtr<BoolPromise> promise = 1259 quotaManager 1260 ->OpenClientDirectory(GetTestClientMetadata(), 1261 /* aInitializeOrigin */ true) 1262 ->Then(GetCurrentSerialEventTarget(), __func__, 1263 [&directoryLockHandle]( 1264 QuotaManager::ClientDirectoryLockHandlePromise:: 1265 ResolveOrRejectValue&& aValue) { 1266 if (aValue.IsReject()) { 1267 return BoolPromise::CreateAndReject(aValue.RejectValue(), 1268 __func__); 1269 } 1270 1271 [&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }(); 1272 1273 directoryLockHandle = std::move(aValue.ResolveValue()); 1274 1275 return BoolPromise::CreateAndResolve(true, __func__); 1276 }) 1277 ->Then(quotaManager->IOThread(), __func__, 1278 [](const BoolPromise::ResolveOrRejectValue& aValue) { 1279 if (aValue.IsReject()) { 1280 return BoolPromise::CreateAndReject(aValue.RejectValue(), 1281 __func__); 1282 } 1283 1284 []() { 1285 QuotaManager* quotaManager = QuotaManager::Get(); 1286 ASSERT_TRUE(quotaManager); 1287 1288 ASSERT_TRUE( 1289 quotaManager->IsTemporaryOriginInitializedInternal( 1290 GetTestOriginMetadata())); 1291 }(); 1292 1293 return BoolPromise::CreateAndResolve(true, __func__); 1294 }) 1295 ->Then(GetCurrentSerialEventTarget(), __func__, 1296 [&directoryLockHandle]( 1297 const BoolPromise::ResolveOrRejectValue& aValue) { 1298 { 1299 auto destroyingDirectoryLockHandle = 1300 std::move(directoryLockHandle); 1301 } 1302 1303 if (aValue.IsReject()) { 1304 return BoolPromise::CreateAndReject(aValue.RejectValue(), 1305 __func__); 1306 } 1307 1308 return BoolPromise::CreateAndResolve(true, __func__); 1309 }); 1310 1311 { 1312 auto value = Await(promise); 1313 ASSERT_TRUE(value.IsResolve()); 1314 ASSERT_TRUE(value.ResolveValue()); 1315 } 1316 }); 1317 ASSERT_NO_FATAL_FAILURE( 1318 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 1319 1320 ASSERT_NO_FATAL_FAILURE(ClearStoragesForOrigin(GetTestOriginMetadata())); 1321 1322 PerformOnBackgroundThread([]() { 1323 QuotaManager* quotaManager = QuotaManager::Get(); 1324 ASSERT_TRUE(quotaManager); 1325 1326 ClientDirectoryLockHandle directoryLockHandle; 1327 1328 RefPtr<QuotaManager::ClientDirectoryLockHandlePromise> promise = 1329 quotaManager->OpenClientDirectory(GetTestClientMetadata(), 1330 /* aInitializeOrigin */ false); 1331 1332 { 1333 auto value = Await(promise); 1334 ASSERT_TRUE(value.IsReject()); 1335 ASSERT_EQ(value.RejectValue(), 1336 NS_ERROR_DOM_QM_CLIENT_INIT_ORIGIN_UNINITIALIZED); 1337 } 1338 }); 1339 ASSERT_NO_FATAL_FAILURE( 1340 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 1341 1342 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1343 1344 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1345 } 1346 1347 // Test simple InitializeStorage. 1348 TEST_F(TestQuotaManager, InitializeStorage_Simple) { 1349 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1350 1351 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1352 1353 PerformOnBackgroundThread([]() { 1354 QuotaManager* quotaManager = QuotaManager::Get(); 1355 ASSERT_TRUE(quotaManager); 1356 1357 { 1358 auto value = Await(quotaManager->InitializeStorage()); 1359 ASSERT_TRUE(value.IsResolve()); 1360 1361 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1362 } 1363 }); 1364 1365 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1366 1367 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1368 } 1369 1370 // Test InitializeStorage when a storage initialization is already ongoing. 1371 TEST_F(TestQuotaManager, InitializeStorage_Ongoing) { 1372 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1373 1374 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1375 1376 PerformOnBackgroundThread([]() { 1377 QuotaManager* quotaManager = QuotaManager::Get(); 1378 ASSERT_TRUE(quotaManager); 1379 1380 nsTArray<RefPtr<BoolPromise>> promises; 1381 1382 promises.AppendElement(quotaManager->InitializeStorage()); 1383 promises.AppendElement(quotaManager->InitializeStorage()); 1384 1385 { 1386 auto value = 1387 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1388 ASSERT_TRUE(value.IsResolve()); 1389 1390 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1391 } 1392 }); 1393 1394 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1395 1396 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1397 } 1398 1399 // Test InitializeStorage when a storage initialization is already ongoing and 1400 // storage shutdown is scheduled after that. 1401 TEST_F(TestQuotaManager, InitializeStorage_OngoingWithScheduledShutdown) { 1402 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1403 1404 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1405 1406 PerformOnBackgroundThread([]() { 1407 QuotaManager* quotaManager = QuotaManager::Get(); 1408 ASSERT_TRUE(quotaManager); 1409 1410 nsTArray<RefPtr<BoolPromise>> promises; 1411 1412 promises.AppendElement(quotaManager->InitializeStorage()); 1413 promises.AppendElement(quotaManager->ShutdownStorage()); 1414 promises.AppendElement(quotaManager->InitializeStorage()); 1415 1416 { 1417 auto value = 1418 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1419 ASSERT_TRUE(value.IsResolve()); 1420 1421 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1422 } 1423 }); 1424 1425 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1426 1427 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1428 } 1429 1430 // Test InitializeStorage when a storage initialization is already ongoing and 1431 // storage shutdown is scheduled after that. The tested InitializeStorage call 1432 // is delayed to the point when storage shutdown is about to finish. 1433 TEST_F(TestQuotaManager, 1434 InitializeStorage_OngoingWithScheduledShutdown_Delayed) { 1435 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1436 1437 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1438 1439 PerformOnBackgroundThread([]() { 1440 QuotaManager* quotaManager = QuotaManager::Get(); 1441 ASSERT_TRUE(quotaManager); 1442 1443 nsTArray<RefPtr<BoolPromise>> promises; 1444 1445 promises.AppendElement(quotaManager->InitializeStorage()); 1446 1447 OriginOperationCallbackOptions callbackOptions; 1448 callbackOptions.mWantWillFinishSync = true; 1449 1450 OriginOperationCallbacks callbacks; 1451 promises.AppendElement(quotaManager->ShutdownStorage(Some(callbackOptions), 1452 SomeRef(callbacks))); 1453 1454 promises.AppendElement(callbacks.mWillFinishSyncPromise.ref()->Then( 1455 GetCurrentSerialEventTarget(), __func__, 1456 [quotaManager = RefPtr(quotaManager)]( 1457 const ExclusiveBoolPromise::ResolveOrRejectValue& aValue) { 1458 return InvokeAsync( 1459 GetCurrentSerialEventTarget(), __func__, 1460 [quotaManager]() { return quotaManager->InitializeStorage(); }); 1461 })); 1462 1463 { 1464 auto value = 1465 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1466 ASSERT_TRUE(value.IsResolve()); 1467 1468 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1469 } 1470 }); 1471 1472 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1473 1474 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1475 } 1476 1477 // Test InitializeStorage when a storage initialization is already ongoing and 1478 // an exclusive directory lock is requested after that. 1479 TEST_F(TestQuotaManager, InitializeStorage_OngoingWithExclusiveDirectoryLock) { 1480 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1481 1482 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1483 1484 PerformOnBackgroundThread([]() { 1485 QuotaManager* quotaManager = QuotaManager::Get(); 1486 ASSERT_TRUE(quotaManager); 1487 1488 RefPtr<UniversalDirectoryLock> directoryLock = 1489 quotaManager->CreateDirectoryLockInternal( 1490 PersistenceScope::CreateFromNull(), OriginScope::FromNull(), 1491 ClientStorageScope::CreateFromNull(), 1492 /* aExclusive */ true); 1493 1494 nsTArray<RefPtr<BoolPromise>> promises; 1495 1496 promises.AppendElement(quotaManager->InitializeStorage()->Then( 1497 GetCurrentSerialEventTarget(), __func__, 1498 [&directoryLock](const BoolPromise::ResolveOrRejectValue& aValue) { 1499 // The exclusive directory lock must be released when the first 1500 // storage initialization is finished, otherwise it would endlessly 1501 // block the second storage initialization. 1502 DropDirectoryLock(directoryLock); 1503 1504 if (aValue.IsReject()) { 1505 return BoolPromise::CreateAndReject(aValue.RejectValue(), __func__); 1506 } 1507 1508 return BoolPromise::CreateAndResolve(true, __func__); 1509 })); 1510 promises.AppendElement(directoryLock->Acquire()); 1511 promises.AppendElement(quotaManager->InitializeStorage()); 1512 1513 { 1514 auto value = 1515 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1516 ASSERT_TRUE(value.IsResolve()); 1517 1518 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1519 } 1520 }); 1521 1522 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1523 1524 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1525 } 1526 1527 // Test InitializeStorage when a storage initialization is already ongoing and 1528 // shared client directory locks are requested after that. 1529 // The shared client directory locks don't have to be released in this case. 1530 TEST_F(TestQuotaManager, InitializeStorage_OngoingWithClientDirectoryLocks) { 1531 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1532 1533 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1534 1535 PerformOnBackgroundThread([]() { 1536 QuotaManager* quotaManager = QuotaManager::Get(); 1537 ASSERT_TRUE(quotaManager); 1538 1539 RefPtr<ClientDirectoryLock> directoryLock = 1540 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 1541 /* aExclusive */ false); 1542 1543 RefPtr<ClientDirectoryLock> directoryLock2 = 1544 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 1545 /* aExclusive */ false); 1546 1547 nsTArray<RefPtr<BoolPromise>> promises; 1548 1549 promises.AppendElement(quotaManager->InitializeStorage()); 1550 promises.AppendElement(directoryLock->Acquire()); 1551 promises.AppendElement(quotaManager->InitializeStorage()); 1552 promises.AppendElement(directoryLock2->Acquire()); 1553 1554 { 1555 auto value = 1556 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1557 ASSERT_TRUE(value.IsResolve()); 1558 1559 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1560 } 1561 1562 DropDirectoryLock(directoryLock); 1563 DropDirectoryLock(directoryLock2); 1564 }); 1565 1566 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1567 1568 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1569 } 1570 1571 // Test InitializeStorage when a storage initialization is already ongoing and 1572 // shared client directory locks are requested after that with storage shutdown 1573 // scheduled in between. 1574 TEST_F(TestQuotaManager, 1575 InitializeStorage_OngoingWithClientDirectoryLocksAndScheduledShutdown) { 1576 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1577 1578 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1579 1580 PerformOnBackgroundThread([]() { 1581 QuotaManager* quotaManager = QuotaManager::Get(); 1582 ASSERT_TRUE(quotaManager); 1583 1584 RefPtr<ClientDirectoryLock> directoryLock = 1585 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 1586 /* aExclusive */ false); 1587 1588 directoryLock->OnInvalidate( 1589 [&directoryLock]() { DropDirectoryLock(directoryLock); }); 1590 1591 RefPtr<ClientDirectoryLock> directoryLock2 = 1592 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 1593 /* aExclusive */ false); 1594 1595 nsTArray<RefPtr<BoolPromise>> promises; 1596 1597 promises.AppendElement(quotaManager->InitializeStorage()); 1598 promises.AppendElement(directoryLock->Acquire()); 1599 promises.AppendElement(quotaManager->ShutdownStorage()); 1600 promises.AppendElement(quotaManager->InitializeStorage()); 1601 promises.AppendElement(directoryLock2->Acquire()); 1602 1603 { 1604 auto value = 1605 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1606 ASSERT_TRUE(value.IsResolve()); 1607 1608 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1609 } 1610 1611 DropDirectoryLock(directoryLock2); 1612 }); 1613 1614 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1615 1616 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1617 } 1618 1619 // Test InitializeStorage when a storage initialization already finished. 1620 TEST_F(TestQuotaManager, InitializeStorage_Finished) { 1621 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1622 1623 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1624 1625 PerformOnBackgroundThread([]() { 1626 QuotaManager* quotaManager = QuotaManager::Get(); 1627 ASSERT_TRUE(quotaManager); 1628 1629 { 1630 auto value = Await(quotaManager->InitializeStorage()); 1631 ASSERT_TRUE(value.IsResolve()); 1632 1633 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1634 } 1635 1636 { 1637 auto value = Await(quotaManager->InitializeStorage()); 1638 ASSERT_TRUE(value.IsResolve()); 1639 1640 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1641 } 1642 }); 1643 1644 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1645 1646 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1647 } 1648 1649 // Test InitializeStorage when a storage initialization already finished but 1650 // storage shutdown has just been scheduled. 1651 TEST_F(TestQuotaManager, InitializeStorage_FinishedWithScheduledShutdown) { 1652 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1653 1654 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1655 1656 PerformOnBackgroundThread([]() { 1657 QuotaManager* quotaManager = QuotaManager::Get(); 1658 ASSERT_TRUE(quotaManager); 1659 1660 { 1661 auto value = Await(quotaManager->InitializeStorage()); 1662 ASSERT_TRUE(value.IsResolve()); 1663 1664 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1665 } 1666 1667 nsTArray<RefPtr<BoolPromise>> promises; 1668 1669 promises.AppendElement(quotaManager->ShutdownStorage()); 1670 promises.AppendElement(quotaManager->InitializeStorage()); 1671 1672 { 1673 auto value = 1674 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1675 ASSERT_TRUE(value.IsResolve()); 1676 1677 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1678 } 1679 }); 1680 1681 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1682 1683 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1684 } 1685 1686 // Test InitializeStorage when a storage initialization already finished and 1687 // shared client directory locks are requested immediately after requesting 1688 // storage initialization. 1689 TEST_F(TestQuotaManager, InitializeStorage_FinishedWithClientDirectoryLocks) { 1690 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1691 1692 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1693 1694 PerformOnBackgroundThread([]() { 1695 QuotaManager* quotaManager = QuotaManager::Get(); 1696 ASSERT_TRUE(quotaManager); 1697 1698 RefPtr<ClientDirectoryLock> directoryLock = 1699 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 1700 /* aExclusive */ false); 1701 1702 nsTArray<RefPtr<BoolPromise>> promises; 1703 1704 promises.AppendElement(quotaManager->InitializeStorage()); 1705 promises.AppendElement(directoryLock->Acquire()); 1706 1707 { 1708 auto value = 1709 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1710 ASSERT_TRUE(value.IsResolve()); 1711 1712 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1713 } 1714 1715 RefPtr<ClientDirectoryLock> directoryLock2 = 1716 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 1717 /* aExclusive */ false); 1718 1719 promises.Clear(); 1720 1721 promises.AppendElement(quotaManager->InitializeStorage()); 1722 promises.AppendElement(directoryLock2->Acquire()); 1723 1724 { 1725 auto value = 1726 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1727 ASSERT_TRUE(value.IsResolve()); 1728 1729 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1730 } 1731 1732 DropDirectoryLock(directoryLock); 1733 DropDirectoryLock(directoryLock2); 1734 }); 1735 1736 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1737 1738 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1739 } 1740 1741 // Test InitializeStorage when a storage initialization already finished and 1742 // shared client directory locks are requested immediatelly after requesting 1743 // storage initialization with storage shutdown performed in between. 1744 // The shared client directory lock is released when it gets invalidated by 1745 // storage shutdown which then unblocks the shutdown. 1746 TEST_F(TestQuotaManager, 1747 InitializeStorage_FinishedWithClientDirectoryLocksAndScheduledShutdown) { 1748 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1749 1750 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1751 1752 PerformOnBackgroundThread([]() { 1753 QuotaManager* quotaManager = QuotaManager::Get(); 1754 ASSERT_TRUE(quotaManager); 1755 1756 RefPtr<ClientDirectoryLock> directoryLock = 1757 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 1758 /* aExclusive */ false); 1759 1760 directoryLock->OnInvalidate( 1761 [&directoryLock]() { DropDirectoryLock(directoryLock); }); 1762 1763 nsTArray<RefPtr<BoolPromise>> promises; 1764 1765 promises.AppendElement(quotaManager->InitializeStorage()); 1766 promises.AppendElement(directoryLock->Acquire()); 1767 1768 { 1769 auto value = 1770 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1771 ASSERT_TRUE(value.IsResolve()); 1772 1773 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1774 } 1775 1776 { 1777 auto value = Await(quotaManager->ShutdownStorage()); 1778 ASSERT_TRUE(value.IsResolve()); 1779 1780 ASSERT_FALSE(quotaManager->IsStorageInitialized()); 1781 } 1782 1783 RefPtr<ClientDirectoryLock> directoryLock2 = 1784 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 1785 /* aExclusive */ false); 1786 1787 promises.Clear(); 1788 1789 promises.AppendElement(quotaManager->InitializeStorage()); 1790 promises.AppendElement(directoryLock2->Acquire()); 1791 1792 { 1793 auto value = 1794 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1795 ASSERT_TRUE(value.IsResolve()); 1796 1797 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1798 } 1799 1800 DropDirectoryLock(directoryLock2); 1801 }); 1802 1803 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1804 1805 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1806 } 1807 1808 TEST_F(TestQuotaManager, 1809 InitializePersistentStorage_OtherExclusiveDirectoryLockAcquired) { 1810 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1811 1812 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1813 1814 PerformOnBackgroundThread([]() { 1815 QuotaManager* quotaManager = QuotaManager::Get(); 1816 ASSERT_TRUE(quotaManager); 1817 1818 { 1819 auto value = Await(quotaManager->InitializeStorage()); 1820 ASSERT_TRUE(value.IsResolve()); 1821 1822 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1823 } 1824 1825 RefPtr<UniversalDirectoryLock> directoryLock = 1826 quotaManager->CreateDirectoryLockInternal( 1827 PersistenceScope::CreateFromSet(PERSISTENCE_TYPE_TEMPORARY, 1828 PERSISTENCE_TYPE_DEFAULT), 1829 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 1830 /* aExclusive */ true); 1831 1832 { 1833 auto value = Await(directoryLock->Acquire()); 1834 ASSERT_TRUE(value.IsResolve()); 1835 } 1836 1837 { 1838 auto value = Await(quotaManager->InitializePersistentStorage()); 1839 ASSERT_TRUE(value.IsResolve()); 1840 1841 ASSERT_TRUE(quotaManager->IsPersistentStorageInitialized()); 1842 } 1843 1844 DropDirectoryLock(directoryLock); 1845 }); 1846 1847 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1848 1849 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1850 } 1851 1852 // Test InitializePersistentStorage when a persistent storage initialization is 1853 // already ongoing and an exclusive directory lock is requested after that. 1854 TEST_F(TestQuotaManager, 1855 InitializePersistentStorage_OngoingWithExclusiveDirectoryLock) { 1856 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1857 1858 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1859 1860 PerformOnBackgroundThread([]() { 1861 QuotaManager* quotaManager = QuotaManager::Get(); 1862 ASSERT_TRUE(quotaManager); 1863 1864 RefPtr<UniversalDirectoryLock> directoryLock = 1865 quotaManager->CreateDirectoryLockInternal( 1866 PersistenceScope::CreateFromNull(), OriginScope::FromNull(), 1867 ClientStorageScope::CreateFromNull(), 1868 /* aExclusive */ true); 1869 1870 nsTArray<RefPtr<BoolPromise>> promises; 1871 1872 promises.AppendElement(quotaManager->InitializeStorage()); 1873 promises.AppendElement(quotaManager->InitializePersistentStorage()->Then( 1874 GetCurrentSerialEventTarget(), __func__, 1875 [&directoryLock](const BoolPromise::ResolveOrRejectValue& aValue) { 1876 // The exclusive directory lock must be released when the first 1877 // Persistent storage initialization is finished, otherwise it would 1878 // endlessly block the second persistent storage initialization. 1879 DropDirectoryLock(directoryLock); 1880 1881 if (aValue.IsReject()) { 1882 return BoolPromise::CreateAndReject(aValue.RejectValue(), __func__); 1883 } 1884 1885 return BoolPromise::CreateAndResolve(true, __func__); 1886 })); 1887 promises.AppendElement(directoryLock->Acquire()); 1888 promises.AppendElement(quotaManager->InitializeStorage()); 1889 promises.AppendElement(quotaManager->InitializePersistentStorage()); 1890 1891 { 1892 auto value = 1893 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1894 ASSERT_TRUE(value.IsResolve()); 1895 1896 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1897 ASSERT_TRUE(quotaManager->IsPersistentStorageInitialized()); 1898 } 1899 }); 1900 1901 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1902 1903 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1904 } 1905 1906 // Test InitializePersistentStorage when a persistent storage initialization 1907 // already finished. 1908 TEST_F(TestQuotaManager, InitializePersistentStorage_Finished) { 1909 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1910 1911 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1912 1913 PerformOnBackgroundThread([]() { 1914 nsTArray<RefPtr<BoolPromise>> promises; 1915 1916 QuotaManager* quotaManager = QuotaManager::Get(); 1917 ASSERT_TRUE(quotaManager); 1918 1919 promises.AppendElement(quotaManager->InitializeStorage()); 1920 promises.AppendElement(quotaManager->InitializePersistentStorage()); 1921 1922 { 1923 auto value = 1924 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1925 ASSERT_TRUE(value.IsResolve()); 1926 1927 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1928 ASSERT_TRUE(quotaManager->IsPersistentStorageInitialized()); 1929 } 1930 1931 promises.Clear(); 1932 1933 promises.AppendElement(quotaManager->InitializeStorage()); 1934 promises.AppendElement(quotaManager->InitializePersistentStorage()); 1935 1936 { 1937 auto value = 1938 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1939 ASSERT_TRUE(value.IsResolve()); 1940 1941 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1942 ASSERT_TRUE(quotaManager->IsPersistentStorageInitialized()); 1943 } 1944 }); 1945 1946 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1947 1948 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1949 } 1950 1951 TEST_F(TestQuotaManager, 1952 InitializePersistentStorage_FinishedWithScheduledShutdown) { 1953 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1954 1955 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 1956 1957 PerformOnBackgroundThread([]() { 1958 nsTArray<RefPtr<BoolPromise>> promises; 1959 1960 QuotaManager* quotaManager = QuotaManager::Get(); 1961 ASSERT_TRUE(quotaManager); 1962 1963 promises.AppendElement(quotaManager->InitializeStorage()); 1964 promises.AppendElement(quotaManager->InitializePersistentStorage()); 1965 1966 { 1967 auto value = 1968 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1969 ASSERT_TRUE(value.IsResolve()); 1970 1971 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1972 ASSERT_TRUE(quotaManager->IsPersistentStorageInitialized()); 1973 } 1974 1975 promises.Clear(); 1976 1977 promises.AppendElement(quotaManager->ShutdownStorage()); 1978 promises.AppendElement(quotaManager->InitializeStorage()); 1979 promises.AppendElement(quotaManager->InitializePersistentStorage()); 1980 1981 { 1982 auto value = 1983 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 1984 ASSERT_TRUE(value.IsResolve()); 1985 1986 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 1987 ASSERT_TRUE(quotaManager->IsPersistentStorageInitialized()); 1988 } 1989 }); 1990 1991 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 1992 1993 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1994 } 1995 1996 TEST_F(TestQuotaManager, 1997 InitializeTemporaryStorage_OtherExclusiveDirectoryLockAcquired) { 1998 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 1999 2000 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2001 2002 PerformOnBackgroundThread([]() { 2003 QuotaManager* quotaManager = QuotaManager::Get(); 2004 ASSERT_TRUE(quotaManager); 2005 2006 { 2007 auto value = Await(quotaManager->InitializeStorage()); 2008 ASSERT_TRUE(value.IsResolve()); 2009 2010 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2011 } 2012 2013 RefPtr<UniversalDirectoryLock> directoryLock = 2014 quotaManager->CreateDirectoryLockInternal( 2015 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 2016 OriginScope::FromNull(), ClientStorageScope::CreateFromNull(), 2017 /* aExclusive */ true); 2018 2019 { 2020 auto value = Await(directoryLock->Acquire()); 2021 ASSERT_TRUE(value.IsResolve()); 2022 } 2023 2024 { 2025 auto value = Await(quotaManager->InitializeTemporaryStorage()); 2026 ASSERT_TRUE(value.IsResolve()); 2027 2028 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2029 } 2030 2031 DropDirectoryLock(directoryLock); 2032 }); 2033 2034 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2035 2036 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2037 } 2038 2039 // Test InitializeTemporaryStorage when a temporary storage initialization is 2040 // already ongoing and an exclusive directory lock is requested after that. 2041 TEST_F(TestQuotaManager, 2042 InitializeTemporaryStorage_OngoingWithExclusiveDirectoryLock) { 2043 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2044 2045 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2046 2047 PerformOnBackgroundThread([]() { 2048 QuotaManager* quotaManager = QuotaManager::Get(); 2049 ASSERT_TRUE(quotaManager); 2050 2051 RefPtr<UniversalDirectoryLock> directoryLock = 2052 quotaManager->CreateDirectoryLockInternal( 2053 PersistenceScope::CreateFromNull(), OriginScope::FromNull(), 2054 ClientStorageScope::CreateFromNull(), 2055 /* aExclusive */ true); 2056 2057 nsTArray<RefPtr<BoolPromise>> promises; 2058 2059 promises.AppendElement(quotaManager->InitializeStorage()); 2060 promises.AppendElement(quotaManager->InitializeTemporaryStorage()->Then( 2061 GetCurrentSerialEventTarget(), __func__, 2062 [&directoryLock](const BoolPromise::ResolveOrRejectValue& aValue) { 2063 // The exclusive directory lock must be dropped when the first 2064 // temporary storage initialization is finished, otherwise it would 2065 // endlessly block the second temporary storage initialization. 2066 DropDirectoryLock(directoryLock); 2067 2068 if (aValue.IsReject()) { 2069 return BoolPromise::CreateAndReject(aValue.RejectValue(), __func__); 2070 } 2071 2072 return BoolPromise::CreateAndResolve(true, __func__); 2073 })); 2074 promises.AppendElement(directoryLock->Acquire()); 2075 promises.AppendElement(quotaManager->InitializeStorage()); 2076 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2077 2078 { 2079 auto value = 2080 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2081 ASSERT_TRUE(value.IsResolve()); 2082 2083 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2084 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2085 } 2086 }); 2087 2088 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2089 2090 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2091 } 2092 2093 // Test InitializeTemporaryStorage when a temporary storage initialization 2094 // already finished. 2095 TEST_F(TestQuotaManager, InitializeTemporaryStorage_Finished) { 2096 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2097 2098 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2099 2100 PerformOnBackgroundThread([]() { 2101 nsTArray<RefPtr<BoolPromise>> promises; 2102 2103 QuotaManager* quotaManager = QuotaManager::Get(); 2104 ASSERT_TRUE(quotaManager); 2105 2106 promises.AppendElement(quotaManager->InitializeStorage()); 2107 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2108 2109 { 2110 auto value = 2111 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2112 ASSERT_TRUE(value.IsResolve()); 2113 2114 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2115 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2116 } 2117 2118 promises.Clear(); 2119 2120 promises.AppendElement(quotaManager->InitializeStorage()); 2121 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2122 2123 { 2124 auto value = 2125 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2126 ASSERT_TRUE(value.IsResolve()); 2127 2128 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2129 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2130 } 2131 }); 2132 2133 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2134 2135 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2136 } 2137 2138 TEST_F(TestQuotaManager, 2139 InitializeTemporaryStorage_FinishedWithScheduledShutdown) { 2140 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2141 2142 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2143 2144 PerformOnBackgroundThread([]() { 2145 nsTArray<RefPtr<BoolPromise>> promises; 2146 2147 QuotaManager* quotaManager = QuotaManager::Get(); 2148 ASSERT_TRUE(quotaManager); 2149 2150 promises.AppendElement(quotaManager->InitializeStorage()); 2151 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2152 2153 { 2154 auto value = 2155 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2156 ASSERT_TRUE(value.IsResolve()); 2157 2158 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2159 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2160 } 2161 2162 promises.Clear(); 2163 2164 promises.AppendElement(quotaManager->ShutdownStorage()); 2165 promises.AppendElement(quotaManager->InitializeStorage()); 2166 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2167 2168 { 2169 auto value = 2170 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2171 ASSERT_TRUE(value.IsResolve()); 2172 2173 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2174 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2175 } 2176 }); 2177 2178 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2179 2180 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2181 } 2182 2183 TEST_F(TestQuotaManager, 2184 InitializeTemporaryGroup_OtherExclusiveDirectoryLockAcquired) { 2185 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2186 2187 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2188 2189 PerformOnBackgroundThread([]() { 2190 auto testOriginMetadata = GetTestOriginMetadata(); 2191 2192 QuotaManager* quotaManager = QuotaManager::Get(); 2193 ASSERT_TRUE(quotaManager); 2194 2195 { 2196 auto value = Await(quotaManager->InitializeStorage()); 2197 ASSERT_TRUE(value.IsResolve()); 2198 2199 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2200 } 2201 2202 { 2203 auto value = Await(quotaManager->InitializeTemporaryStorage()); 2204 ASSERT_TRUE(value.IsResolve()); 2205 2206 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2207 } 2208 2209 RefPtr<UniversalDirectoryLock> directoryLock = 2210 quotaManager->CreateDirectoryLockInternal( 2211 PersistenceScope::CreateFromValue(PERSISTENCE_TYPE_PERSISTENT), 2212 OriginScope::FromGroup(testOriginMetadata.mGroup), 2213 ClientStorageScope::CreateFromNull(), 2214 /* aExclusive */ true); 2215 2216 { 2217 auto value = Await(directoryLock->Acquire()); 2218 ASSERT_TRUE(value.IsResolve()); 2219 } 2220 2221 { 2222 auto value = 2223 Await(quotaManager->InitializeTemporaryGroup(testOriginMetadata)); 2224 ASSERT_TRUE(value.IsResolve()); 2225 2226 ASSERT_TRUE( 2227 quotaManager->IsTemporaryGroupInitialized(testOriginMetadata)); 2228 } 2229 2230 DropDirectoryLock(directoryLock); 2231 }); 2232 2233 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2234 2235 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2236 } 2237 2238 // Test InitializeTemporaryGroup when a temporary group initialization is 2239 // already ongoing and an exclusive directory lock is requested after that. 2240 TEST_F(TestQuotaManager, 2241 InitializeTemporaryGroup_OngoingWithExclusiveDirectoryLock) { 2242 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2243 2244 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2245 2246 PerformOnBackgroundThread([]() { 2247 auto testOriginMetadata = GetTestOriginMetadata(); 2248 2249 QuotaManager* quotaManager = QuotaManager::Get(); 2250 ASSERT_TRUE(quotaManager); 2251 2252 RefPtr<UniversalDirectoryLock> directoryLock = 2253 quotaManager->CreateDirectoryLockInternal( 2254 PersistenceScope::CreateFromSet(PERSISTENCE_TYPE_TEMPORARY, 2255 PERSISTENCE_TYPE_DEFAULT), 2256 OriginScope::FromGroup(testOriginMetadata.mGroup), 2257 ClientStorageScope::CreateFromNull(), 2258 /* aExclusive */ true); 2259 2260 nsTArray<RefPtr<BoolPromise>> promises; 2261 2262 promises.AppendElement(quotaManager->InitializeStorage()); 2263 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2264 promises.AppendElement( 2265 quotaManager->InitializeTemporaryGroup(testOriginMetadata) 2266 ->Then(GetCurrentSerialEventTarget(), __func__, 2267 [&directoryLock]( 2268 const BoolPromise::ResolveOrRejectValue& aValue) { 2269 // The exclusive directory lock must be dropped when the 2270 // first temporary group initialization is finished, 2271 // otherwise it would endlessly block the second temporary 2272 // group initialization. 2273 DropDirectoryLock(directoryLock); 2274 2275 if (aValue.IsReject()) { 2276 return BoolPromise::CreateAndReject(aValue.RejectValue(), 2277 __func__); 2278 } 2279 2280 return BoolPromise::CreateAndResolve(true, __func__); 2281 })); 2282 promises.AppendElement(directoryLock->Acquire()); 2283 promises.AppendElement(quotaManager->InitializeStorage()); 2284 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2285 promises.AppendElement( 2286 quotaManager->InitializeTemporaryGroup(testOriginMetadata)); 2287 2288 { 2289 auto value = 2290 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2291 ASSERT_TRUE(value.IsResolve()); 2292 2293 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2294 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2295 ASSERT_TRUE( 2296 quotaManager->IsTemporaryGroupInitialized(testOriginMetadata)); 2297 } 2298 }); 2299 2300 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2301 2302 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2303 } 2304 2305 // Test InitializeTemporaryGroup when a temporary group initialization already 2306 // finished. 2307 TEST_F(TestQuotaManager, InitializeTemporaryGroup_Finished) { 2308 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2309 2310 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2311 2312 PerformOnBackgroundThread([]() { 2313 auto testOriginMetadata = GetTestOriginMetadata(); 2314 2315 nsTArray<RefPtr<BoolPromise>> promises; 2316 2317 QuotaManager* quotaManager = QuotaManager::Get(); 2318 ASSERT_TRUE(quotaManager); 2319 2320 promises.AppendElement(quotaManager->InitializeStorage()); 2321 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2322 promises.AppendElement( 2323 quotaManager->InitializeTemporaryGroup(testOriginMetadata)); 2324 2325 { 2326 auto value = 2327 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2328 ASSERT_TRUE(value.IsResolve()); 2329 2330 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2331 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2332 ASSERT_TRUE( 2333 quotaManager->IsTemporaryGroupInitialized(testOriginMetadata)); 2334 } 2335 2336 promises.Clear(); 2337 2338 promises.AppendElement(quotaManager->InitializeStorage()); 2339 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2340 promises.AppendElement( 2341 quotaManager->InitializeTemporaryGroup(testOriginMetadata)); 2342 2343 { 2344 auto value = 2345 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2346 ASSERT_TRUE(value.IsResolve()); 2347 2348 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2349 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2350 ASSERT_TRUE( 2351 quotaManager->IsTemporaryGroupInitialized(testOriginMetadata)); 2352 } 2353 }); 2354 2355 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2356 2357 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2358 } 2359 2360 TEST_F(TestQuotaManager, 2361 InitializeTemporaryGroup_FinishedWithScheduledShutdown) { 2362 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2363 2364 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2365 2366 PerformOnBackgroundThread([]() { 2367 auto testOriginMetadata = GetTestOriginMetadata(); 2368 2369 nsTArray<RefPtr<BoolPromise>> promises; 2370 2371 QuotaManager* quotaManager = QuotaManager::Get(); 2372 ASSERT_TRUE(quotaManager); 2373 2374 promises.AppendElement(quotaManager->InitializeStorage()); 2375 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2376 promises.AppendElement( 2377 quotaManager->InitializeTemporaryGroup(testOriginMetadata)); 2378 2379 { 2380 auto value = 2381 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2382 ASSERT_TRUE(value.IsResolve()); 2383 2384 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2385 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2386 ASSERT_TRUE( 2387 quotaManager->IsTemporaryGroupInitialized(testOriginMetadata)); 2388 } 2389 2390 promises.Clear(); 2391 2392 promises.AppendElement(quotaManager->ShutdownStorage()); 2393 promises.AppendElement(quotaManager->InitializeStorage()); 2394 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2395 promises.AppendElement( 2396 quotaManager->InitializeTemporaryGroup(testOriginMetadata)); 2397 2398 { 2399 auto value = 2400 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2401 ASSERT_TRUE(value.IsResolve()); 2402 2403 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2404 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2405 ASSERT_TRUE( 2406 quotaManager->IsTemporaryGroupInitialized(testOriginMetadata)); 2407 } 2408 }); 2409 2410 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2411 2412 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2413 } 2414 2415 TEST_F(TestQuotaManager, 2416 InitializePersistentOrigin_FinishedWithScheduledShutdown) { 2417 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2418 2419 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2420 2421 PerformOnBackgroundThread([]() { 2422 auto testOriginMetadata = GetTestPersistentOriginMetadata(); 2423 2424 nsTArray<RefPtr<BoolPromise>> promises; 2425 2426 QuotaManager* quotaManager = QuotaManager::Get(); 2427 ASSERT_TRUE(quotaManager); 2428 2429 promises.AppendElement(quotaManager->InitializeStorage()); 2430 promises.AppendElement( 2431 quotaManager->InitializePersistentOrigin(testOriginMetadata)); 2432 2433 { 2434 auto value = 2435 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2436 ASSERT_TRUE(value.IsResolve()); 2437 2438 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2439 ASSERT_TRUE( 2440 quotaManager->IsPersistentOriginInitialized(testOriginMetadata)); 2441 } 2442 2443 promises.Clear(); 2444 2445 promises.AppendElement(quotaManager->ShutdownStorage()); 2446 promises.AppendElement(quotaManager->InitializeStorage()); 2447 promises.AppendElement( 2448 quotaManager->InitializePersistentOrigin(testOriginMetadata)); 2449 2450 { 2451 auto value = 2452 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2453 ASSERT_TRUE(value.IsResolve()); 2454 2455 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2456 ASSERT_TRUE( 2457 quotaManager->IsPersistentOriginInitialized(testOriginMetadata)); 2458 } 2459 }); 2460 2461 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2462 2463 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2464 } 2465 2466 TEST_F(TestQuotaManager, 2467 InitializeTemporaryOrigin_FinishedWithScheduledShutdown) { 2468 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2469 2470 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2471 2472 PerformOnBackgroundThread([]() { 2473 auto testOriginMetadata = GetTestOriginMetadata(); 2474 2475 nsTArray<RefPtr<BoolPromise>> promises; 2476 2477 QuotaManager* quotaManager = QuotaManager::Get(); 2478 ASSERT_TRUE(quotaManager); 2479 2480 promises.AppendElement(quotaManager->InitializeStorage()); 2481 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2482 promises.AppendElement(quotaManager->InitializeTemporaryOrigin( 2483 testOriginMetadata, 2484 /* aCreateIfNonExistent */ false)); 2485 2486 { 2487 auto value = 2488 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2489 ASSERT_TRUE(value.IsResolve()); 2490 2491 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2492 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2493 ASSERT_TRUE( 2494 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 2495 } 2496 2497 promises.Clear(); 2498 2499 promises.AppendElement(quotaManager->ShutdownStorage()); 2500 promises.AppendElement(quotaManager->InitializeStorage()); 2501 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2502 promises.AppendElement(quotaManager->InitializeTemporaryOrigin( 2503 testOriginMetadata, 2504 /* aCreateIfNonExistent */ true)); 2505 2506 { 2507 auto value = 2508 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2509 ASSERT_TRUE(value.IsResolve()); 2510 2511 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2512 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2513 ASSERT_TRUE( 2514 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 2515 } 2516 }); 2517 2518 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2519 2520 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2521 } 2522 2523 TEST_F(TestQuotaManager, 2524 InitializePersistentClient_FinishedWithScheduledShutdown) { 2525 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2526 2527 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2528 2529 PerformOnBackgroundThread([]() { 2530 auto testClientMetadata = GetTestPersistentClientMetadata(); 2531 2532 nsTArray<RefPtr<BoolPromise>> promises; 2533 2534 QuotaManager* quotaManager = QuotaManager::Get(); 2535 ASSERT_TRUE(quotaManager); 2536 2537 promises.AppendElement(quotaManager->InitializeStorage()); 2538 promises.AppendElement( 2539 quotaManager->InitializePersistentOrigin(testClientMetadata)); 2540 promises.AppendElement( 2541 quotaManager->InitializePersistentClient(testClientMetadata)); 2542 2543 { 2544 auto value = 2545 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2546 ASSERT_TRUE(value.IsResolve()); 2547 2548 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2549 ASSERT_TRUE( 2550 quotaManager->IsPersistentOriginInitialized(testClientMetadata)); 2551 ASSERT_TRUE( 2552 quotaManager->IsPersistentClientInitialized(testClientMetadata)); 2553 } 2554 2555 promises.Clear(); 2556 2557 promises.AppendElement(quotaManager->ShutdownStorage()); 2558 promises.AppendElement(quotaManager->InitializeStorage()); 2559 promises.AppendElement( 2560 quotaManager->InitializePersistentOrigin(testClientMetadata)); 2561 promises.AppendElement( 2562 quotaManager->InitializePersistentClient(testClientMetadata)); 2563 2564 { 2565 auto value = 2566 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2567 ASSERT_TRUE(value.IsResolve()); 2568 2569 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2570 ASSERT_TRUE( 2571 quotaManager->IsPersistentOriginInitialized(testClientMetadata)); 2572 ASSERT_TRUE( 2573 quotaManager->IsPersistentClientInitialized(testClientMetadata)); 2574 } 2575 }); 2576 2577 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2578 2579 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2580 } 2581 2582 TEST_F(TestQuotaManager, 2583 InitializeTemporaryClient_FinishedWithScheduledShutdown) { 2584 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2585 2586 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2587 2588 PerformOnBackgroundThread([]() { 2589 auto testClientMetadata = GetTestClientMetadata(); 2590 2591 nsTArray<RefPtr<BoolPromise>> promises; 2592 2593 QuotaManager* quotaManager = QuotaManager::Get(); 2594 ASSERT_TRUE(quotaManager); 2595 2596 promises.AppendElement(quotaManager->InitializeStorage()); 2597 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2598 promises.AppendElement(quotaManager->InitializeTemporaryOrigin( 2599 testClientMetadata, 2600 /* aCreateIfNonExistent */ true)); 2601 promises.AppendElement(quotaManager->InitializeTemporaryClient( 2602 testClientMetadata, 2603 /* aCreateIfNonExistent */ true)); 2604 2605 { 2606 auto value = 2607 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2608 ASSERT_TRUE(value.IsResolve()); 2609 2610 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2611 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2612 ASSERT_TRUE( 2613 quotaManager->IsTemporaryOriginInitialized(testClientMetadata)); 2614 ASSERT_TRUE( 2615 quotaManager->IsTemporaryClientInitialized(testClientMetadata)); 2616 } 2617 2618 promises.Clear(); 2619 2620 promises.AppendElement(quotaManager->ShutdownStorage()); 2621 promises.AppendElement(quotaManager->InitializeStorage()); 2622 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2623 promises.AppendElement(quotaManager->InitializeTemporaryOrigin( 2624 testClientMetadata, 2625 /* aCreateIfNonExistent */ true)); 2626 promises.AppendElement(quotaManager->InitializeTemporaryClient( 2627 testClientMetadata, 2628 /* aCreateIfNonExistent */ true)); 2629 2630 { 2631 auto value = 2632 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2633 ASSERT_TRUE(value.IsResolve()); 2634 2635 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2636 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2637 ASSERT_TRUE( 2638 quotaManager->IsTemporaryOriginInitialized(testClientMetadata)); 2639 ASSERT_TRUE( 2640 quotaManager->IsTemporaryClientInitialized(testClientMetadata)); 2641 } 2642 }); 2643 2644 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2645 2646 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2647 } 2648 2649 // Test simple SaveOriginAccessTime behavior. 2650 TEST_F(TestQuotaManager, SaveOriginAccessTime_Simple) { 2651 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2652 2653 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2654 2655 PerformOnBackgroundThread([]() { 2656 auto testOriginMetadata = GetTestOriginMetadata(); 2657 2658 nsTArray<RefPtr<BoolPromise>> promises; 2659 2660 QuotaManager* quotaManager = QuotaManager::Get(); 2661 ASSERT_TRUE(quotaManager); 2662 2663 promises.AppendElement(quotaManager->InitializeStorage()); 2664 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2665 promises.AppendElement(quotaManager->InitializeTemporaryOrigin( 2666 testOriginMetadata, 2667 /* aCreateIfNonExistent */ false)); 2668 2669 { 2670 auto value = 2671 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2672 ASSERT_TRUE(value.IsResolve()); 2673 2674 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2675 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2676 ASSERT_TRUE( 2677 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 2678 } 2679 2680 { 2681 auto value = 2682 Await(quotaManager->SaveOriginAccessTime(testOriginMetadata)); 2683 ASSERT_TRUE(value.IsResolve()); 2684 } 2685 }); 2686 2687 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2688 2689 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2690 } 2691 2692 // Test SaveOriginAccessTime when an exclusive client directory lock for a 2693 // different client scope is acquired. 2694 TEST_F(TestQuotaManager, 2695 SaveOriginAccessTime_SimpleWithOtherExclusiveClientDirectoryLock) { 2696 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2697 2698 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2699 2700 PerformOnBackgroundThread([]() { 2701 auto testOriginMetadata = GetTestOriginMetadata(); 2702 2703 nsTArray<RefPtr<BoolPromise>> promises; 2704 2705 QuotaManager* quotaManager = QuotaManager::Get(); 2706 ASSERT_TRUE(quotaManager); 2707 2708 // Storage, temporary storage and temporary origin must be initialized 2709 // before saving the origin access time. This also needs to happen before 2710 // acquiring the exclusive directory lock below, otherwise it would lead to 2711 // a hang. 2712 promises.AppendElement(quotaManager->InitializeStorage()); 2713 promises.AppendElement(quotaManager->InitializeTemporaryStorage()); 2714 promises.AppendElement(quotaManager->InitializeTemporaryOrigin( 2715 testOriginMetadata, 2716 /* aCreateIfNonExistent */ false)); 2717 2718 { 2719 auto value = 2720 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 2721 ASSERT_TRUE(value.IsResolve()); 2722 2723 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2724 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2725 ASSERT_TRUE( 2726 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 2727 } 2728 2729 // Acquire an exclusive directory lock for the SimpleDB quota client. 2730 RefPtr<ClientDirectoryLock> directoryLock = 2731 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 2732 /* aExclusive */ true); 2733 2734 { 2735 auto value = Await(directoryLock->Acquire()); 2736 ASSERT_TRUE(value.IsResolve()); 2737 } 2738 2739 // Save origin access time while the exclusive directory lock for SimpleDB 2740 // is held. Verifies that saving origin access time uses a lock that does 2741 // not overlap with quota client directory locks. 2742 { 2743 auto value = 2744 Await(quotaManager->SaveOriginAccessTime(testOriginMetadata)); 2745 ASSERT_TRUE(value.IsResolve()); 2746 } 2747 2748 DropDirectoryLock(directoryLock); 2749 }); 2750 2751 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2752 2753 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2754 } 2755 2756 // Test simple ClearStoragesForOrigin. 2757 TEST_F(TestQuotaManager, ClearStoragesForOrigin_Simple) { 2758 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2759 2760 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2761 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 2762 ASSERT_NO_FATAL_FAILURE( 2763 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 2764 2765 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 2766 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 2767 ASSERT_NO_FATAL_FAILURE( 2768 InitializeTemporaryOrigin(GetTestOriginMetadata(), 2769 /* aCreateIfNonExistent */ true)); 2770 2771 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2772 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 2773 ASSERT_NO_FATAL_FAILURE( 2774 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 2775 2776 PerformOnBackgroundThread([]() { 2777 auto testOriginMetadata = GetTestOriginMetadata(); 2778 2779 nsCOMPtr<nsIPrincipal> principal = 2780 BasePrincipal::CreateContentPrincipal(testOriginMetadata.mOrigin); 2781 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 2782 2783 mozilla::ipc::PrincipalInfo principalInfo; 2784 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 2785 QM_TEST_FAIL); 2786 2787 QuotaManager* quotaManager = QuotaManager::Get(); 2788 ASSERT_TRUE(quotaManager); 2789 2790 { 2791 auto value = Await(quotaManager->ClearStoragesForOrigin( 2792 /* aPersistenceType */ Nothing(), principalInfo)); 2793 ASSERT_TRUE(value.IsResolve()); 2794 2795 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2796 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2797 ASSERT_FALSE( 2798 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 2799 } 2800 }); 2801 2802 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2803 2804 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2805 } 2806 2807 TEST_F(TestQuotaManager, ClearStoragesForOrigin_NonExistentOriginDirectory) { 2808 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2809 2810 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2811 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 2812 ASSERT_NO_FATAL_FAILURE( 2813 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 2814 2815 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 2816 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 2817 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 2818 GetTestOriginMetadata(), /* aCreateIfNonExistent */ false)); 2819 2820 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2821 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 2822 ASSERT_NO_FATAL_FAILURE( 2823 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 2824 2825 PerformOnBackgroundThread([]() { 2826 auto testOriginMetadata = GetTestOriginMetadata(); 2827 2828 nsCOMPtr<nsIPrincipal> principal = 2829 BasePrincipal::CreateContentPrincipal(testOriginMetadata.mOrigin); 2830 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 2831 2832 mozilla::ipc::PrincipalInfo principalInfo; 2833 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 2834 QM_TEST_FAIL); 2835 2836 QuotaManager* quotaManager = QuotaManager::Get(); 2837 ASSERT_TRUE(quotaManager); 2838 2839 { 2840 auto value = Await(quotaManager->ClearStoragesForOrigin( 2841 /* aPersistenceType */ Nothing(), principalInfo)); 2842 ASSERT_TRUE(value.IsResolve()); 2843 2844 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2845 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2846 ASSERT_FALSE( 2847 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 2848 } 2849 }); 2850 2851 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2852 2853 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2854 } 2855 2856 TEST_F(TestQuotaManager, ClearStoragesForOrigin_ClientDirectoryExists) { 2857 auto testClientMetadata = GetTestClientMetadata(); 2858 2859 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2860 2861 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2862 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 2863 ASSERT_NO_FATAL_FAILURE( 2864 AssertTemporaryOriginNotInitialized(testClientMetadata)); 2865 2866 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 2867 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 2868 ASSERT_NO_FATAL_FAILURE( 2869 InitializeTemporaryOrigin(testClientMetadata, 2870 /* aCreateIfNonExistent */ true)); 2871 ASSERT_NO_FATAL_FAILURE( 2872 InitializeTemporaryClient(testClientMetadata, 2873 /* aCreateIfNonExistent */ true)); 2874 2875 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2876 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 2877 ASSERT_NO_FATAL_FAILURE(AssertTemporaryOriginInitialized(testClientMetadata)); 2878 2879 PerformOnBackgroundThread([testClientMetadata]() { 2880 nsCOMPtr<nsIPrincipal> principal = 2881 BasePrincipal::CreateContentPrincipal(testClientMetadata.mOrigin); 2882 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 2883 2884 mozilla::ipc::PrincipalInfo principalInfo; 2885 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 2886 QM_TEST_FAIL); 2887 2888 QuotaManager* quotaManager = QuotaManager::Get(); 2889 ASSERT_TRUE(quotaManager); 2890 2891 { 2892 auto value = Await(quotaManager->ClearStoragesForOrigin( 2893 /* aPersistenceType */ Nothing(), principalInfo)); 2894 ASSERT_TRUE(value.IsResolve()); 2895 2896 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2897 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2898 ASSERT_FALSE( 2899 quotaManager->IsTemporaryOriginInitialized(testClientMetadata)); 2900 ASSERT_FALSE( 2901 quotaManager->IsTemporaryClientInitialized(testClientMetadata)); 2902 } 2903 }); 2904 2905 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2906 2907 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2908 } 2909 2910 // Test simple ClearStoragesForClient. 2911 TEST_F(TestQuotaManager, ClearStoragesForClient_Simple) { 2912 auto testClientMetadata = GetTestClientMetadata(); 2913 2914 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2915 2916 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2917 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 2918 ASSERT_NO_FATAL_FAILURE( 2919 AssertTemporaryOriginNotInitialized(testClientMetadata)); 2920 2921 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 2922 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 2923 ASSERT_NO_FATAL_FAILURE( 2924 InitializeTemporaryOrigin(testClientMetadata, 2925 /* aCreateIfNonExistent */ true)); 2926 ASSERT_NO_FATAL_FAILURE( 2927 InitializeTemporaryClient(testClientMetadata, 2928 /* aCreateIfNonExistent */ true)); 2929 2930 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2931 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 2932 ASSERT_NO_FATAL_FAILURE(AssertTemporaryOriginInitialized(testClientMetadata)); 2933 2934 PerformOnBackgroundThread([testClientMetadata]() { 2935 nsCOMPtr<nsIPrincipal> principal = 2936 BasePrincipal::CreateContentPrincipal(testClientMetadata.mOrigin); 2937 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 2938 2939 mozilla::ipc::PrincipalInfo principalInfo; 2940 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 2941 QM_TEST_FAIL); 2942 2943 QuotaManager* quotaManager = QuotaManager::Get(); 2944 ASSERT_TRUE(quotaManager); 2945 2946 { 2947 auto value = Await(quotaManager->ClearStoragesForClient( 2948 /* aPersistenceType */ Nothing(), principalInfo, 2949 testClientMetadata.mClientType)); 2950 ASSERT_TRUE(value.IsResolve()); 2951 2952 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 2953 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 2954 ASSERT_TRUE( 2955 quotaManager->IsTemporaryOriginInitialized(testClientMetadata)); 2956 ASSERT_FALSE( 2957 quotaManager->IsTemporaryClientInitialized(testClientMetadata)); 2958 } 2959 }); 2960 2961 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2962 2963 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2964 } 2965 2966 // Test simple ClearStoragesForOriginPrefix. 2967 TEST_F(TestQuotaManager, ClearStoragesForOriginPrefix_Simple) { 2968 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 2969 2970 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 2971 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 2972 ASSERT_NO_FATAL_FAILURE( 2973 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 2974 2975 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 2976 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 2977 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 2978 GetTestOriginMetadata(), /* aCreateIfNonExistent */ true)); 2979 2980 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 2981 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 2982 ASSERT_NO_FATAL_FAILURE( 2983 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 2984 2985 PerformOnBackgroundThread([]() { 2986 auto testOriginMetadata = GetTestOriginMetadata(); 2987 2988 nsCOMPtr<nsIPrincipal> principal = 2989 BasePrincipal::CreateContentPrincipal(testOriginMetadata.mOrigin); 2990 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 2991 2992 mozilla::ipc::PrincipalInfo principalInfo; 2993 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 2994 QM_TEST_FAIL); 2995 2996 QuotaManager* quotaManager = QuotaManager::Get(); 2997 ASSERT_TRUE(quotaManager); 2998 2999 { 3000 auto value = Await(quotaManager->ClearStoragesForOriginPrefix( 3001 /* aPersistenceType */ Nothing(), principalInfo)); 3002 ASSERT_TRUE(value.IsResolve()); 3003 3004 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3005 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3006 ASSERT_FALSE( 3007 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 3008 } 3009 }); 3010 3011 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3012 3013 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3014 } 3015 3016 TEST_F(TestQuotaManager, 3017 ClearStoragesForOriginPrefix_NonExistentOriginDirectory) { 3018 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3019 3020 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3021 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3022 ASSERT_NO_FATAL_FAILURE( 3023 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 3024 3025 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3026 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3027 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3028 GetTestOriginMetadata(), /* aCreateIfNonExistent */ false)); 3029 3030 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3031 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3032 ASSERT_NO_FATAL_FAILURE( 3033 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 3034 3035 PerformOnBackgroundThread([]() { 3036 auto testOriginMetadata = GetTestOriginMetadata(); 3037 3038 nsCOMPtr<nsIPrincipal> principal = 3039 BasePrincipal::CreateContentPrincipal(testOriginMetadata.mOrigin); 3040 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 3041 3042 mozilla::ipc::PrincipalInfo principalInfo; 3043 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 3044 QM_TEST_FAIL); 3045 3046 QuotaManager* quotaManager = QuotaManager::Get(); 3047 ASSERT_TRUE(quotaManager); 3048 3049 { 3050 auto value = Await(quotaManager->ClearStoragesForOriginPrefix( 3051 /* aPersistenceType */ Nothing(), principalInfo)); 3052 ASSERT_TRUE(value.IsResolve()); 3053 3054 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3055 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3056 ASSERT_FALSE( 3057 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 3058 } 3059 }); 3060 3061 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3062 3063 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3064 } 3065 3066 // Test simple ClearStoragesForOriginAttributesPattern. 3067 TEST_F(TestQuotaManager, ClearStoragesForOriginAttributesPattern_Simple) { 3068 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3069 3070 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3071 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3072 ASSERT_NO_FATAL_FAILURE( 3073 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 3074 3075 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3076 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3077 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3078 GetTestOriginMetadata(), /* aCreateIfNonExistent */ true)); 3079 3080 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3081 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3082 ASSERT_NO_FATAL_FAILURE( 3083 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 3084 3085 PerformOnBackgroundThread([]() { 3086 auto testOriginMetadata = GetTestOriginMetadata(); 3087 3088 nsCOMPtr<nsIPrincipal> principal = 3089 BasePrincipal::CreateContentPrincipal(testOriginMetadata.mOrigin); 3090 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 3091 3092 mozilla::ipc::PrincipalInfo principalInfo; 3093 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 3094 QM_TEST_FAIL); 3095 3096 QuotaManager* quotaManager = QuotaManager::Get(); 3097 ASSERT_TRUE(quotaManager); 3098 3099 { 3100 auto value = Await(quotaManager->ClearStoragesForOriginAttributesPattern( 3101 OriginAttributesPattern())); 3102 ASSERT_TRUE(value.IsResolve()); 3103 3104 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3105 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3106 ASSERT_FALSE( 3107 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 3108 } 3109 }); 3110 3111 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3112 3113 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3114 } 3115 3116 TEST_F(TestQuotaManager, 3117 ClearStoragesForOriginAttributesPattern_NonExistentOriginDirectory) { 3118 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3119 3120 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3121 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3122 ASSERT_NO_FATAL_FAILURE( 3123 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 3124 3125 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3126 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3127 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3128 GetTestOriginMetadata(), /* aCreateIfNonExistent */ false)); 3129 3130 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3131 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3132 ASSERT_NO_FATAL_FAILURE( 3133 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 3134 3135 PerformOnBackgroundThread([]() { 3136 auto testOriginMetadata = GetTestOriginMetadata(); 3137 3138 QuotaManager* quotaManager = QuotaManager::Get(); 3139 ASSERT_TRUE(quotaManager); 3140 3141 { 3142 auto value = Await(quotaManager->ClearStoragesForOriginAttributesPattern( 3143 OriginAttributesPattern())); 3144 ASSERT_TRUE(value.IsResolve()); 3145 3146 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3147 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3148 ASSERT_FALSE( 3149 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 3150 } 3151 }); 3152 3153 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3154 3155 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3156 } 3157 3158 TEST_F(TestQuotaManager, ClearPrivateRepository_OriginDirectoryExists) { 3159 auto testOriginMetadata = GetTestPrivateOriginMetadata(); 3160 3161 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3162 3163 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3164 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3165 ASSERT_NO_FATAL_FAILURE( 3166 AssertTemporaryOriginNotInitialized(testOriginMetadata)); 3167 3168 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3169 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3170 ASSERT_NO_FATAL_FAILURE( 3171 InitializeTemporaryOrigin(testOriginMetadata, 3172 /* aCreateIfNonExistent */ true)); 3173 3174 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3175 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3176 ASSERT_NO_FATAL_FAILURE(AssertTemporaryOriginInitialized(testOriginMetadata)); 3177 3178 PerformOnBackgroundThread([testOriginMetadata]() { 3179 QuotaManager* quotaManager = QuotaManager::Get(); 3180 ASSERT_TRUE(quotaManager); 3181 3182 { 3183 auto value = Await(quotaManager->ClearPrivateRepository()); 3184 ASSERT_TRUE(value.IsResolve()); 3185 3186 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3187 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3188 ASSERT_FALSE( 3189 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 3190 } 3191 }); 3192 3193 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3194 3195 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3196 } 3197 3198 TEST_F(TestQuotaManager, ClearPrivateRepository_ClientDirectoryExists) { 3199 auto testClientMetadata = GetTestPrivateClientMetadata(); 3200 3201 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3202 3203 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3204 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3205 ASSERT_NO_FATAL_FAILURE( 3206 AssertTemporaryOriginNotInitialized(testClientMetadata)); 3207 3208 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3209 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3210 ASSERT_NO_FATAL_FAILURE( 3211 InitializeTemporaryOrigin(testClientMetadata, 3212 /* aCreateIfNonExistent */ true)); 3213 ASSERT_NO_FATAL_FAILURE( 3214 InitializeTemporaryClient(testClientMetadata, 3215 /* aCreateIfNonExistent */ true)); 3216 3217 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3218 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3219 ASSERT_NO_FATAL_FAILURE(AssertTemporaryOriginInitialized(testClientMetadata)); 3220 3221 PerformOnBackgroundThread([testClientMetadata]() { 3222 QuotaManager* quotaManager = QuotaManager::Get(); 3223 ASSERT_TRUE(quotaManager); 3224 3225 { 3226 auto value = Await(quotaManager->ClearPrivateRepository()); 3227 ASSERT_TRUE(value.IsResolve()); 3228 3229 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3230 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3231 ASSERT_FALSE( 3232 quotaManager->IsTemporaryOriginInitialized(testClientMetadata)); 3233 ASSERT_FALSE( 3234 quotaManager->IsTemporaryClientInitialized(testClientMetadata)); 3235 } 3236 }); 3237 3238 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3239 3240 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3241 } 3242 3243 // Test simple ShutdownStoragesForOrigin. 3244 TEST_F(TestQuotaManager, ShutdownStoragesForOrigin_Simple) { 3245 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3246 3247 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3248 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3249 ASSERT_NO_FATAL_FAILURE( 3250 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 3251 3252 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3253 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3254 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3255 GetTestOriginMetadata(), /* aCreateIfNonExistent */ true)); 3256 3257 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3258 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3259 ASSERT_NO_FATAL_FAILURE( 3260 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 3261 3262 PerformOnBackgroundThread([]() { 3263 auto testOriginMetadata = GetTestOriginMetadata(); 3264 3265 nsCOMPtr<nsIPrincipal> principal = 3266 BasePrincipal::CreateContentPrincipal(testOriginMetadata.mOrigin); 3267 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 3268 3269 mozilla::ipc::PrincipalInfo principalInfo; 3270 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 3271 QM_TEST_FAIL); 3272 3273 QuotaManager* quotaManager = QuotaManager::Get(); 3274 ASSERT_TRUE(quotaManager); 3275 3276 { 3277 auto value = Await(quotaManager->ShutdownStoragesForOrigin( 3278 /* aPersistenceType */ Nothing(), principalInfo)); 3279 ASSERT_TRUE(value.IsResolve()); 3280 3281 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3282 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3283 ASSERT_FALSE( 3284 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 3285 } 3286 }); 3287 3288 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3289 3290 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3291 } 3292 3293 TEST_F(TestQuotaManager, ShutdownStoragesForOrigin_NonExistentOriginDirectory) { 3294 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3295 3296 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3297 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3298 ASSERT_NO_FATAL_FAILURE( 3299 AssertTemporaryOriginNotInitialized(GetTestOriginMetadata())); 3300 3301 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3302 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3303 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3304 GetTestOriginMetadata(), /* aCreateIfNonExistent */ false)); 3305 3306 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3307 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3308 ASSERT_NO_FATAL_FAILURE( 3309 AssertTemporaryOriginInitialized(GetTestOriginMetadata())); 3310 3311 PerformOnBackgroundThread([]() { 3312 auto testOriginMetadata = GetTestOriginMetadata(); 3313 3314 nsCOMPtr<nsIPrincipal> principal = 3315 BasePrincipal::CreateContentPrincipal(testOriginMetadata.mOrigin); 3316 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 3317 3318 mozilla::ipc::PrincipalInfo principalInfo; 3319 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 3320 QM_TEST_FAIL); 3321 3322 QuotaManager* quotaManager = QuotaManager::Get(); 3323 ASSERT_TRUE(quotaManager); 3324 3325 { 3326 auto value = Await(quotaManager->ShutdownStoragesForOrigin( 3327 /* aPersistenceType */ Nothing(), principalInfo)); 3328 ASSERT_TRUE(value.IsResolve()); 3329 3330 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3331 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3332 ASSERT_FALSE( 3333 quotaManager->IsTemporaryOriginInitialized(testOriginMetadata)); 3334 } 3335 }); 3336 3337 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3338 3339 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3340 } 3341 3342 TEST_F(TestQuotaManager, ShutdownStoragesForOrigin_ClientDirectoryExists) { 3343 auto testClientMetadata = GetTestClientMetadata(); 3344 3345 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3346 3347 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3348 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3349 ASSERT_NO_FATAL_FAILURE( 3350 AssertTemporaryOriginNotInitialized(testClientMetadata)); 3351 3352 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3353 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3354 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3355 testClientMetadata, /* aCreateIfNonExistent */ true)); 3356 ASSERT_NO_FATAL_FAILURE( 3357 InitializeTemporaryClient(testClientMetadata, 3358 /* aCreateIfNonExistent */ true)); 3359 3360 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3361 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3362 ASSERT_NO_FATAL_FAILURE(AssertTemporaryOriginInitialized(testClientMetadata)); 3363 3364 PerformOnBackgroundThread([testClientMetadata]() { 3365 nsCOMPtr<nsIPrincipal> principal = 3366 BasePrincipal::CreateContentPrincipal(testClientMetadata.mOrigin); 3367 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 3368 3369 mozilla::ipc::PrincipalInfo principalInfo; 3370 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 3371 QM_TEST_FAIL); 3372 3373 QuotaManager* quotaManager = QuotaManager::Get(); 3374 ASSERT_TRUE(quotaManager); 3375 3376 { 3377 auto value = Await(quotaManager->ShutdownStoragesForOrigin( 3378 /* aPersistenceType */ Nothing(), principalInfo)); 3379 ASSERT_TRUE(value.IsResolve()); 3380 3381 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3382 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3383 ASSERT_FALSE( 3384 quotaManager->IsTemporaryOriginInitialized(testClientMetadata)); 3385 ASSERT_FALSE( 3386 quotaManager->IsTemporaryClientInitialized(testClientMetadata)); 3387 } 3388 }); 3389 3390 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3391 3392 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3393 } 3394 3395 // Test simple ShutdownStoragesForClient. 3396 TEST_F(TestQuotaManager, ShutdownStoragesForClient_Simple) { 3397 auto testClientMetadata = GetTestClientMetadata(); 3398 3399 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3400 3401 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3402 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized()); 3403 ASSERT_NO_FATAL_FAILURE( 3404 AssertTemporaryOriginNotInitialized(testClientMetadata)); 3405 3406 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3407 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3408 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3409 testClientMetadata, /* aCreateIfNonExistent */ true)); 3410 ASSERT_NO_FATAL_FAILURE( 3411 InitializeTemporaryClient(testClientMetadata, 3412 /* aCreateIfNonExistent */ true)); 3413 3414 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3415 ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageInitialized()); 3416 ASSERT_NO_FATAL_FAILURE(AssertTemporaryOriginInitialized(testClientMetadata)); 3417 3418 PerformOnBackgroundThread([testClientMetadata]() { 3419 nsCOMPtr<nsIPrincipal> principal = 3420 BasePrincipal::CreateContentPrincipal(testClientMetadata.mOrigin); 3421 QM_TRY(MOZ_TO_RESULT(principal), QM_TEST_FAIL); 3422 3423 mozilla::ipc::PrincipalInfo principalInfo; 3424 QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)), 3425 QM_TEST_FAIL); 3426 3427 QuotaManager* quotaManager = QuotaManager::Get(); 3428 ASSERT_TRUE(quotaManager); 3429 3430 { 3431 auto value = Await(quotaManager->ShutdownStoragesForClient( 3432 /* aPersistenceType */ Nothing(), principalInfo, 3433 testClientMetadata.mClientType)); 3434 ASSERT_TRUE(value.IsResolve()); 3435 3436 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3437 ASSERT_TRUE(quotaManager->IsTemporaryStorageInitialized()); 3438 ASSERT_TRUE( 3439 quotaManager->IsTemporaryOriginInitialized(testClientMetadata)); 3440 ASSERT_FALSE( 3441 quotaManager->IsTemporaryClientInitialized(testClientMetadata)); 3442 } 3443 }); 3444 3445 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3446 3447 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3448 } 3449 3450 // Test simple ShutdownStorage. 3451 TEST_F(TestQuotaManager, ShutdownStorage_Simple) { 3452 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3453 3454 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3455 3456 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3457 3458 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3459 3460 PerformOnBackgroundThread([]() { 3461 QuotaManager* quotaManager = QuotaManager::Get(); 3462 ASSERT_TRUE(quotaManager); 3463 3464 { 3465 auto value = Await(quotaManager->ShutdownStorage()); 3466 ASSERT_TRUE(value.IsResolve()); 3467 3468 ASSERT_FALSE(quotaManager->IsStorageInitialized()); 3469 } 3470 }); 3471 3472 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3473 3474 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3475 } 3476 3477 // Test ShutdownStorage when a storage shutdown is already ongoing. 3478 TEST_F(TestQuotaManager, ShutdownStorage_Ongoing) { 3479 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3480 3481 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3482 3483 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3484 3485 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3486 3487 PerformOnBackgroundThread([]() { 3488 QuotaManager* quotaManager = QuotaManager::Get(); 3489 ASSERT_TRUE(quotaManager); 3490 3491 nsTArray<RefPtr<BoolPromise>> promises; 3492 3493 promises.AppendElement(quotaManager->ShutdownStorage()); 3494 promises.AppendElement(quotaManager->ShutdownStorage()); 3495 3496 { 3497 auto value = 3498 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 3499 ASSERT_TRUE(value.IsResolve()); 3500 3501 ASSERT_FALSE(quotaManager->IsStorageInitialized()); 3502 } 3503 }); 3504 3505 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3506 3507 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3508 } 3509 3510 // Test ShutdownStorage when a storage shutdown is already ongoing and storage 3511 // initialization is scheduled after that. 3512 TEST_F(TestQuotaManager, ShutdownStorage_OngoingWithScheduledInitialization) { 3513 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3514 3515 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3516 3517 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3518 3519 ASSERT_NO_FATAL_FAILURE(AssertStorageInitialized()); 3520 3521 PerformOnBackgroundThread([]() { 3522 QuotaManager* quotaManager = QuotaManager::Get(); 3523 ASSERT_TRUE(quotaManager); 3524 3525 nsTArray<RefPtr<BoolPromise>> promises; 3526 3527 promises.AppendElement(quotaManager->ShutdownStorage()); 3528 promises.AppendElement(quotaManager->InitializeStorage()); 3529 promises.AppendElement(quotaManager->ShutdownStorage()); 3530 3531 { 3532 auto value = 3533 Await(BoolPromise::All(GetCurrentSerialEventTarget(), promises)); 3534 ASSERT_TRUE(value.IsResolve()); 3535 3536 ASSERT_FALSE(quotaManager->IsStorageInitialized()); 3537 } 3538 }); 3539 3540 ASSERT_NO_FATAL_FAILURE(AssertStorageNotInitialized()); 3541 3542 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3543 } 3544 3545 // Test ShutdownStorage when a storage shutdown is already ongoing and a shared 3546 // client directory lock is requested after that. 3547 // The shared client directory lock doesn't have to be explicitly released 3548 // because it gets invalidated while it's still pending which causes that any 3549 // directory locks that were blocked by the shared client directory lock become 3550 // unblocked. 3551 TEST_F(TestQuotaManager, ShutdownStorage_OngoingWithClientDirectoryLock) { 3552 PerformOnBackgroundThread([]() { 3553 QuotaManager* quotaManager = QuotaManager::Get(); 3554 ASSERT_TRUE(quotaManager); 3555 3556 RefPtr<ClientDirectoryLock> directoryLock = 3557 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 3558 /* aExclusive */ false); 3559 3560 nsTArray<RefPtr<BoolPromise>> promises; 3561 3562 // This creates an exclusive directory lock internally. 3563 promises.AppendElement(quotaManager->ShutdownStorage()); 3564 3565 // This directory lock can't be acquired yet because a storage shutdown 3566 // (which uses an exclusive diretory lock internall) is ongoing. 3567 promises.AppendElement(directoryLock->Acquire()); 3568 3569 // This second ShutdownStorage invalidates the directoryLock, so that 3570 // directory lock can't ever be successfully acquired, the promise for it 3571 // will be rejected when the first ShutdownStorage is finished (it 3572 // releases its exclusive directory lock); 3573 promises.AppendElement(quotaManager->ShutdownStorage()); 3574 3575 { 3576 auto value = Await( 3577 BoolPromise::AllSettled(GetCurrentSerialEventTarget(), promises)); 3578 ASSERT_TRUE(value.IsResolve()); 3579 } 3580 }); 3581 } 3582 3583 // Test basic ProcessPendingNormalOriginOperations behavior when a normal 3584 // origin operation is triggered but not explicitly awaited. 3585 TEST_F(TestQuotaManager, ProcessPendingNormalOriginOperations_Basic) { 3586 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3587 3588 AssertStorageNotInitialized(); 3589 3590 PerformOnBackgroundThread([]() { 3591 QuotaManager* quotaManager = QuotaManager::Get(); 3592 ASSERT_TRUE(quotaManager); 3593 3594 ASSERT_FALSE(quotaManager->IsStorageInitialized()); 3595 3596 // Intentionally do not await the returned promise to test that 3597 // ProcessPendingNormalOriginOperations correctly processes any pending 3598 // events and waits for the completion of any normal origin operation, 3599 // such as the one triggered by InitializeStorage. In theory, any similar 3600 // method could be used here, InitializeStorage was chosen for its 3601 // simplicity. 3602 quotaManager->InitializeStorage(); 3603 3604 ASSERT_FALSE(quotaManager->IsStorageInitialized()); 3605 3606 quotaManager->ProcessPendingNormalOriginOperations(); 3607 3608 ASSERT_TRUE(quotaManager->IsStorageInitialized()); 3609 }); 3610 3611 AssertStorageInitialized(); 3612 3613 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3614 } 3615 3616 TEST_F(TestQuotaManager, GetOriginStateMetadata_EmptyRepository) { 3617 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3618 3619 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3620 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3621 3622 const auto maybeOriginStateMetadata = 3623 GetOriginStateMetadata(GetTestOriginMetadata()); 3624 ASSERT_FALSE(maybeOriginStateMetadata); 3625 3626 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3627 } 3628 3629 TEST_F(TestQuotaManager, GetOriginStateMetadata_OriginDirectoryExists) { 3630 auto testOriginMetadata = GetTestOriginMetadata(); 3631 3632 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3633 3634 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3635 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3636 ASSERT_NO_FATAL_FAILURE( 3637 InitializeTemporaryOrigin(testOriginMetadata, 3638 /* aCreateIfNonExistent */ true)); 3639 3640 auto maybeOriginStateMetadata = GetOriginStateMetadata(testOriginMetadata); 3641 ASSERT_TRUE(maybeOriginStateMetadata); 3642 3643 auto originStateMetadata = maybeOriginStateMetadata.extract(); 3644 ASSERT_GT(originStateMetadata.mLastAccessTime, 0); 3645 ASSERT_FALSE(originStateMetadata.mAccessed); 3646 ASSERT_FALSE(originStateMetadata.mPersisted); 3647 3648 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3649 } 3650 3651 TEST_F(TestQuotaManager, TotalDirectoryIterations_ClearingEmptyRepository) { 3652 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3653 3654 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3655 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3656 3657 const auto totalDirectoryIterationsBefore = TotalDirectoryIterations(); 3658 3659 ClearStoragesForOriginAttributesPattern(u""_ns); 3660 3661 const auto totalDirectoryIterationsAfter = TotalDirectoryIterations(); 3662 3663 ASSERT_EQ(totalDirectoryIterationsAfter - totalDirectoryIterationsBefore, 0u); 3664 3665 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3666 } 3667 3668 TEST_F(TestQuotaManager, TotalDirectoryIterations_ClearingNonEmptyRepository) { 3669 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3670 3671 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3672 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3673 ASSERT_NO_FATAL_FAILURE( 3674 InitializeTemporaryOrigin(GetTestOriginMetadata(), 3675 /* aCreateIfNonExistent */ true)); 3676 3677 const auto totalDirectoryIterationsBefore = TotalDirectoryIterations(); 3678 3679 ClearStoragesForOriginAttributesPattern(u""_ns); 3680 3681 const auto totalDirectoryIterationsAfter = TotalDirectoryIterations(); 3682 3683 ASSERT_EQ(totalDirectoryIterationsAfter - totalDirectoryIterationsBefore, 1u); 3684 3685 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3686 } 3687 3688 TEST_F(TestQuotaManager, SaveOriginAccessTimeCount_EmptyRepository) { 3689 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3690 3691 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3692 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3693 3694 const auto saveOriginAccessTimeCountBefore = SaveOriginAccessTimeCount(); 3695 const auto saveOriginAccessTimeCountInternalBefore = 3696 SaveOriginAccessTimeCountInternal(); 3697 3698 PerformOnBackgroundThread([]() { 3699 QuotaManager* quotaManager = QuotaManager::Get(); 3700 MOZ_RELEASE_ASSERT(quotaManager); 3701 3702 auto value = 3703 Await(quotaManager->SaveOriginAccessTime(GetTestOriginMetadata())); 3704 MOZ_RELEASE_ASSERT(value.IsReject()); 3705 }); 3706 3707 const auto saveOriginAccessTimeCountAfter = SaveOriginAccessTimeCount(); 3708 const auto saveOriginAccessTimeCountInternalAfter = 3709 SaveOriginAccessTimeCountInternal(); 3710 3711 // Ensure access time update doesn't occur when origin doesn't exist. 3712 ASSERT_EQ(saveOriginAccessTimeCountAfter - saveOriginAccessTimeCountBefore, 3713 0u); 3714 ASSERT_EQ(saveOriginAccessTimeCountInternalAfter - 3715 saveOriginAccessTimeCountInternalBefore, 3716 0u); 3717 3718 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3719 } 3720 3721 TEST_F(TestQuotaManager, SaveOriginAccessTimeCount_OriginDirectoryExists) { 3722 auto testOriginMetadata = GetTestOriginMetadata(); 3723 3724 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3725 3726 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3727 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3728 ASSERT_NO_FATAL_FAILURE( 3729 InitializeTemporaryOrigin(testOriginMetadata, 3730 /* aCreateIfNonExistent */ true)); 3731 3732 const auto saveOriginAccessTimeCountBefore = SaveOriginAccessTimeCount(); 3733 const auto saveOriginAccessTimeCountInternalBefore = 3734 SaveOriginAccessTimeCountInternal(); 3735 3736 SaveOriginAccessTime(testOriginMetadata); 3737 3738 const auto saveOriginAccessTimeCountAfter = SaveOriginAccessTimeCount(); 3739 const auto saveOriginAccessTimeCountInternalAfter = 3740 SaveOriginAccessTimeCountInternal(); 3741 3742 // Confirm the access time update was recorded. 3743 ASSERT_EQ(saveOriginAccessTimeCountAfter - saveOriginAccessTimeCountBefore, 3744 1u); 3745 ASSERT_EQ(saveOriginAccessTimeCountInternalAfter - 3746 saveOriginAccessTimeCountInternalBefore, 3747 1u); 3748 3749 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3750 } 3751 3752 TEST_F(TestQuotaManager, SaveOriginAccessTimeCount_NonExistingOriginDirectory) { 3753 auto testOriginMetadata = GetTestOriginMetadata(); 3754 3755 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3756 3757 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3758 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3759 ASSERT_NO_FATAL_FAILURE( 3760 InitializeTemporaryOrigin(testOriginMetadata, 3761 /* aCreateIfNonExistent */ false)); 3762 3763 const auto saveOriginAccessTimeCountBefore = SaveOriginAccessTimeCount(); 3764 const auto saveOriginAccessTimeCountInternalBefore = 3765 SaveOriginAccessTimeCountInternal(); 3766 3767 SaveOriginAccessTime(testOriginMetadata); 3768 3769 const auto saveOriginAccessTimeCountAfter = SaveOriginAccessTimeCount(); 3770 const auto saveOriginAccessTimeCountInternalAfter = 3771 SaveOriginAccessTimeCountInternal(); 3772 3773 // Ensure access time update doesn't occur when origin doesn't exist. 3774 ASSERT_EQ(saveOriginAccessTimeCountAfter - saveOriginAccessTimeCountBefore, 3775 0u); 3776 ASSERT_EQ(saveOriginAccessTimeCountInternalAfter - 3777 saveOriginAccessTimeCountInternalBefore, 3778 0u); 3779 3780 ASSERT_NO_FATAL_FAILURE(ShutdownStorage()); 3781 } 3782 3783 TEST_P(TestQuotaManagerAndClearStorageWithBoolPair, 3784 ClearStoragesForOriginAttributesPattern_ThumbnailPrivateIdentity) { 3785 const BoolPairTestParams& param = GetParam(); 3786 3787 const bool createThumbnailPrivateIdentityOrigins = param.first; 3788 const bool keepTemporaryStorageInitialized = param.second; 3789 3790 const uint32_t thumbnailPrivateIdentityId = PerformOnIOThread([]() { 3791 QuotaManager* quotaManager = QuotaManager::Get(); 3792 MOZ_RELEASE_ASSERT(quotaManager); 3793 3794 return quotaManager->GetThumbnailPrivateIdentityId(); 3795 }); 3796 3797 ASSERT_NO_FATAL_FAILURE(InitializeStorage()); 3798 3799 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage()); 3800 3801 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3802 GetOriginMetadata(""_ns, "mozilla.org"_ns, "http://www.mozilla.org"_ns), 3803 /* aCreateIfNonExistent */ true)); 3804 3805 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3806 GetOriginMetadata("^userContextId=1"_ns, "mozilla.org"_ns, 3807 "http://www.mozilla.org"_ns), 3808 /* aCreateIfNonExistent */ true)); 3809 3810 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3811 GetOriginMetadata("^userContextId=1"_ns, "mozilla.com"_ns, 3812 "http://www.mozilla.com"_ns), 3813 /* aCreateIfNonExistent */ true)); 3814 3815 if (createThumbnailPrivateIdentityOrigins) { 3816 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3817 GetOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 3818 thumbnailPrivateIdentityId), 3819 "mozilla.org"_ns, "http://www.mozilla.org"_ns), 3820 /* aCreateIfNonExistent */ true)); 3821 3822 ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin( 3823 GetOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 3824 thumbnailPrivateIdentityId), 3825 "mozilla.com"_ns, "http://www.mozilla.com"_ns), 3826 /* aCreateIfNonExistent */ true)); 3827 } 3828 3829 if (!keepTemporaryStorageInitialized) { 3830 ASSERT_NO_FATAL_FAILURE(ShutdownTemporaryStorage()); 3831 } 3832 3833 const auto iterationsBefore = TotalDirectoryIterations(); 3834 3835 ClearStoragesForOriginAttributesPattern(nsFmtString( 3836 FMT_STRING(u"{{ \"userContextId\": {} }}"), thumbnailPrivateIdentityId)); 3837 3838 const auto iterationsAfter = TotalDirectoryIterations(); 3839 3840 const auto iterations = iterationsAfter - iterationsBefore; 3841 3842 uint64_t expectedIterations = createThumbnailPrivateIdentityOrigins ? 5u 3843 : !keepTemporaryStorageInitialized ? 3u 3844 : 0u; 3845 ASSERT_EQ(iterations, expectedIterations); 3846 3847 const auto matchesUserContextId = 3848 [thumbnailPrivateIdentityId](const auto& origin) { 3849 return FindInReadable(nsFmtCString(FMT_STRING("userContextId={}"), 3850 thumbnailPrivateIdentityId), 3851 origin); 3852 }; 3853 3854 const auto origins = ListOrigins(); 3855 3856 const bool anyOriginsMatch = 3857 std::any_of(origins.cbegin(), origins.cend(), matchesUserContextId); 3858 ASSERT_FALSE(anyOriginsMatch); 3859 3860 const auto cachedOrigins = ListCachedOrigins(); 3861 3862 const bool anyCachedOriginsMatch = std::any_of( 3863 cachedOrigins.cbegin(), cachedOrigins.cend(), matchesUserContextId); 3864 ASSERT_FALSE(anyCachedOriginsMatch); 3865 } 3866 3867 INSTANTIATE_TEST_SUITE_P( 3868 , TestQuotaManagerAndClearStorageWithBoolPair, 3869 testing::Values( 3870 std::make_pair(/* createThumbnailPrivateIdentityOrigins */ true, 3871 /* keepTemporaryStorageInitialized */ true), 3872 std::make_pair(/* createThumbnailPrivateIdentityOrigins */ true, 3873 /* keepTemporaryStorageInitialized */ false), 3874 std::make_pair(/* createThumbnailPrivateIdentityOrigins */ false, 3875 /* keepTemporaryStorageInitialized */ true), 3876 std::make_pair(/* createThumbnailPrivateIdentityOrigins */ false, 3877 /* keepTemporaryStorageInitialized */ false)), 3878 [](const testing::TestParamInfo<BoolPairTestParams>& aParam) 3879 -> std::string { 3880 const BoolPairTestParams& param = aParam.param; 3881 3882 const bool createThumbnailPrivateIdentityOrigins = param.first; 3883 const bool keepTemporaryStorageInitialized = param.second; 3884 3885 std::stringstream ss; 3886 3887 ss << (createThumbnailPrivateIdentityOrigins 3888 ? "CreateThumbnailPrivateIdentityOrigins" 3889 : "NoThumbnailPrivateIdentityOrigins") 3890 << "_" 3891 << (keepTemporaryStorageInitialized ? "KeepTemporaryStorageInitialized" 3892 : "ShutdownTemporaryStorage"); 3893 3894 return ss.str(); 3895 }); 3896 3897 TEST_F(TestQuotaManagerAndShutdownFixture, 3898 ThumbnailPrivateIdentityTemporaryOriginCount) { 3899 PerformOnIOThread([]() { 3900 QuotaManager* quotaManager = QuotaManager::Get(); 3901 ASSERT_TRUE(quotaManager); 3902 3903 const uint32_t thumbnailPrivateIdentityId = 3904 quotaManager->GetThumbnailPrivateIdentityId(); 3905 3906 { 3907 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3908 0u); 3909 3910 quotaManager->AddTemporaryOrigin(GetFullOriginMetadata( 3911 ""_ns, "mozilla.org"_ns, "http://www.mozilla.org"_ns)); 3912 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3913 0u); 3914 3915 quotaManager->AddTemporaryOrigin( 3916 GetFullOriginMetadata("^userContextId=1"_ns, "mozilla.org"_ns, 3917 "http://www.mozilla.org"_ns)); 3918 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3919 0u); 3920 3921 quotaManager->AddTemporaryOrigin( 3922 GetFullOriginMetadata("^userContextId=1"_ns, "mozilla.com"_ns, 3923 "http://www.mozilla.com"_ns)); 3924 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3925 0u); 3926 3927 quotaManager->AddTemporaryOrigin( 3928 GetFullOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 3929 thumbnailPrivateIdentityId), 3930 "mozilla.org"_ns, "http://www.mozilla.org"_ns)); 3931 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3932 1u); 3933 3934 quotaManager->AddTemporaryOrigin( 3935 GetFullOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 3936 thumbnailPrivateIdentityId), 3937 "mozilla.com"_ns, "http://www.mozilla.com"_ns)); 3938 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3939 2u); 3940 3941 quotaManager->RemoveTemporaryOrigin(GetFullOriginMetadata( 3942 ""_ns, "mozilla.org"_ns, "http://www.mozilla.org"_ns)); 3943 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3944 2u); 3945 3946 quotaManager->RemoveTemporaryOrigin( 3947 GetFullOriginMetadata("^userContextId=1"_ns, "mozilla.org"_ns, 3948 "http://www.mozilla.org"_ns)); 3949 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3950 2u); 3951 3952 quotaManager->RemoveTemporaryOrigin( 3953 GetFullOriginMetadata("^userContextId=1"_ns, "mozilla.com"_ns, 3954 "http://www.mozilla.com"_ns)); 3955 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3956 2u); 3957 3958 quotaManager->RemoveTemporaryOrigin( 3959 GetFullOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 3960 thumbnailPrivateIdentityId), 3961 "mozilla.org"_ns, "http://www.mozilla.org"_ns)); 3962 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3963 1u); 3964 3965 quotaManager->RemoveTemporaryOrigin( 3966 GetFullOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 3967 thumbnailPrivateIdentityId), 3968 "mozilla.com"_ns, "http://www.mozilla.com"_ns)); 3969 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3970 0u); 3971 } 3972 3973 { 3974 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3975 0u); 3976 3977 quotaManager->AddTemporaryOrigin(GetFullOriginMetadata( 3978 ""_ns, "mozilla.org"_ns, "http://www.mozilla.org"_ns)); 3979 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3980 0u); 3981 3982 quotaManager->AddTemporaryOrigin( 3983 GetFullOriginMetadata("^userContextId=1"_ns, "mozilla.org"_ns, 3984 "http://www.mozilla.org"_ns)); 3985 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3986 0u); 3987 3988 quotaManager->AddTemporaryOrigin( 3989 GetFullOriginMetadata("^userContextId=1"_ns, "mozilla.com"_ns, 3990 "http://www.mozilla.com"_ns)); 3991 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3992 0u); 3993 3994 quotaManager->AddTemporaryOrigin( 3995 GetFullOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 3996 thumbnailPrivateIdentityId), 3997 "mozilla.org"_ns, "http://www.mozilla.org"_ns)); 3998 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 3999 1u); 4000 4001 quotaManager->AddTemporaryOrigin( 4002 GetFullOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 4003 thumbnailPrivateIdentityId), 4004 "mozilla.com"_ns, "http://www.mozilla.com"_ns)); 4005 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4006 2u); 4007 4008 quotaManager->RemoveTemporaryOrigins(PERSISTENCE_TYPE_TEMPORARY); 4009 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4010 2u); 4011 4012 quotaManager->RemoveTemporaryOrigins(PERSISTENCE_TYPE_DEFAULT); 4013 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4014 0u); 4015 } 4016 4017 { 4018 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4019 0u); 4020 4021 quotaManager->AddTemporaryOrigin(GetFullOriginMetadata( 4022 ""_ns, "mozilla.org"_ns, "http://www.mozilla.org"_ns)); 4023 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4024 0u); 4025 4026 quotaManager->AddTemporaryOrigin( 4027 GetFullOriginMetadata("^userContextId=1"_ns, "mozilla.org"_ns, 4028 "http://www.mozilla.org"_ns)); 4029 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4030 0u); 4031 4032 quotaManager->AddTemporaryOrigin( 4033 GetFullOriginMetadata("^userContextId=1"_ns, "mozilla.com"_ns, 4034 "http://www.mozilla.com"_ns)); 4035 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4036 0u); 4037 4038 quotaManager->AddTemporaryOrigin( 4039 GetFullOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 4040 thumbnailPrivateIdentityId), 4041 "mozilla.org"_ns, "http://www.mozilla.org"_ns)); 4042 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4043 1u); 4044 4045 quotaManager->AddTemporaryOrigin( 4046 GetFullOriginMetadata(nsFmtCString(FMT_STRING("^userContextId={}"), 4047 thumbnailPrivateIdentityId), 4048 "mozilla.com"_ns, "http://www.mozilla.com"_ns)); 4049 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4050 2u); 4051 4052 quotaManager->RemoveTemporaryOrigins(); 4053 ASSERT_EQ(quotaManager->ThumbnailPrivateIdentityTemporaryOriginCount(), 4054 0u); 4055 } 4056 }); 4057 } 4058 4059 } // namespace mozilla::dom::quota::test