<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[171687] trunk/Tools</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/171687">171687</a></dd>
<dt>Author</dt> <dd>dfarler@apple.com</dd>
<dt>Date</dt> <dd>2014-07-28 13:03:45 -0700 (Mon, 28 Jul 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Allow for multiple DumpRenderTree and WebKitTestRunner instances in the iOS Simulator
https://bugs.webkit.org/show_bug.cgi?id=135272

Reviewed by Simon Fraser.

* DumpRenderTree/mac/DumpRenderTree.mm:
(dumpRenderTree): Remove hard-coding of FIFO paths.
(-[DumpRenderTree applicationDidEnterBackground:]): Create background task.
(DumpRenderTreeMain): Set DumpRenderTree as UIApplication delegate.
* DumpRenderTree/mac/DumpRenderTreeMac.h: bgTask ivar.
* Scripts/old-run-webkit-tests: Update FIFO paths for ORWT.
* WebKitTestRunner/TestController.cpp: Remove hard-coding of FIFO paths.
* WebKitTestRunner/ios/TestControllerIOS.mm: Move dup2 calls to platformInitialize
* WebKitTestRunner/ios/mainIOS.mm: bgTask ivar.
(-[WebKitTestRunnerApp applicationDidEnterBackground:]): Create background task.
(main): Set WebKitTestRunnerApp as UIApplication delegate.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreemacDumpRenderTreemm">trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm</a></li>
<li><a href="#trunkToolsDumpRenderTreemacDumpRenderTreeMach">trunk/Tools/DumpRenderTree/mac/DumpRenderTreeMac.h</a></li>
<li><a href="#trunkToolsScriptsoldrunwebkittests">trunk/Tools/Scripts/old-run-webkit-tests</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestControllercpp">trunk/Tools/WebKitTestRunner/TestController.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunneriosTestControllerIOSmm">trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunneriosmainIOSmm">trunk/Tools/WebKitTestRunner/ios/mainIOS.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (171686 => 171687)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-07-28 19:59:43 UTC (rev 171686)
+++ trunk/Tools/ChangeLog        2014-07-28 20:03:45 UTC (rev 171687)
</span><span class="lines">@@ -1,5 +1,24 @@
</span><span class="cx"> 2014-07-24  David Farler  &lt;dfarler@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Allow for multiple DumpRenderTree and WebKitTestRunner instances in the iOS Simulator
+        https://bugs.webkit.org/show_bug.cgi?id=135272
+
+        Reviewed by Simon Fraser.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (dumpRenderTree): Remove hard-coding of FIFO paths.
+        (-[DumpRenderTree applicationDidEnterBackground:]): Create background task.
+        (DumpRenderTreeMain): Set DumpRenderTree as UIApplication delegate.
+        * DumpRenderTree/mac/DumpRenderTreeMac.h: bgTask ivar.
+        * Scripts/old-run-webkit-tests: Update FIFO paths for ORWT.
+        * WebKitTestRunner/TestController.cpp: Remove hard-coding of FIFO paths.
+        * WebKitTestRunner/ios/TestControllerIOS.mm: Move dup2 calls to platformInitialize
+        * WebKitTestRunner/ios/mainIOS.mm: bgTask ivar.
+        (-[WebKitTestRunnerApp applicationDidEnterBackground:]): Create background task.
+        (main): Set WebKitTestRunnerApp as UIApplication delegate.
+
+2014-07-24  David Farler  &lt;dfarler@apple.com&gt;
+
</ins><span class="cx">         ImageDiff builds for the simulator when running iOS layout tests
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=135270
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacDumpRenderTreemm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (171686 => 171687)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm        2014-07-28 19:59:43 UTC (rev 171686)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm        2014-07-28 20:03:45 UTC (rev 171687)
</span><span class="lines">@@ -1119,11 +1119,16 @@
</span><span class="cx"> void dumpRenderTree(int argc, const char *argv[])
</span><span class="cx"> {
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    int infd = open(&quot;/tmp/DumpRenderTree_IN&quot;, O_RDWR);
</del><ins>+    NSString *identifier = [[NSBundle mainBundle] bundleIdentifier];
+    const char *stdinPath = [[NSString stringWithFormat:@&quot;/tmp/%@_IN&quot;, identifier] UTF8String];
+    const char *stdoutPath = [[NSString stringWithFormat:@&quot;/tmp/%@_OUT&quot;, identifier] UTF8String];
+    const char *stderrPath = [[NSString stringWithFormat:@&quot;/tmp/%@_ERROR&quot;, identifier] UTF8String];
+
+    int infd = open(stdinPath, O_RDWR);
</ins><span class="cx">     dup2(infd, STDIN_FILENO);
</span><del>-    int outfd = open(&quot;/tmp/DumpRenderTree_OUT&quot;, O_RDWR);
</del><ins>+    int outfd = open(stdoutPath, O_RDWR);
</ins><span class="cx">     dup2(outfd, STDOUT_FILENO);
</span><del>-    int errfd = open(&quot;/tmp/DumpRenderTree_ERROR&quot;, O_RDWR | O_NONBLOCK);
</del><ins>+    int errfd = open(stderrPath, O_RDWR | O_NONBLOCK);
</ins><span class="cx">     dup2(errfd, STDERR_FILENO);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -1225,6 +1230,29 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+    /* Apps will get suspended or killed some time after entering the background state but we want to be able to run multiple copies of DumpRenderTree. Periodically check to see if our remaining background time dips below a threshold and create a new background task.
+    */
+    void (^expirationHandler)() = ^ {
+        [application endBackgroundTask:backgroundTaskIdentifier];
+        backgroundTaskIdentifier = UIBackgroundTaskInvalid;
+    };
+
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+
+        NSTimeInterval timeRemaining;
+        while (true) {
+            timeRemaining = [application backgroundTimeRemaining];
+            if (timeRemaining &lt;= 10.0 || backgroundTaskIdentifier == UIBackgroundTaskInvalid) {
+                [application endBackgroundTask:backgroundTaskIdentifier];
+                backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:expirationHandler];
+            }
+            sleep(5);
+        }
+    });
+}
+
</ins><span class="cx"> // The test can end in response to a delegate callback while there are still methods queued on the Web Thread.
</span><span class="cx"> // If we do not ensure the Web Thread has been run, the callback can be done on a WebView that no longer exists.
</span><span class="cx"> // To avoid this, _waitForWebThread dispatches a call to the WebThread event loop, actively processing the delegate
</span><span class="lines">@@ -1262,7 +1290,7 @@
</span><span class="cx"> #else
</span><span class="cx">     _argc = argc;
</span><span class="cx">     _argv = argv;
</span><del>-    UIApplicationMain(argc, (char**)argv, @&quot;DumpRenderTree&quot;, nil);
</del><ins>+    UIApplicationMain(argc, (char**)argv, @&quot;DumpRenderTree&quot;, @&quot;DumpRenderTree&quot;);
</ins><span class="cx"> #endif
</span><span class="cx">     [WebCoreStatistics garbageCollectJavaScriptObjects];
</span><span class="cx">     [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacDumpRenderTreeMach"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTreeMac.h (171686 => 171687)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/DumpRenderTreeMac.h        2014-07-28 19:59:43 UTC (rev 171686)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTreeMac.h        2014-07-28 20:03:45 UTC (rev 171687)
</span><span class="lines">@@ -77,6 +77,7 @@
</span><span class="cx"> #if PLATFORM(IOS) &amp;&amp; defined(__OBJC__)
</span><span class="cx"> @interface DumpRenderTree : UIApplication {
</span><span class="cx">     BOOL _hasFlushedWebThreadRunQueue;
</span><ins>+    UIBackgroundTaskIdentifier backgroundTaskIdentifier;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_waitForWebThread;
</span></span></pre></div>
<a id="trunkToolsScriptsoldrunwebkittests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/old-run-webkit-tests (171686 => 171687)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/old-run-webkit-tests        2014-07-28 19:59:43 UTC (rev 171686)
+++ trunk/Tools/Scripts/old-run-webkit-tests        2014-07-28 20:03:45 UTC (rev 171687)
</span><span class="lines">@@ -1506,11 +1506,8 @@
</span><span class="cx"> 
</span><span class="cx"> sub unlinkFIFOs()
</span><span class="cx"> {
</span><del>-    if ($useWebKitTestRunner) {
-        unlink &lt;/tmp/WebKitTestRunner_*&gt;;
-    } else {
-        unlink &lt;/tmp/DumpRenderTree_*&gt;;
-    }
</del><ins>+    my $identifier = iOSDumpToolAppIdentifier();
+    unlink glob &quot;/tmp/${identifier}_*&quot;;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub buildDumpTool($)
</span><span class="lines">@@ -1643,10 +1640,9 @@
</span><span class="cx"> 
</span><span class="cx">         my $appIdentifier = iOSDumpToolAppIdentifier();
</span><span class="cx"> 
</span><del>-        my $fifoName = $useWebKitTestRunner ? &quot;WebKitTestRunner&quot; : &quot;DumpRenderTree&quot;;
-        my $fifoOut = &quot;/tmp/${fifoName}_OUT&quot;;
-        my $fifoIn = &quot;/tmp/${fifoName}_IN&quot;;
-        my $fifoError = &quot;/tmp/${fifoName}_ERROR&quot;;
</del><ins>+        my $fifoOut = &quot;/tmp/${appIdentifier}_OUT&quot;;
+        my $fifoIn = &quot;/tmp/${appIdentifier}_IN&quot;;
+        my $fifoError = &quot;/tmp/${appIdentifier}_ERROR&quot;;
</ins><span class="cx"> 
</span><span class="cx">         foreach my $fifo ($fifoOut, $fifoIn, $fifoError) {
</span><span class="cx">             if (! -e $fifo) {
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (171686 => 171687)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestController.cpp        2014-07-28 19:59:43 UTC (rev 171686)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp        2014-07-28 20:03:45 UTC (rev 171687)
</span><span class="lines">@@ -124,16 +124,6 @@
</span><span class="cx">     , m_shouldUseRemoteLayerTree(false)
</span><span class="cx">     , m_shouldLogHistoryClientCallbacks(false)
</span><span class="cx"> {
</span><del>-
-#if PLATFORM(IOS)
-    int infd = open(&quot;/tmp/WebKitTestRunner_IN&quot;, O_RDWR);
-    dup2(infd, STDIN_FILENO);
-    int outfd = open(&quot;/tmp/WebKitTestRunner_OUT&quot;, O_RDWR);
-    dup2(outfd, STDOUT_FILENO);
-    int errfd = open(&quot;/tmp/WebKitTestRunner_ERROR&quot;, O_RDWR | O_NONBLOCK);
-    dup2(errfd, STDERR_FILENO);
-#endif
-
</del><span class="cx">     initialize(argc, argv);
</span><span class="cx">     controller = this;
</span><span class="cx">     run();
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosTestControllerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm (171686 => 171687)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm        2014-07-28 19:59:43 UTC (rev 171686)
+++ trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm        2014-07-28 20:03:45 UTC (rev 171687)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #import &quot;TestController.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #import &quot;CrashReporterInfo.h&quot;
</span><ins>+#import &lt;Foundation/Foundation.h&gt;
</ins><span class="cx"> #import &quot;PlatformWebView.h&quot;
</span><span class="cx"> #import &quot;TestInvocation.h&quot;
</span><span class="cx"> #import &lt;WebKit/WKStringCF.h&gt;
</span><span class="lines">@@ -40,6 +41,17 @@
</span><span class="cx"> 
</span><span class="cx"> void TestController::platformInitialize()
</span><span class="cx"> {
</span><ins>+    NSString *identifier = [[NSBundle mainBundle] bundleIdentifier];
+    const char *stdinPath = [[NSString stringWithFormat:@&quot;/tmp/%@_IN&quot;, identifier] UTF8String];
+    const char *stdoutPath = [[NSString stringWithFormat:@&quot;/tmp/%@_OUT&quot;, identifier] UTF8String];
+    const char *stderrPath = [[NSString stringWithFormat:@&quot;/tmp/%@_ERROR&quot;, identifier] UTF8String];
+
+    int infd = open(stdinPath, O_RDWR);
+    dup2(infd, STDIN_FILENO);
+    int outfd = open(stdoutPath, O_RDWR);
+    dup2(outfd, STDOUT_FILENO);
+    int errfd = open(stderrPath, O_RDWR | O_NONBLOCK);
+    dup2(errfd, STDERR_FILENO);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TestController::platformDestroy()
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosmainIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/mainIOS.mm (171686 => 171687)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/mainIOS.mm        2014-07-28 19:59:43 UTC (rev 171686)
+++ trunk/Tools/WebKitTestRunner/ios/mainIOS.mm        2014-07-28 20:03:45 UTC (rev 171687)
</span><span class="lines">@@ -31,7 +31,9 @@
</span><span class="cx"> static int _argc;
</span><span class="cx"> static const char **_argv;
</span><span class="cx"> 
</span><del>-@interface WebKitTestRunnerApp : UIApplication
</del><ins>+@interface WebKitTestRunnerApp : UIApplication {
+    UIBackgroundTaskIdentifier backgroundTaskIdentifier;
+}
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> @implementation WebKitTestRunnerApp
</span><span class="lines">@@ -46,6 +48,29 @@
</span><span class="cx">     [self performSelectorOnMainThread:@selector(_runTestController) withObject:nil waitUntilDone:NO];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+    /* Apps will get suspended or killed some time after entering the background state but we want to be able to run multiple copies of DumpRenderTree. Periodically check to see if our remaining background time dips below a threshold and create a new background task.
+    */
+    void (^expirationHandler)() = ^ {
+        [application endBackgroundTask:backgroundTaskIdentifier];
+        backgroundTaskIdentifier = UIBackgroundTaskInvalid;
+    };
+
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+
+        NSTimeInterval timeRemaining;
+        while (true) {
+            timeRemaining = [application backgroundTimeRemaining];
+            if (timeRemaining &lt;= 10.0 || backgroundTaskIdentifier == UIBackgroundTaskInvalid) {
+                [application endBackgroundTask:backgroundTaskIdentifier];
+                backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:expirationHandler];
+            }
+            sleep(5);
+        }
+    });
+}
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> int main(int argc, const char* argv[])
</span><span class="lines">@@ -53,6 +78,6 @@
</span><span class="cx">     _argc = argc;
</span><span class="cx">     _argv = argv;
</span><span class="cx"> 
</span><del>-    UIApplicationMain(argc, (char**)argv, NSStringFromClass([WebKitTestRunnerApp class]), nil);
</del><ins>+    UIApplicationMain(argc, (char**)argv, @&quot;WebKitTestRunnerApp&quot;, @&quot;WebKitTestRunnerApp&quot;);
</ins><span class="cx">     return 0;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>