diff --git a/integration-test/pom.xml b/integration-test/pom.xml index 53f5c53..d23109a 100644 --- a/integration-test/pom.xml +++ b/integration-test/pom.xml @@ -38,24 +38,12 @@ yupiik-logging-jul ${project.version} - - org.testcontainers - testcontainers - 1.18.0 - test - org.slf4j slf4j-jdk14 1.7.30 test - - org.apache.geronimo.arthur - arthur-maven-plugin - 1.0.6 - test - @@ -63,7 +51,6 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 ${skip.it} @@ -71,6 +58,8 @@ ${project.version} ${settings.localRepository} ${project.basedir}/projects + ${maven.home} + ${java.home} diff --git a/integration-test/projects/execute.sh b/integration-test/projects/execute.sh deleted file mode 100644 index 4cb8a46..0000000 --- a/integration-test/projects/execute.sh +++ /dev/null @@ -1,25 +0,0 @@ -#! /bin/bash -# -# Copyright (c) 2021-2023 - Yupiik SAS - https://www.yupiik.com -# 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. -# - - -rm -Rf "/tmp/$1" && \ -cp -r "$1" "/tmp/$1" && \ -cd "/tmp/$1" && \ -sed -i "s/project\.version/$3/g" pom.xml && \ -mvn clean package -e 1>&2 && \ -"./target/$1.graal.bin" "$2" - diff --git a/integration-test/src/test/java/io/yupiik/logging/tests/JULTest.java b/integration-test/src/test/java/io/yupiik/logging/tests/JULTest.java index f6be00f..936f7eb 100644 --- a/integration-test/src/test/java/io/yupiik/logging/tests/JULTest.java +++ b/integration-test/src/test/java/io/yupiik/logging/tests/JULTest.java @@ -15,38 +15,37 @@ */ package io.yupiik.logging.tests; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.testcontainers.containers.Container; -import org.testcontainers.containers.GenericContainer; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.io.TempDir; import java.io.IOException; - +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Locale.ROOT; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.toList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; +@TestInstance(PER_CLASS) class JULTest { - private static GenericContainer container; - - @BeforeAll - static void start() { - container = new GenericContainer<>("quay.io/quarkus/centos-quarkus-maven:22.1.0-java11"); - container.setWorkingDirectory("/opt/projects"); - container.withFileSystemBind(System.getProperty("maven.test.repository"), "/home/quarkus/.m2/repository"); - container.withFileSystemBind(System.getProperty("maven.test.projects", "projects"), "/opt/projects"); - container.setCommand("sleep", "infinity"); - container.start(); - } - - @AfterAll - static void stop() { - container.stop(); - } + private final String maven = findMaven(); @Test - void jul() throws IOException, InterruptedException { - final var firstOutput = buildProject("jul", "-DignoreJulConfigForThisTest"); + void jul(@TempDir final Path work) throws IOException { + final var firstRun = buildAndRun(work, "jul", List.of("clean", "package", "-e"), "-DuseDefaultJulConfigForThisTest"); + final var firstOutput = assertExitCode(firstRun); // default setup, ie inline formatter at info level final var defaultOutput = firstOutput // no, we didn't log an EOL but due to testcontainers bug and out #testContainerStdWorkaround we get one @@ -56,21 +55,18 @@ void jul() throws IOException, InterruptedException { // // already built so execute it another time with different config // - final String projectBase = "/tmp/jul/"; + final var base = work.resolve("project"); + final var bin = base.resolve("target/jul.graal.bin").toString(); // change level to FINEST for test logger - final var finestOutput = ensureSuccessAndGetStdout(container.execInContainer( - projectBase + "target/jul.graal.bin", - "-Djava.util.logging.config.file=" + projectBase + "logging.properties", - getVersion())) - .trim(); + final var finestOutput = assertExitCode(exec( + new ProcessBuilder(bin, "-Djava.util.logging.config.file=" + base.resolve("logging.properties")), base)) + .strip(); // use json formatting - final var jsonOutput = ensureSuccessAndGetStdout(container.execInContainer( - projectBase + "target/jul.graal.bin", - "-Djava.util.logging.config.file=" + projectBase + "logging.json.properties", - getVersion())) - .trim(); + final var jsonOutput = assertExitCode(exec( + new ProcessBuilder(bin, "-Djava.util.logging.config.file=" + base.resolve("logging.json.properties")), base)) + .strip(); // since it is a bit long to native-image the main we run all tests then assert to be able to debug more easily // all cases at once @@ -84,46 +80,94 @@ void jul() throws IOException, InterruptedException { System.out.println("--"); } - final String dateRegex = "[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.?[0-9]+)?Z "; + final var dateRegex = "[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.?[0-9]+)?Z "; assertTrue(defaultOutput.matches( - dateRegex + "\\[INFO]\\[test\\.Main] info entry point of the test"), + dateRegex + "\\[INFO]\\[test\\.Main] info entry point of the test"), defaultOutput); assertTrue(finestOutput.matches("" + - dateRegex + "\\[FINEST]\\[test\\.Main] severe entry point of the test" + /*\n was replaced by our std workaround */ - dateRegex + "\n\\[INFO]\\[test\\.Main] info entry point of the test"), finestOutput); + dateRegex + "\\[FINEST]\\[test\\.Main] severe entry point of the test\n" + + dateRegex + "\\[INFO]\\[test\\.Main] info entry point of the test"), finestOutput); assertTrue(jsonOutput.matches("" + "\\{\"timestamp\":\"" + dateRegex.trim() + "\",\"level\":\"INFO\",\"logger\":\"test\\.Main\"," + "\"method\":\"log\",\"message\":\"info entry point of the test\"," + "\"class\":\"io\\.yupiik\\.logging\\.jul\\.logger\\.YupiikLogger\"}"), jsonOutput); } - private String buildProject(final String name, final String runtimeSystemProp) throws IOException, InterruptedException { - final var result = container.execInContainer( - "sh", "./execute.sh", name, runtimeSystemProp, getVersion()); - return ensureSuccessAndGetStdout(result); + private String getVersion() { + return System.getProperty("project.version", "1.0.8-SNAPSHOT"); } - private String getVersion() { - return System.getProperty("project.version", "1.0-SNAPSHOT"); + private String assertExitCode(final Process result) throws IOException { + assertEquals(0, result.exitValue(), () -> { + try { + return "" + + "status=" + result.exitValue() + "\n" + + "stdout=\n" + new String(result.getInputStream().readAllBytes(), UTF_8) + "\n" + + "stderr=\n" + new String(result.getErrorStream().readAllBytes(), UTF_8); + } catch (final IOException e) { + return "status=" + result.exitValue(); + } + }); + return new String(result.getInputStream().readAllBytes(), UTF_8); + } + + private String findMaven() { + return ofNullable(System.getProperty("maven.home")) + .flatMap(h -> { + final var bin = "mvn" + + (System.getProperty("os.name", "").toLowerCase(ROOT).contains("win") ? + ".cmd" : ""); + try (final var list = Files.list(Path.of(h).resolve("bin"))) { + return list.filter(it -> Objects.equals(it.getFileName().toString(), bin)).findFirst(); + } catch (final IOException e) { + throw new IllegalStateException(e); + } + }) + .map(Path::toString) + .orElse("mvn"); } - private String ensureSuccessAndGetStdout(final Container.ExecResult result) { - assertEquals(0, result.getExitCode(), () -> "" + - "status=" + result.getExitCode() + "\n" + - "stdout=\n" + testContainerStdWorkaround(result.getStdout()) + "\n" + - "stderr=\n" + testContainerStdWorkaround(result.getStderr())); - return testContainerStdWorkaround(result.getStdout()); + private Process buildAndRun(final Path work, final String project, final List args, final String binOpt) throws IOException { + final var target = Files.createDirectories(work.resolve("project")); + final var from = Path.of(System.getProperty("maven.test.projects", "projects")).resolve(project); + Files.walkFileTree(from, new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { + final var to = target.resolve(from.relativize(file)); + Files.createDirectories(to.getParent()); + if (!"pom.xml".equals(file.getFileName().toString())) { + Files.copy(file, to); + } else { + Files.writeString(to, Files.readString(file) + .replace("project.version", "" + getVersion() + "")); + } + return super.visitFile(file, attrs); + } + }); + + final var mvnProcessBuilder = new ProcessBuilder(Stream.concat(Stream.of(maven), args.stream()).collect(toList())); + mvnProcessBuilder.inheritIO(); + + final var environment = mvnProcessBuilder.environment(); + environment.put("MAVEN_HOME", System.getProperty("maven.home", "")); + environment.put("JAVA_HOME", System.getProperty("java.home", "")); + + final var mvnResult = exec(mvnProcessBuilder, target); + assertExitCode(mvnResult); + + return exec(new ProcessBuilder("target/" + project + ".graal.bin", binOpt), target); } - // bug of testcontainers with maven logger output - private String testContainerStdWorkaround(final String result) { - return result - .replace("\n", "") - // try to make it more readable with previous hack - .replace("Downloading from ", "\nDownloading from ") - .replace("Downloaded from ", "\nDownloaded from ") - .replace("[INFO]", "\n[INFO]") - .replace("[ERROR]", "\n[ERROR]") - .replace("\tat ", "\n\tat "); // exceptions + private Process exec(final ProcessBuilder builder, final Path target) throws IOException { + builder.directory(target.toFile()); + + try { + final var start = builder.start(); + start.waitFor(); + return start; + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + return fail(e); + } } } diff --git a/pom.xml b/pom.xml index 0929381..43c730e 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ org.apache.maven.plugins maven-resources-plugin - 3.1.0 + 3.3.1 UTF-8 @@ -74,7 +74,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.1 11 11 @@ -86,7 +86,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0 + 3.2.5 false @@ -94,12 +94,12 @@ org.apache.maven.plugins maven-release-plugin - 3.0.0-M1 + 3.0.1 org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.3.0 attach-sources @@ -112,7 +112,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.2.0 + 3.3.0 false @@ -134,7 +134,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.2.0 + 3.6.3 attach-javadocs @@ -144,6 +144,7 @@ + UTF-8 11 none