1
0
mirror of https://github.com/square/okhttp.git synced 2025-07-31 05:04:26 +03:00

Update to official GraalVM tooling (#8613)

This commit is contained in:
Yuri Schimke
2024-12-21 10:56:29 +02:00
committed by GitHub
parent 38bab5dec1
commit fb22f4973e
27 changed files with 168 additions and 636 deletions

View File

@ -78,6 +78,15 @@ jobs:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 17
- uses: graalvm/setup-graalvm@v1
with:
distribution: 'graalvm'
java-version: 21
github-token: ${{ secrets.GITHUB_TOKEN }}
cache: 'gradle'
native-image-job-reports: true
components: 'native-image'
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v4
@ -446,20 +455,26 @@ jobs:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 17
- uses: graalvm/setup-graalvm@v1
with:
distribution: 'graalvm'
java-version: 21
github-token: ${{ secrets.GITHUB_TOKEN }}
cache: 'gradle'
native-image-job-reports: true
components: 'native-image'
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v4
- name: Build okcurl - name: Build okcurl
run: ./gradlew okcurl:nativeImage run: ./gradlew okcurl:nativeBuild
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v4
- name: Build ConsoleLauncher - name: Run native-image tests
run: ./gradlew -PgraalBuild=true native-image-tests:nativeImage run: ./gradlew -PgraalBuild=true native-image-tests:nativeTest
- name: Run Checks
run: ./native-image-tests/build/graal/ConsoleLauncher
testandroid: testandroid:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -19,7 +19,6 @@ buildscript {
classpath(libs.gradlePlugin.kotlinSerialization) classpath(libs.gradlePlugin.kotlinSerialization)
classpath(libs.gradlePlugin.androidJunit5) classpath(libs.gradlePlugin.androidJunit5)
classpath(libs.gradlePlugin.android) classpath(libs.gradlePlugin.android)
classpath(libs.gradlePlugin.graal)
classpath(libs.gradlePlugin.bnd) classpath(libs.gradlePlugin.bnd)
classpath(libs.gradlePlugin.shadow) classpath(libs.gradlePlugin.shadow)
classpath(libs.gradlePlugin.animalsniffer) classpath(libs.gradlePlugin.animalsniffer)
@ -28,6 +27,7 @@ buildscript {
classpath(libs.gradlePlugin.mavenPublish) classpath(libs.gradlePlugin.mavenPublish)
classpath(libs.gradlePlugin.binaryCompatibilityValidator) classpath(libs.gradlePlugin.binaryCompatibilityValidator)
classpath(libs.gradlePlugin.mavenSympathy) classpath(libs.gradlePlugin.mavenSympathy)
classpath(libs.gradlePlugin.graalvmBuildTools)
} }
repositories { repositories {
@ -143,9 +143,16 @@ subprojects {
signature(rootProject.libs.codehaus.signature.java18) { artifact { type = "signature" } } signature(rootProject.libs.codehaus.signature.java18) { artifact { type = "signature" } }
} }
val javaVersionSetting = when (project.name) {
"okcurl", "native-image-tests" -> "11"
else -> "1.8"
}
val projectJvmTarget = JvmTarget.fromTarget(javaVersionSetting)
val projectJavaVersion = JavaVersion.toVersion(javaVersionSetting)
tasks.withType<KotlinCompile> { tasks.withType<KotlinCompile> {
compilerOptions { compilerOptions {
jvmTarget.set(JvmTarget.JVM_1_8) jvmTarget.set(projectJvmTarget)
freeCompilerArgs = listOf( freeCompilerArgs = listOf(
"-Xjvm-default=all", "-Xjvm-default=all",
) )
@ -214,8 +221,8 @@ subprojects {
} }
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
sourceCompatibility = JavaVersion.VERSION_1_8.toString() sourceCompatibility = projectJavaVersion.toString()
targetCompatibility = JavaVersion.VERSION_1_8.toString() targetCompatibility = projectJavaVersion.toString()
} }
} }

View File

@ -5,7 +5,7 @@ checkStyle = "10.20.2"
com-squareup-moshi = "1.15.2" com-squareup-moshi = "1.15.2"
com-squareup-okio = "3.9.1" com-squareup-okio = "3.9.1"
de-mannodermaus-junit5 = "1.6.0" de-mannodermaus-junit5 = "1.6.0"
graalvm = "22.3.2" graalvm = "24.1.1"
kotlinx-serialization = "1.7.3" kotlinx-serialization = "1.7.3"
ksp = "2.1.0-1.0.29" ksp = "2.1.0-1.0.29"
mockserverClient = "5.15.0" mockserverClient = "5.15.0"
@ -32,13 +32,14 @@ bouncycastle-bcprov = { module = "org.bouncycastle:bcprov-jdk15to18", version.re
bouncycastle-bctls = { module = "org.bouncycastle:bctls-jdk15to18", version.ref = "org-bouncycastle" } bouncycastle-bctls = { module = "org.bouncycastle:bctls-jdk15to18", version.ref = "org-bouncycastle" }
brotli-dec = "org.brotli:dec:0.1.2" brotli-dec = "org.brotli:dec:0.1.2"
checkStyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkStyle" } checkStyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkStyle" }
clikt = "com.github.ajalt.clikt:clikt:4.4.0" clikt = "com.github.ajalt.clikt:clikt:5.0.2"
codehaus-signature-java18 = "org.codehaus.mojo.signature:java18:1.0" codehaus-signature-java18 = "org.codehaus.mojo.signature:java18:1.0"
conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref = "org-conscrypt" } conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref = "org-conscrypt" }
conscrypt-openjdk = { module = "org.conscrypt:conscrypt-openjdk-uber", version.ref = "org-conscrypt" } conscrypt-openjdk = { module = "org.conscrypt:conscrypt-openjdk-uber", version.ref = "org-conscrypt" }
converter-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" } converter-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
eclipseOsgi = "org.eclipse.platform:org.eclipse.osgi:3.22.0" eclipseOsgi = "org.eclipse.platform:org.eclipse.osgi:3.22.0"
findbugs-jsr305 = "com.google.code.findbugs:jsr305:3.0.2" findbugs-jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
graal-sdk = { module = "org.graalvm.sdk:graal-sdk", version.ref = "graalvm" }
gradlePlugin-android = "com.android.tools.build:gradle:8.7.3" gradlePlugin-android = "com.android.tools.build:gradle:8.7.3"
gradlePlugin-androidJunit5 = "de.mannodermaus.gradle.plugins:android-junit5:1.11.2.0" gradlePlugin-androidJunit5 = "de.mannodermaus.gradle.plugins:android-junit5:1.11.2.0"
gradlePlugin-animalsniffer = "ru.vyarus:gradle-animalsniffer-plugin:1.7.2" gradlePlugin-animalsniffer = "ru.vyarus:gradle-animalsniffer-plugin:1.7.2"
@ -46,7 +47,7 @@ gradlePlugin-binaryCompatibilityValidator = "org.jetbrains.kotlinx.binary-compat
gradlePlugin-bnd = { module = "biz.aQute.bnd:biz.aQute.bnd.gradle", version.ref = "biz-aQute-bnd" } gradlePlugin-bnd = { module = "biz.aQute.bnd:biz.aQute.bnd.gradle", version.ref = "biz-aQute-bnd" }
gradlePlugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.9.20" gradlePlugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.9.20"
gradlePlugin-errorprone = "net.ltgt.gradle:gradle-errorprone-plugin:4.1.0" gradlePlugin-errorprone = "net.ltgt.gradle:gradle-errorprone-plugin:4.1.0"
gradlePlugin-graal = "com.palantir.graal:gradle-graal:0.12.0" gradlePlugin-graalvmBuildTools = "org.graalvm.buildtools.native:org.graalvm.buildtools.native.gradle.plugin:0.10.4"
gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "org-jetbrains-kotlin" } gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "org-jetbrains-kotlin" }
gradlePlugin-kotlinSerialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "org-jetbrains-kotlin" } gradlePlugin-kotlinSerialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "org-jetbrains-kotlin" }
gradlePlugin-mavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.30.0" gradlePlugin-mavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.30.0"

