Add callbacks to testRunner.statisticsSetShouldPartitionCookiesForHost() and testRunn...
authorwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Jan 2018 06:01:54 +0000 (06:01 +0000)
committerwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Jan 2018 06:01:54 +0000 (06:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181958
https://bugs.webkit.org/show_bug.cgi?id=182072
<rdar://problem/36801804>
<rdar://problem/36845795>

Reviewed by Brent Fulgham.

Because of the asynchronous nature of XPC and cookies,
we need callbacks in these TestRunner functions so that
the layout tests can wait for state changes to finish
before checking test conditions.

Source/WebKit:

* UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
(WKWebsiteDataStoreStatisticsUpdateCookiePartitioning):
(WKWebsiteDataStoreSetStatisticsShouldPartitionCookiesForHost):
* UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
(-[WKWebsiteDataStore _resourceLoadStatisticsUpdateCookiePartitioning]):
(-[WKWebsiteDataStore _resourceLoadStatisticsUpdateCookiePartitioning:]):
(-[WKWebsiteDataStore _resourceLoadStatisticsSetShouldPartitionCookies:forHost:]):
(-[WKWebsiteDataStore _resourceLoadStatisticsSetShouldPartitionCookies:forHost:completionHandler:]):
* UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated):
(WebKit::WebResourceLoadStatisticsStore::logUserInteraction):
(WebKit::WebResourceLoadStatisticsStore::logNonRecentUserInteraction):
(WebKit::WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdate):
(WebKit::WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdateForDomains):
(WebKit::WebResourceLoadStatisticsStore::scheduleClearPartitioningStateForDomains):
(WebKit::WebResourceLoadStatisticsStore::mergeWithDataFromDecoder):
(WebKit::WebResourceLoadStatisticsStore::clearInMemory):
(WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioning):
(WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains):
(WebKit::WebResourceLoadStatisticsStore::clearPartitioningStateForDomains):
* UIProcess/WebResourceLoadStatisticsStore.h:

Tools:

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didReceiveMessageToPage):
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::statisticsUpdateCookiePartitioning):
(WTR::TestRunner::statisticsSetShouldPartitionCookiesForHost):
(WTR::TestRunner::statisticsCallDidSetPartitionOrBlockCookiesForHostCallback):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didSetPartitionOrBlockCookiesForHost):
* WebKitTestRunner/TestInvocation.h:
* WebKitTestRunner/cocoa/TestControllerCocoa.mm:
(WTR::TestController::statisticsUpdateCookiePartitioning):
(WTR::TestController::statisticsSetShouldPartitionCookiesForHost):

LayoutTests:

* http/tests/resourceLoadStatistics/add-blocking-to-redirect-expected.txt:
* http/tests/resourceLoadStatistics/add-blocking-to-redirect.html:
* http/tests/resourceLoadStatistics/add-partitioning-to-redirect-expected.txt:
* http/tests/resourceLoadStatistics/add-partitioning-to-redirect.html:
* http/tests/resourceLoadStatistics/non-prevalent-resources-can-access-cookies-in-a-third-party-context.html:
* http/tests/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-deletion.html:
* http/tests/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-with-partitioning-timeout.html:
* http/tests/resourceLoadStatistics/partitioned-cookies-with-and-without-user-interaction-expected.txt:
* http/tests/resourceLoadStatistics/partitioned-cookies-with-and-without-user-interaction.html:
* http/tests/resourceLoadStatistics/remove-blocking-in-redirect-expected.txt:
* http/tests/resourceLoadStatistics/remove-blocking-in-redirect.html:
* http/tests/resourceLoadStatistics/remove-partitioning-in-redirect-expected.txt:
* http/tests/resourceLoadStatistics/remove-partitioning-in-redirect.html:
* http/tests/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html:
* platform/mac-wk2/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@227875 268f45cc-cd09-0410-ab3c-d52691b4dbfc

30 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/resourceLoadStatistics/add-blocking-to-redirect-expected.txt
LayoutTests/http/tests/resourceLoadStatistics/add-blocking-to-redirect.html
LayoutTests/http/tests/resourceLoadStatistics/add-partitioning-to-redirect-expected.txt
LayoutTests/http/tests/resourceLoadStatistics/add-partitioning-to-redirect.html
LayoutTests/http/tests/resourceLoadStatistics/non-prevalent-resources-can-access-cookies-in-a-third-party-context.html
LayoutTests/http/tests/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-deletion.html
LayoutTests/http/tests/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-with-partitioning-timeout.html
LayoutTests/http/tests/resourceLoadStatistics/partitioned-cookies-with-and-without-user-interaction-expected.txt
LayoutTests/http/tests/resourceLoadStatistics/partitioned-cookies-with-and-without-user-interaction.html
LayoutTests/http/tests/resourceLoadStatistics/remove-blocking-in-redirect-expected.txt
LayoutTests/http/tests/resourceLoadStatistics/remove-blocking-in-redirect.html
LayoutTests/http/tests/resourceLoadStatistics/remove-partitioning-in-redirect-expected.txt
LayoutTests/http/tests/resourceLoadStatistics/remove-partitioning-in-redirect.html
LayoutTests/http/tests/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html
LayoutTests/platform/mac-wk2/TestExpectations
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/TestInvocation.cpp
Tools/WebKitTestRunner/TestInvocation.h
Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm

