Skip to content

Commit

Permalink
Merge pull request #914 from MarathonLabs/feature/xctestrunEnv
Browse files Browse the repository at this point in the history
feature(xctestrunEnv): EnvironmentVariables and TestingEnvironment va…
  • Loading branch information
Malinskiy authored Mar 29, 2024
2 parents 4b8a0f7 + f90eb34 commit 7911e7c
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.malinskiy.marathon.config.vendor.apple.ios.SigningConfiguration
import com.malinskiy.marathon.config.vendor.apple.SshConfiguration
import com.malinskiy.marathon.config.vendor.apple.TimeoutConfiguration as AppleTimeoutConfiguration
import com.malinskiy.marathon.config.vendor.apple.ios.XcresultConfiguration
import com.malinskiy.marathon.config.vendor.apple.ios.XctestrunEnvConfiguration
import java.io.File
import com.malinskiy.marathon.config.vendor.android.TimeoutConfiguration as AndroidTimeoutConfiguration
import com.malinskiy.marathon.config.vendor.apple.TestParserConfiguration as AppleTestParserConfiguration
Expand Down Expand Up @@ -159,7 +160,7 @@ sealed class VendorConfiguration {

@JsonProperty("xcresult") val xcresult: XcresultConfiguration = XcresultConfiguration(),
@JsonProperty("screenRecordConfiguration") val screenRecordConfiguration: IosScreenRecordConfiguration = IosScreenRecordConfiguration(),
@JsonProperty("xctestrunEnv") val xctestrunEnv: Map<String, String> = emptyMap(),
@JsonProperty("xctestrunEnv") val xctestrunEnv: XctestrunEnvConfiguration = XctestrunEnvConfiguration(),
@JsonProperty("lifecycle") val lifecycleConfiguration: LifecycleConfiguration = LifecycleConfiguration(),
@JsonProperty("permissions") val permissions: PermissionsConfiguration = PermissionsConfiguration(),
@JsonProperty("timeoutConfiguration") val timeoutConfiguration: AppleTimeoutConfiguration = AppleTimeoutConfiguration(),
Expand Down Expand Up @@ -188,7 +189,7 @@ sealed class VendorConfiguration {
@JsonProperty("ssh") val ssh: SshConfiguration = SshConfiguration(),

@JsonProperty("xcresult") val xcresult: XcresultConfiguration = XcresultConfiguration(),
@JsonProperty("xctestrunEnv") val xctestrunEnv: Map<String, String> = emptyMap(),
@JsonProperty("xctestrunEnv") val xctestrunEnv: XctestrunEnvConfiguration = XctestrunEnvConfiguration(),
@JsonProperty("timeoutConfiguration") val timeoutConfiguration: AppleTimeoutConfiguration = AppleTimeoutConfiguration(),
@JsonProperty("threadingConfiguration") val threadingConfiguration: AppleThreadingConfiguration = AppleThreadingConfiguration(),
@JsonProperty("hideRunnerOutput") val hideRunnerOutput: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.malinskiy.marathon.config.vendor.apple.ios

import com.fasterxml.jackson.annotation.JsonProperty

data class XctestrunEnvConfiguration(
@JsonProperty("app") val appEnvs: Map<String, String> = emptyMap(),
@JsonProperty("test") val testEnvs: Map<String, String> = emptyMap(),
)
14 changes: 9 additions & 5 deletions docs/runner/apple/configure/ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,17 +299,21 @@ The `display` and `mask` fields have the same options as the video recorder.
The `type` specifies the format of a single frame and is advised not to be changes.
The `delay` field specifies the minimal delay between frames using [ISO 8601][3] notation.

### xctestrun environment variables
### xctestrun Environment and TestingEnvironment variables

You specify additional environment variables for your test run:
You can specify additional Environment and TestingEnvironment variables for your test run:

```yaml
xctestrunEnv:
MY_ENV_VAR_1: A
MY_ENV_VAR_2: B
app: # EnvironmentVariables
MY_ENV_VAR_1: A
MY_ENV_VAR_2: B
test: # TestingEnvironmentVariables
MY_TEST_ENV_VAR_1: AA
MY_TEST_ENV_VAR_2: BB
```

These will be placed in the generated xctestrun property list file under the `TestingEnvironmentVariables` key.
These will be placed in the generated xctestrun property list file under the `EnvironmentVariables` and `TestingEnvironmentVariables` keys.

:::info

Expand Down
18 changes: 12 additions & 6 deletions docs/runner/apple/configure/macos.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,19 +184,25 @@ deleted on success and user attachments will always be kept in the xcresult, but

Possible values for the lifetime are `KEEP_ALWAYS`, `DELETE_ON_SUCCESS` and `KEEP_NEVER`.

### xctestrun environment variables
You specify additional environment variables for your test run:
### xctestrun Environment and TestingEnvironment variables

You can specify additional Environment and TestingEnvironment variables for your test run:

```yaml
xctestrunEnv:
MY_ENV_VAR_1: A
MY_ENV_VAR_2: B
app: # EnvironmentVariables
MY_ENV_VAR_1: A
MY_ENV_VAR_2: B
test: # TestingEnvironmentVariables
MY_TEST_ENV_VAR_1: AA
MY_TEST_ENV_VAR_2: BB
```

These will be placed in the generated xctestrun property list file under the `TestingEnvironmentVariables` key.
These will be placed in the generated xctestrun property list file under the `EnvironmentVariables` and `TestingEnvironmentVariables` keys.

:::info

Marathon generates required values for `DYLD_FRAMEWORK_PATH`, `DYLD_LIBRARY_PATH` and `DYLD_INSERT_LIBRARIES` for test environment.
Marathon generates required values for `DYLD_FRAMEWORK_PATH`, `DYLD_LIBRARY_PATH` and `DYLD_INSERT_LIBRARIES` for test environment.
If you specify custom ones then your values will be placed as a lower priority path elements at the end of the specified envvar.

:::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.malinskiy.marathon.apple.extensions
import com.malinskiy.marathon.config.vendor.VendorConfiguration
import com.malinskiy.marathon.config.vendor.apple.AppleTestBundleConfiguration
import com.malinskiy.marathon.config.vendor.apple.ios.XcresultConfiguration
import com.malinskiy.marathon.config.vendor.apple.ios.XctestrunEnvConfiguration

fun VendorConfiguration.bundleConfiguration(): AppleTestBundleConfiguration? {
return when (this) {
Expand All @@ -18,7 +19,7 @@ fun VendorConfiguration.bundleConfiguration(): AppleTestBundleConfiguration? {
}
}

fun VendorConfiguration.xctestrunEnv(): Map<String, String>? {
fun VendorConfiguration.xctestrunEnv(): XctestrunEnvConfiguration? {
return when (this) {
is VendorConfiguration.IOSConfiguration -> {
this.xctestrunEnv
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.malinskiy.marathon.apple.xctestrun.v2.Xctestrun
import com.malinskiy.marathon.config.exceptions.ConfigurationException
import com.malinskiy.marathon.config.vendor.apple.TestType
import com.malinskiy.marathon.config.vendor.apple.ios.XcresultConfiguration
import com.malinskiy.marathon.config.vendor.apple.ios.XctestrunEnvConfiguration
import com.malinskiy.marathon.exceptions.DeviceSetupException
import com.malinskiy.marathon.exceptions.IncompatibleDeviceException
import com.malinskiy.marathon.exceptions.TransferException
Expand All @@ -27,7 +28,7 @@ import com.malinskiy.marathon.apple.xctestrun.v2.Metadata as Metadata

class TestRootFactory(
private val device: AppleDevice,
private val xctestrunEnv: Map<String, String>,
private val xctestrunEnv: XctestrunEnvConfiguration,
private val xcresultConfiguration: XcresultConfiguration,
) {
suspend fun generate(testType: TestType, bundle: AppleTestBundle, useXctestParser: Boolean) {
Expand Down Expand Up @@ -135,10 +136,11 @@ class TestRootFactory(
val privateFrameworks = remoteFileManager.joinPath(developerPath, "Library", "PrivateFrameworks")
val usrLib = remoteFileManager.joinPath(developerPath, "usr", "lib")

val xctestrunTestEnv = xctestrunEnv.testEnvs
val userFrameworkPath =
xctestrunEnv["DYLD_FRAMEWORK_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
val userLibraryPath = xctestrunEnv["DYLD_LIBRARY_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
val userInsertLibraries = xctestrunEnv["DYLD_INSERT_LIBRARIES"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
xctestrunTestEnv["DYLD_FRAMEWORK_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
val userLibraryPath = xctestrunTestEnv["DYLD_LIBRARY_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
val userInsertLibraries = xctestrunTestEnv["DYLD_INSERT_LIBRARIES"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()

val dyldFrameworks = mutableListOf<String>().apply {
add("__TESTROOT__")
Expand Down Expand Up @@ -194,7 +196,7 @@ class TestRootFactory(
"DYLD_LIBRARY_PATH" to dyldLibraries.joinToString(":"),
"DYLD_INSERT_LIBRARIES" to dyldInsertLibraries.joinToString(":")
).apply {
xctestrunEnv
xctestrunTestEnv
.filterKeys { !setOf("DYLD_FRAMEWORK_PATH", "DYLD_LIBRARY_PATH", "DYLD_INSERT_LIBRARIES").contains(it) }
.forEach {
put(it.key, it.value)
Expand All @@ -209,6 +211,7 @@ class TestRootFactory(
arrayOf(
TestTarget.withArtifactReinstall(
name = bundle.testBundleId,
environmentVariables = xctestrunEnv.appEnvs.ifEmpty { null },
testingEnvironmentVariables = testEnv,
productModuleName = bundle.testBundleId,
systemAttachmentLifetime = xcresultConfiguration.attachments.systemAttachmentLifetime.value,
Expand Down Expand Up @@ -265,11 +268,12 @@ class TestRootFactory(
val privateFrameworks = remoteFileManager.joinPath(developerPath, "Library", "PrivateFrameworks")
val usrLib = remoteFileManager.joinPath(developerPath, "usr", "lib")

val xctestrunTestEnvs = xctestrunEnv.testEnvs
val userFrameworkPath =
xctestrunEnv["DYLD_FRAMEWORK_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
val userLibraryPath = xctestrunEnv["DYLD_LIBRARY_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
xctestrunTestEnvs["DYLD_FRAMEWORK_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
val userLibraryPath = xctestrunTestEnvs["DYLD_LIBRARY_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
val userInsertLibraries =
xctestrunEnv["DYLD_INSERT_LIBRARIES"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()
xctestrunTestEnvs["DYLD_INSERT_LIBRARIES"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet()

val dyldFrameworks = mutableListOf("__TESTROOT__", frameworks, privateFrameworks, *userFrameworkPath.toTypedArray())
/**
Expand All @@ -293,7 +297,7 @@ class TestRootFactory(
"DYLD_LIBRARY_PATH" to dyldLibraries.joinToString(":"),
"XCInjectBundleInto" to "__TESTHOST__/${remoteFileManager.appUnderTestFileName()}"
).apply {
xctestrunEnv
xctestrunTestEnvs
.filterKeys { !setOf("DYLD_FRAMEWORK_PATH", "DYLD_INSERT_LIBRARIES", "DYLD_LIBRARY_PATH").contains(it) }
.forEach {
put(it.key, it.value)
Expand All @@ -308,6 +312,7 @@ class TestRootFactory(
arrayOf(
TestTarget.withArtifactReinstall(
name = bundle.testBundleId,
environmentVariables = xctestrunEnv.appEnvs.ifEmpty { null },
testingEnvironmentVariables = testEnv,
productModuleName = bundle.testBundleId,
systemAttachmentLifetime = xcresultConfiguration.attachments.systemAttachmentLifetime.value,
Expand Down

0 comments on commit 7911e7c

Please sign in to comment.