Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract the test concurrency settings to scripts.gradle.kts file #1173

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions api-schema/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,8 @@ dependencies {
annotationProcessor(libs.lombok)
}

tasks.test {
// Enable parallel test execution
systemProperty("junit.jupiter.execution.parallel.enabled", true)
// Allocate thread count based on available processors
systemProperty("junit.jupiter.execution.parallel.config.strategy", "dynamic")
// Set default parallel mode to same thread. All tests within a class are run in sequence.
systemProperty("junit.jupiter.execution.parallel.mode.default", "same_thread")
// Set default parallel mode for classes to concurrent. All test classes are run in parallel.
systemProperty("junit.jupiter.execution.parallel.mode.classes.default", "concurrent")
apply(from = "$rootDir/scripts.gradle.kts")
@Suppress("UNCHECKED_CAST")
val enableTestConcurrency = extra["enableTestConcurrency"] as (Test) -> Unit

// Set default test class order to order annotation. All test classes are run in parallel.
// Some tests take longer to run. Enabling the order will execute long-running tests first to
// shorten the overall test time.
systemProperty(
"junit.jupiter.testclass.order.default",
"org.junit.jupiter.api.ClassOrderer\$OrderAnnotation"
)
maxParallelForks =
(Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1).also {
println("junit5 ... setting maxParallelForks to $it")
}
}
tasks.test { enableTestConcurrency(this) }
8 changes: 5 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ subprojects {

test {
useJUnitPlatform()
systemProperty(
"junit.jupiter.testclass.order.default",
"org.junit.jupiter.api.ClassOrderer\$OrderAnnotation"
)

exclude("**/AnchorPlatformCustodyEnd2EndTest**")
exclude("**/AnchorPlatformCustodyApiRpcEnd2EndTest**")
Expand Down Expand Up @@ -181,6 +185,4 @@ allprojects {
}
}

tasks.register("printVersionName") {
println(rootProject.version.toString())
}
tasks.register("printVersionName") { println(rootProject.version.toString()) }
38 changes: 7 additions & 31 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dependencies {
implementation(
libs.scala.library
) // used to force the version of scala-library (used by kafka-json-schema-serializer) to a safer
// one.
// one.
implementation(libs.bundles.kafka)

// TODO: Consider to simplify
Expand Down Expand Up @@ -119,33 +119,9 @@ publishing {
configure<SigningExtension> { sign(publishing.publications) }
}

// TODO: when we enable parallelization for all sub-projects, we can extract the following block.
tasks.test {
// Enable parallel test execution
systemProperty("junit.jupiter.execution.parallel.enabled", true)
// Use PER_METHOD test instance life cycle. This avoids the race condition when tests are run in parallel mode
// if the test class has a non-static fields. The non-static fields are shared across all test methods. If the life
// cycle is not PER_METHOD, the test methods may overwrite the fields and cause test failures.
//
// However, the life cycle can still be over-written by @TestInstance(Lifecycle) annotation.
// See https://junit.org/junit5/docs/current/user-guide/#writing-tests-parallel-execution
systemProperty("junit.jupiter.testinstance.lifecycle.default", "per_method")
// Allocate thread count based on available processors
systemProperty("junit.jupiter.execution.parallel.config.strategy", "dynamic")
// Set default parallel mode to same thread. All tests within a class are run in sequence.
systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent")
// Set default parallel mode for classes to concurrent. All test classes are run in parallel.
systemProperty("junit.jupiter.execution.parallel.mode.classes.default", "concurrent")

// Set default test class order to order annotation. All test classes are run in parallel.
// Some tests take longer to run. Enabling the order will execute long-running tests first to
// shorten the overall test time.
systemProperty(
"junit.jupiter.testclass.order.default",
"org.junit.jupiter.api.ClassOrderer\$OrderAnnotation"
)
maxParallelForks =
(Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1).also {
println("junit5 ... setting maxParallelForks to $it")
}
}
apply(from = "$rootDir/scripts.gradle.kts")

@Suppress("UNCHECKED_CAST")
val enableTestConcurrency = extra["enableTestConcurrency"] as (Test) -> Unit

tasks.test { enableTestConcurrency(this) }
13 changes: 3 additions & 10 deletions integration-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ dependencies {
implementation("org.springframework.boot:spring-boot-autoconfigure")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation(
libs.snakeyaml) // used to force the version of snakeyaml (used by springboot) to a safer one.
libs.snakeyaml
) // used to force the version of snakeyaml (used by springboot) to a safer one.
implementation("org.springframework.boot:spring-boot-starter-web")

implementation(libs.commons.cli)
Expand Down Expand Up @@ -47,12 +48,4 @@ dependencies {
testImplementation(libs.dotenv)
}

tasks {
bootJar { enabled = false }
test {
useJUnitPlatform()
// Setting forkEvery to 1 makes Gradle test execution to start a separeate JVM for each integration test classes.
// This is to to avoid the interaction between static states between each integration test classes.
setForkEvery(1)
}
}
tasks { bootJar { enabled = false } }
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.stellar.anchor.platform.test

import java.lang.Thread.sleep
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.assertThrows
import org.stellar.anchor.api.exception.SepNotFoundException
Expand Down Expand Up @@ -64,14 +63,11 @@ class Sep12Tests(config: TestConfig, toml: Sep1Helper.TomlContent, jwt: String)
var pr = sep12Client.putCustomer(customer)
printResponse(pr)

sleep(1000)

// make sure the customer was uploaded correctly.
printRequest("Calling GET /customer", customer)
var gr = sep12Client.getCustomer(pr!!.id)
printResponse(gr)

assertEquals(Sep12Status.NEEDS_INFO, gr?.status)
assertEquals(pr.id, gr?.id)

customer.emailAddress = "[email protected]"
Expand Down Expand Up @@ -102,6 +98,7 @@ class Sep12Tests(config: TestConfig, toml: Sep1Helper.TomlContent, jwt: String)
assertEquals("customer for 'id' '$id' not found", ex.message)
println(ex)
}

fun testAll() {
println("Performing Sep12 tests...")
`test put, get customers`()
Expand Down
27 changes: 5 additions & 22 deletions platform/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -55,29 +55,12 @@ dependencies {
testImplementation(libs.okhttp3.tls)
}

tasks.test {
// Enable parallel test execution
systemProperty("junit.jupiter.execution.parallel.enabled", true)
// Enable parallel test execution
systemProperty("junit.jupiter.testinstance.lifecycle.default", "per_method")
// Allocate thread count based on available processors
systemProperty("junit.jupiter.execution.parallel.config.strategy", "dynamic")
// Set default parallel mode to same thread. All tests within a class are run in sequence.
systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent")
// Set default parallel mode for classes to concurrent. All test classes are run in parallel.
systemProperty("junit.jupiter.execution.parallel.mode.classes.default", "concurrent")
apply(from = "$rootDir/scripts.gradle.kts")
@Suppress("UNCHECKED_CAST")
val enableTestConcurrency = extra["enableTestConcurrency"] as (Test) -> Unit

// Set default test class order to order annotation. All test classes are run in parallel.
// Some tests take longer to run. Enabling the order will execute long-running tests first to
// shorten the overall test time.
systemProperty(
"junit.jupiter.testclass.order.default",
"org.junit.jupiter.api.ClassOrderer\$OrderAnnotation"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious why not include this in scriptw.gradle.kts?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that kind of make sense too. But it is not part of enableConcurrency. But we may refactor in the future if we think we should extract this as well.

)
maxParallelForks =
(Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1).also {
println("junit5 ... setting maxParallelForks to $it")
}
tasks.test {
enableTestConcurrency(this)
testLogging {
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
events = setOf(org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED)
Expand Down
24 changes: 24 additions & 0 deletions scripts.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
extra["enableTestConcurrency"] =
fun(test: Test) {
test.systemProperty("junit.jupiter.execution.parallel.enabled", true)
// Use PER_METHOD test instance life cycle. This avoids the race condition when tests are run in
// parallel mode and
// if the test class has a non-static fields. The non-static fields are shared across all test
// methods. If the life cycle is not PER_METHOD, the test methods may overwrite the fields and
// cause test failures.
//
// However, the life cycle can still be over-written by @TestInstance(Lifecycle) annotation.
// See https://junit.org/junit5/docs/current/user-guide/#writing-tests-parallel-execution
test.systemProperty("junit.jupiter.testinstance.lifecycle.default", "per_method")
// Allocate thread count based on available processors
test.systemProperty("junit.jupiter.execution.parallel.config.strategy", "dynamic")
// Set default parallel mode to same thread. All tests within a class are run in sequence.
test.systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent")
// Set default parallel mode for classes to concurrent. All test classes are run in parallel.
test.systemProperty("junit.jupiter.execution.parallel.mode.classes.default", "concurrent")

test.maxParallelForks =
(Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1).also {
println("$test setting maxParallelForks to $it")
}
}
Loading