index b950257..92402bb 100644 (file)
@@ -1,3 +1,34 @@
+2018-01-30  John Wilander  <wilander@apple.com>
+
+        Add callbacks to testRunner.statisticsSetShouldPartitionCookiesForHost() and testRunner.statisticsUpdateCookiePartitioning()
+        https://bugs.webkit.org/show_bug.cgi?id=181958
+        https://bugs.webkit.org/show_bug.cgi?id=182072
+        <rdar://problem/36801804>
+        <rdar://problem/36845795>
+
+        Reviewed by Brent Fulgham.
+
+        Because of the asynchronous nature of XPC and cookies,
+        we need callbacks in these TestRunner functions so that
+        the layout tests can wait for state changes to finish
+        before checking test conditions.
+
+        * http/tests/resourceLoadStatistics/add-blocking-to-redirect-expected.txt:
+        * http/tests/resourceLoadStatistics/add-blocking-to-redirect.html:
+        * http/tests/resourceLoadStatistics/add-partitioning-to-redirect-expected.txt:
+        * http/tests/resourceLoadStatistics/add-partitioning-to-redirect.html:
+        * http/tests/resourceLoadStatistics/non-prevalent-resources-can-access-cookies-in-a-third-party-context.html:
+        * http/tests/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-deletion.html:
+        * http/tests/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-with-partitioning-timeout.html:
+        * http/tests/resourceLoadStatistics/partitioned-cookies-with-and-without-user-interaction-expected.txt:
+        * http/tests/resourceLoadStatistics/partitioned-cookies-with-and-without-user-interaction.html:
+        * http/tests/resourceLoadStatistics/remove-blocking-in-redirect-expected.txt:
+        * http/tests/resourceLoadStatistics/remove-blocking-in-redirect.html:
+        * http/tests/resourceLoadStatistics/remove-partitioning-in-redirect-expected.txt:
+        * http/tests/resourceLoadStatistics/remove-partitioning-in-redirect.html:
+        * http/tests/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html:
+        * platform/mac-wk2/TestExpectations:
+
 2018-01-30  Youenn Fablet  <youenn@apple.com>
 
         Move http/wpt/service-workers/clone-opaque-being-loaded-response.https.html to use HTTP
index 53a1e75..3386c57 100644 (file)
@@ -6,7 +6,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
-
+  
 
 --------
 Frame: '<!--framePath //<!--frame0-->-->'
index c33ec08..0666eff 100644 (file)
@@ -4,7 +4,7 @@
     <meta charset="UTF-8">
     <script src="/js-test-resources/js-test.js"></script>
 </head>
-<body onload="runTest()">
+<body>
 <script>
     description("Tests that blocking is added mid-flight in redirects.");
     jsTestIsAsync = true;
         testRunner.setCookieStoragePartitioningEnabled(enable);
     }
 
-    if (document.location.hash === "") {
-        setEnableFeature(true);
-        if (testRunner.isStatisticsPrevalentResource("http://localhost"))
-            testFailed("Localhost was classified as prevalent resource before the test starts.");
-        // Make sure the network process is up-to-date.
-        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false);
-        testRunner.dumpChildFramesAsText();
-        document.location.hash = "step1";
-    }
-
     const partitionHost = "127.0.0.1:8000";
     const thirdPartyOrigin = "http://localhost:8000";
     const resourcePath = "/resourceLoadStatistics/resources";
                 // Set localhost as prevalent and with no user interaction to put it in the blocking category.
                 document.location.hash = "step5";
                 testRunner.setStatisticsPrevalentResource("http://localhost", true);
-                testRunner.statisticsUpdateCookiePartitioning();
                 if (!testRunner.isStatisticsPrevalentResource("http://localhost"))
                     testFailed("Host did not get set as prevalent resource.");
-                runTest();
+                testRunner.statisticsUpdateCookiePartitioning(function() {
+                    runTest();
+                });
                 break;
             case "#step5":
                 // Check that no cookie gets sent for localhost under 127.0.0.1 since localhost's cookies are blocked.
                 break;
         }
     }
+
+    if (document.location.hash === "") {
+        setEnableFeature(true);
+        if (testRunner.isStatisticsPrevalentResource("http://localhost"))
+            testFailed("Localhost was classified as prevalent resource before the test starts.");
+        testRunner.dumpChildFramesAsText();
+        document.location.hash = "step1";
+        // Make sure the network process is up-to-date.
+        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false, runTest);
+    } else {
+        runTest();
+    }
 </script>
 </body>
 </html>
index 88592ed..4f636db 100644 (file)
@@ -6,7 +6,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
-
+  
 
 --------
 Frame: '<!--framePath //<!--frame0-->-->'
index 7412921..7c5f9fe 100644 (file)
@@ -4,7 +4,7 @@
     <meta charset="UTF-8">
     <script src="/js-test-resources/js-test.js"></script>
 </head>
-<body onload="runTest()">
+<body>
 <script>
     description("Tests that partitioning is added mid-flight in redirects.");
     jsTestIsAsync = true;
         testRunner.setCookieStoragePartitioningEnabled(enable);
     }
 
-    if (document.location.hash === "") {
-        setEnableFeature(true);
-        if (testRunner.isStatisticsPrevalentResource("http://localhost"))
-            testFailed("Localhost was classified as prevalent resource before the test starts.");
-        // Make sure the network process is up-to-date.
-        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false);
-        testRunner.dumpChildFramesAsText();
-        document.location.hash = "step1";
-    }
-
     const partitionHost = "127.0.0.1:8000";
     const thirdPartyOrigin = "http://localhost:8000";
     const resourcePath = "/resourceLoadStatistics/resources";
                 // Set localhost as prevalent and with non-recent user interaction to put it in the partitioning category.
                 document.location.hash = "step5";
                 testRunner.setStatisticsPrevalentResource("http://localhost", true);
-                testRunner.setStatisticsHasHadNonRecentUserInteraction("http://localhost");
-                testRunner.statisticsUpdateCookiePartitioning();
                 if (!testRunner.isStatisticsPrevalentResource("http://localhost"))
                     testFailed("Host did not get set as prevalent resource.");
-                runTest();
+                testRunner.setStatisticsHasHadNonRecentUserInteraction("http://localhost");
+                testRunner.statisticsUpdateCookiePartitioning(function() {
+                    runTest();
+                });
                 break;
             case "#step5":
                 // Check that no cookie gets sent for localhost under 127.0.0.1 since localhost is partitioned.
                 break;
         }
     }
+
+    if (document.location.hash === "") {
+        setEnableFeature(true);
+        if (testRunner.isStatisticsPrevalentResource("http://localhost"))
+            testFailed("Localhost was classified as prevalent resource before the test started.");
+        testRunner.dumpChildFramesAsText();
+        document.location.hash = "step1";
+        // Make sure the network process is up-to-date.
+        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false, runTest);
+    } else {
+        runTest();
+    }
 </script>
 </body>
 </html>
index 787d7b9..b8df5ae 100644 (file)
                 openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive one cookie.", runTest);
                 break;
             case "#step3":
-                // Setup localhost for partitioning and set a partitioned cookie for localhost under 127.0.0.1.
+                // Setup localhost for partitioning.
                 document.location.hash = "step4";
