Add a unit test for StorageQuotaManager
https://bugs.webkit.org/show_bug.cgi?id=202755

Reviewed by Youenn Fablet.

Source/WebCore:

Expose state of StorageQuotaManager for newly added unit test.

* storage/StorageQuotaManager.h:
(WebCore::StorageQuotaManager::state const):

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/StorageQuotaManager.cpp: Added.
(TestWebKitAPI::TEST):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@250975 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index a1f7d31..dd61c58 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,15 @@
+2019-10-10  Sihui Liu  <sihui_liu@apple.com>
+
+        Add a unit test for StorageQuotaManager
+        https://bugs.webkit.org/show_bug.cgi?id=202755
+
+        Reviewed by Youenn Fablet.
+
+        Expose state of StorageQuotaManager for newly added unit test.
+
+        * storage/StorageQuotaManager.h:
+        (WebCore::StorageQuotaManager::state const):
+
 2019-10-10  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Support programmatic paste requests on macOS
diff --git a/Source/WebCore/storage/StorageQuotaManager.h b/Source/WebCore/storage/StorageQuotaManager.h
index 5ce3a22..0956630 100644
--- a/Source/WebCore/storage/StorageQuotaManager.h
+++ b/Source/WebCore/storage/StorageQuotaManager.h
@@ -62,6 +62,15 @@
 
     WEBCORE_EXPORT void updateQuotaBasedOnSpaceUsage();
 
+    enum class State {
+        Uninitialized,
+        ComputingSpaceUsed,
+        WaitingForSpaceIncreaseResponse,
+        AskingForMoreSpace,
+        MakingDecisionForRequest,
+    };
+    State state() const { return m_state; }
+
 private:
     uint64_t spaceUsage() const;
     bool shouldAskForMoreSpace(uint64_t spaceIncrease) const;
@@ -86,13 +95,6 @@
     };
     Deque<PendingRequest> m_pendingRequests;
 
-    enum class State {
-        Uninitialized,
-        ComputingSpaceUsed,
-        WaitingForSpaceIncreaseResponse,
-        AskingForMoreSpace,
-        MakingDecisionForRequest,
-    };
     State m_state { State::Uninitialized };
 };
 
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index c8edfc3..0520c5d 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,14 @@
+2019-10-10  Sihui Liu  <sihui_liu@apple.com>
+
+        Add a unit test for StorageQuotaManager
+        https://bugs.webkit.org/show_bug.cgi?id=202755
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/StorageQuotaManager.cpp: Added.
+        (TestWebKitAPI::TEST):
+
 2019-10-10  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Support programmatic paste requests on macOS
diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
index 92de553..7119764 100644
--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
@@ -718,6 +718,7 @@
 		936F72811CD7D9EC0068A0FB /* large-video-with-audio.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 936F727F1CD7D9D00068A0FB /* large-video-with-audio.mp4 */; };
 		93AF4ECE1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */; };
 		93AF4ED11506F130007FD57E /* lots-of-images.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93AF4ECF1506F123007FD57E /* lots-of-images.html */; };
+		93B62054234EA62C00D49B97 /* StorageQuotaManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B62053234EA32B00D49B97 /* StorageQuotaManager.cpp */; };
 		93CFA8671CEB9E38000565A8 /* autofocused-text-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93CFA8661CEB9DE1000565A8 /* autofocused-text-input.html */; };
 		93D119FC22C680F7009BE3C7 /* localstorage-open-window-private.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93D119FB22C57112009BE3C7 /* localstorage-open-window-private.html */; };
 		93E2C5551FD3204100E1DF6A /* LineEnding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93E2C5541FD3204100E1DF6A /* LineEnding.cpp */; };
@@ -2087,6 +2088,7 @@
 		93AF4ECA1506F035007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutForImages.cpp; sourceTree = "<group>"; };
 		93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp; sourceTree = "<group>"; };
 		93AF4ECF1506F123007FD57E /* lots-of-images.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "lots-of-images.html"; sourceTree = "<group>"; };
+		93B62053234EA32B00D49B97 /* StorageQuotaManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageQuotaManager.cpp; sourceTree = "<group>"; };
 		93CFA8661CEB9DE1000565A8 /* autofocused-text-input.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autofocused-text-input.html"; sourceTree = "<group>"; };
 		93CFA8681CEBCFED000565A8 /* CandidateTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CandidateTests.mm; sourceTree = "<group>"; };
 		93D119FB22C57112009BE3C7 /* localstorage-open-window-private.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "localstorage-open-window-private.html"; sourceTree = "<group>"; };
@@ -3046,6 +3048,7 @@
 				41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */,
 				A17991891E1CA24100A505ED /* SharedBufferTest.cpp */,
 				A179918A1E1CA24100A505ED /* SharedBufferTest.h */,
