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:
27
.github/workflows/build.yml
vendored
27
.github/workflows/build.yml
vendored
@ -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
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -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")
|
|
||||||
}
|
|
||||||
|
@ -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) {
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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"))
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
@ -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()
|
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"resources": [
|
"resources": [
|
||||||
{"pattern": "testlist.txt"},
|
|
||||||
{"pattern": "web-platform-test-urltestdata.txt"}
|
{"pattern": "web-platform-test-urltestdata.txt"}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -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")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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>) {
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user