From 779b957584ea981aeb66cdd787f00079564ae672 Mon Sep 17 00:00:00 2001 From: Thomas Segismont Date: Thu, 9 Nov 2023 17:23:50 +0100 Subject: [PATCH] OTEL and OT: verify db.system attribute is present Related to https://github.com/eclipse-vertx/vertx-tracing/issues/64 Signed-off-by: Thomas Segismont --- .../tracing/opentelemetry/SqlClientTest.java | 134 ++++++++++++++++++ .../tracing/opentracing/SqlClientTest.java | 6 +- 2 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/SqlClientTest.java diff --git a/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/SqlClientTest.java b/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/SqlClientTest.java new file mode 100644 index 0000000..59f4149 --- /dev/null +++ b/vertx-opentelemetry/src/test/java/io/vertx/tracing/opentelemetry/SqlClientTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2011-2021 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ +package io.vertx.tracing.opentelemetry; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.vertx.core.Vertx; +import io.vertx.core.VertxOptions; +import io.vertx.core.http.HttpClient; +import io.vertx.core.http.HttpClientOptions; +import io.vertx.core.http.HttpMethod; +import io.vertx.core.tracing.TracingPolicy; +import io.vertx.junit5.VertxExtension; +import io.vertx.junit5.VertxTestContext; +import io.vertx.pgclient.PgBuilder; +import io.vertx.pgclient.PgConnectOptions; +import io.vertx.sqlclient.Pool; +import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.RowSet; +import io.vertx.sqlclient.Tuple; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.testcontainers.containers.PostgreSQLContainer; + +import java.util.List; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(VertxExtension.class) +public class SqlClientTest { + + private static PostgreSQLContainer server; + private static PgConnectOptions connectOptions; + + @RegisterExtension + final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create(); + private Vertx vertx; + private Pool pool; + + @BeforeAll + public static void startDB() { + server = new PostgreSQLContainer<>("postgres:10") + .withDatabaseName("postgres") + .withUsername("postgres") + .withPassword("postgres"); + server.start(); + connectOptions = new PgConnectOptions() + .setUser("postgres") + .setPassword("postgres") + .setDatabase("postgres") + .setHost(server.getContainerIpAddress()) + .setPort(server.getMappedPort(5432)); + + } + + @AfterAll + public static void stopDB() { + server.stop(); + } + + @BeforeEach + public void before() { + vertx = Vertx.vertx(new VertxOptions().setTracingOptions(new OpenTelemetryOptions(otelTesting.getOpenTelemetry()))); + pool = PgBuilder.pool().connectingTo(connectOptions).using(vertx).build(); + } + + @AfterEach + public void after(VertxTestContext context) throws Exception { + vertx.close().onComplete(context.succeedingThenComplete()); + } + + @Test + public void testPreparedQuery(VertxTestContext ctx) throws Exception { + long baseDurationInMs = 500; + vertx.createHttpServer().requestHandler(req -> { + pool.preparedQuery("SELECT $1 \"VAL\"") + .execute(Tuple.of("Hello World")) + .onComplete(ar -> { + vertx.setTimer(baseDurationInMs, (__) -> { + if (ar.succeeded()) { + RowSet rows = ar.result(); + req.response() + .end(); + } else { + req.response() + .setStatusCode(500) + .end(); + } + }); + }); + }).listen(8080).onComplete(ctx.succeeding(srv -> { + HttpClient client = vertx.createHttpClient(new HttpClientOptions().setTracingPolicy(TracingPolicy.ALWAYS)); + client.request(HttpMethod.GET, 8080, "localhost", "/").compose(req -> { + return req.send().compose(resp -> resp.body().map(resp)); + }).onComplete(ctx.succeeding(resp -> { + ctx.verify(() -> { + assertEquals(200, resp.statusCode()); + List spans = otelTesting.getSpans(); + assertEquals(3, spans.size()); + SpanData requestSpan = spans.get(1); + assertEquals("GET", requestSpan.getName()); + assertEquals("GET", requestSpan.getAttributes().get(AttributeKey.stringKey("http.method"))); + assertEquals("http://localhost:8080/", requestSpan.getAttributes().get(AttributeKey.stringKey("http.url"))); + assertEquals("200", requestSpan.getAttributes().get(AttributeKey.stringKey("http.status_code"))); + assertTrue(MILLISECONDS.convert(requestSpan.getEndEpochNanos() - requestSpan.getStartEpochNanos(), NANOSECONDS) > baseDurationInMs); + SpanData querySpan = spans.get(0); + assertEquals("Query", querySpan.getName()); + assertEquals("client", querySpan.getAttributes().get(AttributeKey.stringKey("span.kind"))); + assertEquals("SELECT $1 \"VAL\"", querySpan.getAttributes().get(AttributeKey.stringKey("db.statement"))); + assertEquals("sql", querySpan.getAttributes().get(AttributeKey.stringKey("db.type"))); + assertEquals("postgres", querySpan.getAttributes().get(AttributeKey.stringKey("db.user"))); + assertEquals("postgres", querySpan.getAttributes().get(AttributeKey.stringKey("db.instance"))); + assertEquals("postgresql", querySpan.getAttributes().get(AttributeKey.stringKey("db.system"))); + assertEquals(querySpan.getParentSpanId(), requestSpan.getSpanId()); + assertEquals(querySpan.getTraceId(), requestSpan.getTraceId()); + ctx.completeNow(); + }); + })); + })); + } +} diff --git a/vertx-opentracing/src/test/java/io/vertx/tracing/opentracing/SqlClientTest.java b/vertx-opentracing/src/test/java/io/vertx/tracing/opentracing/SqlClientTest.java index 9ab7a87..7a68fda 100644 --- a/vertx-opentracing/src/test/java/io/vertx/tracing/opentracing/SqlClientTest.java +++ b/vertx-opentracing/src/test/java/io/vertx/tracing/opentracing/SqlClientTest.java @@ -23,7 +23,10 @@ import io.vertx.ext.unit.junit.VertxUnitRunner; import io.vertx.pgclient.PgBuilder; import io.vertx.pgclient.PgConnectOptions; -import io.vertx.sqlclient.*; +import io.vertx.sqlclient.Pool; +import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.RowSet; +import io.vertx.sqlclient.Tuple; import org.junit.*; import org.junit.runner.RunWith; import org.testcontainers.containers.PostgreSQLContainer; @@ -136,6 +139,7 @@ public void testPreparedQuery(TestContext ctx) throws Exception { assertEquals("sql", querySpan.tags().get("db.type")); assertEquals("postgres", querySpan.tags().get("db.user")); assertEquals("postgres", querySpan.tags().get("db.instance")); + assertEquals("postgresql", querySpan.tags().get("db.system")); assertEquals(querySpan.parentId(), requestSpan.context().spanId()); assertEquals(querySpan.context().traceId(), requestSpan.context().traceId()); }