From 7e77882c29bf0837ed186cba0f231be99405e116 Mon Sep 17 00:00:00 2001 From: Jamie Li Date: Tue, 24 Oct 2023 14:09:26 -0700 Subject: [PATCH 1/2] Refactor with enableTestConcurrency function --- api-schema/build.gradle.kts | 25 ++++---------------- build.gradle.kts | 8 ++++--- core/build.gradle.kts | 38 ++++++------------------------ integration-tests/build.gradle.kts | 13 +++------- platform/build.gradle.kts | 27 ++++----------------- scripts.gradle.kts | 24 +++++++++++++++++++ 6 files changed, 48 insertions(+), 87 deletions(-) create mode 100644 scripts.gradle.kts diff --git a/api-schema/build.gradle.kts b/api-schema/build.gradle.kts index 01ce980aef..b162a0ad0e 100644 --- a/api-schema/build.gradle.kts +++ b/api-schema/build.gradle.kts @@ -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) } diff --git a/build.gradle.kts b/build.gradle.kts index 1a25322e4d..517a06f245 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -123,6 +123,10 @@ subprojects { test { useJUnitPlatform() + systemProperty( + "junit.jupiter.testclass.order.default", + "org.junit.jupiter.api.ClassOrderer\$OrderAnnotation" + ) exclude("**/AnchorPlatformCustodyEnd2EndTest**") exclude("**/AnchorPlatformCustodyApiRpcEnd2EndTest**") @@ -181,6 +185,4 @@ allprojects { } } -tasks.register("printVersionName") { - println(rootProject.version.toString()) -} \ No newline at end of file +tasks.register("printVersionName") { println(rootProject.version.toString()) } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index dc26b99aa0..1b360130a9 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -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 @@ -119,33 +119,9 @@ publishing { configure { 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) } diff --git a/integration-tests/build.gradle.kts b/integration-tests/build.gradle.kts index 12bf019503..f7c646e96a 100644 --- a/integration-tests/build.gradle.kts +++ b/integration-tests/build.gradle.kts @@ -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) @@ -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 } } diff --git a/platform/build.gradle.kts b/platform/build.gradle.kts index bd1956ce2f..284b6f1e9c 100644 --- a/platform/build.gradle.kts +++ b/platform/build.gradle.kts @@ -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" - ) - 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) diff --git a/scripts.gradle.kts b/scripts.gradle.kts new file mode 100644 index 0000000000..2f2607af52 --- /dev/null +++ b/scripts.gradle.kts @@ -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") + } + } From 33b5ea76fb7389497a494db7e8492095a87b93c8 Mon Sep 17 00:00:00 2001 From: Jamie Li Date: Tue, 24 Oct 2023 15:06:08 -0700 Subject: [PATCH 2/2] Removed ambiguous status --- .../kotlin/org/stellar/anchor/platform/test/Sep12Tests.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/integration-tests/src/test/kotlin/org/stellar/anchor/platform/test/Sep12Tests.kt b/integration-tests/src/test/kotlin/org/stellar/anchor/platform/test/Sep12Tests.kt index 7145175ef8..22ae3f78eb 100644 --- a/integration-tests/src/test/kotlin/org/stellar/anchor/platform/test/Sep12Tests.kt +++ b/integration-tests/src/test/kotlin/org/stellar/anchor/platform/test/Sep12Tests.kt @@ -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 @@ -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 = "john.doe@stellar.org" @@ -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`()