Skip to content

Commit

Permalink
Quarkus native test (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
mizosoft committed Apr 29, 2024
1 parent c99b77d commit 1c57604
Show file tree
Hide file tree
Showing 11 changed files with 370 additions and 32 deletions.
32 changes: 28 additions & 4 deletions .github/actions/gradle/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,37 @@ description: Setup Java & Gradle & optionally run a Gradle command
inputs:
java:
default: '21'
description: Java version
description: Java version. Set to 'GraalVM' for a GraalVM setup.
gradle-args:
required: false
description: Arguments to Gradle command (optional)
description: Arguments to Gradle command (optional).
cmd:
required: false
description: Command to run (optional). Runs after Gradle if gradle-args is set.

runs:
using: composite
steps:
- name: Setup Java ${{ inputs.java }}
id: setup-java
if: inputs.java != 'GraalVM'
uses: actions/setup-java@v4
with:
java-version: ${{ inputs.java }}
distribution: temurin

- name: Setup Java ${{ inputs.java }}
if: inputs.java == 'GraalVM'
uses: graalvm/setup-graalvm@v1
with:
java-version: '21'
distribution: graalvm-community
github-token: ${{ github.token }}

- name: Verify GraalVM installation
if: inputs.java == 'GraalVM'
shell: bash
run: native-image --version

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

Expand All @@ -29,8 +45,16 @@ runs:
run: chmod +x gradlew

- name: Run Gradle command
if: ${{ inputs.gradle-args }} != ''
if: inputs.gradle-args != ''
env:
JAVA_HOME: ${{ steps.setup-gradle-jdk.outputs.path }}
shell: bash
run: ./gradlew ${{ inputs.gradle-args }}

- name: Run command
if: inputs.cmd != ''
env:
JAVA_HOME: ${{ steps.setup-gradle-jdk.outputs.path }}
shell: bash
run: |
${{ inputs.cmd }}
25 changes: 25 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,31 @@ jobs:
**/build/test-results/
**/build/**/*.exec
native-tests:
name: Test on GraalVM
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run tests
uses: ./.github/actions/gradle
with:
java: GraalVM
cmd: |
# For some reason, this never works with one command either by just running `build` or
# running `quarkusBuild` & `test` on one run.
./gradlew :quarkus-native-test:quarkusBuild -PincludeNativeTests
./gradlew :quarkus-native-test:test -PincludeNativeTests
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: ubuntu-java-native-test-results
path: |
**/build/test-results/
**/build/**/*.exec
coverage:
name: Upload coverage report
needs: tests
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package conventions

import extensions.enableCheckerframework
import extensions.enableErrorprone
import extensions.libs
import net.ltgt.gradle.errorprone.errorprone
import net.ltgt.gradle.nullaway.nullaway
Expand All @@ -21,15 +23,15 @@ dependencies {

checkerFramework {
excludeTests = true
if (project.hasProperty("enableCheckerframework")) {
if (project.enableCheckerframework) {
checkers = listOf(
"org.checkerframework.checker.nullness.NullnessChecker"
)
}
}

tasks.withType<JavaCompile> {
options.errorprone.isEnabled = project.hasProperty("enableErrorprone")
options.errorprone.isEnabled = project.enableErrorprone

options.errorprone {
nullaway {
Expand Down
15 changes: 11 additions & 4 deletions buildSrc/src/main/kotlin/extensions/ProjectExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,16 @@ val Project.libs
get() = the<LibrariesForLibs>()

val Project.javaVersion: String?
get() =
project.findProperty("javaVersion")?.toString()
get() = project.findProperty("javaVersion")?.toString()

val Project.javaVendor: String?
get() =
project.findProperty("javaVendor")?.toString()
get() = project.findProperty("javaVendor")?.toString()

val Project.enableNativeTests: Boolean
get() = project.hasProperty("enableNativeTests")

val Project.enableErrorprone: Boolean
get() = project.hasProperty("enableErrorprone")

val Project.enableCheckerframework: Boolean
get() = project.hasProperty("enableCheckerframework")
27 changes: 5 additions & 22 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
#
# Copyright (c) 2023 Moataz Abdelnasser
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

systemProp.org.gradle.internal.publish.checksums.insecure=true
systemProp.javax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
systemProp.javax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
systemProp.javax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
quarkusPluginId=io.quarkus
quarkusPluginVersion=3.9.1
quarkusPlatformGroupId=io.quarkus.platform
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformVersion=3.9.1
62 changes: 62 additions & 0 deletions quarkus-native-test/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
plugins {
id("conventions.java-library")
id("conventions.static-analysis")
id("conventions.testing")
id("conventions.coverage")
id("io.quarkus")
}

dependencies {
implementation(project(":methanol"))
implementation(project(":methanol-jackson"))
implementation(project(":methanol-testing"))
implementation(libs.jackson.databind)
implementation(libs.mockwebserver)
implementation(libs.autoservice.annotations)
annotationProcessor(libs.autoservice.annprocess)

val quarkusPlatformGroupId: String by project
val quarkusPlatformArtifactId: String by project
val quarkusPlatformVersion: String by project
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))

implementation("io.quarkus:quarkus-rest-jackson")
testImplementation("io.quarkus:quarkus-junit5")
testImplementation("io.rest-assured:rest-assured")
}

tasks.withType<Test> {
systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
}

tasks.withType<JavaCompile> {
// Generate metadata for reflection on method parameters
options.compilerArgs.add("-parameters")
}

quarkus {
buildForkOptions {
// Always generate a native image.
systemProperty("quarkus.package.type", "native")

// Make ServiceLoader work.
systemProperty("quarkus.native.auto-service-loader-registration", "true")

systemProperty(
"quarkus.native.additional-build-args",
listOf(
// For debuggability.
"-H:+ReportExceptionStackTraces",

// These depend on Inet4Address, which cannot be initialized in build-time. Discovered
// through trial and error.
"--initialize-at-run-time=io.lettuce.core.resource.DefaultClientResources",
"--initialize-at-run-time=io.lettuce.core.resource.AddressResolverGroupProvider",
"--initialize-at-run-time=io.lettuce.core.resource.AddressResolverGroupProvider\$DefaultDnsAddressResolverGroupWrapper",

// Okhttp accesses internal GraalVM API.
"-J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.configure=ALL-UNNAMED"
).joinToString(",")
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 Moataz Abdelnasser
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package com.github.mizosoft.quarkus.graal.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.mizosoft.methanol.BodyAdapter;
import com.github.mizosoft.methanol.adapter.ForwardingDecoder;
import com.github.mizosoft.methanol.adapter.ForwardingEncoder;
import com.github.mizosoft.methanol.adapter.jackson.JacksonAdapterFactory;
import com.google.auto.service.AutoService;

public class JacksonAdapters {
private static final ObjectMapper mapper = new ObjectMapper();

private JacksonAdapters() {}

@AutoService(BodyAdapter.Encoder.class)
public static class JacksonEncoder extends ForwardingEncoder {
public JacksonEncoder() {
super(JacksonAdapterFactory.createJsonEncoder(mapper));
}
}

@AutoService(BodyAdapter.Decoder.class)
public static class JacksonDecoder extends ForwardingDecoder {
public JacksonDecoder() {
super(JacksonAdapterFactory.createJsonDecoder(mapper));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Moataz Abdelnasser
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package com.github.mizosoft.quarkus.graal.test;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;

public final class Point {
public final int x;
public final int y;

@JsonCreator
public Point(@JsonProperty("x") int x, @JsonProperty("y") int y) {
this.x = x;
this.y = y;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof Point)) return false;

var that = (Point) obj;
return this.x == that.x && this.y == that.y;
}

@Override
public int hashCode() {
return Objects.hash(x, y);
}

@Override
public String toString() {
return "Point(" + "x=" + x + ", " + "y=" + y + ")";
}
}
Loading

0 comments on commit 1c57604

Please sign in to comment.