-                testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, true);
-                openIframe(thirdPartyBaseUrl + subPathToSetPartitionedCookie + "&message=Setting partitioned, third party cookie.", runTest);
+                testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, true, runTest);
                 break;
             case "#step4":
-                // Load localhost under 127.0.0.1 and check that it gets only the partitioned cookie. End by aquiring user interaction for localhost.
+                // Set a partitioned cookie for localhost under 127.0.0.1.
                 document.location.hash = "step5";
-                openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive one partitioned, third party cookie.", setUserInteractionAndContinue);
+                openIframe(thirdPartyBaseUrl + subPathToSetPartitionedCookie + "&message=Setting partitioned, third party cookie.", runTest);
                 break;
             case "#step5":
+                // Load localhost under 127.0.0.1 and check that it gets only the partitioned cookie. End by acquiring user interaction for localhost.
+                document.location.hash = "step6";
+                openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive one partitioned, third party cookie.", setUserInteractionAndContinue);
+                break;
+            case "#step6":
                 // Load localhost under 127.0.0.1 and check that it gets its non-partitioned cookie after user interaction.
                 openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=After user interaction, should receive one non-partitioned, first party cookie.", finishTest);
                 break;
 
         testRunner.setStatisticsPrevalentResource(thirdPartyHostname, false);
         testRunner.setStatisticsHasHadUserInteraction(thirdPartyOrigin, false);
-        testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, false);
-
         testRunner.waitUntilDone();
         testRunner.dumpChildFramesAsText();
         document.location.hash = "step1";
-    }
 
-    runTest();
+        testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, false, runTest);
+    } else {
+        runTest();
+    }
 </script>
 </body>
 </html>
index a60007c..26461a4 100644 (file)
         }
     }
 
-
     if (document.location.host === partitionHost && document.location.hash === "" && window.testRunner && window.internals) {
         setEnableFeature(true);
 
         testRunner.setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(false);
         testRunner.setStatisticsMinimumTimeBetweenDataRecordsRemoval(0);
 
-        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", true);
+        testRunner.waitUntilDone();
+        testRunner.dumpChildFramesAsText();
+        document.location.hash = "step1";
+
         testRunner.setStatisticsPrevalentResource("http://localhost", true);
         if (!testRunner.isStatisticsPrevalentResource("http://localhost"))
             testFailed("Host did not get set as prevalent resource.");
 
-        testRunner.waitUntilDone();
-        testRunner.dumpChildFramesAsText();
-        document.location.hash = "step1";
+        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", true, runTest);
+    } else {
+        runTest();
     }
 
-    runTest();
 </script>
 </body>
 </html>
index 01b3708..ad5e975 100644 (file)
@@ -40,8 +40,7 @@
     }
 
     function fireShouldPartitionCookiesHandlerAndContinue() {
-        testRunner.statisticsUpdateCookiePartitioning();
-        runTest();
+        testRunner.statisticsUpdateCookiePartitioning(runTest);
     }
 
     function setShortCookiePartitioningTimeOutPlusFireShouldPartitionCookiesHandlerAndContinue() {
index 3403495..0fdedc2 100644 (file)
@@ -5,7 +5,7 @@
     <title>Test for Partitioned Cookies With and Without User Interaction</title>
     <script src="../../resources/js-test-pre.js"></script>
 </head>
-<body onload="runTest()">
+<body>
 <script>
     const partitionHost = "127.0.0.1:8000";
     const thirdPartyOrigin = "http://localhost:8000";
     if (document.location.host === partitionHost && document.location.hash == "" && window.testRunner && window.internals) {
         setEnableFeature(true);
 
-        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", true);
-
         testRunner.waitUntilDone();
         testRunner.dumpChildFramesAsText();
         document.location.hash = "step1";
+
+        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", true, runTest);
+    } else {
+        runTest();
     }
 </script>
 </body>
index 8fa51fa..f23a656 100644 (file)
@@ -6,7 +6,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
-
+  
 
 --------
 Frame: '<!--framePath //<!--frame0-->-->'
index f771870..cd7046d 100644 (file)
@@ -4,7 +4,7 @@
     <meta charset="UTF-8">
     <script src="/js-test-resources/js-test.js"></script>
 </head>
-<body onload="runTest()">
+<body>
 <script>
     description("Tests that blocking is removed mid-flight in redirects.");
     jsTestIsAsync = true;
         testRunner.setCookieStoragePartitioningEnabled(enable);
     }
 
-    if (document.location.hash === "") {
-        setEnableFeature(true);
-        if (testRunner.isStatisticsPrevalentResource("http://localhost"))
-            testFailed("Localhost was classified as prevalent resource before the test starts.");
-        // Make sure the network process is up-to-date.
-        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false);
-        testRunner.dumpChildFramesAsText();
-        document.location.hash = "step1";
-    }
-
     const partitionHost = "127.0.0.1:8000";
     const thirdPartyOrigin = "http://localhost:8000";
     const resourcePath = "/resourceLoadStatistics/resources";
                 // Set localhost as prevalent and with non-recent user interaction to put it in the blocking category.
                 document.location.hash = "step5";
                 testRunner.setStatisticsPrevalentResource("http://localhost", true);
-                testRunner.statisticsUpdateCookiePartitioning();
                 if (!testRunner.isStatisticsPrevalentResource("http://localhost"))
                     testFailed("Host did not get set as prevalent resource.");
-                runTest();
+                testRunner.statisticsUpdateCookiePartitioning(function() {
+                    runTest();
+                });
                 break;
             case "#step5":
                 // Set partitioned cookie for localhost under 127.0.0.1.
                 break;
         }
     }
+
+    if (document.location.hash === "") {
+        setEnableFeature(true);
+        if (testRunner.isStatisticsPrevalentResource("http://localhost"))
+            testFailed("Localhost was classified as prevalent resource before the test starts.");
+        testRunner.dumpChildFramesAsText();
+        document.location.hash = "step1";
+        // Make sure the network process is up-to-date.
+        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false, runTest);
+    } else {
+        runTest();
+    }
 </script>
 </body>
 </html>
index 95a3ff0..f9527ad 100644 (file)
@@ -6,7 +6,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
-
+  
 
 --------
 Frame: '<!--framePath //<!--frame0-->-->'
