TestWebKitAPI.AsyncFunction.Promise times out on slower machines in debug builds.
<rdar://problem/58445164> and https://bugs.webkit.org/show_bug.cgi?id=206012

Reviewed by Keith Miller.

Source/WebKit:

For existing API test.

* UIProcess/API/Cocoa/WKProcessPool.mm:
(-[WKProcessPool _garbageCollectJavaScriptObjectsForTesting]):
* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:

Tools:

Previously, to force GC, over 30,000 function calls would be made.
This was too slow on slower machines in debug builds. It eventually would've worked given enough time, but...
It turns just a few hundred function calls with an API call to force GC seems reliable and is much faster.

* TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm:
(TestWebKitAPI::TEST):
(TestWebKitAPI::tryGCPromise): Deleted.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254756 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 4904817..f516afc 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,16 @@
+2020-01-17  Brady Eidson  <beidson@apple.com>
+
+        TestWebKitAPI.AsyncFunction.Promise times out on slower machines in debug builds.
+        <rdar://problem/58445164> and https://bugs.webkit.org/show_bug.cgi?id=206012
+
+        Reviewed by Keith Miller.
+
+        For existing API test.
+
+        * UIProcess/API/Cocoa/WKProcessPool.mm:
+        (-[WKProcessPool _garbageCollectJavaScriptObjectsForTesting]):
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+
 2020-01-17  Daniel Bates  <dabates@apple.com>
 
         [iOS] Focusing editable element with WebPage::selectPositionAtPoint() does not bring up keyboard
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm b/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm
index dbfdd62..08e5b9f 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm
@@ -673,4 +673,9 @@
 #endif
 }
 
+- (void)_garbageCollectJavaScriptObjectsForTesting
+{
+    _processPool->garbageCollectJavaScriptObjects();
+}
+
 @end
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h
index b661560..7cfd056 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h
@@ -135,5 +135,6 @@
 
 // Test only.
 - (void)_seedResourceLoadStatisticsForTestingWithFirstParty:(NSURL *)firstPartyURL thirdParty:(NSURL *)thirdPartyURL shouldScheduleNotification:(BOOL)shouldScheduleNotification completionHandler:(void(^)(void))completionHandler  WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_garbageCollectJavaScriptObjectsForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 7033fa4..f7b4512 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,18 @@
+2020-01-17  Brady Eidson  <beidson@apple.com>
+
+        TestWebKitAPI.AsyncFunction.Promise times out on slower machines in debug builds.
+        <rdar://problem/58445164> and https://bugs.webkit.org/show_bug.cgi?id=206012
+
+        Reviewed by Keith Miller.
+
+        Previously, to force GC, over 30,000 function calls would be made.
+        This was too slow on slower machines in debug builds. It eventually would've worked given enough time, but...
+        It turns just a few hundred function calls with an API call to force GC seems reliable and is much faster.
+        
+        * TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm:
+        (TestWebKitAPI::TEST):
+        (TestWebKitAPI::tryGCPromise): Deleted.
+
 2020-01-16  Keith Miller  <keith_miller@apple.com>
 
         Reland bytecode checkpoints since bugs have been fixed
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm
index 72b94fa..04a88ab 100644
--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm
+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm
@@ -28,6 +28,7 @@
 #import "PlatformUtilities.h"
 #import "Test.h"
 #import "TestWKWebView.h"
+#import <WebKit/WKProcessPoolPrivate.h>
 #import <WebKit/WKWebViewPrivate.h>
 #import <WebKit/_WKContentWorld.h>
 
@@ -178,22 +179,6 @@
     EXPECT_TRUE([value isEqual:result]);
 }
 
-static void tryGCPromise(WKWebView *webView, bool& done)
-{
-    if (done)
-        return;
-
-    NSString *functionBody = @"return new Promise(function(resolve, reject) { })";
-    [webView _callAsyncJavaScriptFunction:functionBody withArguments:nil inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
-        EXPECT_NULL(result);
-        EXPECT_TRUE(error != nil);
-        EXPECT_TRUE([[error description] containsString:@"no longer reachable"]);
-        done = true;
-    }];
-
-    dispatch_async(dispatch_get_main_queue(), ^{ tryGCPromise(webView, done); });
-}
-
 TEST(AsyncFunction, Promise)
 {
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
@@ -279,8 +264,19 @@
     }];
     TestWebKitAPI::Util::run(&done);
 
+    // Promises known to become unreachable (e.g. via garbage collection) should call back with an error.
     done = false;
-    tryGCPromise(webView.get(), done);
+    functionBody = @"return new Promise(function(resolve, reject) { })";
+    for (int i = 0; i < 500; ++i) {
+        [webView _callAsyncJavaScriptFunction:functionBody withArguments:nil inWorld:_WKContentWorld.pageContentWorld completionHandler:[&] (id result, NSError *error) {
+            EXPECT_NULL(result);
+            EXPECT_TRUE(error != nil);
+            EXPECT_TRUE([[error description] containsString:@"no longer reachable"]);
+            done = true;
+        }];
+    }
+
+    [webView.get().configuration.processPool _garbageCollectJavaScriptObjectsForTesting];
     TestWebKitAPI::Util::run(&done);
 }