Skip to content

Commit

Permalink
Merge branch 'develop' into feature/apple-container-clear
Browse files Browse the repository at this point in the history
# Conflicts:
#	configuration/src/main/kotlin/com/malinskiy/marathon/config/vendor/VendorConfiguration.kt
#	docs/docs/ios/configure.md
#	vendor/vendor-ios/src/main/kotlin/com/malinskiy/marathon/ios/AppleApplicationInstaller.kt
#	vendor/vendor-ios/src/main/kotlin/com/malinskiy/marathon/ios/AppleSimulatorDevice.kt
#	vendor/vendor-ios/src/main/kotlin/com/malinskiy/marathon/ios/xctestrun/TestRootFactory.kt
  • Loading branch information
Malinskiy committed Nov 14, 2023
2 parents d41b9b0 + 8feb03d commit 2326d4c
Show file tree
Hide file tree
Showing 59 changed files with 751 additions and 181 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ iOS:
```yaml
name: "My application"
outputDir: "derived-data/Marathon"
testClassRegexes: ["^((?!Abstract).)*Tests$"]
vendorConfiguration:
type: "iOS"
bundle:
Expand Down Expand Up @@ -137,7 +136,8 @@ See [contributing docs][contributing]

## License

See [LICENSE][LICENSE]
Marathon codebase is GPL 2.0 [LICENSE][LICENSE] with following optional components under specific licenses:
* [libxctest-parser][libxctest-parser-license]

<!--
Repo References
Expand All @@ -161,5 +161,6 @@ Link References
[contributing]:https://docs.marathonlabs.io/intro/contribute
[prs]:http://makeapullrequest.com "Make a Pull Request (external link) ➶"
[LICENSE]:https://github.com/MarathonLabs/marathon/blob/-/LICENSE
[libxctest-parser-license]: https://github.com/MarathonLabs/marathon/blob/-/vendor/vendor-ios/src/main/resources/EULA.md

[marathon-cloud]:https://marathonlabs.io
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ buildscript {


plugins {
id("io.gitlab.arturbosch.detekt") version "1.23.1"
id("com.github.ben-manes.versions") version "0.47.0"
id("io.gitlab.arturbosch.detekt") version "1.23.3"
id("com.github.ben-manes.versions") version "0.49.0"
}

configure<DetektExtension> {
Expand Down
6 changes: 3 additions & 3 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ repositories {
}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10")
implementation("com.squareup:kotlinpoet:1.12.0")
implementation("com.google.code.gson:gson:2.10")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10")
implementation("com.squareup:kotlinpoet:1.14.2")
implementation("com.google.code.gson:gson:2.10.1")
}
44 changes: 22 additions & 22 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
object Versions {
val marathon = System.getenv("GIT_TAG_NAME") ?: "0.8.5"

val kotlin = "1.8.20"
val kotlin = "1.9.10"
val coroutines = "1.7.3"
val coroutinesTest = coroutines

val androidCommon = "31.1.0"
val adam = "0.5.1"
val androidCommon = "31.1.3"
val adam = "0.5.2"
val dexTestParser = "2.3.4"
val kotlinLogging = "3.0.5"
val logbackClassic = "1.4.8"
val logbackClassic = "1.4.11"
val axmlParser = "1.0"
val bugsnag = "3.7.0"
val bugsnag = "3.7.1"

val junitGradle = "1.2.0"
val androidGradleVersion = "7.4.1"
val gradlePluginPublish = "1.2.0"
val androidGradleVersion = "8.1.3"
val gradlePluginPublish = "1.2.1"
val gradlePluginShadow = "8.1.1"

val junit5 = "5.10.0"
val junit5 = "5.10.1"
val kluent = "1.73"

val kakao = "3.0.2"
Expand All @@ -27,37 +27,37 @@ object Versions {
val espressoRunner = "1.0.1"
val junit = "4.13.2"
val gson = "2.10.1"
val apacheCommonsText = "1.10.0"
val apacheCommonsText = "1.11.0"
val apacheCommonsIO = "2.11.0"
val apacheCommonsCodec = "1.15"
val okhttp = "4.11.0"
val okhttp = "4.12.0"
val influxDbClient = "2.23"
val influxDb2Client = "6.10.0"
val clikt = "4.1.0"
val jacksonDatabind = "2.15.2"
val clikt = "4.2.1"
val jacksonDatabind = "2.15.3"
val jacksonKotlin = jacksonDatabind
val jacksonYaml = jacksonDatabind
val jacksonJSR310 = jacksonDatabind
val jacksonAnnotations = jacksonDatabind
val ddPlist = "1.27"
val guava = "32.1.1-jre"
val rsync4j = "3.2.7-1"
val sshj = "0.35.0"
val guava = "32.1.3-jre"
val rsync4j = "3.2.7-5"
val sshj = "0.37.0"
val kotlinProcess = "1.4.1"
val testContainers = "1.18.3"
val testContainers = "1.19.1"
val jupiterEngine = junit5
val jansi = "2.4.0"
val jansi = "2.4.1"
val scalr = "4.2"
val allureTestFilter = "2.23.0"
val allureJava = "2.23.0"
val allureTestFilter = "2.24.0"
val allureJava = "2.24.0"
val allureKotlin = "2.4.0"
val allureEnvironment = "1.0.0"
val mockitoKotlin = "2.2.0"
val dokka = "1.8.10"
val koin = "3.4.3"
val dokka = "1.9.10"
val koin = "3.5.0"
val jsonAssert = "1.5.1"
val xmlUnit = "2.9.1"
val assertk = "0.26.1"
val assertk = "0.27.0"
}

object BuildPlugins {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ sealed class AnalyticsConfiguration {
val default: RetentionPolicyConfiguration = RetentionPolicyConfiguration("rpMarathon", "30d", "30m", 2, true)
}
}

/**
* Hide sensitive information
*/
override fun toString(): String {
return "InfluxDbConfiguration(url='*****', user='*****', password='*****', dbName='$dbName', retentionPolicyConfiguration=$retentionPolicyConfiguration)"
}
}

data class InfluxDb2Configuration(
Expand All @@ -51,6 +58,12 @@ sealed class AnalyticsConfiguration {
val default: RetentionPolicyConfiguration = RetentionPolicyConfiguration(86400 * 30, 0L)
}
}

override fun toString(): String {
return "InfluxDb2Configuration(url='*****', token='*****', organization='$organization', bucket='$bucket', retentionPolicyConfiguration=$retentionPolicyConfiguration)"
}


}

data class GraphiteConfiguration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ data class Configuration private constructor(
val isCodeCoverageEnabled: Boolean,
val uncompletedTestRetryQuota: Int,

val testClassRegexes: Collection<Regex>,
val includeSerialRegexes: Collection<Regex>,
val excludeSerialRegexes: Collection<Regex>,

Expand Down Expand Up @@ -68,7 +67,6 @@ data class Configuration private constructor(
"ignoreFailures" to ignoreFailures.toString(),
"isCodeCoverageEnabled" to isCodeCoverageEnabled.toString(),
"executionStrategy" to executionStrategy.toString(),
"testClassRegexes" to testClassRegexes.toString(),
"includeSerialRegexes" to includeSerialRegexes.toString(),
"excludeSerialRegexes" to excludeSerialRegexes.toString(),
"testBatchTimeoutMillis" to testBatchTimeoutMillis.toString(),
Expand Down Expand Up @@ -100,8 +98,6 @@ data class Configuration private constructor(
if (isCodeCoverageEnabled != other.isCodeCoverageEnabled) return false
if (executionStrategy != other.executionStrategy) return false
if (uncompletedTestRetryQuota != other.uncompletedTestRetryQuota) return false
//For testing we need to compare configuration instances. Unfortunately Regex equality is broken so need to map it to String
if (testClassRegexes.map { it.pattern } != other.testClassRegexes.map { it.pattern }) return false
if (includeSerialRegexes.map { it.pattern } != other.includeSerialRegexes.map { it.pattern }) return false
if (excludeSerialRegexes.map { it.pattern } != other.excludeSerialRegexes.map { it.pattern }) return false
if (testBatchTimeoutMillis != other.testBatchTimeoutMillis) return false
Expand Down Expand Up @@ -132,7 +128,6 @@ data class Configuration private constructor(
result = 31 * result + isCodeCoverageEnabled.hashCode()
result = 31 * result + executionStrategy.hashCode()
result = 31 * result + uncompletedTestRetryQuota
result = 31 * result + testClassRegexes.hashCode()
result = 31 * result + includeSerialRegexes.hashCode()
result = 31 * result + excludeSerialRegexes.hashCode()
result = 31 * result + testBatchTimeoutMillis.hashCode()
Expand Down Expand Up @@ -163,7 +158,6 @@ data class Configuration private constructor(
var executionStrategy: ExecutionStrategyConfiguration = ExecutionStrategyConfiguration(),
var uncompletedTestRetryQuota: Int = Integer.MAX_VALUE,

var testClassRegexes: Collection<Regex> = listOf(Regex("^((?!Abstract).)*Test[s]*$")),
var includeSerialRegexes: Collection<Regex> = emptyList(),
var excludeSerialRegexes: Collection<Regex> = emptyList(),

Expand Down Expand Up @@ -197,7 +191,6 @@ data class Configuration private constructor(
isCodeCoverageEnabled = isCodeCoverageEnabled,
executionStrategy = executionStrategy,
uncompletedTestRetryQuota = uncompletedTestRetryQuota,
testClassRegexes = testClassRegexes,
includeSerialRegexes = includeSerialRegexes,
excludeSerialRegexes = excludeSerialRegexes,
testBatchTimeoutMillis = testBatchTimeoutMillis,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class LogicalConfigurationValidator : ConfigurationValidator {
is VendorConfiguration.IOSConfiguration -> {
configuration.vendorConfiguration.validate()
}
is VendorConfiguration.AndroidConfiguration -> {
configuration.vendorConfiguration.validate()
}

else -> Unit
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,26 @@ sealed class VendorConfiguration {
@JsonProperty("disableWindowAnimation") val disableWindowAnimation: Boolean = DEFAULT_DISABLE_WINDOW_ANIMATION,
) : VendorConfiguration() {
fun safeAndroidSdk(): File = androidSdk ?: throw ConfigurationException("No android SDK path specified")

fun validate() {
validateFile(applicationOutput)
validateFile(testApplicationOutput)
splitApks?.forEach { validateFile(it) }
extraApplicationsOutput?.forEach { validateFile(it) }
outputs?.forEach {
validateFile(it.application)
validateFile(it.testApplication)
it.splitApks?.forEach { apk -> validateFile(apk) }
it.extraApplications?.forEach { apk -> validateFile(apk) }
}
}

private fun validateFile(file: File?) {
if (file != null) {
if (!file.exists()) throw ConfigurationException("${file.absolutePath} does not exist")
if (!file.isFile) throw ConfigurationException("${file.absolutePath} must be a regular file")
}
}
}

class AndroidConfigurationBuilder {
Expand Down Expand Up @@ -143,6 +163,7 @@ sealed class VendorConfiguration {
@JsonProperty("rsync") val rsync: RsyncConfiguration = RsyncConfiguration(),
@JsonProperty("xcodebuildTestArgs") val xcodebuildTestArgs: Map<String, String> = emptyMap(),
@JsonProperty("dataContainerClear") val dataContainerClear: Boolean = false,
@JsonProperty("testParserConfiguration") val testParserConfiguration: com.malinskiy.marathon.config.vendor.ios.TestParserConfiguration = com.malinskiy.marathon.config.vendor.ios.TestParserConfiguration.NmTestParserConfiguration(),

@JsonProperty("signing") val signing: SigningConfiguration = SigningConfiguration(),
) : VendorConfiguration() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.malinskiy.marathon.config.vendor.ios

import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes(
JsonSubTypes.Type(value = TestParserConfiguration.NmTestParserConfiguration::class, name = "nm"),
JsonSubTypes.Type(value = TestParserConfiguration.XCTestParserConfiguration::class, name = "xctest"),
)
sealed class TestParserConfiguration {
data class NmTestParserConfiguration(val testClassRegexes: Collection<Regex> = listOf(Regex("^((?!Abstract).)*Test[s]*$"))) : TestParserConfiguration() {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as NmTestParserConfiguration

//For testing we need to compare configuration instances. Unfortunately Regex equality is broken so need to map it to String
return testClassRegexes.map { it.pattern } == other.testClassRegexes.map { it.pattern }
}

override fun hashCode(): Int {
return testClassRegexes.hashCode()
}
}
object XCTestParserConfiguration : TestParserConfiguration()
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ class ConfigurationFactoryTest {
TestFilterConfiguration.AnnotationFilterConfiguration(".*".toRegex()),
TestFilterConfiguration.AnnotationDataFilterConfiguration(".*".toRegex(), ".*".toRegex())
)
configuration.testClassRegexes.map { it.toString() } shouldContainSame listOf("^((?!Abstract).)*Test$")

// Regex doesn't have proper equals method. Need to check the patter itself
configuration.includeSerialRegexes.joinToString(separator = "") { it.pattern } shouldBeEqualTo """emulator-500[2,4]""".toRegex().pattern
Expand Down Expand Up @@ -189,7 +188,7 @@ class ConfigurationFactoryTest {
screenshotConfiguration = ScreenshotConfiguration(false, 1080, 1920, 200)
),
15000L,
AllureConfiguration()
AllureConfiguration(),
)
}

Expand Down Expand Up @@ -231,8 +230,6 @@ class ConfigurationFactoryTest {
configuration.filteringConfiguration.allowlist.shouldBeEmpty()
configuration.filteringConfiguration.blocklist.shouldBeEmpty()

configuration.testClassRegexes.map { it.toString() } shouldContainSame listOf("^((?!Abstract).)*Test[s]*$")

configuration.includeSerialRegexes shouldBeEqualTo emptyList()
configuration.excludeSerialRegexes shouldBeEqualTo emptyList()
configuration.ignoreFailures shouldBeEqualTo false
Expand Down
2 changes: 0 additions & 2 deletions configuration/src/test/resources/fixture/config/sample_1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ filteringConfiguration:
- type: "annotationData"
nameRegex: ".*"
valueRegex: ".*"
testClassRegexes:
- "^((?!Abstract).)*Test$"
includeSerialRegexes:
- "emulator-500[2,4]"
excludeSerialRegexes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ filteringConfiguration:
- type: "annotationData"
nameRegex: ".*"
valueRegex: ".*"
testClassRegexes:
- "^((?!Abstract).)*Test$"
includeSerialRegexes:
- "emulator-500[2,4]"
excludeSerialRegexes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ filteringConfiguration:
regex: ".*"
- type: "annotation"
regex: ".*"
testClassRegexes:
- "^((?!Abstract).)*Test$"
includeSerialRegexes:
- "emulator-500[2,4]"
excludeSerialRegexes:
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/kotlin/com/malinskiy/marathon/Marathon.kt
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,7 @@ class Marathon(
}

private fun applyTestFilters(parsedTests: List<Test>): List<Test> {
var tests = parsedTests.filter { test ->
configuration.testClassRegexes.all { it.matches(test.clazz) }
}
var tests = parsedTests
configuration.filteringConfiguration.allowlist.forEach { tests = it.toTestFilter().filter(tests) }
configuration.filteringConfiguration.blocklist.forEach { tests = it.toTestFilter().filterNot(tests) }
return tests
Expand Down
1 change: 0 additions & 1 deletion docs/docs/android/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ marathon {
add(SimpleClassnameFilterConfiguration("$^".toRegex()))
}
}
testClassRegexes = listOf("^((?!Abstract).)*Test$")
includeSerialRegexes = emptyList()
excludeSerialRegexes = emptyList()
uncompletedTestRetryQuota = 100
Expand Down
1 change: 0 additions & 1 deletion docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ vendorConfiguration:
```yaml
name: "My application"
outputDir: "derived-data/Marathon"
testClassRegexes: ["^((?!Abstract).)*Tests$"]
vendorConfiguration:
type: "iOS"
bundle:
Expand Down
Loading

0 comments on commit 2326d4c

Please sign in to comment.