index 805e7d5..aed5cf4 100644 (file)
@@ -4,7 +4,7 @@
     <meta charset="UTF-8">
     <script src="/js-test-resources/js-test.js"></script>
 </head>
-<body onload="runTest()">
+<body>
 <script>
     description("Tests that partitioning is removed mid-flight in redirects.");
     jsTestIsAsync = true;
         testRunner.setCookieStoragePartitioningEnabled(enable);
     }
 
-    if (document.location.hash === "") {
-        setEnableFeature(true);
-        if (testRunner.isStatisticsPrevalentResource("http://localhost"))
-            testFailed("Localhost was classified as prevalent resource before the test starts.");
-        // Make sure the network process is up-to-date.
-        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false);
-        testRunner.dumpChildFramesAsText();
-        document.location.hash = "step1";
-    }
-
     const partitionHost = "127.0.0.1:8000";
     const thirdPartyOrigin = "http://localhost:8000";
     const resourcePath = "/resourceLoadStatistics/resources";
                 // Set localhost as prevalent and with non-recent user interaction to put it in the partitioning category.
                 document.location.hash = "step5";
                 testRunner.setStatisticsPrevalentResource("http://localhost", true);
-                testRunner.setStatisticsHasHadNonRecentUserInteraction("http://localhost");
-                testRunner.statisticsUpdateCookiePartitioning();
                 if (!testRunner.isStatisticsPrevalentResource("http://localhost"))
                     testFailed("Host did not get set as prevalent resource.");
-                runTest();
+                testRunner.setStatisticsHasHadNonRecentUserInteraction("http://localhost");
+                testRunner.statisticsUpdateCookiePartitioning(function() {
+                    runTest();
+                });
                 break;
             case "#step5":
                 // Set partitioned cookie for localhost under 127.0.0.1.
                 break;
         }
     }
+
+    if (document.location.hash === "") {
+        setEnableFeature(true);
+        if (testRunner.isStatisticsPrevalentResource("http://localhost"))
+            testFailed("Localhost was classified as prevalent resource before the test starts.");
+        testRunner.dumpChildFramesAsText();
+        document.location.hash = "step1";
+        // Make sure the network process is up-to-date.
+        testRunner.statisticsSetShouldPartitionCookiesForHost("localhost", false, runTest);
+    } else {
+        runTest();
+    }
 </script>
 </body>
 </html>
index 733050f..84fdc97 100644 (file)
             case "#step4":
                 // Flag localhost for partitioning and set a partitioned cookie.
                 document.location.hash = "step5";
-                testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, true);
-                openIframe(thirdPartyBaseUrl + subPathToSetPartitionedThirdPartyCookie + "&message=Setting partitioned, third party cookie.", runTest);
+                testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, true, runTest);
                 break;
             case "#step5":
+                // Flag localhost for partitioning and set a partitioned cookie.
                 document.location.hash = "step6";
-                openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should only receive partitioned, third party cookie.", setUserInteractionAndContinue);
+                openIframe(thirdPartyBaseUrl + subPathToSetPartitionedThirdPartyCookie + "&message=Setting partitioned, third party cookie.", runTest);
                 break;
             case "#step6":
+                document.location.hash = "step7";
+                openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should only receive partitioned, third party cookie.", setUserInteractionAndContinue);
+                break;
+            case "#step7":
                 openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=After user interaction, should receive non-partitioned cookies set in a first-party context and in a third-party context.", finishTest);
                 break;
         }
     if (document.location.host === partitionHost && document.location.hash == "" && window.testRunner && window.internals) {
         setEnableFeature(true);
 
-        // Start test with third party as non-prevalent
-        testRunner.setStatisticsPrevalentResource(thirdPartyHostname, false);
-        testRunner.setStatisticsHasHadUserInteraction(thirdPartyOrigin, false);
-        testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, false);
-
         testRunner.waitUntilDone();
         testRunner.dumpChildFramesAsText();
         document.location.hash = "step1";
-    }
 
-    runTest();
+        // Start test with third party as non-prevalent
+        testRunner.setStatisticsPrevalentResource(thirdPartyHostname, false);
+        testRunner.setStatisticsHasHadUserInteraction(thirdPartyOrigin, false);
+        testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, false, runTest);
+    } else {
+        runTest();
+    }
 </script>
 </body>
 </html>
