diff --git a/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt b/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt index fe1533c12b..84e4001f32 100644 --- a/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt +++ b/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt @@ -23,7 +23,9 @@ object AndroidCatalog { .androidDeviceCatalog } - fun devicesCatalogAsTable(projectId: String) = deviceCatalog(projectId).asPrintableTable() + fun devicesCatalogAsTable(projectId: String) = deviceCatalog(projectId).models.asPrintableTable() + + fun supportedVersionsAsTable(projectId: String) = deviceCatalog(projectId).versions.asPrintableTable() fun androidModelIds(projectId: String) = modelMap.getOrPut(projectId) { deviceCatalog(projectId).models.map { it.id } } diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/CommonRunCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/CommonRunCommand.kt index 4f779e6410..d2d3370343 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/CommonRunCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/CommonRunCommand.kt @@ -56,4 +56,14 @@ abstract class CommonRunCommand { names = ["--available-devices"], description = ["Print available devices list"]) var printAvailableDevices: Boolean = false + + @CommandLine.Option( + names = ["--available-software-versions"], + description = ["Print available software versions list"]) + var printAvailableSoftwareVersions: Boolean = false + + @CommandLine.Option( + names = ["--available-environment"], + description = ["Print available devices and software versions list"]) + var printAvailableEnvironment: Boolean = false } diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt index 91871e1b24..648e3141d4 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt @@ -1,6 +1,7 @@ package ftl.cli.firebase.test.android import ftl.android.AndroidCatalog.devicesCatalogAsTable +import ftl.android.AndroidCatalog.supportedVersionsAsTable import ftl.args.AndroidArgs import ftl.cli.firebase.test.CommonRunCommand import ftl.config.FtlConstants @@ -49,7 +50,12 @@ class AndroidRunCommand : CommonRunCommand(), Runnable { runBlocking { when { dumpShards -> dumpShards(args = config, obfuscatedOutput = obfuscate) + printAvailableEnvironment -> { + println(devicesCatalogAsTable(config.project)) + println(supportedVersionsAsTable(config.project)) + } printAvailableDevices -> println(devicesCatalogAsTable(config.project)) + printAvailableSoftwareVersions -> println(supportedVersionsAsTable(config.project)) else -> newTestRun(config) } } diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt index 233f34b537..2ead8df68c 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt @@ -5,6 +5,7 @@ import ftl.cli.firebase.test.CommonRunCommand import ftl.config.FtlConstants import ftl.config.emptyIosConfig import ftl.ios.IosCatalog.devicesCatalogAsTable +import ftl.ios.IosCatalog.softwareVersionsAsTable import ftl.mock.MockServer import ftl.run.IOS_SHARD_FILE import ftl.run.dumpShards @@ -48,7 +49,12 @@ class IosRunCommand : CommonRunCommand(), Runnable { when { dumpShards -> dumpShards(args = config, obfuscatedOutput = obfuscate) + printAvailableEnvironment -> { + println(devicesCatalogAsTable(config.project)) + println(softwareVersionsAsTable(config.project)) + } printAvailableDevices -> println(devicesCatalogAsTable(config.project)) + printAvailableSoftwareVersions -> println(softwareVersionsAsTable(config.project)) else -> runBlocking { newTestRun(config) } } } diff --git a/test_runner/src/main/kotlin/ftl/environment/ListAndroidDevices.kt b/test_runner/src/main/kotlin/ftl/environment/ListAndroidDevices.kt index 21cb428c9a..12cfe92225 100644 --- a/test_runner/src/main/kotlin/ftl/environment/ListAndroidDevices.kt +++ b/test_runner/src/main/kotlin/ftl/environment/ListAndroidDevices.kt @@ -1,26 +1,26 @@ package ftl.environment -import com.google.api.services.testing.model.AndroidDeviceCatalog +import com.google.api.services.testing.model.AndroidModel import ftl.util.SystemOutColor import ftl.util.applyColorsUsing import ftl.util.buildTable -fun AndroidDeviceCatalog.asPrintableTable() = - models - .fold(mutableMapOf>()) { devicesInfo, androidDevice -> - devicesInfo.apply { - getOrCreateList(MODEL_ID).add(androidDevice.codename) - getOrCreateList(MAKE).add(androidDevice.manufacturer) - getOrCreateList(MODEL_NAME).add(androidDevice.name) - getOrCreateList(FORM).add(androidDevice.form) - getOrCreateList(RESOLUTION).add("${androidDevice.screenY} x ${androidDevice.screenX}") - getOrCreateList(OS_VERSION_IDS).add(androidDevice.supportedVersionIds?.joinToString().orEmpty()) - getOrCreateList(TAGS).add(androidDevice.tags?.joinToString().orEmpty()) - } +fun List.asPrintableTable() = createTestEnvironmentInfo().createAndroidDevicesTable() + +private fun List.createTestEnvironmentInfo() = + fold(mutableMapOf>()) { devicesInfo, androidDevice -> + devicesInfo.apply { + getOrCreateList(MODEL_ID).add(androidDevice.codename) + getOrCreateList(MAKE).add(androidDevice.manufacturer) + getOrCreateList(MODEL_NAME).add(androidDevice.name) + getOrCreateList(FORM).add(androidDevice.form) + getOrCreateList(RESOLUTION).add("${androidDevice.screenY} x ${androidDevice.screenX}") + getOrCreateList(OS_VERSION_IDS).add(androidDevice.supportedVersionIds?.joinToString().orEmpty()) + getOrCreateList(TAGS).add(androidDevice.tags?.joinToString().orEmpty()) } - .createAndroidDevicesTable() + } -private fun DevicesInfo.createAndroidDevicesTable() = buildTable( +private fun TestEnvironmentInfo.createAndroidDevicesTable() = buildTable( createTableColumnFor(MODEL_ID), createTableColumnFor(MAKE), createTableColumnFor(MODEL_NAME), diff --git a/test_runner/src/main/kotlin/ftl/environment/ListAndroidSofwareVersions.kt b/test_runner/src/main/kotlin/ftl/environment/ListAndroidSofwareVersions.kt new file mode 100644 index 0000000000..502782732e --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/environment/ListAndroidSofwareVersions.kt @@ -0,0 +1,34 @@ +package ftl.environment + +import com.google.api.services.testing.model.AndroidVersion +import ftl.reports.api.twoDigitString +import ftl.util.applyColorsUsing +import ftl.util.buildTable + +fun List.asPrintableTable() = createTestEnvironmentInfo().createAndroidSoftwareVersionsTable() + +private fun List.createTestEnvironmentInfo() = + fold(mutableMapOf>()) { softwareInfo, softwareVersion -> + softwareInfo.apply { + getOrCreateList(OS_VERSION_ID).add(softwareVersion.id) + getOrCreateList(VERSION).add(softwareVersion.versionString) + getOrCreateList(CODE_NAME).add(softwareVersion.codeName) + getOrCreateList(API_LEVEL).add(softwareVersion.apiLevel.toString()) + getOrCreateList(RELEASE_DATE).add(with(softwareVersion.releaseDate) { "$year-${month.twoDigitString()}-${day.twoDigitString()}" }) + getOrCreateList(TAGS).add(softwareVersion.tags.orEmpty().joinToString()) + } + } + +private fun TestEnvironmentInfo.createAndroidSoftwareVersionsTable() = buildTable( + createTableColumnFor(OS_VERSION_ID), + createTableColumnFor(VERSION), + createTableColumnFor(CODE_NAME), + createTableColumnFor(API_LEVEL), + createTableColumnFor(RELEASE_DATE), + createTableColumnFor(TAGS).applyColorsUsing(tagToSystemOutColorMapper) +) + +const val VERSION = "VERSION" +const val CODE_NAME = "CODE_NAME" +const val API_LEVEL = "API_LEVEL" +const val RELEASE_DATE = "RELEASE_DATE" diff --git a/test_runner/src/main/kotlin/ftl/environment/ListIOsDevices.kt b/test_runner/src/main/kotlin/ftl/environment/ListIOsDevices.kt index b3277423cc..09a79a1fce 100644 --- a/test_runner/src/main/kotlin/ftl/environment/ListIOsDevices.kt +++ b/test_runner/src/main/kotlin/ftl/environment/ListIOsDevices.kt @@ -1,23 +1,23 @@ package ftl.environment -import com.google.api.services.testing.model.IosDeviceCatalog +import com.google.api.services.testing.model.IosModel import ftl.util.applyColorsUsing import ftl.util.buildTable -fun IosDeviceCatalog.asPrintableTable() = - models - .fold(mutableMapOf>()) { deviceInfo, iOsDevice -> - deviceInfo.apply { - getOrCreateList(MODEL_ID).add(iOsDevice.id) - getOrCreateList(MODEL_NAME).add(iOsDevice.name) - getOrCreateList(RESOLUTION).add("${iOsDevice.screenY} x ${iOsDevice.screenX}") - getOrCreateList(OS_VERSION_IDS).add(iOsDevice.supportedVersionIds?.joinToString().orEmpty()) - getOrCreateList(TAGS).add(iOsDevice.tags?.joinToString().orEmpty()) - } +fun List.asPrintableTable() = createTestEnvironmentInfo().createIoDevicesTable() + +fun List.createTestEnvironmentInfo() = + fold(mutableMapOf>()) { deviceInfo, iOsDevice -> + deviceInfo.apply { + getOrCreateList(MODEL_ID).add(iOsDevice.id) + getOrCreateList(MODEL_NAME).add(iOsDevice.name) + getOrCreateList(RESOLUTION).add("${iOsDevice.screenY} x ${iOsDevice.screenX}") + getOrCreateList(OS_VERSION_IDS).add(iOsDevice.supportedVersionIds?.joinToString().orEmpty()) + getOrCreateList(TAGS).add(iOsDevice.tags?.joinToString().orEmpty()) } - .createIoDevicesTable() + } -private fun DevicesInfo.createIoDevicesTable() = buildTable( +private fun TestEnvironmentInfo.createIoDevicesTable() = buildTable( createTableColumnFor(MODEL_ID), createTableColumnFor(MODEL_NAME), createTableColumnFor(RESOLUTION), diff --git a/test_runner/src/main/kotlin/ftl/environment/ListIOsSofwareVersions.kt b/test_runner/src/main/kotlin/ftl/environment/ListIOsSofwareVersions.kt new file mode 100644 index 0000000000..35f347f12c --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/environment/ListIOsSofwareVersions.kt @@ -0,0 +1,30 @@ +package ftl.environment + +import com.google.api.services.testing.model.IosVersion +import ftl.util.applyColorsUsing +import ftl.util.buildTable + +fun List.asPrintableTable() = createTestEnvironmentInfo().createIOsSoftwareVersionsTable() + +private fun List.createTestEnvironmentInfo() = + fold(mutableMapOf>()) { softwareInfo, softwareVersion -> + softwareInfo.apply { + getOrCreateList(OS_VERSION_ID).add(softwareVersion.id) + getOrCreateList(MAJOR_VERSION).add(softwareVersion.majorVersion?.toString().orEmpty()) + getOrCreateList(MINOR_VERSION).add(softwareVersion.minorVersion?.toString().orEmpty()) + getOrCreateList(TAGS).add(softwareVersion.tags.orEmpty().joinToString()) + getOrCreateList(SUPPORTED_XCODE_VERSION_IDS).add(softwareVersion.supportedXcodeVersionIds.joinToString()) + } + } + +private fun TestEnvironmentInfo.createIOsSoftwareVersionsTable() = buildTable( + createTableColumnFor(OS_VERSION_ID), + createTableColumnFor(MAJOR_VERSION), + createTableColumnFor(MINOR_VERSION), + createTableColumnFor(TAGS).applyColorsUsing(tagToSystemOutColorMapper), + createTableColumnFor(SUPPORTED_XCODE_VERSION_IDS) +) + +private const val MAJOR_VERSION = "MAJOR_VERSION" +private const val MINOR_VERSION = "MINOR_VERSION" +private const val SUPPORTED_XCODE_VERSION_IDS = "SUPPORTED_XCODE_VERSION_IDS" diff --git a/test_runner/src/main/kotlin/ftl/environment/ListDevices.kt b/test_runner/src/main/kotlin/ftl/environment/TestEnvironmentInfo.kt similarity index 66% rename from test_runner/src/main/kotlin/ftl/environment/ListDevices.kt rename to test_runner/src/main/kotlin/ftl/environment/TestEnvironmentInfo.kt index 91e96d61db..a342197021 100644 --- a/test_runner/src/main/kotlin/ftl/environment/ListDevices.kt +++ b/test_runner/src/main/kotlin/ftl/environment/TestEnvironmentInfo.kt @@ -3,11 +3,11 @@ package ftl.environment import ftl.util.SystemOutColor import ftl.util.TableColumn -typealias DevicesInfo = MutableMap> +typealias TestEnvironmentInfo = MutableMap> -internal fun DevicesInfo.getOrCreateList(key: String) = getOrPut(key) { mutableListOf() } +internal fun TestEnvironmentInfo.getOrCreateList(key: String) = getOrPut(key) { mutableListOf() } -internal fun DevicesInfo.createTableColumnFor(key: String) = TableColumn(key, getValue(key)) +internal fun TestEnvironmentInfo.createTableColumnFor(key: String) = TableColumn(key, getValue(key)) internal val tagToSystemOutColorMapper: (String) -> SystemOutColor = { when { @@ -26,3 +26,5 @@ const val RESOLUTION = "RESOLUTION" const val OS_VERSION_IDS = "OS_VERSION_IDS" const val TAGS = "TAGS" const val PHYSICAL_DEVICE = "PHYSICAL" + +const val OS_VERSION_ID = "OS_VERSION_ID" diff --git a/test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt b/test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt index 3bcbc38e2a..a4b58418d7 100644 --- a/test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt +++ b/test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt @@ -14,7 +14,9 @@ object IosCatalog { private val catalogMap: MutableMap = mutableMapOf() private val xcodeMap: MutableMap> = mutableMapOf() - fun devicesCatalogAsTable(projectId: String) = iosDeviceCatalog(projectId).asPrintableTable() + fun devicesCatalogAsTable(projectId: String) = iosDeviceCatalog(projectId).models.asPrintableTable() + + fun softwareVersionsAsTable(projectId: String) = iosDeviceCatalog(projectId).versions.asPrintableTable() fun supportedXcode(version: String, projectId: String) = xcodeVersions(projectId).contains(version) diff --git a/test_runner/src/main/kotlin/ftl/reports/api/Utils.kt b/test_runner/src/main/kotlin/ftl/reports/api/Utils.kt index f20c9f139e..9d00ad41a0 100644 --- a/test_runner/src/main/kotlin/ftl/reports/api/Utils.kt +++ b/test_runner/src/main/kotlin/ftl/reports/api/Utils.kt @@ -12,6 +12,8 @@ internal fun Double.format(): String = "%.3f".format(Locale.ROOT, this) internal fun Int?.format() = (this ?: 0).toString() +internal fun Int.twoDigitString() = toString().padStart(2, '0') + internal fun Duration?.millis(): Double = if (this == null) 0.0 else diff --git a/test_runner/src/test/kotlin/Debug.kt b/test_runner/src/test/kotlin/Debug.kt index d87dbd4904..a7ad6ba9d8 100644 --- a/test_runner/src/test/kotlin/Debug.kt +++ b/test_runner/src/test/kotlin/Debug.kt @@ -20,6 +20,9 @@ fun main() { // "--debug", "firebase", "test", "android", "run", +// "--available-devices", +// "--available-software-versions", +// "--available-environment", // "--dry", // "--dump-shards", "--output-style=single", diff --git a/test_runner/src/test/kotlin/ftl/android/AndroidCatalogTest.kt b/test_runner/src/test/kotlin/ftl/android/AndroidCatalogTest.kt index 960053bb57..0b5fffb274 100644 --- a/test_runner/src/test/kotlin/ftl/android/AndroidCatalogTest.kt +++ b/test_runner/src/test/kotlin/ftl/android/AndroidCatalogTest.kt @@ -87,4 +87,24 @@ class AndroidCatalogTest { // number of separators match assertThat(headers.count { it == '│' }).isEqualTo(expectedSeparatorCount) } + + @Test + fun `should print available software versions as table`() { + // given + val expectedHeaders = + arrayOf("OS_VERSION_ID", "VERSION", "CODE_NAME", "API_LEVEL", "RELEASE_DATE", "TAGS") + val expectedSeparatorCount = expectedHeaders.size + 1 + + // when + val devicesTable = AndroidCatalog.supportedVersionsAsTable(projectId) + val headers = devicesTable.lines()[1] + + // then + // has all necessary headers + expectedHeaders.forEach { + assertThat(headers.contains(it)).isTrue() + } + // number of separators match + assertThat(headers.count { it == '│' }).isEqualTo(expectedSeparatorCount) + } } diff --git a/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/AndroidRunCommandTest.kt b/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/AndroidRunCommandTest.kt index 0a3a402399..8bfd190438 100644 --- a/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/AndroidRunCommandTest.kt +++ b/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/AndroidRunCommandTest.kt @@ -475,4 +475,20 @@ class AndroidRunCommandTest { assertThat(cmd.printAvailableDevices).isTrue() } + + @Test + fun `available software versions parse`() { + val cmd = AndroidRunCommand() + CommandLine(cmd).parseArgs("--available-software-versions") + + assertThat(cmd.printAvailableSoftwareVersions).isTrue() + } + + @Test + fun `available environment parse`() { + val cmd = AndroidRunCommand() + CommandLine(cmd).parseArgs("--available-environment") + + assertThat(cmd.printAvailableEnvironment).isTrue() + } } diff --git a/test_runner/src/test/kotlin/ftl/cli/firebase/test/ios/IosRunCommandTest.kt b/test_runner/src/test/kotlin/ftl/cli/firebase/test/ios/IosRunCommandTest.kt index 1cb1c4b106..af995d4239 100644 --- a/test_runner/src/test/kotlin/ftl/cli/firebase/test/ios/IosRunCommandTest.kt +++ b/test_runner/src/test/kotlin/ftl/cli/firebase/test/ios/IosRunCommandTest.kt @@ -334,4 +334,20 @@ class IosRunCommandTest { assertThat(cmd.printAvailableDevices).isTrue() } + + @Test + fun `available software versions parse`() { + val cmd = IosRunCommand() + CommandLine(cmd).parseArgs("--available-software-versions") + + assertThat(cmd.printAvailableSoftwareVersions).isTrue() + } + + @Test + fun `available environment parse`() { + val cmd = IosRunCommand() + CommandLine(cmd).parseArgs("--available-environment") + + assertThat(cmd.printAvailableEnvironment).isTrue() + } } diff --git a/test_runner/src/test/kotlin/ftl/ios/IosCatalogTest.kt b/test_runner/src/test/kotlin/ftl/ios/IosCatalogTest.kt index d79dca29f8..d2e035a9e1 100644 --- a/test_runner/src/test/kotlin/ftl/ios/IosCatalogTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/IosCatalogTest.kt @@ -41,4 +41,23 @@ class IosCatalogTest { // number of separators match assertThat(headers.count { it == '│' }).isEqualTo(expectedSeparatorCount) } + + @Test + fun `should print available software versions as table`() { + // given + val expectedHeaders = arrayOf("OS_VERSION_ID", "MAJOR_VERSION", "MINOR_VERSION", "TAGS", "SUPPORTED_XCODE_VERSION_IDS") + val expectedSeparatorCount = expectedHeaders.size + 1 + + // when + val devicesTable = IosCatalog.softwareVersionsAsTable(projectId) + val headers = devicesTable.lines()[1] + + // then + // has all necessary headers + expectedHeaders.forEach { + assertThat(headers.contains(it)).isTrue() + } + // number of separators match + assertThat(headers.count { it == '│' }).isEqualTo(expectedSeparatorCount) + } } diff --git a/test_runner/src/test/kotlin/ftl/reports/api/UtilsTest.kt b/test_runner/src/test/kotlin/ftl/reports/api/UtilsTest.kt new file mode 100644 index 0000000000..a38b9ce32c --- /dev/null +++ b/test_runner/src/test/kotlin/ftl/reports/api/UtilsTest.kt @@ -0,0 +1,31 @@ +package ftl.reports.api + +import org.junit.Assert.assertEquals +import org.junit.Test + +class UtilsTest { + + @Test + fun `should add leading 0 to single digit integer`() { + // given + val expectedString = "05" + + // when + val actual = 5.twoDigitString() + + // then + assertEquals(expectedString, actual) + } + + @Test + fun `should not add leading 0 to two digits integer`() { + // given + val expectedString = "15" + + // when + val actual = 15.twoDigitString() + + // then + assertEquals(expectedString, actual) + } +}