diff --git a/release_notes.md b/release_notes.md index 13283447cb..92ff8190a2 100644 --- a/release_notes.md +++ b/release_notes.md @@ -2,6 +2,7 @@ - [#890](https://github.com/Flank/flank/pull/890) Convert bitrise ubuntu workflow into GitHub actions. ([piotradamczyk5](https://github.com/piotradamczyk5)) - [#876](https://github.com/Flank/flank/pull/876) Added option to print Android available devices to test against. ([piotradamczyk5](https://github.com/piotradamczyk5)) - [#895](https://github.com/Flank/flank/pull/895) Added option to print iOS available devices to test against. ([piotradamczyk5](https://github.com/piotradamczyk5)) +- [#894](https://github.com/Flank/flank/pull/894) Added option to print Android available versions to test against. ([piotradamczyk5](https://github.com/piotradamczyk5)) - [#897](https://github.com/Flank/flank/pull/897) Added option to print iOS available versions to test against. ([piotradamczyk5](https://github.com/piotradamczyk5)) - - diff --git a/test_runner/docs/ascii/flank.jar_-android.adoc b/test_runner/docs/ascii/flank.jar_-android.adoc index 0b71db91c3..3a4ea33840 100644 --- a/test_runner/docs/ascii/flank.jar_-android.adoc +++ b/test_runner/docs/ascii/flank.jar_-android.adoc @@ -35,6 +35,9 @@ flank.jar *models*:: Information about available models +*versions*:: + Information about available software versions + // end::picocli-generated-man-section-commands[] // end::picocli-generated-full-manpage[] \ No newline at end of file diff --git a/test_runner/docs/ascii/flank.jar_-firebase-test-android.adoc b/test_runner/docs/ascii/flank.jar_-firebase-test-android.adoc index dab0bb11f4..638d7e2c95 100644 --- a/test_runner/docs/ascii/flank.jar_-firebase-test-android.adoc +++ b/test_runner/docs/ascii/flank.jar_-firebase-test-android.adoc @@ -35,6 +35,9 @@ flank.jar *models*:: Information about available models +*versions*:: + Information about available software versions + // end::picocli-generated-man-section-commands[] // end::picocli-generated-full-manpage[] \ No newline at end of file diff --git a/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt b/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt index 2e7a3228d0..84e4001f32 100644 --- a/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt +++ b/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt @@ -25,6 +25,8 @@ object AndroidCatalog { 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/AndroidCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/AndroidCommand.kt index 249bfbb3b4..92994ceaba 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/AndroidCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/AndroidCommand.kt @@ -3,6 +3,7 @@ package ftl.cli.firebase.test import ftl.cli.firebase.test.android.AndroidDoctorCommand import ftl.cli.firebase.test.android.AndroidRunCommand import ftl.cli.firebase.test.android.models.AndroidModelsCommand +import ftl.cli.firebase.test.android.versions.AndroidVersionsCommand import picocli.CommandLine import picocli.CommandLine.Command @@ -12,7 +13,8 @@ import picocli.CommandLine.Command subcommands = [ AndroidRunCommand::class, AndroidDoctorCommand::class, - AndroidModelsCommand::class + AndroidModelsCommand::class, + AndroidVersionsCommand::class ], usageHelpAutoWidth = true ) diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsCommand.kt new file mode 100644 index 0000000000..efc3c7e0a2 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsCommand.kt @@ -0,0 +1,21 @@ +package ftl.cli.firebase.test.android.versions + +import picocli.CommandLine + +@CommandLine.Command( + name = "versions", + headerHeading = "", + synopsisHeading = "%n", + descriptionHeading = "%n@|bold,underline Description:|@%n%n", + parameterListHeading = "%n@|bold,underline Parameters:|@%n", + optionListHeading = "%n@|bold,underline Options:|@%n", + header = ["Information about available software versions"], + description = ["Information about available software versions. For example prints list of available software versions"], + subcommands = [AndroidVersionsListCommand::class], + usageHelpAutoWidth = true +) +class AndroidVersionsCommand : Runnable { + override fun run() { + CommandLine.usage(AndroidVersionsCommand(), System.out) + } +} diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsListCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsListCommand.kt new file mode 100644 index 0000000000..b596788699 --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsListCommand.kt @@ -0,0 +1,30 @@ +package ftl.cli.firebase.test.android.versions + +import ftl.android.AndroidCatalog.supportedVersionsAsTable +import ftl.args.AndroidArgs +import ftl.config.FtlConstants +import picocli.CommandLine +import java.nio.file.Paths + +@CommandLine.Command( + name = "list", + headerHeading = "", + synopsisHeading = "%n", + descriptionHeading = "%n@|bold,underline Description:|@%n%n", + parameterListHeading = "%n@|bold,underline Parameters:|@%n", + optionListHeading = "%n@|bold,underline Options:|@%n", + header = ["List of OS versions available to test against"], + description = ["Print current list of Android OS versions available to test against"], + usageHelpAutoWidth = true +) +class AndroidVersionsListCommand : Runnable { + override fun run() { + println(supportedVersionsAsTable(AndroidArgs.load(Paths.get(configPath)).project)) + } + + @CommandLine.Option(names = ["-c", "--config"], description = ["YAML config file path"]) + var configPath: String = FtlConstants.defaultAndroidConfig + + @CommandLine.Option(names = ["-h", "--help"], usageHelp = true, description = ["Prints this help message"]) + var usageHelpRequested: Boolean = false +} 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..4e0e85313f --- /dev/null +++ b/test_runner/src/main/kotlin/ftl/environment/ListAndroidSofwareVersions.kt @@ -0,0 +1,39 @@ +package ftl.environment + +import com.google.api.services.testing.model.AndroidVersion +import com.google.api.services.testing.model.Date +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.orUnknown()) + getOrCreateList(VERSION).add(softwareVersion.versionString.orUnknown()) + getOrCreateList(CODE_NAME).add(softwareVersion.codeName.orUnknown()) + getOrCreateList(API_LEVEL).add(softwareVersion.apiLevel?.toString().orUnknown()) + getOrCreateList(RELEASE_DATE).add(softwareVersion.releaseDate.printableReleaseDate()) + getOrCreateList(TAGS).add(softwareVersion.tags.orEmpty().joinToString()) + } + } + +private fun Date?.printableReleaseDate() = + if (this == null || year == null || month == null || day == null) "UNKNOWN" + else "$year-${month.twoDigitString()}-${day.twoDigitString()}" + +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/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/ftl/android/AndroidCatalogTest.kt b/test_runner/src/test/kotlin/ftl/android/AndroidCatalogTest.kt index c3b46ae3e8..0b5fffb274 100644 --- a/test_runner/src/test/kotlin/ftl/android/AndroidCatalogTest.kt +++ b/test_runner/src/test/kotlin/ftl/android/AndroidCatalogTest.kt @@ -67,4 +67,44 @@ class AndroidCatalogTest { brokenModel.androidModelId = "brokenModel" assertFalse(AndroidCatalog.isVirtualDevice(brokenModel, projectId)) } + + @Test + fun `should print available devices as table`() { + // given + val expectedHeaders = + arrayOf("MODEL_ID", "MAKE", "MODEL_NAME", "FORM", "RESOLUTION", "OS_VERSION_IDS", "TAGS") + val expectedSeparatorCount = expectedHeaders.size + 1 + + // when + val devicesTable = AndroidCatalog.devicesCatalogAsTable(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) + } + + @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/models/AndroidModelsListCommandTest.kt b/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/models/AndroidModelsListCommandTest.kt index 959301174e..82adef78dd 100644 --- a/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/models/AndroidModelsListCommandTest.kt +++ b/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/models/AndroidModelsListCommandTest.kt @@ -1,24 +1,11 @@ package ftl.cli.firebase.test.android.models import com.google.common.truth.Truth.assertThat -import ftl.config.FtlConstants import org.junit.Test import picocli.CommandLine class AndroidModelsListCommandTest { - @Test - fun androidModelsListCommandOptions() { - val cmd = AndroidModelsListCommand() - assertThat(cmd.configPath).isEqualTo(FtlConstants.defaultAndroidConfig) - cmd.configPath = "tmp" - assertThat(cmd.configPath).isEqualTo("tmp") - - assertThat(cmd.usageHelpRequested).isFalse() - cmd.usageHelpRequested = true - assertThat(cmd.usageHelpRequested).isTrue() - } - @Test fun androidModelsListCommandShouldParseConfig() { val cmd = AndroidModelsListCommand() diff --git a/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsListCommandTest.kt b/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsListCommandTest.kt new file mode 100644 index 0000000000..04cb02736f --- /dev/null +++ b/test_runner/src/test/kotlin/ftl/cli/firebase/test/android/versions/AndroidVersionsListCommandTest.kt @@ -0,0 +1,16 @@ +package ftl.cli.firebase.test.android.versions + +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import picocli.CommandLine + +class AndroidVersionsListCommandTest { + + @Test + fun androidVersionsListCommandShouldParseConfig() { + val cmd = AndroidVersionsListCommand() + CommandLine(cmd).parseArgs("--config=a") + + assertThat(cmd.configPath).isEqualTo("a") + } +} 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) + } +}