iOS Simulator LayoutTestRelay
authordfarler@apple.com <dfarler@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Jul 2014 16:49:33 +0000 (16:49 +0000)
committerdfarler@apple.com <dfarler@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Jul 2014 16:49:33 +0000 (16:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=135269

Reviewed by David Kilzer.

* LayoutTestRelay/Configurations/Base.xcconfig: Added.
* LayoutTestRelay/Configurations/DebugRelease.xcconfig: Added.
* LayoutTestRelay/LayoutTestRelay.xcodeproj/project.pbxproj: Added.
* LayoutTestRelay/LayoutTestRelay/LTPipeRelay.h: Added.
* LayoutTestRelay/LayoutTestRelay/LTPipeRelay.m: Added.
(-[LTPipeRelay inPipePath]):
(-[LTPipeRelay outPipePath]):
(-[LTPipeRelay errorPipePath]):
(-[LTPipeRelay outputStream]):
(-[LTPipeRelay initWithPrefix:]):
(-[LTPipeRelay setup]):
(-[LTPipeRelay tearDown]):
(-[LTPipeRelay connect]):
(-[LTPipeRelay disconnect]):
(-[LTPipeRelay createFIFOs]):
(-[LTPipeRelay destroyFIFOs]):
(-[LTPipeRelay relayStream:]):
(-[LTPipeRelay stream:handleEvent:]):
* LayoutTestRelay/LayoutTestRelay/LTRelay.h: Added.
* LayoutTestRelay/LayoutTestRelay/LTRelayController.h: Added.
* LayoutTestRelay/LayoutTestRelay/LTRelayController.m: Added.
(-[LTRelayController uniqueAppPath]):
(-[LTRelayController uniqueAppURL]):
(-[LTRelayController uniqueAppIdentifier]):
(-[LTRelayController processName]):
(-[LTRelayController initWithDevice:productDir:appPath:identifierSuffix:dumpToolArguments:]):
(-[LTRelayController readFileHandle:]):
(-[LTRelayController receivedStandardOutputData:]):
(-[LTRelayController receivedStandardErrorData:]):
(-[LTRelayController disconnected]):
(-[LTRelayController connected]):
(-[LTRelayController crashWithMessage:]):
(-[LTRelayController launchSimulator]):
(-[LTRelayController bootDevice]):
(-[LTRelayController createUniqueApp]):
(-[LTRelayController killApp]):
(-[LTRelayController launchApp]):
(-[LTRelayController start]):
* LayoutTestRelay/LayoutTestRelay/main.m: Added.
(usage):
(getTestingSimDevice):
(getRequiredStringArgument):
(getRemainderArguments):
(main):
* LayoutTestRelay/Makefile: Added.
* Tools/Scripts/build-layouttestrelay: Added.

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

12 files changed:
Tools/ChangeLog
Tools/LayoutTestRelay/Configurations/Base.xcconfig [new file with mode: 0644]
Tools/LayoutTestRelay/Configurations/DebugRelease.xcconfig [new file with mode: 0644]
Tools/LayoutTestRelay/LayoutTestRelay.xcodeproj/project.pbxproj [new file with mode: 0644]
Tools/LayoutTestRelay/LayoutTestRelay/LTPipeRelay.h [new file with mode: 0644]
Tools/LayoutTestRelay/LayoutTestRelay/LTPipeRelay.m [new file with mode: 0644]
Tools/LayoutTestRelay/LayoutTestRelay/LTRelay.h [new file with mode: 0644]
Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.h [new file with mode: 0644]
Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.m [new file with mode: 0644]
Tools/LayoutTestRelay/LayoutTestRelay/main.m [new file with mode: 0644]
Tools/LayoutTestRelay/Makefile [new file with mode: 0644]
Tools/Scripts/build-layouttestrelay [new file with mode: 0755]

index 5eaf7e8429d717f0cc8eaf61caf5596a2cf55322..28165fac99c16d09b25392b55a4e72f8e5450c1d 100644 (file)
@@ -1,3 +1,57 @@
+2014-07-29  David Farler  <dfarler@apple.com>
+
+        iOS Simulator LayoutTestRelay
+        https://bugs.webkit.org/show_bug.cgi?id=135269
+
+        Reviewed by David Kilzer.
+
+        * LayoutTestRelay/Configurations/Base.xcconfig: Added.
+        * LayoutTestRelay/Configurations/DebugRelease.xcconfig: Added.
+        * LayoutTestRelay/LayoutTestRelay.xcodeproj/project.pbxproj: Added.
+        * LayoutTestRelay/LayoutTestRelay/LTPipeRelay.h: Added.
+        * LayoutTestRelay/LayoutTestRelay/LTPipeRelay.m: Added.
+        (-[LTPipeRelay inPipePath]):
+        (-[LTPipeRelay outPipePath]):
+        (-[LTPipeRelay errorPipePath]):
+        (-[LTPipeRelay outputStream]):
+        (-[LTPipeRelay initWithPrefix:]):
+        (-[LTPipeRelay setup]):
+        (-[LTPipeRelay tearDown]):
+        (-[LTPipeRelay connect]):
+        (-[LTPipeRelay disconnect]):
+        (-[LTPipeRelay createFIFOs]):
+        (-[LTPipeRelay destroyFIFOs]):
+        (-[LTPipeRelay relayStream:]):
+        (-[LTPipeRelay stream:handleEvent:]):
+        * LayoutTestRelay/LayoutTestRelay/LTRelay.h: Added.
+        * LayoutTestRelay/LayoutTestRelay/LTRelayController.h: Added.
+        * LayoutTestRelay/LayoutTestRelay/LTRelayController.m: Added.
+        (-[LTRelayController uniqueAppPath]):
+        (-[LTRelayController uniqueAppURL]):
+        (-[LTRelayController uniqueAppIdentifier]):
+        (-[LTRelayController processName]):
+        (-[LTRelayController initWithDevice:productDir:appPath:identifierSuffix:dumpToolArguments:]):
+        (-[LTRelayController readFileHandle:]):
+        (-[LTRelayController receivedStandardOutputData:]):
+        (-[LTRelayController receivedStandardErrorData:]):
+        (-[LTRelayController disconnected]):
+        (-[LTRelayController connected]):
+        (-[LTRelayController crashWithMessage:]):
+        (-[LTRelayController launchSimulator]):
+        (-[LTRelayController bootDevice]):
+        (-[LTRelayController createUniqueApp]):
+        (-[LTRelayController killApp]):
+        (-[LTRelayController launchApp]):
+        (-[LTRelayController start]):
+        * LayoutTestRelay/LayoutTestRelay/main.m: Added.
+        (usage):
+        (getTestingSimDevice):
+        (getRequiredStringArgument):
+        (getRemainderArguments):
+        (main):
+        * LayoutTestRelay/Makefile: Added.
+        * Tools/Scripts/build-layouttestrelay: Added.
+
 2014-07-29  Brent Fulgham  <bfulgham@apple.com>
 
         [Win] Modify version numbering scheme to support 5-tuple versions
diff --git a/Tools/LayoutTestRelay/Configurations/Base.xcconfig b/Tools/LayoutTestRelay/Configurations/Base.xcconfig
new file mode 100644 (file)
index 0000000..8105243
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2014 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+CLANG_CXX_LANGUAGE_STANDARD = gnu++0x;
+CLANG_ENABLE_OBJC_ARC = YES;
+CLANG_WARN_CXX0X_EXTENSIONS = NO;
+HEADER_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR)/usr/local/include $(WEBCORE_PRIVATE_HEADERS_DIR)/ForwardingHeaders $(SRCROOT)/../../Source/JavaScriptCore/icu $(NEXT_ROOT)/usr/local/include/WebCoreTestSupport;
+GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) ENABLE_DASHBOARD_SUPPORT WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST;
+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym;
+PREBINDING = NO
+GCC_C_LANGUAGE_STANDARD = gnu99
+GCC_ENABLE_CPP_EXCEPTIONS = NO;
+GCC_ENABLE_CPP_RTTI = NO;
+GCC_PRECOMPILE_PREFIX_HEADER = YES
+GCC_TREAT_WARNINGS_AS_ERRORS = YES
+GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
+GCC_WARN_UNUSED_FUNCTION = YES
+GCC_WARN_UNUSED_VARIABLE = YES
+GCC_WARN_64_TO_32_BIT_CONVERSION[arch=x86_64] = NO;
+WARNING_CFLAGS = -Wall -W -Wno-unused-parameter -Wundef
+LINKER_DISPLAYS_MANGLED_NAMES = YES;
+
+DEBUG_DEFINES_debug = ;
+DEBUG_DEFINES_normal = NDEBUG;
+DEBUG_DEFINES = $(DEBUG_DEFINES_$(CURRENT_VARIANT));
+
+TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR);
+
+SDKROOT = macosx.internal;
+
+TOOLCHAINS = $(TOOLCHAINS_$(PLATFORM_NAME));
+TOOLCHAINS_iphoneos = $(TOOLCHAINS);
+TOOLCHAINS_iphonesimulator = $(TOOLCHAINS);
+TOOLCHAINS_macosx = $(TOOLCHAINS_macosx_$(MAC_OS_X_VERSION_MAJOR));
+TOOLCHAINS_macosx_1080 = default;
+TOOLCHAINS_macosx_1090 = $(TOOLCHAINS);
+TOOLCHAINS_macosx_101000 = $(TOOLCHAINS_macosx_1090);
+
+SUPPORTED_PLATFORMS = macosx;
diff --git a/Tools/LayoutTestRelay/Configurations/DebugRelease.xcconfig b/Tools/LayoutTestRelay/Configurations/DebugRelease.xcconfig
new file mode 100644 (file)
index 0000000..be18841
--- /dev/null
@@ -0,0 +1 @@
+// Copyright (C) 2014 Apple Inc. All rights reserved.\r//\r// Redistribution and use in source and binary forms, with or without\r// modification, are permitted provided that the following conditions\r// are met:\r// 1. Redistributions of source code must retain the above copyright\r//    notice, this list of conditions and the following disclaimer.\r// 2. Redistributions in binary form must reproduce the above copyright\r//    notice, this list of conditions and the following disclaimer in the\r//    documentation and/or other materials provided with the distribution.\r//\r// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY\r// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR\r// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\r// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\r#include "Base.xcconfig"\r\rARCHS = $(ARCHS_STANDARD_64_BIT);\r\rMACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR))\rMACOSX_DEPLOYMENT_TARGET_1080 = 10.8;\rMACOSX_DEPLOYMENT_TARGET_1090 = 10.9;\rMACOSX_DEPLOYMENT_TARGET_101000 = 10.10;\r\rFRAMEWORK_SEARCH_PATHS = $(DEVELOPER_DIR)/Library/PrivateFrameworks;\rLD_RUNPATH_SEARCH_PATHS = $(DEVELOPER_DIR)/Library/PrivateFrameworks;\rOTHER_LDFLAGS = -framework CoreSimulator -framework AppKit;\r\rSDKROOT = $(SDKROOT_macosx_$(USE_INTERNAL_SDK));\rSDKROOT_macosx_ = macosx;\rSDKROOT_macosx_YES = macosx.internal;\r
\ No newline at end of file
diff --git a/Tools/LayoutTestRelay/LayoutTestRelay.xcodeproj/project.pbxproj b/Tools/LayoutTestRelay/LayoutTestRelay.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..782a2e6
--- /dev/null
@@ -0,0 +1,200 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 46;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               2E8D3EF819881D43004F6CC2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E8D3EF719881D43004F6CC2 /* main.m */; };
+               2E8D3F0219881FD0004F6CC2 /* LTPipeRelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E8D3F0119881FD0004F6CC2 /* LTPipeRelay.m */; };
+               2E8D3F0619882406004F6CC2 /* LTRelayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E8D3F0519882406004F6CC2 /* LTRelayController.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+               2E8D3EF219881D43004F6CC2 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+               2E8D3EF419881D43004F6CC2 /* LayoutTestRelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = LayoutTestRelay; sourceTree = BUILT_PRODUCTS_DIR; };
+               2E8D3EF719881D43004F6CC2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+               2E8D3EFE19881E13004F6CC2 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = DebugRelease.xcconfig; path = Configurations/DebugRelease.xcconfig; sourceTree = "<group>"; };
+               2E8D3EFF19881E25004F6CC2 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Base.xcconfig; path = Configurations/Base.xcconfig; sourceTree = "<group>"; };
+               2E8D3F0019881F29004F6CC2 /* LTRelay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTRelay.h; sourceTree = "<group>"; };
+               2E8D3F0119881FD0004F6CC2 /* LTPipeRelay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LTPipeRelay.m; sourceTree = "<group>"; };
+               2E8D3F0319881FE2004F6CC2 /* LTPipeRelay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTPipeRelay.h; sourceTree = "<group>"; };
+               2E8D3F0419882406004F6CC2 /* LTRelayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LTRelayController.h; sourceTree = "<group>"; };
+               2E8D3F0519882406004F6CC2 /* LTRelayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LTRelayController.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               2E8D3EF119881D43004F6CC2 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               2E8D3EEB19881D43004F6CC2 = {
+                       isa = PBXGroup;
+                       children = (
+                               2E8D3EFF19881E25004F6CC2 /* Base.xcconfig */,
+                               2E8D3EFE19881E13004F6CC2 /* DebugRelease.xcconfig */,
+                               2E8D3EF619881D43004F6CC2 /* LayoutTestRelay */,
+                               2E8D3EF519881D43004F6CC2 /* Products */,
+                       );
+                       sourceTree = "<group>";
+               };
+               2E8D3EF519881D43004F6CC2 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               2E8D3EF419881D43004F6CC2 /* LayoutTestRelay */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               2E8D3EF619881D43004F6CC2 /* LayoutTestRelay */ = {
+                       isa = PBXGroup;
+                       children = (
+                               2E8D3EF719881D43004F6CC2 /* main.m */,
+                               2E8D3F0019881F29004F6CC2 /* LTRelay.h */,
+                               2E8D3F0119881FD0004F6CC2 /* LTPipeRelay.m */,
+                               2E8D3F0319881FE2004F6CC2 /* LTPipeRelay.h */,
+                               2E8D3F0419882406004F6CC2 /* LTRelayController.h */,
+                               2E8D3F0519882406004F6CC2 /* LTRelayController.m */,
+                       );
+                       path = LayoutTestRelay;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+               2E8D3EF319881D43004F6CC2 /* LayoutTestRelay */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 2E8D3EFB19881D43004F6CC2 /* Build configuration list for PBXNativeTarget "LayoutTestRelay" */;
+                       buildPhases = (
+                               2E8D3EF019881D43004F6CC2 /* Sources */,
+                               2E8D3EF119881D43004F6CC2 /* Frameworks */,
+                               2E8D3EF219881D43004F6CC2 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = LayoutTestRelay;
+                       productName = LayoutTestRelay;
+                       productReference = 2E8D3EF419881D43004F6CC2 /* LayoutTestRelay */;
+                       productType = "com.apple.product-type.tool";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               2E8D3EEC19881D43004F6CC2 /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastUpgradeCheck = 0600;
+                               ORGANIZATIONNAME = "Apple, Inc.";
+                               TargetAttributes = {
+                                       2E8D3EF319881D43004F6CC2 = {
+                                               CreatedOnToolsVersion = 6.0;
+                                       };
+                               };
+                       };
+                       buildConfigurationList = 2E8D3EEF19881D43004F6CC2 /* Build configuration list for PBXProject "LayoutTestRelay" */;
+                       compatibilityVersion = "Xcode 3.2";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               en,
+                       );
+                       mainGroup = 2E8D3EEB19881D43004F6CC2;
+                       productRefGroup = 2E8D3EF519881D43004F6CC2 /* Products */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               2E8D3EF319881D43004F6CC2 /* LayoutTestRelay */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+               2E8D3EF019881D43004F6CC2 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               2E8D3F0619882406004F6CC2 /* LTRelayController.m in Sources */,
+                               2E8D3EF819881D43004F6CC2 /* main.m in Sources */,
+                               2E8D3F0219881FD0004F6CC2 /* LTPipeRelay.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+               2E8D3EF919881D43004F6CC2 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 2E8D3EFE19881E13004F6CC2 /* DebugRelease.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Debug;
+               };
+               2E8D3EFA19881D43004F6CC2 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 2E8D3EFE19881E13004F6CC2 /* DebugRelease.xcconfig */;
+                       buildSettings = {
+                       };
+                       name = Release;
+               };
+               2E8D3EFC19881D43004F6CC2 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 2E8D3EFE19881E13004F6CC2 /* DebugRelease.xcconfig */;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               2E8D3EFD19881D43004F6CC2 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = 2E8D3EFE19881E13004F6CC2 /* DebugRelease.xcconfig */;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               2E8D3EEF19881D43004F6CC2 /* Build configuration list for PBXProject "LayoutTestRelay" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               2E8D3EF919881D43004F6CC2 /* Debug */,
+                               2E8D3EFA19881D43004F6CC2 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               2E8D3EFB19881D43004F6CC2 /* Build configuration list for PBXNativeTarget "LayoutTestRelay" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               2E8D3EFC19881D43004F6CC2 /* Debug */,
+                               2E8D3EFD19881D43004F6CC2 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 2E8D3EEC19881D43004F6CC2 /* Project object */;
+}
diff --git a/Tools/LayoutTestRelay/LayoutTestRelay/LTPipeRelay.h b/Tools/LayoutTestRelay/LayoutTestRelay/LTPipeRelay.h
new file mode 100644 (file)
index 0000000..a2e005f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LTPipeRelay_h
+#define LTPipeRelay_h
+
+#import "LTRelay.h"
+
+@interface LTPipeRelay : NSObject <LTRelay>
+@property (weak) id<LTRelayDelegate> relayDelegate;
+- (id)initWithPrefix:(NSString *)prefix;
+@end
+
+#endif
diff --git a/Tools/LayoutTestRelay/LayoutTestRelay/LTPipeRelay.m b/Tools/LayoutTestRelay/LayoutTestRelay/LTPipeRelay.m
new file mode 100644 (file)
index 0000000..b259dab
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "LTPipeRelay.h"
+
+#import <Foundation/Foundation.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+@interface LTPipeRelay ()
+@property (readonly, strong) NSString *fifoPrefix;
+@property (strong) NSOutputStream *standardInputPipe;
+@property (strong) NSInputStream *standardOutputPipe;
+@property (strong) NSInputStream *standardErrorPipe;
+
+- (void)createFIFOs;
+- (void)destroyFIFOs;
+@end
+
+@implementation LTPipeRelay
+
+- (NSString *)inPipePath
+{
+    return [_fifoPrefix stringByAppendingString:@"_IN"];
+}
+
+- (NSString *)outPipePath
+{
+    return [_fifoPrefix stringByAppendingString:@"_OUT"];
+}
+
+- (NSString *)errorPipePath
+{
+    return [_fifoPrefix stringByAppendingString:@"_ERROR"];
+}
+
+- (NSOutputStream *) outputStream
+{
+    return _standardInputPipe;
+}
+
+- (id)initWithPrefix:(NSString *)prefix
+{
+    if ((self = [super init])) {
+        _fifoPrefix = prefix;
+        [self destroyFIFOs];
+    }
+    return self;
+}
+
+- (void)setup
+{
+    [self destroyFIFOs];
+    [self createFIFOs];
+}
+
+- (void)tearDown
+{
+    [self destroyFIFOs];
+}
+
+-(void) connect
+{
+    _standardInputPipe = [NSOutputStream outputStreamToFileAtPath:[self inPipePath] append:YES];
+    _standardOutputPipe = [NSInputStream inputStreamWithFileAtPath:[self outPipePath]];
+    _standardErrorPipe = [NSInputStream inputStreamWithFileAtPath:[self errorPipePath]];
+
+    [[self standardInputPipe] setDelegate:self];
+    [[self standardOutputPipe] setDelegate:self];
+    [[self standardErrorPipe] setDelegate:self];
+
+    [[self standardOutputPipe] scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
+    [[self standardErrorPipe] scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
+
+    [[self standardInputPipe] open];
+    [[self standardOutputPipe] open];
+    [[self standardErrorPipe] open];
+
+    [[self relayDelegate] didConnect];
+}
+
+- (void)disconnect
+{
+    [[self standardOutputPipe] close];
+    [[self standardErrorPipe] close];
+    [[self standardInputPipe] close];
+    [[self relayDelegate] didDisconnect];
+}
+
+- (void)createFIFOs
+{
+    mkfifo([[self inPipePath] UTF8String], 0666);
+    mkfifo([[self outPipePath] UTF8String], 0666);
+    mkfifo([[self errorPipePath] UTF8String], 0666);
+}
+
+- (void)destroyFIFOs
+{
+    unlink([[self inPipePath] UTF8String]);
+    unlink([[self outPipePath] UTF8String]);
+    unlink([[self errorPipePath] UTF8String]);
+}
+
+- (void) relayStream:(NSInputStream *)stream
+{
+    uint8_t bytes[1024];
+    NSInteger bytesRead = [stream read:bytes maxLength:1024];
+    NSData *data = [NSData dataWithBytes:bytes length:bytesRead];
+
+    if (stream == [self standardOutputPipe])
+        [[self relayDelegate] didReceiveStdoutData:data];
+    else
+        [[self relayDelegate] didReceiveStderrData:data];
+}
+
+- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
+{
+    switch (eventCode) {
+    case NSStreamEventNone:
+        break;
+    case NSStreamEventHasBytesAvailable:
+        [self relayStream:(NSInputStream *)aStream];
+    case NSStreamEventHasSpaceAvailable:
+        break;
+    case NSStreamEventOpenCompleted:
+        break;
+    case NSStreamEventEndEncountered:
+        [[self relayDelegate] didCrashWithMessage:nil];
+        break;
+    case NSStreamEventErrorOccurred:
+        [[self relayDelegate] didCrashWithMessage:[[aStream streamError] description]];
+        break;
+    }
+}
+
+@end
diff --git a/Tools/LayoutTestRelay/LayoutTestRelay/LTRelay.h b/Tools/LayoutTestRelay/LayoutTestRelay/LTRelay.h
new file mode 100644 (file)
index 0000000..fb76636
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LTRelay_h
+#define LTRelay_h
+
+#import <Foundation/Foundation.h>
+
+@protocol LTRelayDelegate <NSObject>
+- (void)didConnect;
+- (void)didDisconnect;
+- (void)didCrashWithMessage:(NSString *)message;
+- (void)didReceiveStdoutData:(NSData *)data;
+- (void)didReceiveStderrData:(NSData *)data;
+@end
+
+@protocol LTRelay <NSObject, NSStreamDelegate>
+- (void)setup;
+- (void)tearDown;
+- (void)connect;
+- (void)disconnect;
+@property (weak) id<LTRelayDelegate> relayDelegate;
+@property (readonly, strong) NSOutputStream *outputStream;
+@end
+
+#endif
diff --git a/Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.h b/Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.h
new file mode 100644 (file)
index 0000000..f93e945
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef LTRelayController_h
+#define LTRelayController_h
+
+#import "LTRelay.h"
+
+#import <Foundation/Foundation.h>
+
+@class SimDevice;
+
+@interface LTRelayController : NSObject <LTRelayDelegate>
+- (id)initWithDevice:(SimDevice *)device productDir:(NSString *)productDir appPath:(NSString *)appPath identifierSuffix:(NSString *)suffix dumpToolArguments:(NSArray *)arguments;
+- (void)start;
+@end
+
+#endif
diff --git a/Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.m b/Tools/LayoutTestRelay/LayoutTestRelay/LTRelayController.m
new file mode 100644 (file)
index 0000000..9557b1b
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "LTRelayController.h"
+#import "LTPipeRelay.h"
+
+#import <AppKit/AppKit.h>
+#import <CoreSimulator/CoreSimulator.h>
+
+@interface LTRelayController ()
+@property (readonly, strong) NSFileHandle *standardInput;
+@property (readonly, strong) NSFileHandle *standardOutput;
+@property (readonly, strong) NSFileHandle *standardError;
+@property (readonly, strong) NSString *uniqueAppPath;
+@property (readonly, strong) NSString *uniqueAppIdentifer;
+@property (readonly, strong) NSURL *uniqueAppURL;
+@property (readonly, strong) NSString *originalAppIdentifier;
+@property (readonly, strong) NSString *originalAppPath;
+@property (readonly, strong) NSString *identifierSuffix;
+@property (readonly, strong) NSArray *dumpToolArguments;
+@property (readonly, strong) NSString *productDir;
+@property (strong) SimDevice *device;
+@property (strong) id<LTRelay> relay;
+@property pid_t pid;
+@property (strong) dispatch_source_t appDispatchSource;
+@end
+
+@implementation LTRelayController
+
+- (id)initWithDevice:(SimDevice *)device productDir:(NSString *)productDir appPath:(NSString *)appPath identifierSuffix:(NSString *)suffix dumpToolArguments:(NSArray *)arguments
+{
+    if ((self = [super init])) {
+        _device = device;
+        _productDir = productDir;
+        _originalAppPath = appPath;
+        _originalAppIdentifier = [NSDictionary dictionaryWithContentsOfFile:[_originalAppPath stringByAppendingPathComponent:@"Info.plist"]][(NSString *)kCFBundleIdentifierKey];
+        _identifierSuffix = suffix;
+        _dumpToolArguments = arguments;
+        _standardInput = [NSFileHandle fileHandleWithStandardInput];
+        _standardOutput = [NSFileHandle fileHandleWithStandardOutput];
+        _standardError = [NSFileHandle fileHandleWithStandardError];
+
+        _relay = [[LTPipeRelay alloc] initWithPrefix:[@"/tmp" stringByAppendingPathComponent:[self uniqueAppIdentifier]]];
+        [_relay setRelayDelegate:self];
+    }
+    return self;
+}
+
+- (NSString *)uniqueAppPath
+{
+    return [[self originalAppPath] stringByReplacingOccurrencesOfString:@".app" withString:[NSString stringWithFormat:@"%@.app", [self identifierSuffix]]];
+}
+
+- (NSURL *)uniqueAppURL
+{
+    return [NSURL fileURLWithPath:[self uniqueAppPath]];
+}
+
+- (NSString *)uniqueAppIdentifier
+{
+    return [[self originalAppIdentifier] stringByAppendingString:[self identifierSuffix]];
+}
+- (NSString *)processName
+{
+    return [[[self originalAppIdentifier] componentsSeparatedByString:@"."] lastObject];
+}
+
+- (void)readFileHandle:(NSFileHandle *)fileHandle
+{
+    NSData *data = [fileHandle availableData];
+    uint8_t bytes[[data length]];
+    [data getBytes:bytes length:[data length]];
+    [[[self relay] outputStream] write:[data bytes] maxLength:[data length]];
+}
+
+
+- (void)didReceiveStdoutData:(NSData *)data
+{
+    [[self standardOutput] writeData:data];
+}
+
+- (void)didReceiveStderrData:(NSData *)data
+{
+    [[self standardError] writeData:data];
+}
+
+- (void)didDisconnect
+{
+    [[self standardInput] setReadabilityHandler:nil];
+}
+
+- (void)didConnect
+{
+    [[self standardInput] setReadabilityHandler: ^(NSFileHandle *fileHandle)
+    {
+        [self readFileHandle:fileHandle];
+    }];
+}
+
+- (void)didCrashWithMessage:(NSString *)message
+{
+    [[self relay] disconnect];
+    NSString *crashMessage = [NSString stringWithFormat:@"\nCRASH: %@ %d\n", [self processName], [self pid]];
+
+    if (message)
+        crashMessage = [crashMessage stringByAppendingFormat:@"%@\n", message];
+
+    [[self standardError] writeData:[crashMessage dataUsingEncoding:NSUTF8StringEncoding]];
+    [[self standardError] closeFile];
+    [[self standardOutput] closeFile];
+    exit(EXIT_FAILURE);
+}
+
+- (void)launchSimulator
+{
+    NSString *developerDir = [[[NSProcessInfo processInfo] environment] valueForKey:@"DEVELOPER_DIR"];
+    if (!developerDir) {
+        NSTask *xcodeSelectTask = [[NSTask alloc] init];
+        [xcodeSelectTask setLaunchPath:@"/usr/bin/xcode-select"];
+        [xcodeSelectTask setArguments:@[@"--print-path"]];
+        [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(@"Not able to determine the path to iOS Simulator.app in your active Xcode.app");
+        exit(EXIT_FAILURE);
+    }
+    NSURL *simulatorURL = [NSURL fileURLWithPath:[developerDir stringByAppendingPathComponent:@"Applications/iOS Simulator.app"]];
+
+    NSDictionary *launchConfiguration = @{
+        NSWorkspaceLaunchConfigurationArguments: @[
+            @"-CurrentDeviceUDID", [[[self device] UDID] UUIDString],
+            ]
+    };
+    NSError *error;
+    [[NSWorkspace sharedWorkspace] launchApplicationAtURL:simulatorURL options:NSWorkspaceLaunchDefault configuration:launchConfiguration error:&error];
+
+    if (error) {
+        NSLog(@"Couldn't launch iOS Simulator from %@: %@", [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:&error];
+    if (error) {
+        NSLog(@"Unable to boot device: %@", [error description]);
+        exit(EXIT_FAILURE);
+    }
+}
+
+- (void)createUniqueApp
+{
+    NSError *error;
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    [fileManager removeItemAtPath:[self uniqueAppPath] error:&error];
+    error = nil;
+
+    [fileManager copyItemAtPath:[self originalAppPath] toPath:[self uniqueAppPath] error:&error];
+    if (error) {
+        NSLog(@"Couldn't copy %@ to %@: %@", [self originalAppPath], [self uniqueAppPath], [error description]);
+        exit(EXIT_FAILURE);
+    }
+
+    NSString *infoPlistPath = [[self uniqueAppPath] stringByAppendingPathComponent:@"Info.plist"];
+    NSMutableDictionary *plist = [NSMutableDictionary dictionaryWithContentsOfFile:infoPlistPath];
+    [plist setValue:[self uniqueAppIdentifier] forKey:(NSString *)kCFBundleIdentifierKey];
+    BOOL written = [plist writeToFile:infoPlistPath atomically:YES];
+    if (!written) {
+        NSLog(@"Couldn't write unique app plist at %@", infoPlistPath);
+        exit(EXIT_FAILURE);
+    }
+
+    NSDictionary *installOptions = @{
+        (NSString *)kCFBundleIdentifierKey: [self uniqueAppIdentifier],
+    };
+
+    if ([[self device] applicationIsInstalled:[self uniqueAppIdentifier] type: nil error: &error]) {
+        BOOL uninstalled = [[self device ] uninstallApplication:[self uniqueAppIdentifier] withOptions:nil error:&error];
+        if (!uninstalled) {
+            NSLog(@"Couldn't uninstall %@: %@", [self uniqueAppIdentifier], [error description]);
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    [[self device] installApplication:[self uniqueAppURL] withOptions:installOptions error:&error];
+    if (error) {
+        NSLog(@"Couldn't install %@: %@", [[self uniqueAppURL] path], [error description]);
+        exit(EXIT_FAILURE);
+    }
+}
+
+- (void)killApp
+{
+    dispatch_source_t dispatch = [self appDispatchSource];
+
+    if (dispatch)
+        dispatch_source_cancel(dispatch);
+
+    if ([self pid] > 1) {
+        kill(self.pid, SIGKILL);
+        [self setPid:-1];
+    }
+    [self setAppDispatchSource:nil];
+}
+
+- (void)launchApp
+{
+    NSDictionary *launchOptions = @{
+        kSimDeviceLaunchApplicationEnvironment: @{
+            @"DYLD_LIBRARY_PATH": [self productDir],
+            @"DYLD_FRAMEWORK_PATH": [self productDir],
+        },
+        kSimDeviceLaunchApplicationArguments: [self dumpToolArguments],
+    };
+
+    NSError *error;
+    pid_t pid = [[self device] launchApplicationWithID:[self uniqueAppIdentifier] options:launchOptions error:&error];
+
+    if (pid < 0) {
+        NSLog(@"Couldn't launch unique app instance %@: %@", [self uniqueAppIdentifier], [error description]);
+        exit(EXIT_FAILURE);
+    }
+
+    [self setPid:pid];
+
+    dispatch_queue_t queue = dispatch_get_main_queue();
+    dispatch_source_t dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, [self pid], DISPATCH_PROC_EXIT, queue);
+    [self setAppDispatchSource:dispatchSource];
+    dispatch_source_set_event_handler(dispatchSource, ^{
+        dispatch_source_cancel(dispatchSource);
+        [self didCrashWithMessage:nil];
+    });
+    dispatch_resume(dispatchSource);
+}
+
+- (void)start
+{
+    [self launchSimulator];
+    [self bootDevice];
+    [self createUniqueApp];
+    [[self relay] setup];
+    [self launchApp];
+    [[self relay] connect];
+}
+
+@end
diff --git a/Tools/LayoutTestRelay/LayoutTestRelay/main.m b/Tools/LayoutTestRelay/LayoutTestRelay/main.m
new file mode 100644 (file)
index 0000000..a142f0d
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "LTRelayController.h"
+
+#import <CoreSimulator/CoreSimulator.h>
+#import <Foundation/Foundation.h>
+
+void usage()
+{
+    NSString *helpText = @"LayoutTestRelay: run a dump tool in the simulator. Not for direct consumption.\n"
+    "Usage: LayoutTestRelay [-h] [options] -- [dump tool arguments]\n"
+    "Required options:\n"
+    "    -app <app_path>          Path to the built iOS .app bundle directory.\n"
+    "    -runtime <identifier>    iOS Simulator Runtime identifier (see `xcrun -sdk iphonesimulator simctl`)\n"
+    "    -deviceType <identifier> iOS Simulator device identifier (see simctl).\n"
+    "    -suffix <text>           Used to create multiple unique instances when installing to the simulator.\n"
+    "    -productDir <dir>        /path/to/WebKitBuild/{configuration}-{short platform}.\n";
+
+    fprintf(stderr, "%s\n", [helpText UTF8String]);
+}
+
+SimDevice *getTestingSimDevice(SimDeviceType *deviceType, SimRuntime *runtime)
+{
+    NSString *deviceName = [[[[deviceType identifier] componentsSeparatedByString:@"."] lastObject] stringByReplacingOccurrencesOfString:@"-" withString:@" "];
+    deviceName = [deviceName stringByAppendingString:@" WebKit Tester"];
+
+    for (SimDevice *device in [[SimDeviceSet defaultSet] devices]) {
+        if ([[device name] isEqualToString:deviceName] && [[device deviceType] isEqualTo:deviceType] && [[device runtime] isEqualTo:runtime])
+            return device;
+    }
+
+    NSError *error;
+    SimDevice *device = [[SimDeviceSet defaultSet] createDeviceWithType:deviceType runtime:runtime name:deviceName error:&error];
+
+    if (error) {
+        NSLog(@"Couldn't create device: %@", [error description]);
+        return nil;
+    }
+
+    while ([device state] == SimDeviceStateCreating)
+        sleep(1);
+
+    return device;
+}
+
+
+NSString *getRequiredStringArgument(NSString *parameter)
+{
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSString *argument = [defaults stringForKey:parameter];
+
+    if (!argument) {
+        NSLog(@"-%@ is required.", parameter);
+        usage();
+        exit(EXIT_FAILURE);
+    }
+    return argument;
+}
+
+NSArray *getDumpToolArguments()
+{
+    NSMutableArray *dumpToolArguments = [[NSMutableArray alloc] init];
+    NSArray *processArgs = [[NSProcessInfo processInfo] arguments];
+    BOOL appending = NO;
+    for (NSString *arg in processArgs) {
+        if ([arg isEqualToString:@"--"]) {
+            appending = YES;
+            continue;
+        }
+        if (appending)
+            [dumpToolArguments addObject:arg];
+    }
+    return dumpToolArguments;
+}
+
+int main(int argc, const char * argv[])
+{
+    @autoreleasepool {
+        NSArray *helpArguments = @[@"-h", @"--help"];
+        for (NSString *helpArgument in helpArguments) {
+            if ([[[NSProcessInfo processInfo] arguments] indexOfObject:helpArgument] != NSNotFound) {
+                usage();
+                exit(EXIT_FAILURE);
+            }
+        }
+        NSString *appPath = getRequiredStringArgument(@"app");
+        NSString *runtimeIdentifier = getRequiredStringArgument(@"runtime");
+        SimRuntime *runtime = [SimRuntime supportedRuntimesByIdentifier][runtimeIdentifier];
+        if (!runtime) {
+            NSLog(@"There is no supported runtime \"%@\"", runtimeIdentifier);
+            exit(EXIT_FAILURE);
+        }
+
+        NSString *deviceTypeIdentifier = getRequiredStringArgument(@"deviceType");
+        SimDeviceType *deviceType = [SimDeviceType supportedDeviceTypesByIdentifier][deviceTypeIdentifier];
+        if (!deviceType) {
+            NSLog(@"There is no supported device type \"%@\"", deviceTypeIdentifier);
+            exit(EXIT_FAILURE);
+        }
+
+        NSString *suffix = getRequiredStringArgument(@"suffix");
+        NSString *productDir = getRequiredStringArgument(@"productDir");
+        NSArray *dumpToolArguments = getDumpToolArguments();
+
+        SimDevice *device = getTestingSimDevice(deviceType, runtime);
+
+        LTRelayController *relayController = [[LTRelayController alloc] initWithDevice:device productDir:productDir appPath:appPath identifierSuffix:suffix dumpToolArguments:dumpToolArguments];
+        [relayController start];
+        [[NSRunLoop mainRunLoop] run];
+    }
+    return 0;
+}
diff --git a/Tools/LayoutTestRelay/Makefile b/Tools/LayoutTestRelay/Makefile
new file mode 100644 (file)
index 0000000..e489fc4
--- /dev/null
@@ -0,0 +1,3 @@
+SCRIPTS_PATH = ../Scripts
+
+include ../../Makefile.shared
diff --git a/Tools/Scripts/build-layouttestrelay b/Tools/Scripts/build-layouttestrelay
new file mode 100755 (executable)
index 0000000..ae4abc8
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2014 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use File::Basename;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+my $showHelp = 0;
+my $clean = 0;
+
+my $programName = basename($0);
+my $usage = <<EOF;
+Usage: $programName [options] [options to pass to build system]
+  --help        Show this help message
+  --clean       Clean up the build directory
+EOF
+
+my $result = GetOptions(
+    'help' => \$showHelp,
+    'clean' => \$clean,
+);
+
+if ($showHelp or not $result) {
+   print STDERR $usage;
+   exit 1;
+}
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+
+chdir "Tools/LayoutTestRelay" or die;
+
+if (isAppleMacWebKit()) {
+    $result = buildXCodeProject("LayoutTestRelay", $clean, XcodeOptions(), @ARGV);
+} else {
+    die "WebKitTestRunner is not supported on this platform.\n";
+}
+
+exit exitStatus($result);