View File

@ -3,21 +3,12 @@ Native Image Tests
This executes OkHttp's test suite inside a Graalvm image. This executes OkHttp's test suite inside a Graalvm image.
Build the Native Image
----------------------
Compile the classes and metadata into a Graalvm native image.
```
./gradlew --info native-image-tests:nativeImage
```
Execute Execute
------- -------
The native image runs JUnit 5 tests in the project. The native image runs JUnit 5 tests in the project.
``` ```
./native-image-tests/build/graal/ConsoleLauncher ./gradlew --info native-image-tests:nativeTest
``` ```

View File

@ -1,10 +1,26 @@
import org.apache.tools.ant.taskdefs.condition.Os
plugins { plugins {
id("com.palantir.graal") id("org.graalvm.buildtools.native")
kotlin("jvm") kotlin("jvm")
} }
animalsniffer {
isIgnoreFailures = true
}
val graal by sourceSets.creating
sourceSets {
named("graal") {}
test {
java.srcDirs(
"../okhttp-brotli/src/test/java",
"../okhttp-dnsoverhttps/src/test/java",
"../okhttp-logging-interceptor/src/test/java",
"../okhttp-sse/src/test/java",
)
}
}
dependencies { dependencies {
implementation(libs.junit.jupiter.api) implementation(libs.junit.jupiter.api)
implementation(libs.junit.jupiter.engine) implementation(libs.junit.jupiter.engine)
@ -21,7 +37,6 @@ dependencies {
implementation(projects.mockwebserver3) implementation(projects.mockwebserver3)
implementation(projects.mockwebserver) implementation(projects.mockwebserver)
implementation(projects.okhttpJavaNetCookiejar) implementation(projects.okhttpJavaNetCookiejar)
implementation(projects.mockwebserver3Junit4)
implementation(projects.mockwebserver3Junit5) implementation(projects.mockwebserver3Junit5)
implementation(libs.aqute.resolve) implementation(libs.aqute.resolve)
implementation(libs.junit.jupiter.api) implementation(libs.junit.jupiter.api)
@ -30,33 +45,24 @@ dependencies {
implementation(libs.kotlin.test.common) implementation(libs.kotlin.test.common)
implementation(libs.kotlin.test.junit) implementation(libs.kotlin.test.junit)
implementation(libs.nativeImageSvm)
compileOnly(libs.findbugs.jsr305) compileOnly(libs.findbugs.jsr305)
"graalCompileOnly"(libs.nativeImageSvm)
"graalCompileOnly"(libs.graal.sdk)
nativeImageTestCompileOnly(graal.output.classesDirs)
} }
animalsniffer { graalvmNative {
isIgnoreFailures = true testSupport = true
}
sourceSets { binaries {
main { named("test") {
java.srcDirs( buildArgs.add("--features=okhttp3.nativeImage.TestRegistration")
"../okhttp-brotli/src/test/java", buildArgs.add("--initialize-at-build-time=org.junit.platform.engine.TestTag")
"../okhttp-dnsoverhttps/src/test/java", buildArgs.add("--strict-image-heap")
"../okhttp-logging-interceptor/src/test/java",
"../okhttp-sse/src/test/java", // speed up development testing
) buildArgs.add("-Ob")
}
} }
} }
graal {
mainClass("okhttp3.RunTestsKt")
outputName("ConsoleLauncher")
graalVersion(libs.versions.graalvm.get())
javaVersion("11")
option("--no-fallback")
option("--report-unsupported-elements-at-runtime")
option("-H:+ReportExceptionStackTraces")
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (C) 2020 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3.nativeImage
import org.graalvm.nativeimage.hosted.Feature
class TestRegistration : Feature {
override fun beforeAnalysis(access: Feature.BeforeAnalysisAccess) {
}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright (C) 2020 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3
import java.io.OutputStream
import java.io.PrintStream
import org.junit.platform.engine.TestExecutionResult
import org.junit.platform.launcher.TestExecutionListener
import org.junit.platform.launcher.TestIdentifier
import org.junit.platform.launcher.TestPlan
object DotListener : TestExecutionListener {
private var originalSystemErr: PrintStream? = null
private var originalSystemOut: PrintStream? = null
private var testCount = 0
override fun executionSkipped(
testIdentifier: TestIdentifier,
reason: String,
) {
printStatus("-")
}
private fun printStatus(s: String) {
if (++testCount % 80 == 0) {
printStatus("\n")
}
originalSystemErr?.print(s)
}
override fun executionFinished(
testIdentifier: TestIdentifier,
testExecutionResult: TestExecutionResult,
) {
if (!testIdentifier.isContainer) {
when (testExecutionResult.status!!) {
TestExecutionResult.Status.ABORTED -> printStatus("-")
TestExecutionResult.Status.FAILED -> printStatus("F")
TestExecutionResult.Status.SUCCESSFUL -> printStatus(".")
}
}
}
override fun testPlanExecutionFinished(testPlan: TestPlan) {
originalSystemErr?.println()
}
fun install() {
originalSystemOut = System.out
originalSystemErr = System.err
System.setOut(object : PrintStream(OutputStream.nullOutputStream()) {})
System.setErr(object : PrintStream(OutputStream.nullOutputStream()) {})
}
fun uninstall() {
originalSystemOut.let {
System.setOut(it)
}
originalSystemErr.let {
System.setErr(it)
}
}
}

View File

@ -1,56 +0,0 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3
import java.io.File
import org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor
import org.junit.platform.engine.discovery.DiscoverySelectors
// TODO move to junit5 tags
val avoidedTests =
setOf(
"okhttp3.BouncyCastleTest",
"okhttp3.ConscryptTest",
"okhttp3.CorrettoTest",
"okhttp3.OpenJSSETest",
"okhttp3.internal.platform.Jdk8WithJettyBootPlatformTest",
"okhttp3.internal.platform.Jdk9PlatformTest",
"okhttp3.internal.platform.PlatformTest",
"okhttp3.internal.platform.android.AndroidSocketAdapterTest",
"okhttp3.osgi.OsgiTest",
// Hanging.
"okhttp3.CookiesTest",
// Hanging.
"okhttp3.WholeOperationTimeoutTest",
)
/**
* Run periodically to refresh the known set of working tests.
*
* TODO use filtering to allow skipping acceptable problem tests
*/
fun main() {
val knownTestFile = File("native-image-tests/src/main/resources/testlist.txt")
val testSelector = DiscoverySelectors.selectPackage("okhttp3")
val testClasses =
findTests(listOf(testSelector))
.filter { it.isContainer }
.mapNotNull { (it as? ClassBasedTestDescriptor)?.testClass?.name }
.filterNot { it in avoidedTests }
.sorted()
.distinct()
knownTestFile.writeText(testClasses.joinToString("\n"))
}

View File

@ -1,153 +0,0 @@
/*
* Copyright (C) 2020 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3
import java.io.File
import java.io.PrintWriter
import kotlin.system.exitProcess
import org.junit.jupiter.engine.JupiterTestEngine
import org.junit.platform.console.options.Theme
import org.junit.platform.engine.DiscoverySelector
import org.junit.platform.engine.TestDescriptor
import org.junit.platform.engine.TestEngine
import org.junit.platform.engine.discovery.DiscoverySelectors.selectClass
import org.junit.platform.launcher.Launcher
import org.junit.platform.launcher.LauncherDiscoveryRequest
import org.junit.platform.launcher.PostDiscoveryFilter
import org.junit.platform.launcher.TestExecutionListener
import org.junit.platform.launcher.core.EngineDiscoveryOrchestrator
import org.junit.platform.launcher.core.LauncherConfig
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder
import org.junit.platform.launcher.core.LauncherFactory
import org.junit.platform.launcher.listeners.SummaryGeneratingListener
/**
* Graal main method to run tests with minimal reflection and automatic settings.
* Uses the test list in native-image-tests/src/main/resources/testlist.txt.
*/
fun main(vararg args: String) {
System.setProperty("junit.jupiter.extensions.autodetection.enabled", "true")
val inputFile = if (args.isNotEmpty()) File(args[0]) else null
val selectors = testSelectors(inputFile)
val summaryListener = SummaryGeneratingListener()
val treeListener = treeListener()
val jupiterTestEngine = buildTestEngine()
val config =
LauncherConfig.builder()
.enableTestExecutionListenerAutoRegistration(false)
.enableTestEngineAutoRegistration(false)
.enablePostDiscoveryFilterAutoRegistration(false)
.addTestEngines(jupiterTestEngine)
.addTestExecutionListeners(DotListener, summaryListener, treeListener)
.build()
val launcher: Launcher = LauncherFactory.create(config)
val request: LauncherDiscoveryRequest = buildRequest(selectors)
DotListener.install()
try {
launcher.execute(request)
} finally {
DotListener.uninstall()
}
val summary = summaryListener.summary
summary.printTo(PrintWriter(System.out))
exitProcess(if (summary.testsFailedCount != 0L) -1 else 0)
}
/**
* Builds the Junit Test Engine for the native image.
*/
fun buildTestEngine(): TestEngine = JupiterTestEngine()
/**
* Returns a fixed set of test classes from testlist.txt, skipping any not found in the
* current classpath. The IDE runs with less classes to avoid conflicting module ownership.
*/
fun testSelectors(inputFile: File? = null): List<DiscoverySelector> {
val sampleTestClass = SampleTest::class.java
val lines =
inputFile?.readLines() ?: sampleTestClass.getResource("/testlist.txt").readText().lines()
val flatClassnameList =
lines
.filter { it.isNotBlank() }
return flatClassnameList
.mapNotNull {
try {
selectClass(Class.forName(it, false, sampleTestClass.classLoader))
} catch (cnfe: ClassNotFoundException) {
println("Missing test class: $cnfe")
null
}
}
}
/**
* Builds a Junit Test Plan request for a fixed set of classes, or potentially a recursive package.
*/
fun buildRequest(selectors: List<DiscoverySelector>): LauncherDiscoveryRequest {
val request: LauncherDiscoveryRequest =
LauncherDiscoveryRequestBuilder.request()
// TODO replace junit.jupiter.extensions.autodetection.enabled with API approach.
// .enableImplicitConfigurationParameters(false)
.selectors(selectors)
.build()
return request
}
/**
* Flattens a test filter into a list of specific test descriptors, usually individual method in a
* test class annotated with @Test.
*/
fun findTests(selectors: List<DiscoverySelector>): List<TestDescriptor> {
val request: LauncherDiscoveryRequest = buildRequest(selectors)
val testEngine = buildTestEngine()
val filters = listOf<PostDiscoveryFilter>()
val discoveryOrchestrator = EngineDiscoveryOrchestrator(listOf(testEngine), filters)
val discovered = discoveryOrchestrator.discover(request, EngineDiscoveryOrchestrator.Phase.EXECUTION)
return discovered.getEngineTestDescriptor(testEngine).descendants.toList()
}
/**
* Builds the awkwardly package private TreePrintingListener listener which we would like to use
* from ConsoleLauncher.
*
* https://github.com/junit-team/junit5/issues/2469
*/
fun treeListener(): TestExecutionListener {
val colorPalette =
Class.forName("org.junit.platform.console.tasks.ColorPalette").getField("DEFAULT").apply {
isAccessible = true
}.get(null)
return Class.forName(
"org.junit.platform.console.tasks.TreePrintingListener",
).declaredConstructors.first()
.apply {
isAccessible = true
}
.newInstance(PrintWriter(System.out), colorPalette, Theme.UNICODE) as TestExecutionListener
}

View File

@ -1,109 +0,0 @@
/*
* Copyright (C) 2020 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3
import com.oracle.svm.core.annotate.AutomaticFeature
import java.io.File
import java.lang.IllegalStateException
import org.graalvm.nativeimage.hosted.Feature
import org.graalvm.nativeimage.hosted.RuntimeClassInitialization
import org.graalvm.nativeimage.hosted.RuntimeReflection
@AutomaticFeature
class TestRegistration : Feature {
override fun beforeAnalysis(access: Feature.BeforeAnalysisAccess) {
// Presumably needed for parsing the testlist.txt file.
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("kotlin.text.Charsets"))
registerKnownTests(access)
registerJupiterClasses(access)
registerParamProvider(access, "okhttp3.SampleTestProvider")
registerParamProvider(access, "okhttp3.internal.http.CancelModelParamProvider")
registerParamProvider(access, "okhttp3.internal.cache.FileSystemParamProvider")
registerParamProvider(access, "okhttp3.internal.http2.HttpOverHttp2Test\$ProtocolParamProvider")
registerParamProvider(access, "okhttp3.internal.cache.FileSystemParamProvider")
registerParamProvider(access, "okhttp3.WebPlatformUrlTest\$TestDataParamProvider")
}
private fun registerParamProvider(
access: Feature.BeforeAnalysisAccess,
provider: String,
) {
val providerClass = access.findClassByName(provider)
if (providerClass != null) {
registerTest(access, providerClass)
} else {
println("Missing $provider")
}
}
private fun registerJupiterClasses(access: Feature.BeforeAnalysisAccess) {
registerStandardClass(access, "org.junit.jupiter.params.ParameterizedTestExtension")
registerStandardClass(access, "org.junit.platform.console.tasks.TreePrintingListener")
}
private fun registerStandardClass(
access: Feature.BeforeAnalysisAccess,
name: String,
) {
val clazz: Class<*> = access.findClassByName(name) ?: throw IllegalStateException("Missing class $name")
RuntimeReflection.register(clazz)
clazz.declaredConstructors.forEach {
RuntimeReflection.register(it)
}
}
private fun registerKnownTests(access: Feature.BeforeAnalysisAccess) {
val knownTestFile = File("src/main/resources/testlist.txt").absoluteFile
knownTestFile.readLines().forEach {
try {
val testClass = access.findClassByName(it)
if (testClass != null) {
access.registerAsUsed(testClass)
registerTest(access, testClass)
}
} catch (e: Exception) {
// If you throw an exception here then native image building fails half way through
// silently without rewriting the binary. So we report noisily, but keep going and prefer
// running most tests still.
e.printStackTrace()
}
}
}
private fun registerTest(
access: Feature.BeforeAnalysisAccess,
java: Class<*>,
) {
access.registerAsUsed(java)
RuntimeReflection.register(java)
java.constructors.forEach {
RuntimeReflection.register(it)
}
java.declaredMethods.forEach {
RuntimeReflection.register(it)
}
java.declaredFields.forEach {
RuntimeReflection.register(it)
}
java.methods.forEach {
RuntimeReflection.register(it)
}
}
}

View File

@ -1,86 +0,0 @@
okhttp3.AddressTest
okhttp3.CacheControlTest
okhttp3.CacheCorruptionTest
okhttp3.CacheTest
okhttp3.CallHandshakeTest
okhttp3.CallKotlinTest
okhttp3.CallTest
okhttp3.CertificateChainCleanerTest
okhttp3.CertificatePinnerKotlinTest
okhttp3.CertificatePinnerTest
okhttp3.CipherSuiteTest
okhttp3.ConnectionCoalescingTest
okhttp3.ConnectionReuseTest
okhttp3.ConnectionSpecTest
okhttp3.CookieTest
okhttp3.DispatcherTest
okhttp3.DuplexTest
okhttp3.EventListenerTest
okhttp3.FormBodyTest
okhttp3.HandshakeTest
okhttp3.HeadersKotlinTest
okhttp3.HeadersTest
okhttp3.HttpUrlTest
okhttp3.InsecureForHostTest
okhttp3.InterceptorTest
okhttp3.KotlinDeprecationErrorTest
okhttp3.KotlinSourceModernTest
okhttp3.MediaTypeGetTest
okhttp3.MediaTypeTest
okhttp3.MultipartBodyTest
okhttp3.MultipartReaderTest
okhttp3.OkHttpClientTest
okhttp3.OkHttpTest
okhttp3.ProtocolTest
okhttp3.PublicSuffixDatabaseTest
okhttp3.PublicInternalApiTest
okhttp3.RequestTest
okhttp3.ResponseBodyTest
okhttp3.ResponseTest
okhttp3.SampleTest
okhttp3.ServerTruncatesRequestTest
okhttp3.SocksProxyTest
okhttp3.URLConnectionTest
okhttp3.WebPlatformUrlTest
okhttp3.brotli.BrotliInterceptorJavaApiTest
okhttp3.brotli.BrotliInterceptorTest
okhttp3.dnsoverhttps.DnsOverHttpsTest
okhttp3.dnsoverhttps.DnsRecordCodecTest
okhttp3.internal.UtilTest
okhttp3.internal.authenticator.JavaNetAuthenticatorTest
okhttp3.internal.cache.DiskLruCacheTest
okhttp3.internal.cache2.FileOperatorTest
okhttp3.internal.cache2.RelayTest
okhttp3.internal.concurrent.TaskLoggerTest
okhttp3.internal.concurrent.TaskRunnerRealBackendTest
okhttp3.internal.concurrent.TaskRunnerTest
okhttp3.internal.connection.ConnectionPoolTest
okhttp3.internal.connection.ConnectionSpecSelectorTest
okhttp3.internal.connection.RouteExceptionTest
okhttp3.internal.connection.RouteSelectorTest
okhttp3.internal.http.CancelTest
okhttp3.internal.http.HttpDateTest
okhttp3.internal.http.StatusLineTest
okhttp3.internal.http.ThreadInterruptTest
okhttp3.internal.http2.FrameLogTest
okhttp3.internal.http2.HpackTest
okhttp3.internal.http2.Http2ConnectionTest
okhttp3.internal.http2.Http2Test
okhttp3.internal.http2.HttpOverHttp2Test
okhttp3.internal.http2.HuffmanTest
okhttp3.internal.http2.SettingsTest
okhttp3.internal.publicsuffix.PublicSuffixDatabaseTest
okhttp3.internal.tls.CertificatePinnerChainValidationTest
okhttp3.internal.tls.ClientAuthTest
okhttp3.internal.tls.HostnameVerifierTest
okhttp3.internal.ws.MessageDeflaterInflaterTest
okhttp3.internal.ws.RealWebSocketTest
okhttp3.internal.ws.WebSocketExtensionsTest
okhttp3.internal.ws.WebSocketHttpTest
okhttp3.internal.ws.WebSocketReaderTest
okhttp3.internal.ws.WebSocketWriterTest
okhttp3.logging.HttpLoggingInterceptorTest
okhttp3.logging.IsProbablyUtf8Test
okhttp3.logging.LoggingEventListenerTest
okhttp3.sse.internal.EventSourceHttpTest
okhttp3.sse.internal.ServerSentEventIteratorTest

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2020 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3.nativeImage
import okhttp3.SampleTest
import okhttp3.findTests
import okhttp3.testSelectors
import okhttp3.treeListener
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
import org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor
import org.junit.platform.engine.discovery.DiscoverySelectors
class NativeImageTestsTest {
@Test
fun testFindsFixedTestsForImage() {
val testSelector = testSelectors()
val x = findTests(testSelector)
x.find { it is ClassBasedTestDescriptor && it.testClass == SampleTest::class.java }
}
@Test
fun testFindsModuleTests() {
val testSelector = DiscoverySelectors.selectPackage("okhttp3")
val x = findTests(listOf(testSelector))
x.find { it is ClassBasedTestDescriptor && it.testClass == SampleTest::class.java }
}
@Test
fun testFindsProjectTests() {
val testSelector = DiscoverySelectors.selectPackage("okhttp3")
val x = findTests(listOf(testSelector))
x.find { it is ClassBasedTestDescriptor && it.testClass == SampleTest::class.java }
}
@Test
fun testTreeListener() {
val listener = treeListener()
assertNotNull(listener)
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3 package okhttp3.nativeImage
import assertk.assertThat import assertk.assertThat
import assertk.assertions.isEqualTo import assertk.assertions.isEqualTo

View File

@ -13,18 +13,24 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3 package okhttp3.nativeImage
import assertk.assertThat import assertk.assertThat
import assertk.assertions.isEqualTo import assertk.assertions.isEqualTo
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import mockwebserver3.junit5.internal.MockWebServerExtension
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClientTestRule
import okhttp3.Request
import okhttp3.SimpleProvider
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ArgumentsSource import org.junit.jupiter.params.provider.ArgumentsSource
@ExtendWith(MockWebServerExtension::class)
class SampleTest { class SampleTest {
@JvmField @RegisterExtension @JvmField @RegisterExtension
val clientRule = OkHttpClientTestRule() val clientRule = OkHttpClientTestRule()

View File

@ -1,6 +1,5 @@
{ {
"resources": [ "resources": [
{"pattern": "testlist.txt"},
{"pattern": "web-platform-test-urltestdata.txt"} {"pattern": "web-platform-test-urltestdata.txt"}
] ]
} }

View File

@ -6,7 +6,7 @@ plugins {
kotlin("jvm") kotlin("jvm")
id("org.jetbrains.dokka") id("org.jetbrains.dokka")
id("com.vanniktech.maven.publish.base") id("com.vanniktech.maven.publish.base")
id("com.palantir.graal") id("org.graalvm.buildtools.native")
id("com.github.johnrengelman.shadow") id("com.github.johnrengelman.shadow")
} }
@ -53,19 +53,12 @@ tasks.shadowJar {
mergeServiceFiles() mergeServiceFiles()
} }
graal { graalvmNative {
mainClass("okhttp3.curl.MainCommandLineKt") binaries {
outputName("okcurl") named("main") {
graalVersion(libs.versions.graalvm.get()) imageName = "okcurl"
javaVersion("11") mainClass = "okhttp3.curl.MainCommandLineKt"
}
option("--no-fallback")
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
// May be possible without, but autodetection is problematic on Windows 10
// see https://github.com/palantir/gradle-graal
// see https://www.graalvm.org/docs/reference-manual/native-image/#prerequisites
windowsVsVarsPath("C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat")
} }
} }

View File

@ -16,9 +16,12 @@
package okhttp3.curl package okhttp3.curl
import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.parameters.arguments.argument import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.help
import com.github.ajalt.clikt.parameters.options.default import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.help
import com.github.ajalt.clikt.parameters.options.multiple import com.github.ajalt.clikt.parameters.options.multiple
import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.int import com.github.ajalt.clikt.parameters.types.int
@ -39,42 +42,54 @@ import okhttp3.internal.platform.Platform
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.LoggingEventListener import okhttp3.logging.LoggingEventListener
class Main : CliktCommand(name = NAME, help = "A curl for the next-generation web.") { class Main : CliktCommand(name = NAME) {
val method: String? by option("-X", "--request", help = "Specify request command to use") override val printHelpOnEmptyArgs = true
val data: String? by option("-d", "--data", help = "HTTP POST data") override fun help(context: Context): String = "A curl for the next-generation web."
val headers: List<String>? by option("-H", "--header", help = "Custom header to pass to server").multiple() val method: String? by option("-X", "--request").help("Specify request command to use")
val userAgent: String by option("-A", "--user-agent", help = "User-Agent to send to server").default(NAME + "/" + versionString()) val data: String? by option("-d", "--data").help("HTTP POST data")
val headers: List<String>? by option("-H", "--header").help("Custom header to pass to server").multiple()
val userAgent: String by option(
"-A",
"--user-agent",
).help(
"User-Agent to send to server",
).default(NAME + "/" + versionString())
val connectTimeout: Int by option( val connectTimeout: Int by option(
"--connect-timeout", "--connect-timeout",
help = "Maximum time allowed for connection (seconds)", ).help(
"Maximum time allowed for connection (seconds)",
).int().default(DEFAULT_TIMEOUT) ).int().default(DEFAULT_TIMEOUT)
val readTimeout: Int by option("--read-timeout", help = "Maximum time allowed for reading data (seconds)").int().default(DEFAULT_TIMEOUT) val readTimeout: Int by option("--read-timeout").help("Maximum time allowed for reading data (seconds)").int()
.default(DEFAULT_TIMEOUT)
val callTimeout: Int by option( val callTimeout: Int by option(
"--call-timeout", "--call-timeout",
help = "Maximum time allowed for the entire call (seconds)", ).help(
"Maximum time allowed for the entire call (seconds)",
).int().default(DEFAULT_TIMEOUT) ).int().default(DEFAULT_TIMEOUT)
val followRedirects: Boolean by option("-L", "--location", help = "Follow redirects").flag() val followRedirects: Boolean by option("-L", "--location").help("Follow redirects").flag()
val allowInsecure: Boolean by option("-k", "--insecure", help = "Allow connections to SSL sites without certs").flag() val allowInsecure: Boolean by option("-k", "--insecure").help("Allow connections to SSL sites without certs").flag()
val showHeaders: Boolean by option("-i", "--include", help = "Include protocol headers in the output").flag() val showHeaders: Boolean by option("-i", "--include").help("Include protocol headers in the output").flag()
val showHttp2Frames: Boolean by option("--frames", help = "Log HTTP/2 frames to STDERR").flag() val showHttp2Frames: Boolean by option("--frames").help("Log HTTP/2 frames to STDERR").flag()
val referer: String? by option("-e", "--referer", help = "Referer URL") val referer: String? by option("-e", "--referer").help("Referer URL")
val verbose: Boolean by option("-v", "--verbose", help = "Makes $NAME verbose during the operation").flag() val verbose: Boolean by option("-v", "--verbose").help("Makes $NAME verbose during the operation").flag()
val sslDebug: Boolean by option(help = "Output SSL Debug").flag() val sslDebug: Boolean by option("--sslDebug").help("Output SSL Debug").flag()
val url: String? by argument(name = "url", help = "Remote resource URL") val url: String? by argument(name = "url").help("Remote resource URL")
var client: Call.Factory? = null var client: Call.Factory? = null
@ -129,17 +144,20 @@ class Main : CliktCommand(name = NAME, help = "A curl for the next-generation we
return prop.getProperty("version", "dev") return prop.getProperty("version", "dev")
} }
@Suppress("TrustAllX509TrustManager", "CustomX509TrustManager")
private fun createInsecureTrustManager(): X509TrustManager = private fun createInsecureTrustManager(): X509TrustManager =
object : X509TrustManager { object : X509TrustManager {
override fun checkClientTrusted( override fun checkClientTrusted(
chain: Array<X509Certificate>, chain: Array<X509Certificate>,
authType: String, authType: String,
) {} ) {
}
override fun checkServerTrusted( override fun checkServerTrusted(
chain: Array<X509Certificate>, chain: Array<X509Certificate>,
authType: String, authType: String,
) {} ) {
}
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf() override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
} }

View File

@ -15,6 +15,7 @@
*/ */
package okhttp3.curl package okhttp3.curl
import com.github.ajalt.clikt.core.main
import kotlin.system.exitProcess import kotlin.system.exitProcess
fun main(args: Array<String>) { fun main(args: Array<String>) {

View File

@ -19,6 +19,7 @@ import assertk.assertThat
import assertk.assertions.isEqualTo import assertk.assertions.isEqualTo
import assertk.assertions.isNull import assertk.assertions.isNull
import assertk.assertions.startsWith import assertk.assertions.startsWith
import com.github.ajalt.clikt.core.parse
import java.io.IOException import java.io.IOException
import kotlin.test.Test import kotlin.test.Test
import okhttp3.RequestBody import okhttp3.RequestBody

View File

@ -15,6 +15,7 @@
*/ */
package okhttp3.curl package okhttp3.curl
import com.github.ajalt.clikt.core.main
import kotlin.test.Test import kotlin.test.Test
class OkcurlTest { class OkcurlTest {

View File

@ -31,6 +31,7 @@ import java.net.UnknownHostException
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import mockwebserver3.junit5.internal.MockWebServerExtension
import okhttp3.Cache import okhttp3.Cache
import okhttp3.Dns import okhttp3.Dns
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -45,9 +46,11 @@ import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
@Tag("Slowish") @Tag("Slowish")
@ExtendWith(MockWebServerExtension::class)
class DnsOverHttpsTest { class DnsOverHttpsTest {
@RegisterExtension @RegisterExtension
val platform = PlatformRule() val platform = PlatformRule()

View File

@ -19,11 +19,12 @@ import assertk.assertThat
import assertk.assertions.isEqualTo import assertk.assertions.isEqualTo
import assertk.assertions.isLessThan import assertk.assertions.isLessThan
import assertk.assertions.isLessThanOrEqualTo import assertk.assertions.isLessThanOrEqualTo
import assertk.assertions.isSameAs import assertk.assertions.isSameInstanceAs
import assertk.assertions.matches import assertk.assertions.matches
import java.net.UnknownHostException import java.net.UnknownHostException
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import mockwebserver3.junit5.internal.MockWebServerExtension
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.MediaType import okhttp3.MediaType
@ -44,8 +45,10 @@ import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.Assumptions import org.junit.jupiter.api.Assumptions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
@ExtendWith(MockWebServerExtension::class)
class HttpLoggingInterceptorTest { class HttpLoggingInterceptorTest {
@RegisterExtension @RegisterExtension
val platform = PlatformRule() val platform = PlatformRule()
@ -104,7 +107,7 @@ class HttpLoggingInterceptorTest {
@Test @Test
fun setLevelShouldReturnSameInstanceOfInterceptor() { fun setLevelShouldReturnSameInstanceOfInterceptor() {
for (level in Level.entries) { for (level in Level.entries) {
assertThat(applicationInterceptor.setLevel(level)).isSameAs(applicationInterceptor) assertThat(applicationInterceptor.setLevel(level)).isSameInstanceAs(applicationInterceptor)
} }
} }

View File

@ -23,6 +23,7 @@ import java.util.Arrays
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import mockwebserver3.SocketPolicy.FailHandshake import mockwebserver3.SocketPolicy.FailHandshake
import mockwebserver3.junit5.internal.MockWebServerExtension
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -36,9 +37,11 @@ import okhttp3.testing.PlatformRule
import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
@Suppress("ktlint:standard:max-line-length") @Suppress("ktlint:standard:max-line-length")
@ExtendWith(MockWebServerExtension::class)
class LoggingEventListenerTest { class LoggingEventListenerTest {
@RegisterExtension @RegisterExtension
val platform = PlatformRule() val platform = PlatformRule()

View File

@ -21,6 +21,7 @@ import assertk.assertions.isEqualTo
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import mockwebserver3.junit5.internal.MockWebServerExtension
import okhttp3.OkHttpClientTestRule import okhttp3.OkHttpClientTestRule
import okhttp3.RecordingEventListener import okhttp3.RecordingEventListener
import okhttp3.Request import okhttp3.Request
@ -31,10 +32,12 @@ import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
import org.junitpioneer.jupiter.RetryingTest import org.junitpioneer.jupiter.RetryingTest
@Tag("Slowish") @Tag("Slowish")
@ExtendWith(MockWebServerExtension::class)
class EventSourceHttpTest { class EventSourceHttpTest {
@RegisterExtension @RegisterExtension
val platform = PlatformRule() val platform = PlatformRule()

View File

@ -17,6 +17,7 @@ package okhttp3.sse.internal
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import mockwebserver3.junit5.internal.MockWebServerExtension
import okhttp3.OkHttpClientTestRule import okhttp3.OkHttpClientTestRule
import okhttp3.Request import okhttp3.Request
import okhttp3.sse.EventSources.processResponse import okhttp3.sse.EventSources.processResponse
@ -25,9 +26,11 @@ import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.extension.RegisterExtension
@Tag("Slowish") @Tag("Slowish")
@ExtendWith(MockWebServerExtension::class)
class EventSourcesHttpTest { class EventSourcesHttpTest {
@RegisterExtension @RegisterExtension
val platform = PlatformRule() val platform = PlatformRule()

View File

@ -18,7 +18,6 @@ package okhttp3.internal.graal
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
import org.graalvm.nativeimage.hosted.Feature import org.graalvm.nativeimage.hosted.Feature
import org.graalvm.nativeimage.hosted.RuntimeResourceAccess
/** /**
* Automatic configuration of OkHttp for native images. * Automatic configuration of OkHttp for native images.
@ -27,10 +26,5 @@ import org.graalvm.nativeimage.hosted.RuntimeResourceAccess
*/ */
class OkHttpFeature : Feature { class OkHttpFeature : Feature {
@IgnoreJRERequirement @IgnoreJRERequirement
override fun beforeAnalysis(access: Feature.BeforeAnalysisAccess?) { override fun beforeAnalysis(access: Feature.BeforeAnalysisAccess?) = Unit
RuntimeResourceAccess.addResource(
ClassLoader.getSystemClassLoader().getUnnamedModule(),
"okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz",
)
}
} }

View File

@ -1 +1 @@
Args = -H:+AddAllCharsets -H:EnableURLProtocols=http,https --enable-https --features=okhttp3.internal.graal.OkHttpFeature Args = -H:+AddAllCharsets --enable-http --enable-https --features=okhttp3.internal.graal.OkHttpFeature --report-unsupported-elements-at-runtime