diff --git a/pom.xml b/pom.xml
index 711609ec..0dc608a3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,27 +7,28 @@
pom
Quarkus StartStop TS: Parent
- 3.11.0
+ 3.13.0
io.quarkus
- 3.11.0
+ 3.13.0
17
17
17
- 3.10.1
- 2.22.2
- 2.22.2
- 3.3.0
+ 3.13.0
+ 3.3.1
+ 3.3.1
+ 3.6.0
UTF-8
- 5.9.2
- 2.11.0
- 3.12.0
- 3.5.0.Final
- 2.19.0
- 1.30.0
- 4.5.7
- 2.22.0
- 1.8.0
- 3.2.2
+ 5.10.3
+ 2.16.1
+ 3.15.0
+ 3.6.0.Final
+ 2.23.1
+ 1.45.0
+ 4.5.9
+ 2.24.1
+ 1.9.0
+ 3.3.1
+ 1.3.2-alpha
generator,startstop,bomtests,codequarkus,special-chars
@@ -60,6 +61,12 @@
${playwright.version}
test
+
+ io.opentelemetry.proto
+ opentelemetry-proto
+ ${opentelemetry-proto.version}
+ test
+
diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/ArtifactGeneratorBOMTest.java b/testsuite/src/it/java/io/quarkus/ts/startstop/ArtifactGeneratorBOMTest.java
index f53c7e47..6bc806e3 100644
--- a/testsuite/src/it/java/io/quarkus/ts/startstop/ArtifactGeneratorBOMTest.java
+++ b/testsuite/src/it/java/io/quarkus/ts/startstop/ArtifactGeneratorBOMTest.java
@@ -86,6 +86,7 @@ public void testRuntime(TestInfo testInfo, String[] extensions, Set f
Files.createDirectories(Paths.get(repoDir));
//Generator
+ LOGGER.info("Running inside " + appDir.getAbsolutePath());
LOGGER.info(mn + ": Generator command " + String.join(" ", generatorCmd));
generateLog = new File(logsDir + File.separator + "bom-artifact-generator.log");
ExecutorService buildService = Executors.newFixedThreadPool(1);
diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/ArtifactGeneratorTest.java b/testsuite/src/it/java/io/quarkus/ts/startstop/ArtifactGeneratorTest.java
index 5ae54eaf..9c17d755 100644
--- a/testsuite/src/it/java/io/quarkus/ts/startstop/ArtifactGeneratorTest.java
+++ b/testsuite/src/it/java/io/quarkus/ts/startstop/ArtifactGeneratorTest.java
@@ -268,7 +268,7 @@ public void testRuntime(TestInfo testInfo, String[] extensions, Set f
} else {
LOGGER.info(mn + ": Testing setup: " + String.join(" ", generatorCmd));
}
-
+ LOGGER.info("Running inside " + appDir.getAbsolutePath());
try {
// Cleanup
cleanDirOrFile(appBaseDir.getAbsolutePath());
diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/SpecialCharsTest.java b/testsuite/src/it/java/io/quarkus/ts/startstop/SpecialCharsTest.java
index 3774cea2..d89058ef 100644
--- a/testsuite/src/it/java/io/quarkus/ts/startstop/SpecialCharsTest.java
+++ b/testsuite/src/it/java/io/quarkus/ts/startstop/SpecialCharsTest.java
@@ -60,8 +60,8 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, String sub
File appDir = new File(appDestDir, app.dir);
File appPomXml = new File(appDir, "pom.xml");
File logsDir = new File(appDir, "special-chars-logs");
- String cn = testInfo.getTestClass().get().getCanonicalName();
- String mn = testInfo.getTestMethod().get().getName();
+ String canonicalName = testInfo.getTestClass().get().getCanonicalName();
+ String methodName = testInfo.getTestMethod().get().getName();
LOGGER.info("Testing app: " + app + ", mode: " + mvnCmds.toString() + ", on path " + appDestDir);
try {
// Clean target directory
@@ -75,6 +75,7 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, String sub
}
// Copy to path with special characters
+ LOGGER.info("Copying " + appBaseDir + "to" + appDestDir);
FileUtils.copyDirectoryToDirectory(appBaseDir, appDestDir);
// Replace relative path to parent project
@@ -99,7 +100,7 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, String sub
baseBuildCmd.add("-Dquarkus.platform.group-id=" + getQuarkusGroupId());
cmd = getBuildCommand(baseBuildCmd.toArray(new String[0]));
- appendln(whatIDidReport, "# " + cn + ", " + mn);
+ appendln(whatIDidReport, "# " + canonicalName + ", " + methodName);
appendln(whatIDidReport, (new Date()).toString());
appendln(whatIDidReport, appDir.getAbsolutePath());
appendlnSection(whatIDidReport, String.join(" ", cmd));
@@ -111,11 +112,11 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, String sub
buildService.awaitTermination(30, TimeUnit.MINUTES);
assertTrue(buildLogA.exists());
- checkLog(cn, mn, app, mvnCmds, buildLogA);
+ checkLog(canonicalName, methodName, app, mvnCmds, buildLogA);
}
// Run
- runLogA = new File(logsDir + File.separator + subdir + "-" + mvnCmds.name().toLowerCase() + "-run.log");
+ runLogA = new File(logsDir + File.separator + subdir + "-" + mvnCmds.name().toLowerCase() + "-run.log");
if (mvnCmds == MvnCmds.DEV) {
List baseBuildCmd = new ArrayList<>();
@@ -148,12 +149,12 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, String sub
// Archive logs
if (buildLogA != null) {
- archiveLog(cn, mn, buildLogA);
+ archiveLog(canonicalName, methodName, buildLogA);
}
if (runLogA != null) {
- archiveLog(cn, mn, runLogA);
+ archiveLog(canonicalName, methodName, runLogA);
}
- writeReport(cn, mn, whatIDidReport.toString());
+ writeReport(canonicalName, methodName, whatIDidReport.toString());
removeDirWithSpecialCharacters(appDestDir);
}
diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/StartStopTest.java b/testsuite/src/it/java/io/quarkus/ts/startstop/StartStopTest.java
index af96bde2..aa44ed5f 100644
--- a/testsuite/src/it/java/io/quarkus/ts/startstop/StartStopTest.java
+++ b/testsuite/src/it/java/io/quarkus/ts/startstop/StartStopTest.java
@@ -82,9 +82,9 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, Supplier asyncProfiler = mvnCmds == MvnCmds.JVM ? AsyncProfiler.create() : Optional.empty();
- String cn = testInfo.getTestClass().get().getCanonicalName();
- String mn = testInfo.getTestMethod().get().getName();
- try(var testResource = testResourceSupplier.get()) {
+ String canonicalName = testInfo.getTestClass().get().getCanonicalName();
+ String methodName = testInfo.getTestMethod().get().getName();
+ try (var testResource = testResourceSupplier.get()) {
// Cleanup
asyncProfiler.ifPresent(ignore -> AsyncProfiler.cleanProfilingResults(app));
cleanTarget(app);
@@ -99,9 +99,10 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, Supplier buildCommand = getBuildCommand(baseBuildCmd.toArray(new String[0]));
+ LOGGER.info("Running " + baseBuildCmd + " in the " + appDir.getAbsolutePath());
buildService.submit(new Commands.ProcessRunner(appDir, buildLogA, buildCommand, 20));
- appendln(whatIDidReport, "# " + cn + ", " + mn);
+ appendln(whatIDidReport, "# " + canonicalName + ", " + methodName);
appendln(whatIDidReport, (new Date()).toString());
appendln(whatIDidReport, appDir.getAbsolutePath());
appendlnSection(whatIDidReport, String.join(" ", buildCommand));
@@ -111,7 +112,7 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, Supplier control.stopProfing(appDir, mvnCmds, currentProcess, runId));
+ asyncProfiler.ifPresent(control -> control.stopProfing(appDir, mvnCmds, currentProcess, runId));
LOGGER.info("Testing web page content...");
for (String[] urlContent : app.urlContent.urlContent) {
@@ -166,12 +167,12 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, Supplier profiler.archiveProfilingResults(cn, mn, appDir));
- archiveLog(cn, mn, buildLogA);
- archiveLog(cn, mn, runLogA);
- writeReport(cn, mn, whatIDidReport.toString());
- if ( !disableCleanup() ){
+ asyncProfiler.ifPresent(profiler -> profiler.archiveProfilingResults(canonicalName, methodName, appDir));
+ archiveLog(canonicalName, methodName, buildLogA);
+ archiveLog(canonicalName, methodName, runLogA);
+ writeReport(canonicalName, methodName, whatIDidReport.toString());
+ if (!disableCleanup()) {
cleanTarget(app);
}
}
diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Commands.java b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Commands.java
index fb805b7c..954eb46b 100644
--- a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Commands.java
+++ b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Commands.java
@@ -418,7 +418,7 @@ public static boolean waitForTcpClosed(String host, int port, long loopTimeoutS)
return false;
}
- // TODO we should get rid of it once Quarkus progresses with walid config per extension in generated examples
+ // TODO we should get rid of it once Quarkus progresses with valid config per extension in generated examples
public static void confAppPropsForSkeleton(String appDir) throws IOException {
// Config, see app-generated-skeleton/README.md
final String appRelativePath =
diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Logs.java b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Logs.java
index 046f5bd3..da81e66b 100644
--- a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Logs.java
+++ b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Logs.java
@@ -213,12 +213,16 @@ public static void archiveLog(String testClass, String testMethod, File log) thr
if (files != null) {
for (File file : files) {
if (!file.isDirectory()) {
- Files.copy(file.toPath(), Paths.get(destDir.toString(), file.getName()), REPLACE_EXISTING);
+ Path target = Paths.get(destDir.toString(), file.getName());
+ LOGGER.info("Saving log to " + target);
+ Files.copy(file.toPath(), target, REPLACE_EXISTING);
}
}
}
} else {
- Files.copy(log.toPath(), Paths.get(destDir.toString(), filename), REPLACE_EXISTING);
+ Path target = Paths.get(destDir.toString(), filename);
+ LOGGER.info("Saving log to " + target);
+ Files.copy(log.toPath(), target, REPLACE_EXISTING);
}
}
@@ -228,6 +232,7 @@ public static void writeReport(String testClass, String testMethod, String text)
Files.write(Paths.get(destDir.toString(), "report.md"), text.getBytes(UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Path agregateReport = Paths.get(getLogsDir().toString(), "aggregated-report.md");
if (Files.notExists(agregateReport)) {
+ LOGGER.info("Saving report to " + agregateReport);
Files.write(agregateReport, ("# Aggregated Report\n\n").getBytes(UTF_8), StandardOpenOption.CREATE);
}
Files.write(agregateReport, text.getBytes(UTF_8), StandardOpenOption.APPEND);
diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/OpenTelemetryCollector.java b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/OpenTelemetryCollector.java
index e5f456dc..18554aea 100644
--- a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/OpenTelemetryCollector.java
+++ b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/OpenTelemetryCollector.java
@@ -1,80 +1,77 @@
package io.quarkus.ts.startstop.utils;
+import io.opentelemetry.proto.collector.trace.v1.ExportTracePartialSuccess;
+import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
+import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
+import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
+import io.opentelemetry.proto.trace.v1.Span;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.HttpServerRequest;
-import io.vertx.grpc.common.GrpcMessage;
+import io.vertx.grpc.common.GrpcStatus;
import io.vertx.grpc.server.GrpcServer;
+import org.jboss.logging.Logger;
import java.io.Closeable;
import java.io.IOException;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* This simplistic collector allows us to test Vert.x-based traces exporter in Quarkus without starting a container.
*/
public class OpenTelemetryCollector implements UnitTestResource {
-
+ private static final Logger LOGGER = Logger.getLogger(OpenTelemetryCollector.class.getName());
private static final String HELLO_ENDPOINT_OPERATION_NAME = "GET /hello";
private static final String GET_HELLO_INVOCATION_NOT_TRACED = HELLO_ENDPOINT_OPERATION_NAME + " invocation not traced";
/**
* If you change this port, you must also change respective 'quarkus.otel.exporter.otlp.traces.endpoint' value.
*/
private static final int OTEL_COLLECTOR_PORT = 4317;
+ private static final int WEB_ENDPOINT = 16686; // Can be changed to anything, currently is the same as Jaeger.
private static final String GET_HELLO_TRACES_PATH = "/recorded-traces/get-hello";
- static final String GET_HELLO_TRACES_URL = "http://localhost:" + OTEL_COLLECTOR_PORT + GET_HELLO_TRACES_PATH;
static final String GET_HELLO_INVOCATION_TRACED = HELLO_ENDPOINT_OPERATION_NAME + " invocation traced";
+ static final String GET_HELLO_TRACES_URL = "http://localhost:" + WEB_ENDPOINT + GET_HELLO_TRACES_PATH;
- private final Closeable closeable;
- private final RequestHandler requestHandler;
+ private final Vertx vertx;
+ private final Closeable backEnd;
+ private final Closeable frontEnd;
+ private final AtomicBoolean helloEndpointCallTraced = new AtomicBoolean(false);
public OpenTelemetryCollector() {
- this.closeable = createGrpcServer();
- this.requestHandler = new RequestHandler();
- }
-
- private Closeable createGrpcServer() {
- Vertx vertx = Vertx.vertx();
- GrpcServer grpcProxy = GrpcServer.server(vertx);
-
- // record incoming traces
- grpcProxy.callHandler(reqFromQuarkus -> reqFromQuarkus.messageHandler(requestHandler::onReceivedTraces));
-
- HttpServer httpServer = vertx.createHttpServer(new HttpServerOptions().setPort(OTEL_COLLECTOR_PORT));
- httpServer.requestHandler(httpServerRequest -> {
- if (httpServerRequest.path().contains(GET_HELLO_TRACES_PATH)) {
- requestHandler.handleTracesRequest(httpServerRequest);
- } else {
- grpcProxy.handle(httpServerRequest);
- }
- }).listen();
-
- // close resources
- return () -> {
- httpServer.close().toCompletionStage().toCompletableFuture().join();
- vertx.close().toCompletionStage().toCompletableFuture().join();
- };
+ vertx = Vertx.vertx();
+ this.backEnd = new GRPCTraceHandler(vertx);
+ this.frontEnd = new FrontEnd(vertx);
}
@Override
public void close() throws IOException {
- closeable.close();
+ frontEnd.close();
+ backEnd.close();
+ vertx.close().toCompletionStage().toCompletableFuture().join();
}
@Override
public void reset() {
- requestHandler.resetTraces();
+ helloEndpointCallTraced.set(false);
}
- private static class RequestHandler {
+ private class FrontEnd implements Closeable {
+ private final HttpServer httpServer;
- private final AtomicBoolean helloEndpointCallTraced = new AtomicBoolean(false);
+ public FrontEnd(Vertx vertx) {
+ httpServer = vertx
+ .createHttpServer()
+ .requestHandler(this::handleTracesRequest);
+ httpServer.listen(WEB_ENDPOINT);
+ }
private void handleTracesRequest(HttpServerRequest request) {
final String response;
- if (helloEndpointCallTraced.get()) {
+ boolean isTraced = helloEndpointCallTraced.get();
+ if (isTraced) {
response = GET_HELLO_INVOCATION_TRACED;
} else {
response = GET_HELLO_INVOCATION_NOT_TRACED;
@@ -82,18 +79,58 @@ private void handleTracesRequest(HttpServerRequest request) {
request.response().end(response);
}
- private void onReceivedTraces(GrpcMessage exportedTraces) {
- if (!helloEndpointCallTraced.get() && helloEndpointCallTraced(exportedTraces)) {
- helloEndpointCallTraced.set(true);
- }
+ @Override
+ public void close() {
+ LOGGER.info("Closing the server");
+ httpServer.close().toCompletionStage().toCompletableFuture().join();
+ LOGGER.info("The server was closed");
}
+ }
- private void resetTraces() {
- helloEndpointCallTraced.set(false);
+ class GRPCTraceHandler implements Closeable {
+ private final HttpServer httpServer;
+
+ public GRPCTraceHandler(Vertx vertx) {
+ GrpcServer grpcHandler = GrpcServer.server(vertx);
+
+ // record incoming traces
+ grpcHandler.callHandler(TraceServiceGrpc.getExportMethod(), request -> {
+ // https://vertx.io/docs/vertx-grpc/java/#_streaming_request, because Quarkus uses streaming since 3.13
+ request.handler((ExportTraceServiceRequest tracesRequest) -> {
+ LOGGER.info("Processing traces");
+ List traces = tracesRequest.getResourceSpansList().stream()
+ .flatMap(resourceSpans -> resourceSpans.getScopeSpansList().stream())
+ .flatMap(scopeSpans -> scopeSpans.getSpansList().stream())
+ .map(Span::getName)
+ .toList();
+
+ for (String trace : traces) {
+ if (trace.contains(HELLO_ENDPOINT_OPERATION_NAME)) {
+ LOGGER.info("Received trace for " + HELLO_ENDPOINT_OPERATION_NAME);
+ helloEndpointCallTraced.compareAndSet(false, true);
+ }
+ }
+ });
+ request.endHandler(v -> {
+ // https://opentelemetry.io/docs/specs/otlp/#full-success
+ request.response().end(ExportTraceServiceResponse.newBuilder().build());
+ });
+ request.exceptionHandler(err -> { // https://opentelemetry.io/docs/specs/otlp/#failures
+ request.response().status(GrpcStatus.INVALID_ARGUMENT).end();
+ });
+ });
+ httpServer = vertx
+ .createHttpServer()
+ .requestHandler(grpcHandler);
+ httpServer.listen(OTEL_COLLECTOR_PORT);
+ LOGGER.info("The listener started!");
}
- private static boolean helloEndpointCallTraced(GrpcMessage msgFromQuarkus) {
- return msgFromQuarkus.payload().toString().contains(HELLO_ENDPOINT_OPERATION_NAME);
+ @Override
+ public void close() {
+ LOGGER.info("Closing the listener");
+ httpServer.close().toCompletionStage().toCompletableFuture().join();
+ LOGGER.info("The listener was closed");
}
}
}
diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/WhitelistLogLines.java b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/WhitelistLogLines.java
index d1f6ab27..979134d9 100755
--- a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/WhitelistLogLines.java
+++ b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/WhitelistLogLines.java
@@ -105,7 +105,9 @@ public enum WhitelistLogLines {
// https://github.com/quarkusio/quarkus/issues/38711
Pattern.compile(".*SplitPackageProcessor.*Following packages were detected in multiple archives.*"),
// TODO: remove next line when 3.7.3 is released, see https://github.com/quarkusio/quarkus/pull/38710
- Pattern.compile(".*This instance of GraphiQLHandler has been created with a deprecated method.*")
+ Pattern.compile(".*This instance of GraphiQLHandler has been created with a deprecated method.*"),
+ // TODO: https://github.com/quarkusio/quarkus/issues/42237
+ Pattern.compile(".*Failed to index org.springframework.aot.hint.annotation.Reflective.*")
}),
// Quarkus is not being gratefully shutdown in Windows when running in Dev mode.
// Reported by https://github.com/quarkusio/quarkus/issues/14647.