Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for other-files option #698

Merged
merged 3 commits into from
Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## next (unreleased)
- [#692](https://github.com/Flank/flank/pull/698) Add support for other-files option. ([jan-gogo](https://github.com/jan-gogo))
- [#695](https://github.com/Flank/flank/pull/695) Add support for additional-apks option. ([jan-gogo](https://github.com/jan-gogo))
- [#683](https://github.com/Flank/flank/pull/683) Print web link. ([pawelpasterz](https://github.com/pawelpasterz))
- [#692](https://github.com/Flank/flank/pull/692) Add support for network-profiles list command & --network-profile option. ([jan-gogo](https://github.com/jan-gogo))
Expand Down
7 changes: 7 additions & 0 deletions test_runner/flank.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ gcloud:
# directories-to-pull:
# - /sdcard/

## A list of device-path: file-path pairs that indicate the device paths to push files to the device before starting tests, and the paths of files to push.
## Device paths must be under absolute, whitelisted paths (${EXTERNAL_STORAGE}, or ${ANDROID_DATA}/local/tmp).
## Source file paths may be in the local filesystem or in Google Cloud Storage (gs://…).
# other-files
# - /sdcard/dir1/file1.txt: local/file.txt
# - /sdcard/dir2/file2.jpg: gs://bucket/file.jpg

## Monitor and record performance metrics: CPU, memory, network usage, and FPS (game-loop only).
## Enabled by default, use --no-performance-metrics to disable.
# performance-metrics: true
Expand Down
16 changes: 10 additions & 6 deletions test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,18 @@ class AndroidArgs(
override val flakyTestAttempts = cli?.flakyTestAttempts ?: gcloud.flakyTestAttempts

private val androidGcloud = androidGcloudYml.gcloud
val appApk = (cli?.app ?: androidGcloud.app ?: fatalError("app is not set")).processApkPath("from app")
val testApk = (cli?.test ?: androidGcloud.test ?: fatalError("test is not set")).processApkPath("from test")
val additionalApks = (cli?.additionalApks ?: androidGcloud.additionalApks).map { it.processApkPath("from additional-apks") }
val appApk = (cli?.app ?: androidGcloud.app ?: fatalError("app is not set")).processFilePath("from app")
val testApk = (cli?.test ?: androidGcloud.test ?: fatalError("test is not set")).processFilePath("from test")
val additionalApks = (cli?.additionalApks ?: androidGcloud.additionalApks).map { it.processFilePath("from additional-apks") }
val autoGoogleLogin = cli?.autoGoogleLogin ?: cli?.noAutoGoogleLogin?.not() ?: androidGcloud.autoGoogleLogin

// We use not() on noUseOrchestrator because if the flag is on, useOrchestrator needs to be false
val useOrchestrator = cli?.useOrchestrator ?: cli?.noUseOrchestrator?.not() ?: androidGcloud.useOrchestrator
val environmentVariables = cli?.environmentVariables ?: androidGcloud.environmentVariables
val directoriesToPull = cli?.directoriesToPull ?: androidGcloud.directoriesToPull
val otherFiles = (cli?.otherFiles ?: androidGcloud.otherFiles).map { (devicePath, filePath) ->
devicePath to filePath.processFilePath("from otherFiles")
}.toMap()
val performanceMetrics = cli?.performanceMetrics ?: cli?.noPerformanceMetrics?.not() ?: androidGcloud.performanceMetrics
val testRunnerClass = cli?.testRunnerClass ?: androidGcloud.testRunnerClass
val testTargets = cli?.testTargets ?: androidGcloud.testTargets.filterNotNull()
Expand All @@ -83,8 +86,8 @@ class AndroidArgs(
private val androidFlank = androidFlankYml.flank
val additionalAppTestApks = (cli?.additionalAppTestApks ?: androidFlank.additionalAppTestApks).map { (app, test) ->
AppTestPair(
app = app?.processApkPath("from additional-app-test-apks.app"),
test = test.processApkPath("from additional-app-test-apks.test")
app = app?.processFilePath("from additional-app-test-apks.app"),
test = test.processFilePath("from additional-app-test-apks.test")
)
}
val keepFilePath = cli?.keepFilePath ?: androidFlank.keepFilePath
Expand Down Expand Up @@ -128,6 +131,7 @@ AndroidArgs
auto-google-login: $autoGoogleLogin
use-orchestrator: $useOrchestrator
directories-to-pull:${listToString(directoriesToPull)}
other-files:${mapToString(otherFiles)}
performance-metrics: $performanceMetrics
test-runner-class: $testRunnerClass
test-targets:${listToString(testTargets)}
Expand Down Expand Up @@ -191,7 +195,7 @@ AndroidArgs
}
}

private fun String.processApkPath(name: String): String =
private fun String.processFilePath(name: String): String =
if (startsWith(FtlConstants.GCS_PREFIX))
this.also { assertGcsFileExists(it) } else
evaluateFilePath(this).also { assertFileExists(it, name) }
4 changes: 4 additions & 0 deletions test_runner/src/main/kotlin/ftl/args/yml/AndroidGcloudYml.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class AndroidGcloudYmlParams(
@field:JsonProperty("directories-to-pull")
val directoriesToPull: List<String> = emptyList(),

@field:JsonProperty("other-files")
val otherFiles: Map<String, String> = emptyMap(),

@field:JsonProperty("performance-metrics")
val performanceMetrics: Boolean = FlankDefaults.DISABLE_PERFORMANCE_METRICS,

Expand All @@ -52,6 +55,7 @@ class AndroidGcloudYmlParams(
"use-orchestrator",
"environment-variables",
"directories-to-pull",
"other-files",
"performance-metrics",
"test-runner-class",
"test-targets",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,17 @@ class AndroidRunCommand : CommonRunCommand(), Runnable {
)
var directoriesToPull: List<String>? = null

@Option(
names = ["--other-files"],
split = ",",
description = [
"A list of device-path=file-path pairs that indicate the device paths to push files to the device before starting tests, and the paths of files to push.",
"Device paths must be under absolute, whitelisted paths (\${EXTERNAL_STORAGE}, or \${ANDROID_DATA}/local/tmp).",
"Source file paths may be in the local filesystem or in Google Cloud Storage (gs://…). "
]
)
var otherFiles: Map<String, String>? = null

@Option(
names = ["--performance-metrics"],
description = ["Monitor and record performance metrics: CPU, memory, " +
Expand Down
12 changes: 12 additions & 0 deletions test_runner/src/main/kotlin/ftl/gc/GcAndroidTestMatrix.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import com.google.api.services.testing.model.AndroidDeviceList
import com.google.api.services.testing.model.AndroidInstrumentationTest
import com.google.api.services.testing.model.Apk
import com.google.api.services.testing.model.ClientInfo
import com.google.api.services.testing.model.DeviceFile
import com.google.api.services.testing.model.EnvironmentMatrix
import com.google.api.services.testing.model.EnvironmentVariable
import com.google.api.services.testing.model.FileReference
import com.google.api.services.testing.model.GoogleAuto
import com.google.api.services.testing.model.GoogleCloudStorage
import com.google.api.services.testing.model.ManualSharding
import com.google.api.services.testing.model.RegularFile
import com.google.api.services.testing.model.ResultStorage
import com.google.api.services.testing.model.ShardingOption
import com.google.api.services.testing.model.TestMatrix
Expand All @@ -35,6 +37,7 @@ object GcAndroidTestMatrix {
fun build(
appApkGcsPath: String,
testApkGcsPath: String,
otherFiles: Map<String, String>,
runGcsPath: String,
androidDeviceList: AndroidDeviceList,
testShards: ShardChunks,
Expand Down Expand Up @@ -84,6 +87,7 @@ object GcAndroidTestMatrix {
.setNetworkProfile(args.networkProfile)
.setDirectoriesToPull(args.directoriesToPull)
.setAdditionalApks(additionalApkGcsPaths.mapGcsPathsToApks())
.setFilesToPush(otherFiles.mapToDeviceFiles())

if (args.environmentVariables.isNotEmpty()) {
testSetup.environmentVariables =
Expand Down Expand Up @@ -125,3 +129,11 @@ object GcAndroidTestMatrix {
private fun List<String>?.mapGcsPathsToApks(): List<Apk>? = this
?.takeIf { it.isNotEmpty() }
?.map { gcsPath -> Apk().setLocation(FileReference().setGcsPath(gcsPath)) }

private fun Map<String, String>.mapToDeviceFiles() = map { (devicePath: String, gcsFilePath: String) ->
DeviceFile().setRegularFile(
RegularFile()
.setDevicePath(devicePath)
.setContent(FileReference().setGcsPath(gcsFilePath))
)
}
13 changes: 13 additions & 0 deletions test_runner/src/main/kotlin/ftl/run/platform/RunAndroidTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ internal suspend fun runAndroidTests(args: AndroidArgs): TestResult = coroutineS
val runCount = args.repeatTests
val history = GcToolResults.createToolResultsHistory(args)
val resolvedTestApks = args.getResolvedTestApks()
val otherGcsFiles = args.otherFiles.uploadOtherFiles(args.resultsBucket, runGcsPath)

val allTestShardChunks: ShardChunks = resolvedTestApks.map { apks: ResolvedTestApks ->
// Ensure we only shard tests that are part of the test apk. Use the resolved test apk path to make sure
Expand All @@ -45,6 +46,7 @@ internal suspend fun runAndroidTests(args: AndroidArgs): TestResult = coroutineS
args = args,
runGcsPath = runGcsPath
),
otherFiles = otherGcsFiles,
runGcsPath = runGcsPath,
androidDeviceList = androidDeviceList,
testShards = testShards,
Expand Down Expand Up @@ -81,6 +83,7 @@ private suspend fun executeAndroidTestMatrix(
args: AndroidArgs,
testShards: ShardChunks,
uploadedTestApks: UploadedTestApks,
otherFiles: Map<String, String>,
androidDeviceList: AndroidDeviceList,
history: ToolResultsHistory,
runCount: Int
Expand All @@ -94,6 +97,7 @@ private suspend fun executeAndroidTestMatrix(
androidDeviceList = androidDeviceList,
testShards = testShards,
args = args,
otherFiles = otherFiles,
toolResultsHistory = history,
additionalApkGcsPaths = uploadedTestApks.additionalApks
).executeWithRetry()
Expand Down Expand Up @@ -123,3 +127,12 @@ private suspend fun uploadTestApks(
additionalApks = additionalApkGcsPaths.awaitAll()
)
}

private suspend fun Map<String, String>.uploadOtherFiles(
gcsBucket: String,
runGcsPath: String
): Map<String, String> = coroutineScope {
map { (devicePath: String, filePath: String) ->
async(Dispatchers.IO) { devicePath to GcStorage.upload(filePath, gcsBucket, runGcsPath) }
}.awaitAll().toMap()
}
13 changes: 13 additions & 0 deletions test_runner/src/test/kotlin/ftl/args/AndroidArgsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class AndroidArgsTest {
directories-to-pull:
- /sdcard/screenshots
- /sdcard/screenshots2
other-files:
/sdcard/dir1/file1.txt: $appApk
/sdcard/dir2/file2.jpg: $testApk
performance-metrics: false
test-runner-class: com.foo.TestRunner
test-targets:
Expand Down Expand Up @@ -190,6 +193,12 @@ class AndroidArgsTest {
assert(useOrchestrator, false)
assert(environmentVariables, linkedMapOf("clearPackageData" to "true", "randomEnvVar" to "false"))
assert(directoriesToPull, listOf("/sdcard/screenshots", "/sdcard/screenshots2"))
assert(
otherFiles, mapOf(
"/sdcard/dir1/file1.txt" to appApkAbsolutePath,
"/sdcard/dir2/file2.jpg" to testApkAbsolutePath
)
)
assert(performanceMetrics, false)
assert(testRunnerClass, "com.foo.TestRunner")
assert(
Expand Down Expand Up @@ -251,6 +260,9 @@ AndroidArgs
directories-to-pull:
- /sdcard/screenshots
- /sdcard/screenshots2
other-files:
/sdcard/dir1/file1.txt: $appApkAbsolutePath
/sdcard/dir2/file2.jpg: $testApkAbsolutePath
performance-metrics: false
test-runner-class: com.foo.TestRunner
test-targets:
Expand Down Expand Up @@ -314,6 +326,7 @@ AndroidArgs
auto-google-login: false
use-orchestrator: true
directories-to-pull:
other-files:
performance-metrics: false
test-runner-class: null
test-targets:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class AndroidRunCommandTest {
assertThat(cmd.testRunnerClass).isNull()
assertThat(cmd.environmentVariables).isNull()
assertThat(cmd.directoriesToPull).isNull()
assertThat(cmd.otherFiles).isNull()
assertThat(cmd.device).isNull()
assertThat(cmd.resultsBucket).isNull()
assertThat(cmd.recordVideo).isNull()
Expand Down Expand Up @@ -208,6 +209,14 @@ class AndroidRunCommandTest {
assertThat(cmd.directoriesToPull).hasSize(2)
}

@Test
fun `otherFiles parse`() {
val cmd = AndroidRunCommand()
CommandLine(cmd).parseArgs("--other-files=a=1,b=2")

assertThat(cmd.otherFiles).hasSize(2)
}

@Test
fun `device parse`() {
val cmd = AndroidRunCommand()
Expand Down
3 changes: 3 additions & 0 deletions test_runner/src/test/kotlin/ftl/gc/GcAndroidTestMatrixTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class GcAndroidTestMatrixTest {
appApkGcsPath = "",
testApkGcsPath = "",
runGcsPath = "",
otherFiles = emptyMap(),
androidDeviceList = AndroidDeviceList(),
testShards = emptyList(),
args = androidArgs,
Expand All @@ -41,6 +42,7 @@ class GcAndroidTestMatrixTest {
appApkGcsPath = "",
testApkGcsPath = "",
runGcsPath = "",
otherFiles = emptyMap(),
androidDeviceList = AndroidDeviceList(),
testShards = listOf(listOf("")),
args = androidArgs,
Expand All @@ -61,6 +63,7 @@ class GcAndroidTestMatrixTest {
appApkGcsPath = "",
testApkGcsPath = "",
runGcsPath = "",
otherFiles = emptyMap(),
androidDeviceList = AndroidDeviceList(),
testShards = emptyList(),
args = androidArgs,
Expand Down