+				93B62053234EA32B00D49B97 /* StorageQuotaManager.cpp */,
 				ECA680CD1E68CC0900731D20 /* StringUtilities.mm */,
 				CE4D5DE51F6743BA0072CFC6 /* StringWithDirection.cpp */,
 				93A258981F92FF15003E510C /* TextCodec.cpp */,
@@ -4762,6 +4765,7 @@
 				7CCE7ECF1A411A7E00447C4C /* StopLoadingFromDidReceiveResponse.mm in Sources */,
 				CDC0932E21C993440030C4B0 /* StopSuspendResumeAllMedia.mm in Sources */,
 				414AD6862285D1C000777F2D /* StorageQuota.mm in Sources */,
+				93B62054234EA62C00D49B97 /* StorageQuotaManager.cpp in Sources */,
 				515BE1711D428E4B00DD7C68 /* StoreBlobThenDelete.mm in Sources */,
 				7CCE7ED01A411A7E00447C4C /* StringByEvaluatingJavaScriptFromString.mm in Sources */,
 				7CCE7ED11A411A7E00447C4C /* StringTruncator.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebCore/StorageQuotaManager.cpp b/Tools/TestWebKitAPI/Tests/WebCore/StorageQuotaManager.cpp
new file mode 100644
index 0000000..ad1c67b
--- /dev/null
+++ b/Tools/TestWebKitAPI/Tests/WebCore/StorageQuotaManager.cpp
@@ -0,0 +1,103 @@
+/*
+* Copyright (C) 2019 Apple Inc. All Rights Reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+
+#include <WebCore/StorageQuotaManager.h>
+#include <WebCore/StorageQuotaUser.h>
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+static const int defaultQuota = 1 * KB;
+
+class MockQuotaUser final : public WebCore::StorageQuotaUser {
+public:
+    explicit MockQuotaUser(StorageQuotaManager& manager)
+        : m_manager(&manager)
+    {
+        manager.addUser(*this);
+    }
+
+    void setSpaceUsed(uint64_t spaceUsed) { m_spaceUsed = spaceUsed; }
+
+private:
+    uint64_t spaceUsed() const final
+    {
+        return m_spaceUsed;
+    }
+
+    void whenInitialized(CompletionHandler<void()>&& callback) final
+    {
+        if (!m_spaceUsed)
+            ASSERT_EQ(m_manager->state(), StorageQuotaManager::State::Uninitialized);
+        else
+            ASSERT_EQ(m_manager->state(), StorageQuotaManager::State::ComputingSpaceUsed);
+
+        // Reset usage to mock deletion.
+        m_spaceUsed = 0;
+        callback();
+    }
+
+    uint64_t m_spaceUsed { 0 };
+    StorageQuotaManager* m_manager;
+};
+    
+TEST(StorageQuotaManagerTest, Basic)
+{
+    StorageQuotaManager* storageQuotaManagerPtr = nullptr;
+    StorageQuotaManager storageQuotaManager(defaultQuota, [&storageQuotaManagerPtr](uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, CompletionHandler<void(Optional<uint64_t>)>&& completionHanlder) {
+        ASSERT_TRUE(storageQuotaManagerPtr);
+        ASSERT_EQ(storageQuotaManagerPtr->state(), StorageQuotaManager::State::WaitingForSpaceIncreaseResponse);
+
+        // Allow all space increase requests.
+        completionHanlder(spaceIncrease + currentSpace);
+    });
+    storageQuotaManagerPtr = &storageQuotaManager;
+
+
+    MockQuotaUser mockUser(storageQuotaManager);
+
+    // Grant directly.
+    storageQuotaManager.requestSpace(0.1 * KB, [&](WebCore::StorageQuotaManager::Decision decision) {
+        ASSERT_EQ(decision, WebCore::StorageQuotaManager::Decision::Grant);
+        mockUser.setSpaceUsed(0.1 * KB);
+    });
+
+    // Grant after computing accurate usage.
+    storageQuotaManager.requestSpace(1.0 * KB, [&](WebCore::StorageQuotaManager::Decision decision) {
+        ASSERT_EQ(decision, WebCore::StorageQuotaManager::Decision::Grant);
+        mockUser.setSpaceUsed(1.0 * KB);
+    });
+
+    // Grant after computing accurate usage and requesting space increase.
+    storageQuotaManager.requestSpace(10 * KB, [&](WebCore::StorageQuotaManager::Decision decision) {
+        ASSERT_EQ(storageQuotaManagerPtr->state(), StorageQuotaManager::State::MakingDecisionForRequest);
+        ASSERT_EQ(decision, WebCore::StorageQuotaManager::Decision::Grant);
+    });
+}
+
+} // namespace TestWebKitAPI