index 4a17312..705cf31 100644 (file)
@@ -804,13 +804,13 @@ webkit.org/b/176122 media/video-controls-drop-and-restore-timeline.html [ Pass F
 [ HighSierra+ ] http/tests/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html [ Pass ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-deletion.html [ Pass Timeout ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/non-prevalent-resources-can-access-cookies-in-a-third-party-context.html [ Pass ]
+[ HighSierra+ ] http/tests/resourceLoadStatistics/add-partitioning-to-redirect.html [ Pass ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/add-blocking-to-redirect.html [ Pass ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/remove-partitioning-in-redirect.html [ Pass ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/remove-blocking-in-redirect.html [ Pass ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/clear-in-memory-and-persistent-store.html [ Pass ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/clear-in-memory-and-persistent-store-one-hour.html [ Pass ]
-
-webkit.org/b/181958 [ HighSierra+ ] http/tests/resourceLoadStatistics/add-partitioning-to-redirect.html [ Pass Failure ]
+[ HighSierra+ ] http/tests/resourceLoadStatistics/grandfathering.html [ Pass ]
 
 # <rdar://problem/33555759>
 webkit.org/b/177616 [ HighSierra+ ] http/tests/media/video-buffered-range-contains-currentTime.html [ Pass Timeout ]
@@ -875,8 +875,6 @@ webkit.org/b/181839 [ Debug ] inspector/debugger/breakpoint-action-log.html [ Pa
 
 webkit.org/b/181753 [ HighSierra Release ] http/wpt/service-workers/update-service-worker.https.html [ Pass Failure ]
 
-webkit.org/b/181482 http/tests/resourceLoadStatistics/grandfathering.html [ Pass ]
-
 webkit.org/b/181831 [ HighSierra ] fast/forms/searchfield-heights.html [ Pass Failure ]
 
 webkit.org/b/181957 [ Release ] http/tests/misc/resource-timing-resolution.html [ Pass Failure ]
index 4e1551e..af21e34 100644 (file)
@@ -1,3 +1,41 @@
+2018-01-30  John Wilander  <wilander@apple.com>
+
+        Add callbacks to testRunner.statisticsSetShouldPartitionCookiesForHost() and testRunner.statisticsUpdateCookiePartitioning()
+        https://bugs.webkit.org/show_bug.cgi?id=181958
+        https://bugs.webkit.org/show_bug.cgi?id=182072
+        <rdar://problem/36801804>
+        <rdar://problem/36845795>
+
+        Reviewed by Brent Fulgham.
+
+        Because of the asynchronous nature of XPC and cookies,
+        we need callbacks in these TestRunner functions so that
+        the layout tests can wait for state changes to finish
+        before checking test conditions.
+
+        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+        (WKWebsiteDataStoreStatisticsUpdateCookiePartitioning):
+        (WKWebsiteDataStoreSetStatisticsShouldPartitionCookiesForHost):
+        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+        (-[WKWebsiteDataStore _resourceLoadStatisticsUpdateCookiePartitioning]):
+        (-[WKWebsiteDataStore _resourceLoadStatisticsUpdateCookiePartitioning:]):
+        (-[WKWebsiteDataStore _resourceLoadStatisticsSetShouldPartitionCookies:forHost:]):
+        (-[WKWebsiteDataStore _resourceLoadStatisticsSetShouldPartitionCookies:forHost:completionHandler:]):
+        * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
+        * UIProcess/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated):
+        (WebKit::WebResourceLoadStatisticsStore::logUserInteraction):
+        (WebKit::WebResourceLoadStatisticsStore::logNonRecentUserInteraction):
+        (WebKit::WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdate):
+        (WebKit::WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdateForDomains):
+        (WebKit::WebResourceLoadStatisticsStore::scheduleClearPartitioningStateForDomains):
+        (WebKit::WebResourceLoadStatisticsStore::mergeWithDataFromDecoder):
+        (WebKit::WebResourceLoadStatisticsStore::clearInMemory):
+        (WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioning):
+        (WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains):
+        (WebKit::WebResourceLoadStatisticsStore::clearPartitioningStateForDomains):
+        * UIProcess/WebResourceLoadStatisticsStore.h:
+
 2018-01-30  Ryosuke Niwa  <rniwa@webkit.org>
 
         REGRESSION(r227550): Resource timing API is disabled on macOS
index 7796fc9..575d721 100644 (file)
@@ -244,7 +244,7 @@ void WKWebsiteDataStoreStatisticsUpdateCookiePartitioning(WKWebsiteDataStoreRef
     if (!store)
         return;
 
-    store->scheduleCookiePartitioningUpdate();
+    store->scheduleCookiePartitioningUpdate([]() { });
 }
 
 void WKWebsiteDataStoreSetStatisticsShouldPartitionCookiesForHost(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool value)
@@ -254,9 +254,9 @@ void WKWebsiteDataStoreSetStatisticsShouldPartitionCookiesForHost(WKWebsiteDataS
         return;
 
     if (value)
-        store->scheduleCookiePartitioningUpdateForDomains({ WebKit::toImpl(host)->string() }, { }, { }, WebKit::ShouldClearFirst::No);
+        store->scheduleCookiePartitioningUpdateForDomains({ WebKit::toImpl(host)->string() }, { }, { }, WebKit::ShouldClearFirst::No, []() { });
     else
-        store->scheduleClearPartitioningStateForDomains({ WebKit::toImpl(host)->string() });
+        store->scheduleClearPartitioningStateForDomains({ WebKit::toImpl(host)->string() }, []() { });
 }
 
 void WKWebsiteDataStoreStatisticsSubmitTelemetry(WKWebsiteDataStoreRef dataStoreRef)
index c1f1510..d4eeb9f 100644 (file)
@@ -497,23 +497,43 @@ static Vector<WebKit::WebsiteDataRecord> toWebsiteDataRecords(NSArray *dataRecor
 
 - (void)_resourceLoadStatisticsUpdateCookiePartitioning
 {
+    [self _resourceLoadStatisticsUpdateCookiePartitioning:^() { }];
+}
+
+- (void)_resourceLoadStatisticsUpdateCookiePartitioning:(void (^)())completionHandler
+{
     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
-    if (!store)
+    if (!store) {
+        completionHandler();
         return;
-
-    store->scheduleCookiePartitioningUpdate();
+    }
+    
+    store->scheduleCookiePartitioningUpdate([completionHandler = makeBlockPtr(completionHandler)]() {
+        completionHandler();
+    });
 }
 
 - (void)_resourceLoadStatisticsSetShouldPartitionCookies:(BOOL)value forHost:(NSString *)host
 {
+    [self _resourceLoadStatisticsSetShouldPartitionCookies:value forHost:host completionHandler:^() { }];
+}
+
+- (void)_resourceLoadStatisticsSetShouldPartitionCookies:(BOOL)value forHost:(NSString *)host completionHandler:(void (^)())completionHandler
+{
     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
-    if (!store)
+    if (!store) {
+        completionHandler();
         return;
+    }
 
     if (value)
-        store->scheduleCookiePartitioningUpdateForDomains({ host }, { }, { }, WebKit::ShouldClearFirst::No);
+        store->scheduleCookiePartitioningUpdateForDomains({ host }, { }, { }, WebKit::ShouldClearFirst::No, [completionHandler = makeBlockPtr(completionHandler)]() {
+            completionHandler();
+        });
     else
-        store->scheduleClearPartitioningStateForDomains({ host });
+        store->scheduleClearPartitioningStateForDomains({ host }, [completionHandler = makeBlockPtr(completionHandler)]() {
+            completionHandler();
+        });
 }
 
 - (void)_resourceLoadStatisticsSubmitTelemetry
index 2ef1c86..2cec1c1 100644 (file)
@@ -73,8 +73,10 @@ typedef NS_OPTIONS(NSUInteger, _WKWebsiteDataStoreFetchOptions) {
 - (void)_resourceLoadStatisticsSetMaxStatisticsEntries:(size_t)entries WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (void)_resourceLoadStatisticsSetPruneEntriesDownTo:(size_t)entries WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (void)_resourceLoadStatisticsProcessStatisticsAndDataRecords WK_API_AVAILABLE(macosx(10.13), ios(11.0));
-- (void)_resourceLoadStatisticsUpdateCookiePartitioning WK_API_AVAILABLE(macosx(10.13), ios(11.0));
-- (void)_resourceLoadStatisticsSetShouldPartitionCookies:(BOOL)value forHost:(NSString *)host WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (void)_resourceLoadStatisticsUpdateCookiePartitioning WK_API_DEPRECATED_WITH_REPLACEMENT("_resourceLoadStatisticsUpdateCookiePartitioning", macosx(10.13, WK_MAC_TBA), ios(11.0, WK_IOS_TBA));
+- (void)_resourceLoadStatisticsUpdateCookiePartitioning:(void (^)())completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_resourceLoadStatisticsSetShouldPartitionCookies:(BOOL)value forHost:(NSString *)host WK_API_DEPRECATED_WITH_REPLACEMENT("_resourceLoadStatisticsSetShouldPartitionCookies", macosx(10.13, WK_MAC_TBA), ios(11.0, WK_IOS_TBA));
+- (void)_resourceLoadStatisticsSetShouldPartitionCookies:(BOOL)value forHost:(NSString *)host completionHandler:(void (^)())completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (void)_resourceLoadStatisticsSubmitTelemetry WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (void)_resourceLoadStatisticsSetNotifyPagesWhenDataRecordsWereScanned:(BOOL)value WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (void)_resourceLoadStatisticsSetShouldClassifyResourcesBeforeDataRecordsRemoval:(BOOL)value WK_API_AVAILABLE(macosx(10.13), ios(11.0));
index 88e99d9..d4b823b 100644 (file)
@@ -254,7 +254,7 @@ void WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated(Vector<WebCor
 
     mergeStatistics(WTFMove(origins));
     // Fire before processing statistics to propagate user interaction as fast as possible to the network process.
-    updateCookiePartitioning();
+    updateCookiePartitioning([]() { });
     processStatisticsAndDataRecords();
 }
 
@@ -386,7 +386,7 @@ void WebResourceLoadStatisticsStore::logUserInteraction(const URL& url)
         statistics.mostRecentUserInteractionTime = WallTime::now();
 
         if (statistics.isMarkedForCookiePartitioning || statistics.isMarkedForCookieBlocking)
-            updateCookiePartitioningForDomains({ }, { }, { primaryDomain }, ShouldClearFirst::No);
+            updateCookiePartitioningForDomains({ }, { }, { primaryDomain }, ShouldClearFirst::No, []() { });
     });
 }
 
@@ -400,7 +400,7 @@ void WebResourceLoadStatisticsStore::logNonRecentUserInteraction(const URL& url)
         statistics.hadUserInteraction = true;
         statistics.mostRecentUserInteractionTime = WallTime::now() - (m_parameters.timeToLiveCookiePartitionFree + Seconds::fromHours(1));
 
-        updateCookiePartitioningForDomains({ primaryDomain }, { }, { }, ShouldClearFirst::No);
+        updateCookiePartitioningForDomains({ primaryDomain }, { }, { }, ShouldClearFirst::No, []() { });
     });
 }
 
@@ -563,31 +563,31 @@ void WebResourceLoadStatisticsStore::setSubresourceUniqueRedirectTo(const URL& s
     });
 }
 
-void WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdate()
+void WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdate(CompletionHandler<void()>&& callback)
 {
     // Helper function used by testing system. Should only be called from the main thread.
     ASSERT(RunLoop::isMain());
 
-    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this)] {
-        updateCookiePartitioning();
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), callback = WTFMove(callback)] () mutable {
+        updateCookiePartitioning(WTFMove(callback));
     });
 }
 
