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

feat: iOS add directories-to-pull #1266

Merged
merged 9 commits into from
Nov 2, 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
6 changes: 6 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ gcloud:
# version: 12.0
# locale: es_ES
# orientation: landscape

## A list of paths that will be copied from the device's storage to the designated results bucket after the test
## is complete. These must be absolute paths under /private/var/mobile/Media or /Documents
## of the app under test. If the path is under an app's /Documents, it must be prefixed with the app's bundle id and a colon
# directories-to-pull:
# - /private/var/mobile/Media

## A list of device-path=file-path pairs that specify the paths of the test device and the files you want pushed to the device prior to testing.
## Device paths should either be under the Media shared folder (e.g. prefixed with /private/var/mobile/Media) or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,18 +283,18 @@
TargetAttributes = {
2CB7314C1C29E54A00CF35C1 = {
CreatedOnToolsVersion = 7.2;
DevelopmentTeam = AD2V26JBWL;
DevelopmentTeam = L2UF9MLSM6;
LastSwiftMigration = 0800;
TestTargetID = 5F5A53781ADE67D500F81DF0;
};
5F5A53781ADE67D500F81DF0 = {
CreatedOnToolsVersion = 6.3;
DevelopmentTeam = AD2V26JBWL;
DevelopmentTeam = L2UF9MLSM6;
LastSwiftMigration = 0800;
};
5FDE05571B0DAA090037B82F = {
CreatedOnToolsVersion = 6.3.2;
DevelopmentTeam = AD2V26JBWL;
DevelopmentTeam = L2UF9MLSM6;
TestTargetID = 5F5A53781ADE67D500F81DF0;
};
};
Expand Down Expand Up @@ -485,7 +485,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = NO;
DEVELOPMENT_TEAM = AD2V26JBWL;
DEVELOPMENT_TEAM = L2UF9MLSM6;
ENABLE_TESTABILITY = YES;
INFOPLIST_FILE = EarlGreyExampleSwiftTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
Expand Down Expand Up @@ -619,7 +619,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = AD2V26JBWL;
DEVELOPMENT_TEAM = L2UF9MLSM6;
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
INFOPLIST_FILE = "$(SRCROOT)/EarlGreyExample/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
Expand Down Expand Up @@ -666,7 +666,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = NO;
DEVELOPMENT_TEAM = AD2V26JBWL;
DEVELOPMENT_TEAM = L2UF9MLSM6;
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
GCC_PREPROCESSOR_DEFINITIONS = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,27 @@ class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSour

var tableItems = (1...50).map { $0 }

func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}

override func viewDidLoad() {
super.viewDidLoad()


let str = "viewLoaded"
let outputDirectory = getDocumentsDirectory().appendingPathComponent("output")

do {
try FileManager.default.createDirectory(atPath: outputDirectory.path, withIntermediateDirectories: true, attributes: nil)

let filename = outputDirectory.appendingPathComponent("test.txt")

try str.write(to: filename, atomically: true, encoding: String.Encoding.utf8)

} catch {
print("error on create test file")
}
// Create the send message view to contain one of the two send buttons
let sendMessageView = SendMessageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
sendMessageView.translatesAutoresizingMaskIntoConstraints = false
Expand Down
19 changes: 19 additions & 0 deletions test_projects/ios/FlankExample/FlankExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,28 @@ import UIKit

class ViewController: UIViewController {

func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.


let str = "viewLoaded"
let outputDirectory = getDocumentsDirectory().appendingPathComponent("output")

do {
try FileManager.default.createDirectory(atPath: outputDirectory.path, withIntermediateDirectories: true, attributes: nil)
let filename = outputDirectory.appendingPathComponent("test.txt")

try str.write(to: filename, atomically: true, encoding: String.Encoding.utf8)

} catch {
print("error on create test file")
}
}
}

6 changes: 6 additions & 0 deletions test_runner/flank.ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ gcloud:
# locale: es_ES
# orientation: landscape

## A list of paths that will be copied from the device's storage to the designated results bucket after the test
## is complete. These must be absolute paths under /private/var/mobile/Media or /Documents
## of the app under test. If the path is under an app's /Documents, it must be prefixed with the app's bundle id and a colon
# directories-to-pull:
# - /private/var/mobile/Media

