Skip to content

Commit 02ece2b

Browse files
committed
fix(apple): polish up the install
1 parent 07a5883 commit 02ece2b

File tree

6 files changed

+66
-9
lines changed

6 files changed

+66
-9
lines changed

vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/AppleApplicationInstaller.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ open class AppleApplicationInstaller<in T: AppleDevice>(
2525
val xctest = bundleConfiguration?.xctest ?: throw IllegalArgumentException("No test bundle provided")
2626
val app = bundleConfiguration.app
2727
val bundle = AppleTestBundle(app, xctest, device.sdk)
28-
val relativeTestBinaryPath = bundle.relativeTestBinaryPath
28+
val relativeTestBinaryPath = bundle.relativeBinaryPath
2929

3030
logger.debug { "Moving xctest to ${device.serialNumber}" }
3131
val remoteXctest = device.remoteFileManager.remoteXctestFile()

vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/NmTestParser.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class NmTestParser(
4747
bundle: AppleTestBundle,
4848
): List<Test> {
4949
val testBinary = bundle.testBinary
50-
val relativeTestBinaryPath = bundle.relativeTestBinaryPath
50+
val relativeTestBinaryPath = bundle.relativeBinaryPath
5151
val xctest = bundle.testApplication
5252

5353
logger.debug { "Found test binary $testBinary for xctest $xctest" }

vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/bin/AppleBinaryEnvironment.kt

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.malinskiy.marathon.apple.bin
22

33
import com.google.gson.Gson
4+
import com.malinskiy.marathon.apple.bin.chmod.Chmod
45
import com.malinskiy.marathon.apple.bin.codesign.Codesign
56
import com.malinskiy.marathon.apple.bin.getconf.Getconf
67
import com.malinskiy.marathon.apple.bin.ioreg.Ioreg
@@ -32,5 +33,6 @@ class AppleBinaryEnvironment(
3233
val ioreg: Ioreg = Ioreg(commandExecutor, timeoutConfiguration)
3334
val systemProfiler: SystemProfiler = SystemProfiler(commandExecutor, timeoutConfiguration)
3435
val swvers: SwVers = SwVers(commandExecutor, timeoutConfiguration)
36+
val chmod: Chmod = Chmod(commandExecutor, timeoutConfiguration)
3537
val xcrun: Xcrun = Xcrun(commandExecutor, configuration, timeoutConfiguration, gson)
3638
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.malinskiy.marathon.apple.bin.chmod
2+
3+
import com.malinskiy.marathon.apple.cmd.CommandExecutor
4+
import com.malinskiy.marathon.apple.cmd.CommandResult
5+
import com.malinskiy.marathon.apple.extensions.bashEscape
6+
import com.malinskiy.marathon.apple.model.Arch
7+
import com.malinskiy.marathon.config.vendor.apple.TimeoutConfiguration
8+
import com.malinskiy.marathon.exceptions.DeviceSetupException
9+
import java.time.Duration
10+
11+
class Chmod(
12+
private val commandExecutor: CommandExecutor,
13+
private val timeoutConfiguration: TimeoutConfiguration,
14+
) {
15+
suspend fun makeExecutable(path: String): String {
16+
return commandExecutor.criticalExecute(timeoutConfiguration.shell, "chmod", "+x", path.bashEscape()).successfulOrNull()?.combinedStdout?.trim()
17+
?: throw DeviceSetupException("failed to detect operating system version")
18+
}
19+
}

vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/model/AppleTestBundle.kt

+23-4
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ class AppleTestBundle(
3939
}
4040
PropertyList.from(file)
4141
}
42-
val testBundleId = (testBundleInfo.naming.bundleName ?: testApplication.nameWithoutExtension).replace('-', '_')
42+
val testBundleId = (testBundleInfo.naming.bundleName ?: testApplication.nameWithoutExtension).replace("[- ]".toRegex(), "_")
4343

4444
val testBinary: File by lazy {
4545
val possibleTestBinaries = when (sdk) {
4646
Sdk.IPHONEOS, Sdk.IPHONESIMULATOR -> testApplication.listFiles()?.filter { it.isFile && it.extension == "" }
4747
?: throw ConfigurationException("missing test binaries in xctest folder at $testApplication")
4848

49-
Sdk.MACOS -> Paths.get(testApplication.absolutePath, *relativeTestBinaryPath).toFile().listFiles()
49+
Sdk.MACOS -> Paths.get(testApplication.absolutePath, *relativeBinaryPath).toFile().listFiles()
5050
?.filter { it.isFile && it.extension == "" }
5151
?: throw ConfigurationException("missing test binaries in xctest folder at $testApplication")
5252
}
@@ -60,10 +60,29 @@ class AppleTestBundle(
6060
}
6161
}
6262

63+
val applicationBinary: File? by lazy {
64+
application?.let { application ->
65+
when (sdk) {
66+
Sdk.IPHONEOS, Sdk.IPHONESIMULATOR -> application.listFiles()?.filter { it.isFile && it.extension == "" }
67+
Sdk.MACOS -> Paths.get(application.absolutePath, *relativeBinaryPath).toFile().listFiles()
68+
?.filter { it.isFile && it.extension == "" }
69+
}?.let { possibleBinaries ->
70+
when (possibleBinaries.size) {
71+
0 -> null
72+
1 -> possibleBinaries[0]
73+
else -> {
74+
logger.warn { "Multiple application binaries present in app folder" }
75+
possibleBinaries[0]
76+
}
77+
}
78+
}
79+
}
80+
}
81+
6382
/**
64-
* Path of the test binary relative to the xctest folder
83+
* Path of the app and test binaries relative to the bundle's (app/xctest) folder
6584
*/
66-
val relativeTestBinaryPath: Array<String> by lazy {
85+
val relativeBinaryPath: Array<String> by lazy {
6786
when (sdk) {
6887
Sdk.IPHONEOS, Sdk.IPHONESIMULATOR -> emptyArray()
6988
Sdk.MACOS -> arrayOf("Contents", "MacOS")

vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/xctestrun/TestRootFactory.kt

+20-3
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class TestRootFactory(
6262
if (!device.pushFolder(testApp, remoteTestApp)) {
6363
throw DeviceSetupException("failed to push app under test to remote device")
6464
}
65+
ensureApplicationBinaryIsExecutable(remoteFileManager, bundle)
6566
val runnerPlugins = when (device.sdk) {
6667
Sdk.IPHONEOS, Sdk.IPHONESIMULATOR -> remoteFileManager.joinPath(testRunnerApp, "PlugIns")
6768
Sdk.MACOS -> remoteFileManager.joinPath(testRunnerApp, "Contents", "PlugIns")
@@ -150,6 +151,7 @@ class TestRootFactory(
150151
if (!device.pushFolder(testApp, remoteTestApp)) {
151152
throw DeviceSetupException("failed to push app under test to remote device")
152153
}
154+
ensureApplicationBinaryIsExecutable(remoteFileManager, bundle)
153155

154156
/**
155157
* A common scenario is to place xctest for unit tests inside the app's PlugIns.
@@ -163,6 +165,7 @@ class TestRootFactory(
163165
if (!device.pushFolder(bundle.testApplication, remoteXctest)) {
164166
throw DeviceSetupException("failed to push xctest to remote device")
165167
}
168+
ensureApplicationBinaryIsExecutable(remoteFileManager, bundle)
166169
}
167170

168171
if (device.sdk == Sdk.IPHONEOS) {
@@ -234,23 +237,37 @@ class TestRootFactory(
234237
)
235238
}
236239

240+
private suspend fun ensureApplicationBinaryIsExecutable(
241+
remoteFileManager: RemoteFileManager,
242+
bundle: AppleTestBundle
243+
) {
244+
bundle.applicationBinary?.let {
245+
val remoteApplicationBinary = joinPath(
246+
remoteFileManager.remoteApplication(),
247+
*bundle.relativeBinaryPath,
248+
it.name
249+
)
250+
device.binaryEnvironment.chmod.makeExecutable(remoteApplicationBinary)
251+
}
252+
}
253+
237254
private suspend fun generateTestRunnerApp(
238255
testRoot: String,
239256
platformLibraryPath: String,
240257
bundle: AppleTestBundle,
241258
): String {
242259
val remoteTestBinary = joinPath(
243260
device.remoteFileManager.remoteXctestFile(),
244-
*bundle.relativeTestBinaryPath,
261+
*bundle.relativeBinaryPath,
245262
bundle.testBinary.nameWithoutExtension
246263
)
247264
val baseApp = joinPath(platformLibraryPath, "Xcode", "Agents", "XCTRunner.app")
248265
val runnerBinaryName = "${bundle.testBundleId}-Runner"
249266
val testRunnerApp = joinPath(testRoot, "$runnerBinaryName.app")
250267
device.remoteFileManager.copy(baseApp, testRunnerApp)
251268

252-
val baseTestRunnerBinary = joinPath(testRunnerApp, *bundle.relativeTestBinaryPath, "XCTRunner")
253-
val testRunnerBinary = joinPath(testRunnerApp, *bundle.relativeTestBinaryPath, runnerBinaryName)
269+
val baseTestRunnerBinary = joinPath(testRunnerApp, *bundle.relativeBinaryPath, "XCTRunner")
270+
val testRunnerBinary = joinPath(testRunnerApp, *bundle.relativeBinaryPath, runnerBinaryName)
254271
device.remoteFileManager.copy(baseTestRunnerBinary, testRunnerBinary)
255272

256273
matchArchitectures(remoteTestBinary, testRunnerBinary)

0 commit comments

Comments
 (0)