[#31] feat: BuildService 이용한 gradle lifecycle 테스트

- test finished 경우에 result logging 출력을 위한 gradle lifecycle 테스트 진행중
- 전반적인 리팩토링
This commit is contained in:
Hanbin Lee
2023-01-24 02:23:05 +09:00
parent 15744f1a9a
commit f4951990cd
6 changed files with 115 additions and 41 deletions

1
.gitignore vendored
View File

@@ -24,6 +24,7 @@ bin/
out/ out/
!**/src/main/**/out/ !**/src/main/**/out/
!**/src/test/**/out/ !**/src/test/**/out/
lib/
### NetBeans ### ### NetBeans ###
/nbproject/private/ /nbproject/private/

View File

@@ -2,6 +2,8 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.boot.gradle.tasks.bundling.BootJar import org.springframework.boot.gradle.tasks.bundling.BootJar
import plugin.BuildLifecyclePlugin
import plugin.TestSummary
plugins { plugins {
id(Plugins.Spring.boot).version(Version.Spring.boot) id(Plugins.Spring.boot).version(Version.Spring.boot)
@@ -34,7 +36,10 @@ subprojects {
plugin(Plugins.Kotlin.kotlinJpa) plugin(Plugins.Kotlin.kotlinJpa)
} }
java.sourceCompatibility = JavaVersion.VERSION_17 java.apply {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
dependencies { dependencies {
// Spring Boot Project // Spring Boot Project
@@ -81,7 +86,6 @@ subprojects {
events = setOf( events = setOf(
TestLogEvent.FAILED, TestLogEvent.FAILED,
TestLogEvent.SKIPPED, TestLogEvent.SKIPPED,
TestLogEvent.STANDARD_OUT,
TestLogEvent.STANDARD_ERROR TestLogEvent.STANDARD_ERROR
) )
@@ -98,53 +102,56 @@ subprojects {
override fun afterSuite(desc: TestDescriptor, result: TestResult) { override fun afterSuite(desc: TestDescriptor, result: TestResult) {
if (desc.parent != null) return if (desc.parent != null) return
val summary = TestOutcome().apply { val summary = TestSummary(
add("${project.name}:${name} Test result: ${result.resultType}") projectName = project.name,
add("Test summary: ${result.testCount} tests, ${result.successfulTestCount} succeeded, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped") taskName = name,
add("report file: ${reports.html.entryPoint}") result = result
} )
if (result.resultType == TestResult.ResultType.SUCCESS) { // if (result.resultType == TestResult.ResultType.SUCCESS) {
testResults.add(0, summary) // testResults.add(0, summary)
} else { // } else {
testResults.add(summary) // testResults.add(summary)
} // }
} }
override fun beforeTest(testDescriptor: TestDescriptor?) {} override fun beforeTest(testDescriptor: TestDescriptor?) {}
override fun afterTest(testDescriptor: TestDescriptor?, result: TestResult?) {} override fun afterTest(testDescriptor: TestDescriptor?, result: TestResult?) {}
}) })
} }
// for logging when build finished
apply<BuildLifecyclePlugin>()
} }
gradle.buildFinished { //gradle.buildFinished {
if (testResults.isNotEmpty()) { // if (testResults.isNotEmpty()) {
printResults(testResults) // printResults(testResults)
} // }
} //}
fun printResults(allResults:List<TestOutcome>) { //fun printResults(allResults:List<TestOutcome>) {
val maxLength = allResults.maxOfOrNull { it.maxWidth() } ?: 0 // val maxLength = allResults.maxOfOrNull { it.maxWidth() } ?: 0
//
// println("┌${"─".repeat(maxLength)}┐")
//
// println(allResults.joinToString("├${"─".repeat(maxLength)}┤\n") { testOutcome ->
// testOutcome.lines.joinToString("│\n│", "│", "│") {
// it + " ".repeat(maxLength - it.length)
// }
// })
//
// println("└${"─".repeat(maxLength)}┘")
//}
//
//val testResults by extra(mutableListOf<TestOutcome>()) // Container for tests summaries
println("${"─".repeat(maxLength)}") //data class TestOutcome(val lines: MutableList<String> = mutableListOf()) {
// fun add(line: String) {
println(allResults.joinToString("${"─".repeat(maxLength)}\n") { testOutcome -> // lines.add(line)
testOutcome.lines.joinToString("\n", "", "") { // }
it + " ".repeat(maxLength - it.length) //
} // fun maxWidth(): Int {
}) // return lines.maxByOrNull { it.length }?.length ?: 0
// }
println("${"─".repeat(maxLength)}") //}
}
val testResults by extra(mutableListOf<TestOutcome>()) // Container for tests summaries
data class TestOutcome(val lines: MutableList<String> = mutableListOf()) {
fun add(line: String) {
lines.add(line)
}
fun maxWidth(): Int {
return lines.maxBy { it.length }?.length ?: 0
}
}

View File

@@ -0,0 +1,19 @@
package plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.internal.build.event.BuildEventListenerRegistryInternal
import org.gradle.invocation.DefaultGradle
class BuildLifecyclePlugin : Plugin<Project> {
override fun apply(project: Project) {
val gradle = project.gradle
val services = (gradle as DefaultGradle).services
val registry = services[BuildEventListenerRegistryInternal::class.java]
val operationService = gradle.sharedServices.registerIfAbsent("operationService", BuildOperationService::class.java) {}
registry.subscribe(operationService)
}
}

View File

@@ -0,0 +1,22 @@
package plugin
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.gradle.tooling.events.FinishEvent
import org.gradle.tooling.events.OperationCompletionListener
import org.gradle.tooling.events.task.TaskFinishEvent
abstract class BuildOperationService : BuildService<BuildServiceParameters.None>, OperationCompletionListener {
private val targetProjects = listOf("dongne-account-api", "dongne-service-api")
private val targetTask = "test"
override fun onFinish(event: FinishEvent?) {
if (event == null || event !is TaskFinishEvent) {
return
}
if (event.descriptor.taskPath in targetProjects.map { ":$it:$targetTask" }) {
println("####### onFinish 222 ${event}")
}
}
}

View File

@@ -0,0 +1,25 @@
package plugin
import org.gradle.api.tasks.testing.TestResult
data class TestSummary(
val projectName: String? = null,
val taskName: String? = null,
val result: TestResult,
val lines: MutableList<String> = mutableListOf()
) {
fun add(line: String) {
lines.add(line)
}
fun maxWidth(): Int {
return lines.maxByOrNull { it.length }?.length ?: 0
}
fun toLogList(): List<String> {
return listOf(
"${projectName}:${taskName} Test result: ${result.resultType}",
"Test summary: ${result.testCount} tests, ${result.successfulTestCount} succeeded, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped"
)
}
}