-void WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdateForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst)
+void WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdateForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst, CompletionHandler<void()>&& callback)
 {
     // Helper function used by testing system. Should only be called from the main thread.
     ASSERT(RunLoop::isMain());
-    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock), shouldClearFirst] {
-        updateCookiePartitioningForDomains(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock), shouldClearFirst, callback = WTFMove(callback)] () mutable {
+        updateCookiePartitioningForDomains(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst, WTFMove(callback));
     });
 }
 
-void WebResourceLoadStatisticsStore::scheduleClearPartitioningStateForDomains(const Vector<String>& domains)
+void WebResourceLoadStatisticsStore::scheduleClearPartitioningStateForDomains(const Vector<String>& domains, CompletionHandler<void()>&& callback)
 {
     // Helper function used by testing system. Should only be called from the main thread.
     ASSERT(RunLoop::isMain());
-    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), domains = crossThreadCopy(domains)] {
-        clearPartitioningStateForDomains(domains);
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), domains = crossThreadCopy(domains), callback = WTFMove(callback)] () mutable {
+        clearPartitioningStateForDomains(domains, WTFMove(callback));
     });
 }
 
@@ -732,7 +732,7 @@ void WebResourceLoadStatisticsStore::mergeWithDataFromDecoder(KeyedDecoder& deco
         return;
 
     mergeStatistics(WTFMove(loadedStatistics));
-    updateCookiePartitioning();
+    updateCookiePartitioning([]() { });
 
     Vector<OperatingDate> operatingDates;
     succeeded = decoder.decodeObjects("operatingDates", operatingDates, [](KeyedDecoder& decoder, OperatingDate& date) {
@@ -756,7 +756,7 @@ void WebResourceLoadStatisticsStore::clearInMemory()
     m_resourceStatisticsMap.clear();
     m_operatingDates.clear();
 
-    updateCookiePartitioningForDomains({ }, { }, { }, ShouldClearFirst::Yes);
+    updateCookiePartitioningForDomains({ }, { }, { }, ShouldClearFirst::Yes, []() { });
 }
 
 bool WebResourceLoadStatisticsStore::wasAccessedAsFirstPartyDueToUserInteraction(const ResourceLoadStatistics& current, const ResourceLoadStatistics& updated)
@@ -794,7 +794,7 @@ bool WebResourceLoadStatisticsStore::shouldBlockCookies(const ResourceLoadStatis
     return statistic.isPrevalentResource && !statistic.hadUserInteraction;
 }
 
-void WebResourceLoadStatisticsStore::updateCookiePartitioning()
+void WebResourceLoadStatisticsStore::updateCookiePartitioning(CompletionHandler<void()>&& callback)
 {
     ASSERT(!RunLoop::isMain());
 
@@ -819,20 +819,25 @@ void WebResourceLoadStatisticsStore::updateCookiePartitioning()
         }
     }
 
-    if (domainsToPartition.isEmpty() && domainsToBlock.isEmpty() && domainsToNeitherPartitionNorBlock.isEmpty())
+    if (domainsToPartition.isEmpty() && domainsToBlock.isEmpty() && domainsToNeitherPartitionNorBlock.isEmpty()) {
+        callback();
         return;
+    }
 
-    RunLoop::main().dispatch([this, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock)] () {
+    RunLoop::main().dispatch([this, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock), callback = WTFMove(callback)] () {
         m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, ShouldClearFirst::No);
+        callback();
     });
 }
 
