Skip to content

Commit

Permalink
feat(ios): extra artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
Malinskiy committed Feb 21, 2023
1 parent 48c3c9f commit bca5857
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ class ConfigurationFactory(
val resolvedDerivedDataDir = it.derivedDataDir?.let { ddd -> marathonfileDir.resolve(ddd) }
val resolvedApplication = it.application?.let { ddd -> marathonfileDir.resolve(ddd) }
val resolvedTestApplication = it.testApplication?.let { ddd -> marathonfileDir.resolve(ddd) }
val resolvedExtraArtifacts = it.extraArtifacts?.map { ddd -> marathonfileDir.resolve(ddd) }
val resolvedExtraApplications = it.extraApplications?.map { ddd -> marathonfileDir.resolve(ddd) }
AppleTestBundleConfiguration(resolvedApplication, resolvedTestApplication, resolvedExtraApplications, resolvedDerivedDataDir).apply { validate() }

AppleTestBundleConfiguration(resolvedApplication, resolvedTestApplication, resolvedExtraApplications, resolvedExtraArtifacts, resolvedDerivedDataDir).apply { validate() }
}
val optionalDevices = configuration.vendorConfiguration.devicesFile?.resolveAgainst(marathonfileDir)
?: marathonfileDir.resolve("Marathondevices")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data class AppleTestBundleConfiguration(
@JsonProperty("application") val application: File? = null,
@JsonProperty("testApplication") val testApplication: File? = null,
@JsonProperty("extraApplications") val extraApplications: List<File>? = null,
@JsonProperty("extraArtifacts") val extraArtifacts: List<File>? = null,
@JsonProperty("derivedDataDir") val derivedDataDir: File? = null,
@JsonProperty("testType") val testType: TestType? = null,
private val tempDirFor: (File) -> File = { file ->
Expand Down
18 changes: 18 additions & 0 deletions docs/docs/ios/configure.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,24 @@ extraApplications:
- "/path/to/additional.app"
```

#### Extra artifacts
Marathon can push additional artifacts such as files and folders to the remote environment for testing:

```yaml
extraArtifacts:
- "/path/to/my/folder"
```

To retrieve these artifacts from the test marathon passes an environment variable `TEST_EXTRA_ARTIFACTS` with the absolute path of the
folder containing all of the `extraArtifacts`, e.g. for the example above `$TEST_EXTRA_ARTIFACTS/folder` will be a valid path to read.

:::tip

There is no unwrapping during the push process so a local folder `a` will be a remote folder `TEST_EXTRA_ARTIFACTS/a` and
a local file `b` will be a remote file `TEST_EXTRA_ARTIFACTS/b`.

:::

### Devices
By default, marathon will look for a file `Marathondevices` in the same folder as `Marathonfile` for the configuration of workers. You can
override this location with the following property:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AppleApplicationInstaller(
logger.debug { "Moving xctest to ${device.serialNumber}" }
val remoteXctest = device.remoteFileManager.remoteXctestFile()
withRetry(3, 1000L) {
device.remoteFileManager.createRemoteDirectory()
device.remoteFileManager.createRemoteDirectories()
val remoteDirectory = device.remoteFileManager.remoteDirectory()
if (!device.pushFolder(xctest, remoteXctest)) {
throw DeviceSetupException("Error transferring $xctest to ${device.serialNumber}")
Expand Down Expand Up @@ -57,6 +57,16 @@ class AppleApplicationInstaller(
logger.warn { "Extra application $it should be a directory with extension app" }
}
}

bundle.extraArtifacts?.forEach {
logger.debug { "Pushing extra artifact $it to ${device.serialNumber}" }
val remoteArtifactFile = device.remoteFileManager.remoteArtifactFile(it.name)
if (it.isDirectory) {
device.pushFolder(it, remoteArtifactFile)
} else {
device.pushFile(it, remoteArtifactFile)
}
}
}

private suspend fun grantPermissions(device: AppleSimulatorDevice) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class AppleSimulatorDevice(
}
override val coroutineContext: CoroutineContext = dispatcher
override val remoteFileManager: RemoteFileManager = RemoteFileManager(this)
override val storagePath = "/tmp/marathon/$udid"
override val storagePath = "${RemoteFileManager.MARATHON_ROOT_PATH}/$udid"
private lateinit var xcodeVersion: XcodeVersion

/**
Expand Down Expand Up @@ -188,8 +188,8 @@ class AppleSimulatorDevice(
async(CoroutineName("prepare $serialNumber")) {
supervisorScope {
track.trackDevicePreparing(this@AppleSimulatorDevice) {
remoteFileManager.removeRemoteDirectory()
remoteFileManager.createRemoteDirectory()
remoteFileManager.removeRemoteDirectories()
remoteFileManager.createRemoteDirectories()
//Clean slate for the recorder
executeWorkerCommand(listOf("pkill", "-f", "'simctl io ${udid} recordVideo'"))
mutableListOf<Deferred<Unit>>().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.malinskiy.marathon.config.Configuration
import com.malinskiy.marathon.config.exceptions.ConfigurationException
import com.malinskiy.marathon.config.vendor.VendorConfiguration
import com.malinskiy.marathon.device.Device
import com.malinskiy.marathon.device.DeviceProvider
import com.malinskiy.marathon.exceptions.TestParsingException
import com.malinskiy.marathon.execution.RemoteTestParser
import com.malinskiy.marathon.execution.withRetry
Expand Down Expand Up @@ -56,7 +55,7 @@ class AppleTestParser(

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

device.remoteFileManager.createRemoteDirectory()
device.remoteFileManager.createRemoteDirectories()
val remoteXctest = device.remoteFileManager.remoteXctestFile()
if (!device.pushFile(xctest, remoteXctest)) {
throw TestParsingException("failed to push xctest for test parsing")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,23 @@ class RemoteFileManager(private val device: AppleDevice) {
private val outputDir by lazy { device.storagePath }

fun remoteDirectory(): String = outputDir
fun remoteArtifactDirectory(): String = MARATHON_ROOT_PATH.resolve("extraArtifacts")

suspend fun createRemoteDirectory(remoteDir: String = outputDir) {
suspend fun createRemoteDirectories() {
createRemoteDirectory(remoteDirectory())
createRemoteDirectory(remoteArtifactDirectory())
}

suspend fun createRemoteDirectory(path: String) {
executeCommand(
listOf("mkdir", "-p", remoteDirectory()),
"Could not create remote directory ${remoteDirectory()}"
listOf("mkdir", "-p", path),
"Could not create remote directory $path"
)
}

suspend fun removeRemoteDirectory() {
suspend fun removeRemoteDirectories() {
executeCommand(
listOf("rm", "-rf", remoteDirectory()),
listOf("rm", "-rf", MARATHON_ROOT_PATH),
"Unable to remove directory ${remoteDirectory()}"
)
}
Expand All @@ -43,6 +49,7 @@ class RemoteFileManager(private val device: AppleDevice) {
fun remoteXctestFile(): String = remoteFile(xctestFileName())
fun remoteApplication(): String = remoteFile(appUnderTestFileName())
fun remoteExtraApplication(name: String) = remoteFile(name)
fun remoteExtraArtifact(name: String) = remoteFile(name)

/**
* Omitting xcresult extension results in a symlink
Expand All @@ -58,6 +65,7 @@ class RemoteFileManager(private val device: AppleDevice) {
"${device.udid}.${batch.id}.xcresult"

private fun remoteFile(file: String): String = remoteDirectory().resolve(file)
fun remoteArtifactFile(file: String): String = remoteArtifactDirectory().resolve(file)

private suspend fun safeExecuteCommand(command: List<String>) {
try {
Expand Down Expand Up @@ -132,6 +140,7 @@ class RemoteFileManager(private val device: AppleDevice) {

companion object {
const val FILE_SEPARATOR = "/"
const val MARATHON_ROOT_PATH = "/tmp/marathon"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class TestRootFactory(private val device: AppleSimulatorDevice, private val vend
val remoteFileManager = device.remoteFileManager

val testRoot = remoteFileManager.remoteTestRoot()
remoteFileManager.createRemoteDirectory(testRoot)
val xctestrun = when (testType) {
TestType.XCUITEST -> generateXCUITest(testRoot, remoteFileManager, bundleConfiguration)
TestType.XCTEST -> generateXCTest(testRoot, remoteFileManager, bundleConfiguration)
Expand Down Expand Up @@ -102,6 +101,7 @@ class TestRootFactory(private val device: AppleSimulatorDevice, private val vend
.forEach {
put(it.key, it.value)
}
put(ENV_TEST_EXTRA_ARTIFACTS, remoteFileManager.remoteArtifactDirectory())
}.toMap()

return Xctestrun(
Expand Down Expand Up @@ -204,6 +204,7 @@ class TestRootFactory(private val device: AppleSimulatorDevice, private val vend
.forEach {
put(it.key, it.value)
}
put(ENV_TEST_EXTRA_ARTIFACTS, remoteFileManager.remoteArtifactDirectory())
}.toMap()

return Xctestrun(
Expand Down Expand Up @@ -273,4 +274,8 @@ class TestRootFactory(private val device: AppleSimulatorDevice, private val vend
}
}
}

companion object {
const val ENV_TEST_EXTRA_ARTIFACTS = "TEST_EXTRA_ARTIFACTS"
}
}

0 comments on commit bca5857

Please sign in to comment.