Skip to content

Commit

Permalink
Merge pull request #33 from Automattic/build_report_file
Browse files Browse the repository at this point in the history
Test plugin behaviour under configuration cache.
  • Loading branch information
wzieba authored Feb 27, 2024
2 parents 1b8026b + 9e53975 commit d380961
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 6 deletions.
5 changes: 5 additions & 0 deletions measure-builds/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ dependencies {
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.3")
}

detekt {
buildUponDefaultConfig = true
config.setFrom("$rootDir/detekt.yml")
}

tasks.named<Test>("test") {
useJUnitPlatform()
}
Expand Down
7 changes: 7 additions & 0 deletions measure-builds/detekt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
formatting:
MaximumLineLength:
excludes: [ '**/test/**' ]

style:
MaxLineLength:
excludes: [ '**/test/**' ]
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class BuildTimePlugin @Inject constructor(
val extension =
project.extensions.create("measureBuilds", MeasureBuildsExtension::class.java, project)

val analyticsReporter = MetricsReporter(project.logger, extension.authToken)
val analyticsReporter = MetricsReporter(project.logger, extension.authToken, project.buildDir)

val encodedUser: String = UsernameProvider.provide(project, extension)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ object InMemoryReport {
}

val buildData: BuildData
get() = buildDataStore ?: throw NullPointerException("Must not be null")
get() = buildDataStore ?: throw NullPointerException("Build data must not be null")

val executionData: ExecutionData
get() = executionDataStore ?: throw NullPointerException("Must not be null")
get() = executionDataStore ?: throw NullPointerException("Execution data must not be null")
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.gradle.api.logging.Logger
import org.gradle.api.provider.Provider
import java.io.File
import java.util.Locale
import java.util.concurrent.TimeUnit.MILLISECONDS
import java.util.concurrent.TimeUnit.MINUTES
Expand All @@ -40,6 +41,7 @@ import kotlin.time.Duration.Companion.seconds
class MetricsReporter(
private val logger: Logger,
private val authToken: Provider<String>,
private val buildDir: File,
) {
suspend fun report(
report: InMemoryReport,
Expand Down Expand Up @@ -83,7 +85,7 @@ class MetricsReporter(
)
)
logger.lifecycle(
"\n$SUCCESS_ICON Build time report of $timeFormatted has been received by App Metrics."
"\n$SUCCESS_ICON Build time report of $timeFormatted has been received by Apps Metrics."
)
}

Expand All @@ -104,7 +106,7 @@ class MetricsReporter(
}

private fun reportLocally(report: InMemoryReport) {
Path("build/reports/measure_builds")
Path("${buildDir.path}/reports/measure_builds")
.apply {
if (!exists()) {
createDirectories()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package com.automattic.android.measure

import com.automattic.android.measure.models.BuildData
import com.automattic.android.measure.models.ExecutionData
import kotlinx.serialization.json.Json
import org.assertj.core.api.Assertions.assertThat
import org.gradle.testkit.runner.GradleRunner
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import java.io.File

/**
* Test suite focused on validating the behavior of the Build Time Plugin when the configuration cache is enabled.
*/
class BuildTimePluginConfigurationCacheTests {

@BeforeEach
fun clear() {
File("build/functionalTest").listFiles()?.forEach {
if (it.name != "measure-builds") {
it.deleteRecursively()
}
}
File(".gradle/configuration-cache").deleteRecursively()
}

@Test
fun `given a project utilizes configuration cache, when build finishes, then report 0 configuration cache duration`() {
// given
val runner = runner()

// when
runner("help", "--stacktrace").build()

// then
assertThat(executionData.configurationPhaseDuration).isGreaterThan(0)

// when
runner("help").build()

// then
assertThat(executionData.configurationPhaseDuration).isEqualTo(0)
}

@Test
fun `given a project utilizes configuration cache, when build finishes, then assert that build or execution data was not reused`() {
fun runTaskAndGetDetails(vararg arguments: String): Pair<List<String>, Long> {
runner(*arguments).build()
return buildData.tasks to executionData.buildFinishedTimestamp
}

val (tasksA, timestampA) = runTaskAndGetDetails("help")
val (tasksB, timestampB) = runTaskAndGetDetails("outgoingVariants")
val (tasksC, timestampC) = runTaskAndGetDetails("tasks")

assertThat(timestampA).isNotEqualTo(timestampB)
assertThat(timestampA).isNotEqualTo(timestampC)
assertThat(timestampB).isNotEqualTo(timestampC)

assertThat(tasksA).isNotEqualTo(tasksB)
assertThat(tasksA).isNotEqualTo(tasksC)
assertThat(tasksB).isNotEqualTo(tasksC)
}

@Test
fun `given a project utilizes configuration cache, when build finishes twice with the same task, then assert that execution data was not reused`() {
runner("help").build()
val timestampA = executionData.buildFinishedTimestamp
runner("help").build()
val timestampB = executionData.buildFinishedTimestamp

assertThat(timestampA).isNotEqualTo(timestampB)
}

@Test
@Disabled(
"This test is the reason, why we have to be extra careful with the configuration cache. Build data won't always be invalidated." +
"This means that we can have a situation where the build data is, reused what is not expected. "
)
fun `given a project utilizes configuration cache, when build finishes twice with the same task, then assert that build data was not reused`() {
runner("help", "-Dorg.gradle.workers.max=3").build()
runner("help", "-Dorg.gradle.workers.max=5").build()
val maxWorkers = buildData.maxWorkers

assertThat(maxWorkers).isEqualTo(5)
}

private fun runner(vararg arguments: String): GradleRunner {
val projectDir = File("build/functionalTest")
projectDir.mkdirs()

projectDir.resolve("settings.gradle.kts").writeText("")

projectDir.resolve("build.gradle.kts").writeText(
"""
plugins {
id("com.automattic.android.measure-builds")
}
measureBuilds {
enable.set(true)
attachGradleScanId.set(false)
automatticProject.set(com.automattic.android.measure.MeasureBuildsExtension.AutomatticProject.WooCommerce)
}
""".trimIndent()
)

val runner = GradleRunner.create()
runner.forwardOutput()
runner.withPluginClasspath()
runner.withArguments(*arguments, "--configuration-cache")
runner.withProjectDir(projectDir)
return runner
}

private val executionData: ExecutionData
get() {
File("build/functionalTest/build/reports/measure_builds/execution_data.json").let {
return Json.decodeFromString<ExecutionData>(it.readText())
}
}

private val buildData: BuildData
get() {
File("build/functionalTest/build/reports/measure_builds/build_data.json").let {
return Json.decodeFromString<BuildData>(it.readText())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class BuildTimePluginTest {
val run = runner.withArguments("help").build()

// then
File("build/reports/measure_builds/execution_data.json").let {
File("build/functionalTest/build/reports/measure_builds/execution_data.json").let {
val executionData = Json.decodeFromString<ExecutionData>(it.readText())

assertThat(executionData.tasks).hasSize(1)
Expand Down

0 comments on commit d380961

Please sign in to comment.