-void WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst)
+void WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst shouldClearFirst, CompletionHandler<void()>&& callback)
 {
     ASSERT(!RunLoop::isMain());
-    if (domainsToPartition.isEmpty() && domainsToBlock.isEmpty() && domainsToNeitherPartitionNorBlock.isEmpty() && shouldClearFirst == ShouldClearFirst::No)
+    if (domainsToPartition.isEmpty() && domainsToBlock.isEmpty() && domainsToNeitherPartitionNorBlock.isEmpty() && shouldClearFirst == ShouldClearFirst::No) {
+        callback();
         return;
-
+    }
+    
     RunLoop::main().dispatch([this, shouldClearFirst, protectedThis = makeRef(*this), domainsToPartition = crossThreadCopy(domainsToPartition), domainsToBlock = crossThreadCopy(domainsToBlock), domainsToNeitherPartitionNorBlock = crossThreadCopy(domainsToNeitherPartitionNorBlock)] () {
         m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
     });
@@ -852,13 +857,17 @@ void WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(const Ve
 
     for (auto& domain : domainsToBlock)
         ensureResourceStatisticsForPrimaryDomain(domain).isMarkedForCookieBlocking = true;
+
+    callback();
 }
 
-void WebResourceLoadStatisticsStore::clearPartitioningStateForDomains(const Vector<String>& domains)
+void WebResourceLoadStatisticsStore::clearPartitioningStateForDomains(const Vector<String>& domains, CompletionHandler<void()>&& callback)
 {
     ASSERT(!RunLoop::isMain());
-    if (domains.isEmpty())
+    if (domains.isEmpty()) {
+        callback();
         return;
+    }
 
     RunLoop::main().dispatch([this, protectedThis = makeRef(*this), domains = crossThreadCopy(domains)] () {
         m_removeDomainsHandler(domains);
@@ -869,6 +878,8 @@ void WebResourceLoadStatisticsStore::clearPartitioningStateForDomains(const Vect
         statistic.isMarkedForCookiePartitioning = false;
         statistic.isMarkedForCookieBlocking = false;
     }
+
+    callback();
 }
 
 void WebResourceLoadStatisticsStore::resetCookiePartitioningState()
index 5cfd21c..bd211b5 100644 (file)
@@ -106,9 +106,9 @@ public:
     void setSubframeUnderTopFrameOrigin(const WebCore::URL& subframe, const WebCore::URL& topFrame);
     void setSubresourceUnderTopFrameOrigin(const WebCore::URL& subresource, const WebCore::URL& topFrame);
     void setSubresourceUniqueRedirectTo(const WebCore::URL& subresource, const WebCore::URL& hostNameRedirectedTo);
-    void scheduleCookiePartitioningUpdate();
-    void scheduleCookiePartitioningUpdateForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst);
-    void scheduleClearPartitioningStateForDomains(const Vector<String>& domains);
+    void scheduleCookiePartitioningUpdate(CompletionHandler<void()>&&);
+    void scheduleCookiePartitioningUpdateForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst, CompletionHandler<void()>&&);
+    void scheduleClearPartitioningStateForDomains(const Vector<String>& domains, CompletionHandler<void()>&&);
     void scheduleStatisticsAndDataRecordsProcessing();
     void submitTelemetry();
     void scheduleCookiePartitioningStateReset();
@@ -162,9 +162,9 @@ private:
     bool hasHadUnexpiredRecentUserInteraction(WebCore::ResourceLoadStatistics&) const;
     void includeTodayAsOperatingDateIfNecessary();
     Vector<String> topPrivatelyControlledDomainsToRemoveWebsiteDataFor();
-    void updateCookiePartitioning();
-    void updateCookiePartitioningForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst);
-    void clearPartitioningStateForDomains(const Vector<String>& domains);
+    void updateCookiePartitioning(CompletionHandler<void()>&&);
+    void updateCookiePartitioningForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst, CompletionHandler<void()>&&);
+    void clearPartitioningStateForDomains(const Vector<String>& domains, CompletionHandler<void()>&&);
     void mergeStatistics(Vector<WebCore::ResourceLoadStatistics>&&);
     WebCore::ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
     void processStatisticsAndDataRecords();
index 3a9f1bd..745e4e6 100644 (file)
@@ -1,3 +1,33 @@
+2018-01-30  John Wilander  <wilander@apple.com>
+
+        Add callbacks to testRunner.statisticsSetShouldPartitionCookiesForHost() and testRunner.statisticsUpdateCookiePartitioning()
+        https://bugs.webkit.org/show_bug.cgi?id=181958
+        https://bugs.webkit.org/show_bug.cgi?id=182072
+        <rdar://problem/36801804>
+        <rdar://problem/36845795>
+
+        Reviewed by Brent Fulgham.
+
+        Because of the asynchronous nature of XPC and cookies,
+        we need callbacks in these TestRunner functions so that
+        the layout tests can wait for state changes to finish
+        before checking test conditions.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+        (WTR::InjectedBundle::didReceiveMessageToPage):
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::statisticsUpdateCookiePartitioning):
+        (WTR::TestRunner::statisticsSetShouldPartitionCookiesForHost):
+        (WTR::TestRunner::statisticsCallDidSetPartitionOrBlockCookiesForHostCallback):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didSetPartitionOrBlockCookiesForHost):
+        * WebKitTestRunner/TestInvocation.h:
+        * WebKitTestRunner/cocoa/TestControllerCocoa.mm:
+        (WTR::TestController::statisticsUpdateCookiePartitioning):
+        (WTR::TestController::statisticsSetShouldPartitionCookiesForHost):
+
 2018-01-30  Basuke Suzuki  <Basuke.Suzuki@sony.com>
 
         [webkitpy] Config file for apache is copied twice.
