<!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>[173452] trunk</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/173452">173452</a></dd>
<dt>Author</dt> <dd>dfarler@apple.com</dd>
<dt>Date</dt> <dd>2014-09-09 16:31:41 -0700 (Tue, 09 Sep 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>iOS Simulator: run-webkit-tests chokes on unterminated UTF-8 when writing a test result
https://bugs.webkit.org/show_bug.cgi?id=135551

Reviewed by Daniel Bates.

Prevent printing invalid Unicode strings going to stderr.
Also, make filesystem.py more tolerant about receiving
Unicode (encoded as UTF-8) when writing to files, in the
rare case that an NSError description will make it to
stderr, such as -[LTRelayController createUniqueApp].

* LayoutTestRelay/LayoutTestRelay/LTRelayController.m:
(-[LTRelayController launchSimulator]): Removed.
(-[LTRelayController createUniqueApp]):
Don't explicitly try to uninstall the app. It is automatically handled
when installing an app with the same bundle identifier.
(-[LTRelayController start]):
(-[LTRelayController bootDevice]): Removed.
The device already boots as a part of starting the simulator. Attempting
to boot a second time may cause spurious stderr output.
* Scripts/webkitpy/port/driver.py:
(IOSSimulatorDriver._setup_environ_for_driver):
Explicitly set DEVELOPER_DIR once so xcode-select isn't called.
Open the iOS Simulator once instead of the LayoutTestRelay trying
to do it.
* Scripts/webkitpy/port/ios.py:
(IOSSimulatorPort._get_crash_log):
Make sure stderr is at least an empty string.
(IOSSimulatorPort):
(IOSSimulatorPort.developer_dir):
New property for setting up DEVELOPER_DIR in the driver environment.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastblockborderfitwithrightalignmentexpectedhtml">trunk/LayoutTests/fast/block/border-fit-with-right-alignment-expected.html</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsLayoutTestRelayLayoutTestRelayLTRelayControllerm">trunk/Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.m</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonsystemfilesystempy">trunk/Tools/Scripts/webkitpy/common/system/filesystem.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportdriverpy">trunk/Tools/Scripts/webkitpy/port/driver.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportimage_diffpy">trunk/Tools/Scripts/webkitpy/port/image_diff.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportiospy">trunk/Tools/Scripts/webkitpy/port/ios.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsfastblockborderfitwithrightalignmentexpectedhtml"></a>
<div class="binary"><h4>Modified: trunk/LayoutTests/fast/block/border-fit-with-right-alignment-expected.html</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (173451 => 173452)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-09-09 23:21:08 UTC (rev 173451)
+++ trunk/Tools/ChangeLog        2014-09-09 23:31:41 UTC (rev 173452)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2014-08-05  David Farler  &lt;dfarler@apple.com&gt;
+
+        iOS Simulator: run-webkit-tests chokes on unterminated UTF-8 when writing a test result
+        https://bugs.webkit.org/show_bug.cgi?id=135551
+
+        Reviewed by Daniel Bates.
+
+        Prevent printing invalid Unicode strings going to stderr.
+        Also, make filesystem.py more tolerant about receiving
+        Unicode (encoded as UTF-8) when writing to files, in the
+        rare case that an NSError description will make it to
+        stderr, such as -[LTRelayController createUniqueApp].
+
+        * LayoutTestRelay/LayoutTestRelay/LTRelayController.m:
+        (-[LTRelayController launchSimulator]): Removed.
+        (-[LTRelayController createUniqueApp]):
+        Don't explicitly try to uninstall the app. It is automatically handled
+        when installing an app with the same bundle identifier.
+        (-[LTRelayController start]):
+        (-[LTRelayController bootDevice]): Removed.
+        The device already boots as a part of starting the simulator. Attempting
+        to boot a second time may cause spurious stderr output.
+        * Scripts/webkitpy/port/driver.py:
+        (IOSSimulatorDriver._setup_environ_for_driver):
+        Explicitly set DEVELOPER_DIR once so xcode-select isn't called.
+        Open the iOS Simulator once instead of the LayoutTestRelay trying
+        to do it.
+        * Scripts/webkitpy/port/ios.py:
+        (IOSSimulatorPort._get_crash_log):
+        Make sure stderr is at least an empty string.
+        (IOSSimulatorPort):
+        (IOSSimulatorPort.developer_dir):
+        New property for setting up DEVELOPER_DIR in the driver environment.
+
</ins><span class="cx"> 2014-09-09  Dan Bernstein  &lt;mitz@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Clean up the MiniBrowser Xcode project
</span></span></pre></div>
<a id="trunkToolsLayoutTestRelayLayoutTestRelayLTRelayControllerm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.m (173451 => 173452)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.m        2014-09-09 23:21:08 UTC (rev 173451)
+++ trunk/Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.m        2014-09-09 23:31:41 UTC (rev 173452)
</span><span class="lines">@@ -89,10 +89,13 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)readFileHandle:(NSFileHandle *)fileHandle
</span><span class="cx"> {
</span><del>-    NSData *data = [fileHandle availableData];
-    uint8_t bytes[[data length]];
-    [data getBytes:bytes length:[data length]];
-    [[[self relay] outputStream] write:[data bytes] maxLength:[data length]];
</del><ins>+    @try {
+        NSData *data = [fileHandle availableData];
+        [[[self relay] outputStream] write:[data bytes] maxLength:[data length]];
+    } @catch (NSException *e) {
+        // Broken pipe - the dump tool crashed. Time to die.
+        [self didCrashWithMessage:nil];
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -133,66 +136,6 @@
</span><span class="cx">     exit(EXIT_FAILURE);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)launchSimulator
-{
-    NSString *developerDir = [[[NSProcessInfo processInfo] environment] valueForKey:@&quot;DEVELOPER_DIR&quot;];
-    if (!developerDir) {
-        NSTask *xcodeSelectTask = [[NSTask alloc] init];
-        [xcodeSelectTask setLaunchPath:@&quot;/usr/bin/xcode-select&quot;];
-        [xcodeSelectTask setArguments:@[@&quot;--print-path&quot;]];
-        [xcodeSelectTask setStandardOutput:[NSPipe pipe]];
-
-        NSFileHandle *stdoutFileHandle = [[xcodeSelectTask standardOutput] fileHandleForReading];
-        [xcodeSelectTask launch];
-        [xcodeSelectTask waitUntilExit];
-
-        NSData *data = [stdoutFileHandle readDataToEndOfFile];
-        developerDir = [NSString stringWithUTF8String:[data bytes]];
-    }
-
-    developerDir = [developerDir stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
-
-    if (!developerDir || ![developerDir length]) {
-        NSLog(@&quot;Not able to determine the path to iOS Simulator.app in your active Xcode.app&quot;);
-        exit(EXIT_FAILURE);
-    }
-    NSURL *simulatorURL = [NSURL fileURLWithPath:[developerDir stringByAppendingPathComponent:@&quot;Applications/iOS Simulator.app&quot;]];
-
-    NSDictionary *launchConfiguration = @{
-        NSWorkspaceLaunchConfigurationArguments: @[
-            @&quot;-CurrentDeviceUDID&quot;, [[[self device] UDID] UUIDString],
-            ]
-    };
-    NSError *error;
-    [[NSWorkspace sharedWorkspace] launchApplicationAtURL:simulatorURL options:NSWorkspaceLaunchDefault configuration:launchConfiguration error:&amp;error];
-
-    if (error) {
-        NSLog(@&quot;Couldn't launch iOS Simulator from %@: %@&quot;, [simulatorURL path], [error description]);
-        exit(EXIT_FAILURE);
-    }
-
-    while ([[self device] state] == SimDeviceStateShutdown) {
-        // Wait for device to start booting
-        sleep(1);
-    }
-}
-
-- (void)bootDevice
-{
-    while ([[self device] state] == SimDeviceStateBooting)
-        sleep(1);
-
-    if ([[self device] state] == SimDeviceStateBooted)
-        return;
-
-    NSError *error;
-    [[self device] bootWithOptions:nil error:&amp;error];
-    if (error) {
-        NSLog(@&quot;Unable to boot device: %@&quot;, [error description]);
-        exit(EXIT_FAILURE);
-    }
-}
-
</del><span class="cx"> - (void)createUniqueApp
</span><span class="cx"> {
</span><span class="cx">     NSError *error;
</span><span class="lines">@@ -219,14 +162,6 @@
</span><span class="cx">         (NSString *)kCFBundleIdentifierKey: [self uniqueAppIdentifier],
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    if ([[self device] applicationIsInstalled:[self uniqueAppIdentifier] type: nil error: &amp;error]) {
-        BOOL uninstalled = [[self device ] uninstallApplication:[self uniqueAppIdentifier] withOptions:nil error:&amp;error];
-        if (!uninstalled) {
-            NSLog(@&quot;Couldn't uninstall %@: %@&quot;, [self uniqueAppIdentifier], [error description]);
-            exit(EXIT_FAILURE);
-        }
-    }
-
</del><span class="cx">     [[self device] installApplication:[self uniqueAppURL] withOptions:installOptions error:&amp;error];
</span><span class="cx">     if (error) {
</span><span class="cx">         NSLog(@&quot;Couldn't install %@: %@&quot;, [[self uniqueAppURL] path], [error description]);
</span><span class="lines">@@ -280,8 +215,6 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)start
</span><span class="cx"> {
</span><del>-    [self launchSimulator];
-    [self bootDevice];
</del><span class="cx">     [self createUniqueApp];
</span><span class="cx">     [[self relay] setup];
</span><span class="cx">     [self launchApp];
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonsystemfilesystempy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/system/filesystem.py (173451 => 173452)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/system/filesystem.py        2014-09-09 23:21:08 UTC (rev 173451)
+++ trunk/Tools/Scripts/webkitpy/common/system/filesystem.py        2014-09-09 23:31:41 UTC (rev 173452)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> import tempfile
</span><span class="cx"> import time
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class FileSystem(object):
</span><span class="cx">     &quot;&quot;&quot;FileSystem interface for webkitpy.
</span><span class="cx"> 
</span><span class="lines">@@ -223,8 +224,8 @@
</span><span class="cx">         &quot;&quot;&quot;Write the contents to the file at the given location.
</span><span class="cx"> 
</span><span class="cx">         The file is written encoded as UTF-8 with no BOM.&quot;&quot;&quot;
</span><del>-        with codecs.open(path, 'w', 'utf8') as f:
-            f.write(contents)
</del><ins>+        with codecs.open(path, 'w', 'utf-8') as f:
+            f.write(contents.decode('utf-8') if type(contents) == str else contents)
</ins><span class="cx"> 
</span><span class="cx">     def sha1(self, path):
</span><span class="cx">         contents = self.read_binary_file(path)
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportdriverpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/driver.py (173451 => 173452)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/driver.py        2014-09-09 23:21:08 UTC (rev 173451)
+++ trunk/Tools/Scripts/webkitpy/port/driver.py        2014-09-09 23:31:41 UTC (rev 173452)
</span><span class="lines">@@ -513,7 +513,11 @@
</span><span class="cx">         ]
</span><span class="cx">         return [relay_tool] + relay_args + ['--'] + dump_tool_args
</span><span class="cx"> 
</span><ins>+    def _setup_environ_for_driver(self, environment):
+        environment['DEVELOPER_DIR'] = self._port.developer_dir
+        return super(IOSSimulatorDriver, self)._setup_environ_for_driver(environment)
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class ContentBlock(object):
</span><span class="cx">     def __init__(self):
</span><span class="cx">         self.content_type = None
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportimage_diffpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/image_diff.py (173451 => 173452)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/image_diff.py        2014-09-09 23:21:08 UTC (rev 173451)
+++ trunk/Tools/Scripts/webkitpy/port/image_diff.py        2014-09-09 23:31:41 UTC (rev 173452)
</span><span class="lines">@@ -118,7 +118,6 @@
</span><span class="cx"> class IOSSimulatorImageDiffer(ImageDiffer):
</span><span class="cx">     def _start(self, tolerance):
</span><span class="cx">         command = ['xcrun', '-sdk', 'iphonesimulator', 'sim', '--environment=preserve', '--adopt-pid', self._port._path_to_image_diff(), '--tolerance', str(tolerance)]
</span><del>-        print ' '.join(command)
</del><span class="cx">         environment = self._port.setup_environ_for_server('ImageDiff')
</span><span class="cx">         self._process = self._port._server_process_constructor(self._port, 'ImageDiff', command, environment)
</span><span class="cx">         self._process.start()
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportiospy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/ios.py (173451 => 173452)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/ios.py        2014-09-09 23:21:08 UTC (rev 173451)
+++ trunk/Tools/Scripts/webkitpy/port/ios.py        2014-09-09 23:31:41 UTC (rev 173452)
</span><span class="lines">@@ -101,11 +101,8 @@
</span><span class="cx"> 
</span><span class="cx">     def check_build(self, needs_http):
</span><span class="cx">         needs_driver = super(IOSSimulatorPort, self).check_build(needs_http)
</span><del>-        return needs_driver and self._check_build_relay() and self._check_build_image_diff()
</del><ins>+        return needs_driver and self._check_build_relay()
</ins><span class="cx"> 
</span><del>-    def _path_to_image_diff(self):
-        return self._filesystem.join(self._mac_build_directory, 'ImageDiff')
-
</del><span class="cx">     def _build_relay(self):
</span><span class="cx">         environment = self.host.copy_current_environment()
</span><span class="cx">         environment.disable_gcc_smartquotes()
</span><span class="lines">@@ -118,37 +115,10 @@
</span><span class="cx">             return False
</span><span class="cx">         return True
</span><span class="cx"> 
</span><del>-    def _check_image_diff(self):
-        image_diff_path = self._path_to_image_diff()
-        if not self._filesystem.exists(image_diff_path):
-            _log.error(&quot;%s was not found at %s&quot; % ('ImageDiff', image_diff_path))
-            return False
-        return True
-
-    def _check_build_image_diff(self):
-        if not self._root_was_set and self.get_option('build') and not self._build_driver():
-            return False
-        if not self._check_image_diff():
-            return False
-        return True
-
-    def _build_image_diff(self):
-        environment = self.host.copy_current_environment()
-        environment.disable_gcc_smartquotes()
-        env = environment.to_dictionary()
-
-        try:
-            self._run_script(&quot;build-imagediff&quot;, env=env)
-        except ScriptError, e:
-            _log.error(e.message_with_output(output_limit=None))
-            return False
-        return True
-
</del><span class="cx">     def _build_driver(self):
</span><span class="cx">         built_tool = super(IOSSimulatorPort, self)._build_driver()
</span><span class="cx">         built_relay = self._build_relay()
</span><del>-        built_image_diff = self._build_image_diff()
-        return built_tool and built_relay and built_image_diff
</del><ins>+        return built_tool and built_relay
</ins><span class="cx"> 
</span><span class="cx">     def _build_driver_flags(self):
</span><span class="cx">         archs = ['ARCHS=i386'] if self.architecture() == 'x86' else []
</span><span class="lines">@@ -184,6 +154,10 @@
</span><span class="cx"> 
</span><span class="cx">     def setup_test_run(self):
</span><span class="cx">         self._executive.run_command(['osascript', '-e', 'tell application &quot;iOS Simulator&quot; to quit'])
</span><ins>+        time.sleep(2)
+        self._executive.run_command([
+            'open', '-a', os.path.join(self.developer_dir, 'Applications', 'iOS Simulator.app'),
+            '--args', '-CurrentDeviceUDID', self.simulator_udid()])
</ins><span class="cx"> 
</span><span class="cx">     def clean_up_test_run(self):
</span><span class="cx">         super(IOSSimulatorPort, self).clean_up_test_run()
</span><span class="lines">@@ -257,7 +231,7 @@
</span><span class="cx">         crash_prefix = 'CRASH: '
</span><span class="cx">         stderr_lines = []
</span><span class="cx">         crash_lines = []
</span><del>-        for line in stderr.splitlines():
</del><ins>+        for line in (stderr or '').splitlines():
</ins><span class="cx">             crash_lines.append(line) if line.startswith(crash_prefix) else stderr_lines.append(line)
</span><span class="cx"> 
</span><span class="cx">         for crash_line in crash_lines:
</span><span class="lines">@@ -370,5 +344,9 @@
</span><span class="cx">             _log.warn(&quot;xcrun failed; falling back to '%s'.&quot; % fallback)
</span><span class="cx">             return fallback
</span><span class="cx"> 
</span><ins>+    @property
+    def developer_dir(self):
+        return self._executive.run_command(['xcode-select', '--print-path']).rstrip()
+
</ins><span class="cx">     def logging_patterns_to_strip(self):
</span><span class="cx">         return []
</span></span></pre>
</div>
</div>

</body>
</html>