Skip to content

Commit

Permalink
KTOR-7812 Use default JDK for running tests on CI (#4342)
Browse files Browse the repository at this point in the history
* Use LTS JDK in ktor-java-modules-test
* Allow reflective access to java.base modules from tests
* Enable JDK auto-provision
* Drop usage of unsupported curve secp128r1
* Enable dynamic agent loading
* Disable testCookiesWithWrongValue for Java engine
* Refactor onlyWithEngine
* Remove JUnit RetrySupport
  • Loading branch information
osipxd authored Nov 22, 2024
1 parent c9f58b1 commit a3bccae
Show file tree
Hide file tree
Showing 25 changed files with 150 additions and 253 deletions.
1 change: 1 addition & 0 deletions buildSrc/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pluginManagement {
}

plugins {
id("org.gradle.toolchains.foojay-resolver-convention")
id("conventions-dependency-resolution-management")
}

Expand Down
38 changes: 27 additions & 11 deletions buildSrc/src/main/kotlin/JvmConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.*

fun Project.configureJvm() {
val jdk = when (name) {
val compileJdk = when (name) {
in jdk11Modules -> 11
else -> 8
}
Expand Down Expand Up @@ -56,7 +56,7 @@ fun Project.configureJvm() {
maxHeapSize = "2g"
exclude("**/*StressTest*")
useJUnitPlatform()
configureJavaLauncher(jdk)
configureJavaToolchain(compileJdk)
}

tasks.register<Test>("stressTest") {
Expand All @@ -69,7 +69,7 @@ fun Project.configureJvm() {
systemProperty("enable.stress.tests", "true")
include("**/*StressTest*")
useJUnitPlatform()
configureJavaLauncher(jdk)
configureJavaToolchain(compileJdk)
}

val configuredVersion: String by rootProject.extra
Expand All @@ -86,15 +86,31 @@ fun Project.configureJvm() {
}

/**
* JUnit 5 requires Java 11+
* On local machine use for tests the JDK used for compilation.
* On CI use the default JDK.
*/
fun Test.configureJavaLauncher(jdk: Int) {
if (jdk < 11) {
val javaToolchains = project.extensions.getByType<JavaToolchainService>()
val customLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of("11")
}
javaLauncher = customLauncher
private fun Test.configureJavaToolchain(compileJdk: Int) {
// JUnit 5 requires JDK 11+
val testJdk = (if (CI) currentJdk else compileJdk).coerceAtLeast(11)
val javaToolchains = project.the<JavaToolchainService>()

javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(testJdk)
}

if (testJdk >= 16) {
// Allow reflective access from tests
jvmArgs(
"--add-opens=java.base/java.net=ALL-UNNAMED",
"--add-opens=java.base/java.time=ALL-UNNAMED",
"--add-opens=java.base/java.util=ALL-UNNAMED",
)
}

if (testJdk >= 21) {
// coroutines-debug use dynamic agent loading under the hood.
// Remove as soon as the issue is fixed: https://youtrack.jetbrains.com/issue/KT-62096/
jvmArgs("-XX:+EnableDynamicAgentLoading")
}
}

Expand Down
28 changes: 1 addition & 27 deletions buildSrc/src/main/kotlin/KtorBuildProperties.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,6 @@
*/

import org.gradle.api.*
import org.gradle.api.tasks.testing.*
import org.gradle.jvm.toolchain.*
import org.gradle.kotlin.dsl.*

/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

private val java_version: String = System.getProperty("java.version", "8.0.0")

private val versionComponents = java_version
.split(".")
.take(2)
.filter { it.isNotBlank() }
.map { Integer.parseInt(it) }

val IDEA_ACTIVE: Boolean = System.getProperty("idea.active") == "true"

Expand All @@ -30,7 +15,7 @@ val HOST_NAME = when {
else -> error("Unknown os name `$OS_NAME`")
}

val currentJdk = if (versionComponents[0] == 1) versionComponents[1] else versionComponents[0]
val currentJdk = JavaVersion.current().majorVersion.toInt()

val jdk11Modules = listOf(
"ktor-client-java",
Expand All @@ -40,14 +25,3 @@ val jdk11Modules = listOf(
"ktor-server-jetty-test-http2-jakarta",
"ktor-server-tomcat-jakarta",
)

fun Project.useJdkVersionForJvmTests(version: Int) {
tasks.named<Test>("jvmTest") {
val javaToolchains = project.extensions.getByType<JavaToolchainService>()
javaLauncher.set(
javaToolchains.launcherFor {
languageVersion.set(JavaLanguageVersion.of(version))
}
)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.client.engine.cio
Expand All @@ -11,26 +11,26 @@ import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.junit.*
import io.ktor.network.tls.certificates.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.utils.io.*
import kotlinx.coroutines.*
import kotlinx.coroutines.debug.junit5.*
import org.junit.jupiter.api.extension.*
import java.io.*
import java.net.*
import java.util.concurrent.*
import javax.net.ssl.*
import kotlin.concurrent.*
import kotlinx.coroutines.debug.junit5.CoroutinesTimeout
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import java.io.File
import java.net.ConnectException
import java.net.ServerSocket
import java.net.SocketException
import java.util.concurrent.TimeUnit
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager
import kotlin.concurrent.thread
import kotlin.test.*

@CoroutinesTimeout(5 * 60 * 1000)
@ExtendWith(RetrySupport::class)
class ConnectErrorsTest {

private val serverSocket = ServerSocket(0, 1)
Expand All @@ -40,7 +40,7 @@ class ConnectErrorsTest {
serverSocket.close()
}

@RetryableTest(3)
@Test
fun testConnectAfterConnectionErrors(): Unit = runBlocking {
val client = HttpClient(CIO) {
engine {
Expand Down Expand Up @@ -84,7 +84,7 @@ class ConnectErrorsTest {
}
}

@RetryableTest(3)
@Test
fun testResponseWithNoLengthChunkedAndConnectionClosedWithHttp10(): Unit = runBlocking {
val client = HttpClient(CIO)

Expand All @@ -110,7 +110,7 @@ class ConnectErrorsTest {
}
}

@RetryableTest(3)
@Test
fun testResponseErrorWithNoLengthChunkedAndConnectionClosedWithHttp11(): Unit = runBlocking {
val client = HttpClient(CIO)

Expand Down Expand Up @@ -183,7 +183,7 @@ class ConnectErrorsTest {
}
}

@RetryableTest(3)
@Test
fun testLateServerStart(): Unit = runBlocking {
val keyStoreFile = File("build/temp.jks")
val keyStore = generateCertificate(keyStoreFile, algorithm = "SHA256withECDSA", keySizeInBits = 256)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import test.server.*

/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

import test.server.*

description = "Ktor client Auth support"

apply<TestServerPlugin>()

useJdkVersionForJvmTests(11)
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/*
* Copyright 2014-2020 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

description = "Ktor client Byte Order Mark support"

useJdkVersionForJvmTests(11)
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

useJdkVersionForJvmTests(11)

apply<test.server.TestServerPlugin>()

kotlin.sourceSets {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

description = "Ktor client JSON support"

Expand Down Expand Up @@ -29,5 +29,3 @@ kotlin {
}
}
}

useJdkVersionForJvmTests(11)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

kotlin.sourceSets {
commonTest {
Expand All @@ -9,5 +9,3 @@ kotlin.sourceSets {
}
}
}

useJdkVersionForJvmTests(11)
8 changes: 0 additions & 8 deletions ktor-client/ktor-client-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@

import test.server.*

/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

description = "Common tests for client"

plugins {
Expand All @@ -16,8 +12,6 @@ plugins {

apply<TestServerPlugin>()

val osName = System.getProperty("os.name")

kotlin.sourceSets {
commonMain {
dependencies {
Expand Down Expand Up @@ -105,5 +99,3 @@ kotlin.sourceSets {
}
}
}

useJdkVersionForJvmTests(11)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.client.tests.plugins

Expand Down Expand Up @@ -186,7 +186,7 @@ class CookiesIntegrationTests : ClientLoader() {
}

@Test
fun testCookiesWithWrongValue() = clientTests(listOf("js", "Darwin", "DarwinLegacy", "WinHttp")) {
fun testCookiesWithWrongValue() = clientTests(listOf("Js", "Darwin", "DarwinLegacy", "WinHttp", "Java")) {
config {
install(HttpCookies)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import io.ktor.client.*
import io.ktor.client.engine.*
import io.ktor.util.reflect.*
import io.ktor.utils.io.*
import kotlinx.coroutines.*
import kotlinx.coroutines.debug.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.debug.CoroutineInfo
import kotlinx.coroutines.debug.DebugProbes
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import java.util.*
import kotlin.time.Duration.Companion.seconds

Expand Down Expand Up @@ -44,10 +47,17 @@ actual abstract class ClientLoader actual constructor(val timeoutSeconds: Int) {
}
}

fun shouldSkip(engine: HttpClientEngineContainer, skipEngines: List<String>, onlyWithEngine: String?): Boolean =
skipEngines.any { shouldSkip(engine.toString(), it, onlyWithEngine) }
private fun shouldSkip(
engine: HttpClientEngineContainer,
skipEngines: List<String>,
onlyWithEngine: String?
): Boolean {
val engineName = engine.toString()
return onlyWithEngine != null && !onlyWithEngine.equals(engineName, ignoreCase = true) ||
skipEngines.any { shouldSkip(engineName, it) }
}

fun shouldSkip(engineName: String, skipEngine: String, onlyWithEngine: String?): Boolean {
private fun shouldSkip(engineName: String, skipEngine: String): Boolean {
val locale = Locale.getDefault()
val skipEngineArray = skipEngine.lowercase(locale).split(":")

Expand All @@ -61,9 +71,8 @@ actual abstract class ClientLoader actual constructor(val timeoutSeconds: Int) {
val engineShouldBeSkipped = "*" == skipEngineName || engineName.lowercase(locale) == skipEngineName.lowercase(
locale
)
val notOnlyEngine = onlyWithEngine != null && engineName.lowercase(locale) != onlyWithEngine.lowercase(locale)

return (engineShouldBeSkipped && platformShouldBeSkipped) || notOnlyEngine
return engineShouldBeSkipped && platformShouldBeSkipped
}

@OptIn(ExperimentalCoroutinesApi::class)
Expand Down
13 changes: 4 additions & 9 deletions ktor-java-modules-test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,18 @@ tasks.named<JavaCompile>("compileJava") {
classpath = emptyClasspath
}
}

// Here should be specified the latest LTS version
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion = JavaLanguageVersion.of(21)
}
}

dependencies {
rootProject.subprojects
.filter { it.hasJavaModule }
.map {
generateSequence(it) { it.parent }
.toList()
.dropLast(1)
.reversed()
.joinToString(":", prefix = ":") { it.name }
}
.forEach { api(project(it)) }
.forEach { implementation(project(it.path)) }
}

internal val Project.hasJavaModule: Boolean
Expand Down
Loading

0 comments on commit a3bccae

Please sign in to comment.