Skip to content

Commit

Permalink
feat(core): add progress api + rework reporters
Browse files Browse the repository at this point in the history
  • Loading branch information
Malinskiy committed Dec 4, 2024
1 parent 8b5087f commit 182a775
Show file tree
Hide file tree
Showing 50 changed files with 927 additions and 314 deletions.
11 changes: 11 additions & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ object Versions {
val jsonAssert = "1.5.3"
val xmlUnit = "2.10.0"
val assertk = "0.28.1"

val grpc = "1.59.0"
val grpcKotlin = "1.4.0"
val grpcOkhttp = "1.59.0"
val protobufGradle = "0.9.4"
val protobuf = "3.25.0"
}

object BuildPlugins {
Expand Down Expand Up @@ -97,6 +103,11 @@ object Libraries {
val kotlinProcess = "com.github.pgreze:kotlin-process:${Versions.kotlinProcess}"
val okhttp = "com.squareup.okhttp3:okhttp:${Versions.okhttp}"
val ktorNetwork = "io.ktor:ktor-network:${Versions.ktor}"
val protobufLite = "com.google.protobuf:protobuf-javalite:${Versions.protobuf}"
val grpcStub = "io.grpc:grpc-stub:${Versions.grpc}"
val grpcKotlinStub = "io.grpc:grpc-kotlin-stub:${Versions.grpcKotlin}"
val grpcProtobufLite = "io.grpc:grpc-protobuf-lite:${Versions.grpc}"
val grpcOkhttp = "io.grpc:grpc-okhttp:${Versions.grpcOkhttp}"
}

object TestLibraries {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ data class Configuration private constructor(
val analyticsTracking: Boolean,
val bugsnagReporting: Boolean,
val deviceInitializationTimeoutMillis: Long,
val ciConfiguration: CIConfiguration,
val progressConfiguration: ProgressConfiguration,
) {
fun toMap() =
mapOf<String, String>(
Expand All @@ -76,7 +76,7 @@ data class Configuration private constructor(
"screenRecordingPolicy" to screenRecordingPolicy.toString(),
"vendorConfiguration" to vendorConfiguration.toString(),
"deviceInitializationTimeoutMillis" to deviceInitializationTimeoutMillis.toString(),
"ciConfiguration" to ciConfiguration.toString(),
"progressConfiguration" to progressConfiguration.toString(),
)

override fun equals(other: Any?): Boolean {
Expand Down Expand Up @@ -110,7 +110,7 @@ data class Configuration private constructor(
if (analyticsTracking != other.analyticsTracking) return false
if (bugsnagReporting != other.bugsnagReporting) return false
if (deviceInitializationTimeoutMillis != other.deviceInitializationTimeoutMillis) return false
if (ciConfiguration != other.ciConfiguration) return false
if (progressConfiguration != other.progressConfiguration) return false

return true
}
Expand Down Expand Up @@ -141,7 +141,7 @@ data class Configuration private constructor(
result = 31 * result + analyticsTracking.hashCode()
result = 31 * result + bugsnagReporting.hashCode()
result = 31 * result + deviceInitializationTimeoutMillis.hashCode()
result = 31 * result + ciConfiguration.hashCode()
result = 31 * result + progressConfiguration.hashCode()
return result
}

Expand Down Expand Up @@ -177,7 +177,7 @@ data class Configuration private constructor(

var outputConfiguration: OutputConfiguration = OutputConfiguration(),
var vendorConfiguration: VendorConfiguration = VendorConfiguration.EmptyVendorConfiguration(),
var ciConfiguration: CIConfiguration = CIConfiguration.None,
var progressConfiguration: ProgressConfiguration = ProgressConfiguration.Auto,
) {
fun build(): Configuration {
return Configuration(
Expand Down Expand Up @@ -206,7 +206,7 @@ data class Configuration private constructor(
analyticsTracking = analyticsTracking,
bugsnagReporting = bugsnagReporting,
deviceInitializationTimeoutMillis = deviceInitializationTimeoutMillis,
ciConfiguration = ciConfiguration,
progressConfiguration = progressConfiguration,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.malinskiy.marathon.config

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 = ProgressConfiguration.Auto::class, name = "auto"),
JsonSubTypes.Type(value = ProgressConfiguration.Custom::class, name = "custom"),
)

sealed class ProgressConfiguration {
data object Auto : ProgressConfiguration()
data class Custom(val values: List<ProgressReporterConfiguration>) : ProgressConfiguration()
}

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes(
JsonSubTypes.Type(value = ProgressReporterConfiguration.Stdout::class, name = "stdout"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.Teamcity::class, name = "teamcity"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.Device::class, name = "device"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.Billing::class, name = "billing"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.JUnit::class, name = "junit"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.Timeline::class, name = "timeline"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.Raw::class, name = "raw"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.Allure::class, name = "allure"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.Html::class, name = "html"),
JsonSubTypes.Type(value = ProgressReporterConfiguration.ApiV1::class, name = "api_v1"),
)
sealed class ProgressReporterConfiguration {
data object Stdout : ProgressReporterConfiguration()
data object Teamcity : ProgressReporterConfiguration()
data object Device : ProgressReporterConfiguration()
data object Billing : ProgressReporterConfiguration()
data object JUnit : ProgressReporterConfiguration()
data object Timeline : ProgressReporterConfiguration()
data object Raw : ProgressReporterConfiguration()
data object Test : ProgressReporterConfiguration()
data object Allure : ProgressReporterConfiguration()
data object Html : ProgressReporterConfiguration()
data class ApiV1(val target: String, val run_id: String) : ProgressReporterConfiguration()
}
43 changes: 43 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import com.google.protobuf.gradle.id
import com.google.protobuf.gradle.remove

plugins {
idea
Expand All @@ -7,6 +9,7 @@ plugins {
id("org.jetbrains.dokka")
jacoco
id("com.github.gmazzo.buildconfig") version "5.5.0"
id("com.google.protobuf") version Versions.protobufGradle
}

sourceSets {
Expand Down Expand Up @@ -62,6 +65,11 @@ dependencies {
implementation(Libraries.scalr)
api(Libraries.koin)
api(Libraries.bugsnag)
api(Libraries.protobufLite)
api(Libraries.grpcProtobufLite)
api(Libraries.grpcKotlinStub)
api(Libraries.grpcOkhttp)
api(Libraries.grpcStub)
testImplementation(project(":vendor:vendor-test"))
testImplementation(TestLibraries.junit5)
testImplementation(TestLibraries.kluent)
Expand Down Expand Up @@ -90,3 +98,38 @@ val integrationTest = task<Test>("integrationTest") {
setupDeployment()
setupKotlinCompiler()
setupTestTask()

protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${Versions.protobuf}"
}
plugins {
id("java") {
artifact = "io.grpc:protoc-gen-grpc-java:${Versions.grpc}"
}
id("grpc") {
artifact = "io.grpc:protoc-gen-grpc-java:${Versions.grpc}"
}
id("grpckt") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:${Versions.grpcKotlin}:jdk8@jar"
}
}
generateProtoTasks {
all().forEach {
it.builtins {
remove("java")
}
it.plugins {
id("java") {
option("lite")
}
id("grpc") {
option("lite")
}
id("grpckt") {
option("lite")
}
}
}
}
}
4 changes: 4 additions & 0 deletions core/src/main/kotlin/com/malinskiy/marathon/Marathon.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.malinskiy.marathon.execution.TestParser
import com.malinskiy.marathon.execution.TestShard
import com.malinskiy.marathon.execution.bundle.TestBundleIdentifier
import com.malinskiy.marathon.execution.command.parse.MarathonTestParseCommand
import com.malinskiy.marathon.report.ProgressReporter
import com.malinskiy.marathon.execution.withRetry
import com.malinskiy.marathon.extension.toFlakinessStrategy
import com.malinskiy.marathon.extension.toShardingStrategy
Expand Down Expand Up @@ -54,6 +55,7 @@ class Marathon(
private val tracker: TrackerInternal,
private val analytics: Analytics,
private val track: Track,
private val progressReporter: ProgressReporter,
private val timer: Timer,
private val marathonTestParseCommand: MarathonTestParseCommand,
private val usageTracker: UsageTracker,
Expand Down Expand Up @@ -155,6 +157,7 @@ class Marathon(

val shard = prepareTestShard(parsedFilteredTests, analytics)

progressReporter.begin(parsedFilteredTests)
usageTracker.trackEvent(Event.TestsTotal(parsedAllTests.size))
usageTracker.trackEvent(Event.TestsRun(parsedFilteredTests.size))

Expand All @@ -167,6 +170,7 @@ class Marathon(
configuration,
shard,
track,
progressReporter,
timer,
testBundleIdentifier,
currentCoroutineContext
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.malinskiy.marathon.analytics

import com.google.gson.Gson
import com.malinskiy.marathon.analytics.external.graphite.BasicGraphiteClient
import com.malinskiy.marathon.analytics.external.graphite.GraphiteTracker
import com.malinskiy.marathon.analytics.external.influx.InfluxDbProvider
Expand All @@ -15,29 +14,13 @@ import com.malinskiy.marathon.config.AnalyticsConfiguration.GraphiteConfiguratio
import com.malinskiy.marathon.config.AnalyticsConfiguration.InfluxDb2Configuration
import com.malinskiy.marathon.config.AnalyticsConfiguration.InfluxDbConfiguration
import com.malinskiy.marathon.config.Configuration
import com.malinskiy.marathon.io.FileManager
import com.malinskiy.marathon.report.ProgressReporter
import com.malinskiy.marathon.log.MarathonLogging
import com.malinskiy.marathon.report.allure.AllureReporter
import com.malinskiy.marathon.report.bill.BillingReporter
import com.malinskiy.marathon.report.device.DeviceInfoJsonReporter
import com.malinskiy.marathon.report.html.HtmlSummaryReporter
import com.malinskiy.marathon.report.junit.JUnitReporter
import com.malinskiy.marathon.report.raw.RawJsonReporter
import com.malinskiy.marathon.report.stdout.StdoutReporter
import com.malinskiy.marathon.report.test.TestJsonReporter
import com.malinskiy.marathon.report.timeline.TimelineReporter
import com.malinskiy.marathon.report.timeline.TimelineSummaryProvider
import com.malinskiy.marathon.time.Timer
import com.malinskiy.marathon.usageanalytics.tracker.UsageTracker
import java.io.File

internal class TrackerFactory(
private val configuration: Configuration,
private val fileManager: FileManager,
private val gson: Gson,
private val timer: Timer,
private val track: Track,
private val usageTracker: UsageTracker,
private val progressReporter: ProgressReporter,
) {

val log = MarathonLogging.logger("TrackerFactory")
Expand Down Expand Up @@ -88,18 +71,6 @@ internal class TrackerFactory(
}

private fun createExecutionReportGenerator(): ExecutionReportGenerator {
return ExecutionReportGenerator(
listOf(
DeviceInfoJsonReporter(fileManager, gson),
BillingReporter(fileManager, gson, usageTracker),
JUnitReporter(configuration.outputDir),
TimelineReporter(TimelineSummaryProvider(), gson, configuration.outputDir),
RawJsonReporter(fileManager, gson),
TestJsonReporter(fileManager, gson),
AllureReporter(configuration, File(configuration.outputDir, "allure-results")),
HtmlSummaryReporter(gson, fileManager, configuration.outputDir, configuration),
StdoutReporter(timer)
)
)
return ExecutionReportGenerator(progressReporter)
}
}
Loading

0 comments on commit 182a775

Please sign in to comment.