## A list of device-path=file-path pairs that specify the paths of the test device and the files you want pushed to the device prior to testing.
## Device paths should either be under the Media shared folder (e.g. prefixed with /private/var/mobile/Media) or
## within the documents directory of the filesystem of an app under test (e.g. /Documents). Device paths to app
Expand Down
1 change: 0 additions & 1 deletion test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ data class AndroidArgs(
val roboDirectives: List<FlankRoboDirective>,
val roboScript: String?,
val environmentVariables: Map<String, String>, // should not be printed, becuase could contains sensitive informations
val directoriesToPull: List<String>,
val grantPermissions: String?,
val scenarioLabels: List<String>,
val obbFiles: List<String>,
Expand Down
1 change: 1 addition & 0 deletions test_runner/src/main/kotlin/ftl/args/CommonArgs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ data class CommonArgs(
override val networkProfile: String?,
override val otherFiles: Map<String, String>,
override val type: Type?,
override val directoriesToPull: List<String>,
override val scenarioNumbers: List<String>,

// flank
Expand Down
1 change: 0 additions & 1 deletion test_runner/src/main/kotlin/ftl/args/CreateAndroidArgs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ fun createAndroidArgs(
performanceMetrics = gcloud.performanceMetrics!!,
numUniformShards = gcloud.numUniformShards,
environmentVariables = gcloud.environmentVariables!!,
directoriesToPull = gcloud.directoriesToPull!!,
autoGoogleLogin = gcloud.autoGoogleLogin!!,
additionalApks = gcloud.additionalApks!!.map { it.normalizeFilePath() },
roboScript = gcloud.roboScript?.normalizeFilePath(),
Expand Down
1 change: 1 addition & 0 deletions test_runner/src/main/kotlin/ftl/args/CreateCommonArgs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fun CommonConfig.createCommonArgs(
flakyTestAttempts = gcloud.flakyTestAttempts!!,
networkProfile = gcloud.networkProfile,
clientDetails = gcloud.clientDetails,
directoriesToPull = gcloud.directoriesToPull!!,
otherFiles = gcloud.otherFiles!!.mapValues { (_, path) -> path.normalizeFilePath() },
scenarioNumbers = gcloud.scenarioNumbers!!,
type = gcloud.type?.toType(),
Expand Down
1 change: 1 addition & 0 deletions test_runner/src/main/kotlin/ftl/args/IArgs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface IArgs {
val otherFiles: Map<String, String>
val scenarioNumbers: List<String>
val type: Type? get() = null
val directoriesToPull: List<String>

// FlankYml
val maxTestShards: Int
Expand Down
1 change: 1 addition & 0 deletions test_runner/src/main/kotlin/ftl/args/IosArgs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ IosArgs
xcode-version: $xcodeVersion
device:${ArgsToString.objectsToString(devices)}
num-flaky-test-attempts: $flakyTestAttempts
directories-to-pull: ${ArgsToString.listToString(directoriesToPull)}
other-files: ${ArgsToString.mapToString(otherFiles)}
additional-ipas: ${ArgsToString.listToString(additionalIpas)}
scenario-numbers: ${ArgsToString.listToString(scenarioNumbers)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,6 @@ data class AndroidGcloudConfig @JsonIgnore constructor(
@set:JsonProperty("grant-permissions")
var grantPermissions: String? by data

@set:CommandLine.Option(
names = ["--directories-to-pull"],
split = ",",
description = ["A list of paths that will be copied from the device's " +
"storage to the designated results bucket after the test is complete. These must be absolute paths under " +
"/sdcard or /data/local/tmp (for example, --directories-to-pull /sdcard/tempDir1,/data/local/tmp/tempDir2). " +
"Path names are restricted to the characters a-zA-Z0-9_-./+. The paths /sdcard and /data will be made available " +
"and treated as implicit path substitutions. E.g. if /sdcard on a particular device does not map to external " +
"storage, the system will replace it with the external storage path prefix for that device."]
)
@set:JsonProperty("directories-to-pull")
var directoriesToPull: List<String>? by data

@set:CommandLine.Option(
names = ["--scenario-labels"],
split = ",",
Expand Down Expand Up @@ -239,7 +226,6 @@ data class AndroidGcloudConfig @JsonIgnore constructor(
useOrchestrator = true
environmentVariables = emptyMap()
grantPermissions = FlankDefaults.GRANT_PERMISSIONS_ALL
directoriesToPull = emptyList()
scenarioLabels = emptyList()
obbfiles = emptyList()
obbnames = emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ data class CommonGcloudConfig @JsonIgnore constructor(
@set:JsonProperty("num-flaky-test-attempts")
var flakyTestAttempts: Int? by data

@set:CommandLine.Option(
names = ["--directories-to-pull"],
split = ",",
description = ["A list of paths that will be copied from the device's " +
"storage to the designated results bucket after the test is complete. For Android devices these must be absolute paths under " +
"/sdcard or /data/local/tmp (for example, --directories-to-pull /sdcard/tempDir1,/data/local/tmp/tempDir2). " +
"Path names are restricted to the characters a-zA-Z0-9_-./+. The paths /sdcard and /data will be made available " +
"and treated as implicit path substitutions. E.g. if /sdcard on a particular device does not map to external " +
"storage, the system will replace it with the external storage path prefix for that device. " +
"For iOS devices these must be absolute paths under /private/var/mobile/Media or /Documents " +
"of the app under test. If the path is under an app's /Documents, it must be prefixed with the app's bundle id and a colon"]
)
@set:JsonProperty("directories-to-pull")
var directoriesToPull: List<String>? by data

@set:CommandLine.Option(
names = ["--other-files"],
split = ",",
Expand Down Expand Up @@ -170,6 +185,7 @@ data class CommonGcloudConfig @JsonIgnore constructor(
clientDetails = null
networkProfile = null
devices = listOf(defaultDevice(android))
directoriesToPull = emptyList()
otherFiles = emptyMap()
type = null
scenarioNumbers = emptyList()
Expand Down
4 changes: 4 additions & 0 deletions test_runner/src/main/kotlin/ftl/gc/GcIosTestMatrix.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.google.api.services.testing.model.ToolResultsHistory
import ftl.args.IosArgs
import ftl.gc.android.mapGcsPathsToFileReference
import ftl.gc.android.mapToIosDeviceFiles
import ftl.gc.android.toIosDeviceFile
import ftl.ios.Xctestrun
import ftl.ios.Xctestrun.toByteArray
import ftl.run.exception.FlankGeneralError
Expand Down Expand Up @@ -69,6 +70,7 @@ object GcIosTestMatrix {
.setNetworkProfile(args.networkProfile)
.setPushFiles(otherFiles.mapToIosDeviceFiles())
.setAdditionalIpas(additionalIpasGcsPaths.mapGcsPathsToFileReference())
.setPullDirectories(args.directoriesToPull.toIosDeviceFiles())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, for android we pass a list of strings... and the field itself is named differently directoriesToPull 😸

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

google API is full of surprises


val testTimeoutSeconds = timeoutToSeconds(args.testTimeout)

Expand Down Expand Up @@ -98,3 +100,5 @@ object GcIosTestMatrix {
}
}
}

private fun List<String>.toIosDeviceFiles() = map { path -> toIosDeviceFile(path) }
23 changes: 11 additions & 12 deletions test_runner/src/main/kotlin/ftl/gc/android/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,15 @@ internal fun Map<String, String>.mapToDeviceObbFiles(obbnames: List<String>): Li
}
}

internal fun Map<String, String>.mapToIosDeviceFiles(): List<IosDeviceFile> =
map { (testDevicePath, gcsFilePath) ->
IosDeviceFile().apply {
if (testDevicePath.contains(":")) {
val (bundleIdSeparated, pathSeparated) = testDevicePath.split(":")
bundleId = bundleIdSeparated
devicePath = pathSeparated
} else {
devicePath = testDevicePath
}
content = FileReference().setGcsPath(gcsFilePath)
}
internal fun Map<String, String>.mapToIosDeviceFiles(): List<IosDeviceFile> = map { (testDevicePath, gcsFilePath) -> toIosDeviceFile(testDevicePath, gcsFilePath) }

internal fun toIosDeviceFile(testDevicePath: String, gcsFilePath: String = "") = IosDeviceFile().apply {
if (testDevicePath.contains(":")) {
val (bundleIdSeparated, pathSeparated) = testDevicePath.split(":")
bundleId = bundleIdSeparated
devicePath = pathSeparated
} else {
devicePath = testDevicePath
}
content = FileReference().setGcsPath(gcsFilePath)
}
2 changes: 2 additions & 0 deletions test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ IosArgs
locale: c
orientation: default
num-flaky-test-attempts: 4
directories-to-pull:
other-files:
com.my.app:/Documents/file.txt: local/file.txt
/private/var/mobile/Media/file.jpg: gs://bucket/file.jpg
Expand Down Expand Up @@ -300,6 +301,7 @@ IosArgs
locale: en
orientation: portrait
num-flaky-test-attempts: 0
directories-to-pull:
other-files:
additional-ipas:
scenario-numbers:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ class AndroidRunCommandTest {
assertThat(cmd.config.platform.gcloud.numUniformShards).isNull()
assertThat(cmd.config.platform.gcloud.testRunnerClass).isNull()
assertThat(cmd.config.platform.gcloud.environmentVariables).isNull()
assertThat(cmd.config.platform.gcloud.directoriesToPull).isNull()
assertThat(cmd.config.common.gcloud.otherFiles).isNull()
assertThat(cmd.config.common.gcloud.devices).isNull()
assertThat(cmd.config.common.gcloud.resultsBucket).isNull()
Expand All @@ -98,6 +97,7 @@ class AndroidRunCommandTest {
assertThat(cmd.config.common.flank.filesToDownload).isNull()
assertThat(cmd.config.common.gcloud.resultsDir).isNull()
assertThat(cmd.config.common.gcloud.flakyTestAttempts).isNull()
assertThat(cmd.config.common.gcloud.directoriesToPull).isNull()
assertThat(cmd.config.common.flank.disableSharding).isNull()
assertThat(cmd.config.common.flank.localResultsDir).isNull()
assertThat(cmd.config.common.flank.smartFlankDisableUpload).isNull()
Expand Down Expand Up @@ -219,7 +219,7 @@ class AndroidRunCommandTest {
val cmd = AndroidRunCommand()
CommandLine(cmd).parseArgs("--directories-to-pull=a,b")

assertThat(cmd.config.platform.gcloud.directoriesToPull).hasSize(2)
assertThat(cmd.config.common.gcloud.directoriesToPull).hasSize(2)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class IosRunCommandTest {
assertThat(cmd.config.common.gcloud.devices).isNull()
assertThat(cmd.config.common.gcloud.resultsDir).isNull()
assertThat(cmd.config.common.gcloud.flakyTestAttempts).isNull()
assertThat(cmd.config.common.gcloud.directoriesToPull).isNull()
assertThat(cmd.config.common.flank.localResultsDir).isNull()
assertThat(cmd.config.common.flank.smartFlankDisableUpload).isNull()
assertThat(cmd.config.common.flank.smartFlankGcsPath).isNull()
Expand Down
30 changes: 29 additions & 1 deletion test_runner/src/test/kotlin/ftl/gc/GcIosTestMatrixTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package ftl.gc

import com.dd.plist.NSDictionary
import com.google.api.services.testing.model.IosDeviceList
import ftl.shard.Chunk
import ftl.args.IosArgs
import ftl.config.FtlConstants.isWindows
import ftl.ios.FIXTURES_PATH
import ftl.shard.Chunk
import ftl.shard.TestMethod
import ftl.test.util.FlankTestRunner
import ftl.util.ShardCounter
Expand Down Expand Up @@ -165,4 +165,32 @@ class GcIosTestMatrixTest {
val expected = emptyList<String>()
assertEquals(expected, iosArgs.additionalIpas)
}

@Test
fun `should fill directoriesToPull`() {
val iosArgs = IosArgs.load(StringReader("""
gcloud:
test: ./test_runner/src/test/kotlin/ftl/fixtures/tmp/earlgrey_example.zip
xctestrun-file: ./test_runner/src/test/kotlin/ftl/fixtures/tmp/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun
results-dir: test_dir
directories-to-pull:
- test/test/test
""".trimIndent()))

val expected = listOf("test/test/test")
assertEquals(expected, iosArgs.directoriesToPull)
}

@Test
fun `should not fill directoriesToPull`() {
val iosArgs = IosArgs.load(StringReader("""
gcloud:
test: ./test_runner/src/test/kotlin/ftl/fixtures/tmp/earlgrey_example.zip
xctestrun-file: ./test_runner/src/test/kotlin/ftl/fixtures/tmp/EarlGreyExampleSwiftTests_iphoneos13.4-arm64e.xctestrun
results-dir: test_dir
""".trimIndent()))

val expected = emptyList<String>()
assertEquals(expected, iosArgs.directoriesToPull)
}
}