index a3ea375..1ed7af0 100644 (file)
@@ -283,8 +283,8 @@ interface TestRunner {
     void setStatisticsTimeToLiveCookiePartitionFree(double seconds);
     void statisticsNotifyObserver();
     void statisticsProcessStatisticsAndDataRecords();
-    void statisticsUpdateCookiePartitioning();
-    void statisticsSetShouldPartitionCookiesForHost(DOMString hostName, boolean value);
+    void statisticsUpdateCookiePartitioning(object callback);
+    void statisticsSetShouldPartitionCookiesForHost(DOMString hostName, boolean value, object callback);
     void statisticsSubmitTelemetry();
     void setStatisticsNotifyPagesWhenDataRecordsWereScanned(boolean value);
     void setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(boolean value);
index 3de38c3..72ea3d2 100644 (file)
@@ -245,6 +245,11 @@ void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef m
         return;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetPartitionOrBlockCookiesForHost")) {
+        m_testRunner->statisticsCallDidSetPartitionOrBlockCookiesForHostCallback();
+        return;
+    }
+
     if (WKStringIsEqualToUTF8CString(messageName, "CallDidRemoveAllSessionCredentialsCallback")) {
         m_testRunner->callDidRemoveAllSessionCredentialsCallback();
         return;
index 6476adf..270d638 100644 (file)
@@ -651,6 +651,7 @@ enum {
     StatisticsDidScanDataRecordsCallbackID,
     StatisticsDidRunTelemetryCallbackID,
     StatisticsDidClearThroughWebsiteDataRemovalCallbackID,
+    StatisticsDidSetPartitionOrBlockCookiesForHostCallbackID,
     DidRemoveAllSessionCredentialsCallbackID,
     GetApplicationManifestCallbackID,
     FirstUIScriptCallbackID = 100
@@ -1553,14 +1554,18 @@ void TestRunner::statisticsProcessStatisticsAndDataRecords()
     WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, nullptr);
 }
 
-void TestRunner::statisticsUpdateCookiePartitioning()
+void TestRunner::statisticsUpdateCookiePartitioning(JSValueRef callback)
 {
+    cacheTestRunnerCallback(StatisticsDidSetPartitionOrBlockCookiesForHostCallbackID, callback);
+
     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsUpdateCookiePartitioning"));
     WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, nullptr);
 }
 
-void TestRunner::statisticsSetShouldPartitionCookiesForHost(JSStringRef hostName, bool value)
+void TestRunner::statisticsSetShouldPartitionCookiesForHost(JSStringRef hostName, bool value, JSValueRef callback)
 {
+    cacheTestRunnerCallback(StatisticsDidSetPartitionOrBlockCookiesForHostCallbackID, callback);
+
     Vector<WKRetainPtr<WKStringRef>> keys;
     Vector<WKRetainPtr<WKTypeRef>> values;
     
@@ -1584,6 +1589,11 @@ void TestRunner::statisticsSetShouldPartitionCookiesForHost(JSStringRef hostName
     WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
 }
 
+void TestRunner::statisticsCallDidSetPartitionOrBlockCookiesForHostCallback()
+{
+    callTestRunnerCallback(StatisticsDidSetPartitionOrBlockCookiesForHostCallbackID);
+}
+
 void TestRunner::statisticsSubmitTelemetry()
 {
     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("StatisticsSubmitTelemetry"));
index 39077f7..cc60415 100644 (file)
@@ -367,8 +367,9 @@ public:
     void statisticsDidRunTelemetryCallback(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins);
     void statisticsNotifyObserver();
     void statisticsProcessStatisticsAndDataRecords();
-    void statisticsUpdateCookiePartitioning();
-    void statisticsSetShouldPartitionCookiesForHost(JSStringRef hostName, bool value);
+    void statisticsUpdateCookiePartitioning(JSValueRef callback);
+    void statisticsSetShouldPartitionCookiesForHost(JSStringRef hostName, bool value, JSValueRef callback);
+    void statisticsCallDidSetPartitionOrBlockCookiesForHostCallback();
     void statisticsSubmitTelemetry();
     void setStatisticsLastSeen(JSStringRef hostName, double seconds);
     void setStatisticsPrevalentResource(JSStringRef hostName, bool value);
index f5466d8..987ade4 100644 (file)
@@ -1345,6 +1345,12 @@ void TestInvocation::didClearStatisticsThroughWebsiteDataRemoval()
     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
 }
 
+void TestInvocation::didSetPartitionOrBlockCookiesForHost()
+{
+    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetPartitionOrBlockCookiesForHost"));
+    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
+}
+
 void TestInvocation::didRemoveAllSessionCredentials()
 {
     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveAllSessionCredentialsCallback"));
index 42cf965..25ce67d 100644 (file)
@@ -72,6 +72,7 @@ public:
     void notifyDownloadDone();
 
     void didClearStatisticsThroughWebsiteDataRemoval();
+    void didSetPartitionOrBlockCookiesForHost();
 
     void didRemoveAllSessionCredentials();
     
index f98329b..9c19763 100644 (file)
@@ -376,12 +376,16 @@ void TestController::statisticsProcessStatisticsAndDataRecords()
 
 void TestController::statisticsUpdateCookiePartitioning()
 {
-    [globalWebViewConfiguration.websiteDataStore _resourceLoadStatisticsUpdateCookiePartitioning];
+    [globalWebViewConfiguration.websiteDataStore _resourceLoadStatisticsUpdateCookiePartitioning:^() {
+        m_currentInvocation->didSetPartitionOrBlockCookiesForHost();
+    }];
 }
 
 void TestController::statisticsSetShouldPartitionCookiesForHost(WKStringRef hostName, bool value)
 {
-    [globalWebViewConfiguration.websiteDataStore _resourceLoadStatisticsSetShouldPartitionCookies:value forHost:toNSString(hostName)];
+    [globalWebViewConfiguration.websiteDataStore _resourceLoadStatisticsSetShouldPartitionCookies:value forHost:toNSString(hostName) completionHandler:^() {
+        m_currentInvocation->didSetPartitionOrBlockCookiesForHost();
+    }];
 }
 
 void TestController::statisticsSubmitTelemetry()