Fix latest dep tests (#11925)

This commit is contained in:
Lauri Tulmin 2024-07-31 10:49:47 +03:00 committed by GitHub
parent 4619413cd7
commit 14d87e7323
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 234 additions and 84 deletions

View File

@ -18,14 +18,32 @@ dependencies {
testInstrumentation(project(":instrumentation:netty:netty-4.1:javaagent")) testInstrumentation(project(":instrumentation:netty:netty-4.1:javaagent"))
} }
otelJava { val latestDepTest = findProperty("testLatestDeps") as Boolean
// AHC uses Unsafe and so does not run on later java version val testJavaVersion =
maxJavaVersionForTests.set(JavaVersion.VERSION_1_8) gradle.startParameter.projectProperties["testJavaVersion"]?.let(JavaVersion::toVersion)
?: JavaVersion.current()
if (!latestDepTest) {
otelJava {
// AHC uses Unsafe and so does not run on later java version
maxJavaVersionForTests.set(JavaVersion.VERSION_1_8)
}
}
tasks.withType<Test>().configureEach {
systemProperty("testLatestDeps", latestDepTest)
// async-http-client 3.0 requires java 11
// We are not using minJavaVersionSupported for latestDepTest because that way the instrumentation
// gets compiled with java 11 when running latestDepTest. This causes play-mvc-2.4 latest dep tests
// to fail because they require java 8 and instrumentation compiled with java 11 won't apply.
if (latestDepTest && testJavaVersion.isJava8) {
enabled = false
}
} }
// async-http-client 2.0.0 does not work with Netty versions newer than this due to referencing an // async-http-client 2.0.0 does not work with Netty versions newer than this due to referencing an
// internal file. // internal file.
if (!(findProperty("testLatestDeps") as Boolean)) { if (!latestDepTest) {
configurations.configureEach { configurations.configureEach {
if (!name.contains("muzzle")) { if (!name.contains("muzzle")) {
resolutionStrategy { resolutionStrategy {

View File

@ -10,11 +10,14 @@ import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTes
import io.opentelemetry.instrumentation.testing.junit.http.HttpClientInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.http.HttpClientInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.http.HttpClientResult; import io.opentelemetry.instrumentation.testing.junit.http.HttpClientResult;
import io.opentelemetry.instrumentation.testing.junit.http.HttpClientTestOptions; import io.opentelemetry.instrumentation.testing.junit.http.HttpClientTestOptions;
import java.lang.reflect.Method;
import java.net.URI; import java.net.URI;
import java.time.Duration;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import org.asynchttpclient.AsyncCompletionHandler; import org.asynchttpclient.AsyncCompletionHandler;
import org.asynchttpclient.AsyncHttpClient; import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
import org.asynchttpclient.Dsl; import org.asynchttpclient.Dsl;
import org.asynchttpclient.Request; import org.asynchttpclient.Request;
import org.asynchttpclient.RequestBuilder; import org.asynchttpclient.RequestBuilder;
@ -31,11 +34,26 @@ class AsyncHttpClientTest extends AbstractHttpClientTest<Request> {
private static final int CONNECTION_TIMEOUT_MS = (int) CONNECTION_TIMEOUT.toMillis(); private static final int CONNECTION_TIMEOUT_MS = (int) CONNECTION_TIMEOUT.toMillis();
// request timeout is needed in addition to connect timeout on async-http-client versions 2.1.0+ // request timeout is needed in addition to connect timeout on async-http-client versions 2.1.0+
private static final AsyncHttpClient client = private static final AsyncHttpClient client = Dsl.asyncHttpClient(configureTimeout(Dsl.config()));
Dsl.asyncHttpClient(
Dsl.config() private static DefaultAsyncHttpClientConfig.Builder configureTimeout(
.setConnectTimeout(CONNECTION_TIMEOUT_MS) DefaultAsyncHttpClientConfig.Builder builder) {
.setRequestTimeout(CONNECTION_TIMEOUT_MS)); setTimeout(builder, "setConnectTimeout", CONNECTION_TIMEOUT_MS);
setTimeout(builder, "setRequestTimeout", CONNECTION_TIMEOUT_MS);
return builder;
}
private static void setTimeout(
DefaultAsyncHttpClientConfig.Builder builder, String methodName, int timeout) {
boolean testLatestDeps = Boolean.getBoolean("testLatestDeps");
try {
Method method =
builder.getClass().getMethod(methodName, testLatestDeps ? Duration.class : int.class);
method.invoke(builder, testLatestDeps ? Duration.ofMillis(timeout) : timeout);
} catch (Exception exception) {
throw new IllegalStateException("Failed to set timeout " + methodName, exception);
}
}
@Override @Override
public Request buildRequest(String method, URI uri, Map<String, String> headers) { public Request buildRequest(String method, URI uri, Map<String, String> headers) {

View File

@ -24,4 +24,9 @@ class LettuceAsyncClientTest extends AbstractLettuceAsyncClientTest {
protected RedisClient createClient(String uri) { protected RedisClient createClient(String uri) {
return RedisClient.create(uri); return RedisClient.create(uri);
} }
@Override
protected boolean connectHasSpans() {
return Boolean.getBoolean("testLatestDeps");
}
} }

View File

@ -90,6 +90,10 @@ public abstract class AbstractLettuceAsyncClientTest extends AbstractLettuceClie
return true; return true;
} }
protected boolean connectHasSpans() {
return false;
}
@Test @Test
void testConnectUsingGetOnConnectionFuture() throws Exception { void testConnectUsingGetOnConnectionFuture() throws Exception {
RedisClient testConnectionClient = RedisClient.create(embeddedDbUri); RedisClient testConnectionClient = RedisClient.create(embeddedDbUri);
@ -103,8 +107,13 @@ public abstract class AbstractLettuceAsyncClientTest extends AbstractLettuceClie
cleanup.deferCleanup(testConnectionClient::shutdown); cleanup.deferCleanup(testConnectionClient::shutdown);
assertThat(connection1).isNotNull(); assertThat(connection1).isNotNull();
// Lettuce tracing does not trace connect if (connectHasSpans()) {
assertThat(getInstrumentationExtension().spans()).isEmpty(); // ignore CLIENT SETINFO traces
getInstrumentationExtension().waitForTraces(2);
} else {
// Lettuce tracing does not trace connect
assertThat(getInstrumentationExtension().spans()).isEmpty();
}
} }
@Test @Test

View File

@ -8,7 +8,6 @@ package io.opentelemetry.instrumentation.lettuce.v5_1;
import io.lettuce.core.RedisClient; import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.StatefulRedisConnection;
import io.opentelemetry.instrumentation.testing.internal.AutoCleanupExtension; import io.opentelemetry.instrumentation.testing.internal.AutoCleanupExtension;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
@ -22,13 +21,6 @@ import org.testcontainers.containers.wait.strategy.Wait;
abstract class AbstractLettuceClientTest { abstract class AbstractLettuceClientTest {
protected static final Logger logger = LoggerFactory.getLogger(AbstractLettuceClientTest.class); protected static final Logger logger = LoggerFactory.getLogger(AbstractLettuceClientTest.class);
@RegisterExtension
protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
public InstrumentationExtension getInstrumentationExtension() {
return testing;
}
@RegisterExtension static final AutoCleanupExtension cleanup = AutoCleanupExtension.create(); @RegisterExtension static final AutoCleanupExtension cleanup = AutoCleanupExtension.create();
protected static final int DB_INDEX = 0; protected static final int DB_INDEX = 0;
@ -40,18 +32,15 @@ abstract class AbstractLettuceClientTest {
.waitingFor(Wait.forLogMessage(".*Ready to accept connections.*", 1)); .waitingFor(Wait.forLogMessage(".*Ready to accept connections.*", 1));
protected static RedisClient redisClient; protected static RedisClient redisClient;
protected static StatefulRedisConnection<String, String> connection; protected static StatefulRedisConnection<String, String> connection;
protected static String host;
protected static String ip;
protected static int port;
protected static String embeddedDbUri;
protected abstract RedisClient createClient(String uri); protected abstract RedisClient createClient(String uri);
protected static String host; protected abstract InstrumentationExtension getInstrumentationExtension();
protected static String ip;
protected static int port;
protected static String embeddedDbUri;
protected ContainerConnection newContainerConnection() { protected ContainerConnection newContainerConnection() {
GenericContainer<?> server = GenericContainer<?> server =

View File

@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.api.sync.RedisCommands;
import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
import io.opentelemetry.semconv.NetworkAttributes; import io.opentelemetry.semconv.NetworkAttributes;
import io.opentelemetry.semconv.ServerAttributes; import io.opentelemetry.semconv.ServerAttributes;
import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; import io.opentelemetry.semconv.incubating.DbIncubatingAttributes;
@ -59,23 +60,76 @@ public abstract class AbstractLettuceSyncClientAuthTest extends AbstractLettuceC
assertThat(result).isEqualTo("OK"); assertThat(result).isEqualTo("OK");
getInstrumentationExtension() if (Boolean.getBoolean("testLatestDeps")) {
.waitAndAssertTraces( getInstrumentationExtension()
trace -> .waitAndAssertTraces(
trace.hasSpansSatisfyingExactly( trace ->
span -> trace.hasSpansSatisfyingExactly(
span.hasName("AUTH") span ->
.hasKind(SpanKind.CLIENT) span.hasName("CLIENT")
.hasAttributesSatisfyingExactly( .hasKind(SpanKind.CLIENT)
equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"), .hasAttributesSatisfyingExactly(
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip), equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"),
equalTo(NetworkAttributes.NETWORK_PEER_PORT, port), equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip),
equalTo(ServerAttributes.SERVER_ADDRESS, host), equalTo(NetworkAttributes.NETWORK_PEER_PORT, port),
equalTo(ServerAttributes.SERVER_PORT, port), equalTo(ServerAttributes.SERVER_ADDRESS, host),
equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"), equalTo(ServerAttributes.SERVER_PORT, port),
equalTo(DbIncubatingAttributes.DB_STATEMENT, "AUTH ?")) equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"),
.hasEventsSatisfyingExactly( equalTo(
event -> event.hasName("redis.encode.start"), DbIncubatingAttributes.DB_STATEMENT,
event -> event.hasName("redis.encode.end")))); "CLIENT SETINFO lib-name Lettuce"))),
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("CLIENT")
.hasKind(SpanKind.CLIENT)
.hasAttributesSatisfyingExactly(
equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"),
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip),
equalTo(NetworkAttributes.NETWORK_PEER_PORT, port),
equalTo(ServerAttributes.SERVER_ADDRESS, host),
equalTo(ServerAttributes.SERVER_PORT, port),
equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"),
OpenTelemetryAssertions.satisfies(
DbIncubatingAttributes.DB_STATEMENT,
stringAssert ->
stringAssert.startsWith("CLIENT SETINFO lib-ver")))),
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("AUTH")
.hasKind(SpanKind.CLIENT)
.hasAttributesSatisfyingExactly(
equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"),
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip),
equalTo(NetworkAttributes.NETWORK_PEER_PORT, port),
equalTo(ServerAttributes.SERVER_ADDRESS, host),
equalTo(ServerAttributes.SERVER_PORT, port),
equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"),
equalTo(DbIncubatingAttributes.DB_STATEMENT, "AUTH ?"))
.hasEventsSatisfyingExactly(
event -> event.hasName("redis.encode.start"),
event -> event.hasName("redis.encode.end"))));
} else {
getInstrumentationExtension()
.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("AUTH")
.hasKind(SpanKind.CLIENT)
.hasAttributesSatisfyingExactly(
equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"),
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip),
equalTo(NetworkAttributes.NETWORK_PEER_PORT, port),
equalTo(ServerAttributes.SERVER_ADDRESS, host),
equalTo(ServerAttributes.SERVER_PORT, port),
equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"),
equalTo(DbIncubatingAttributes.DB_STATEMENT, "AUTH ?"))
.hasEventsSatisfyingExactly(
event -> event.hasName("redis.encode.start"),
event -> event.hasName("redis.encode.end"))));
}
} }
} }

View File

@ -20,6 +20,7 @@ import io.lettuce.core.api.sync.RedisCommands;
import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.instrumentation.test.utils.PortUtils; import io.opentelemetry.instrumentation.test.utils.PortUtils;
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
import io.opentelemetry.semconv.NetworkAttributes; import io.opentelemetry.semconv.NetworkAttributes;
import io.opentelemetry.semconv.ServerAttributes; import io.opentelemetry.semconv.ServerAttributes;
import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; import io.opentelemetry.semconv.incubating.DbIncubatingAttributes;
@ -81,8 +82,13 @@ public abstract class AbstractLettuceSyncClientTest extends AbstractLettuceClien
StatefulRedisConnection<String, String> testConnection = redisClient.connect(); StatefulRedisConnection<String, String> testConnection = redisClient.connect();
cleanup.deferCleanup(testConnection); cleanup.deferCleanup(testConnection);
// Lettuce tracing does not trace connect if (Boolean.getBoolean("testLatestDeps")) {
assertThat(getInstrumentationExtension().spans()).isEmpty(); // ignore CLIENT SETINFO traces
getInstrumentationExtension().waitForTraces(2);
} else {
// Lettuce tracing does not trace connect
assertThat(getInstrumentationExtension().spans()).isEmpty();
}
} }
@Test @Test
@ -206,6 +212,12 @@ public abstract class AbstractLettuceSyncClientTest extends AbstractLettuceClien
ContainerConnection containerConnection = newContainerConnection(); ContainerConnection containerConnection = newContainerConnection();
RedisCommands<String, String> commands = containerConnection.connection.sync(); RedisCommands<String, String> commands = containerConnection.connection.sync();
if (Boolean.getBoolean("testLatestDeps")) {
// ignore CLIENT SETINFO traces
getInstrumentationExtension().waitForTraces(2);
getInstrumentationExtension().clearData();
}
long res = commands.lpush("TESTLIST", "TESTLIST ELEMENT"); long res = commands.lpush("TESTLIST", "TESTLIST ELEMENT");
assertThat(res).isEqualTo(1); assertThat(res).isEqualTo(1);
@ -350,43 +362,82 @@ public abstract class AbstractLettuceSyncClientTest extends AbstractLettuceClien
commands.debugSegfault(); commands.debugSegfault();
getInstrumentationExtension() if (Boolean.getBoolean("testLatestDeps")) {
.waitAndAssertTraces( getInstrumentationExtension()
trace -> { .waitAndAssertTraces(
if (Boolean.getBoolean("testLatestDeps")) { trace ->
trace.hasSpansSatisfyingExactly( trace.hasSpansSatisfyingExactly(
span -> span ->
span.hasName("DEBUG") span.hasName("CLIENT")
.hasKind(SpanKind.CLIENT) .hasKind(SpanKind.CLIENT)
.hasAttributesSatisfyingExactly( .hasAttributesSatisfyingExactly(
equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"), equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"),
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip), equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip),
equalTo( equalTo(
NetworkAttributes.NETWORK_PEER_PORT, containerConnection.port), NetworkAttributes.NETWORK_PEER_PORT,
equalTo(ServerAttributes.SERVER_ADDRESS, host), containerConnection.port),
equalTo(ServerAttributes.SERVER_PORT, containerConnection.port), equalTo(ServerAttributes.SERVER_ADDRESS, host),
equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"), equalTo(ServerAttributes.SERVER_PORT, containerConnection.port),
equalTo(DbIncubatingAttributes.DB_STATEMENT, "DEBUG SEGFAULT"))); equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"),
} else { equalTo(
trace.hasSpansSatisfyingExactly( DbIncubatingAttributes.DB_STATEMENT,
span -> "CLIENT SETINFO lib-name Lettuce"))),
span.hasName("DEBUG") trace ->
.hasKind(SpanKind.CLIENT) trace.hasSpansSatisfyingExactly(
.hasAttributesSatisfyingExactly( span ->
equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"), span.hasName("CLIENT")
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip), .hasKind(SpanKind.CLIENT)
equalTo( .hasAttributesSatisfyingExactly(
NetworkAttributes.NETWORK_PEER_PORT, containerConnection.port), equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"),
equalTo(ServerAttributes.SERVER_ADDRESS, host), equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip),
equalTo(ServerAttributes.SERVER_PORT, containerConnection.port), equalTo(
equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"), NetworkAttributes.NETWORK_PEER_PORT,
equalTo(DbIncubatingAttributes.DB_STATEMENT, "DEBUG SEGFAULT")) containerConnection.port),
// these are no longer recorded since Lettuce 6.1.6 equalTo(ServerAttributes.SERVER_ADDRESS, host),
.hasEventsSatisfyingExactly( equalTo(ServerAttributes.SERVER_PORT, containerConnection.port),
event -> event.hasName("redis.encode.start"), equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"),
event -> event.hasName("redis.encode.end"))); OpenTelemetryAssertions.satisfies(
} DbIncubatingAttributes.DB_STATEMENT,
}); stringAssert ->
stringAssert.startsWith("CLIENT SETINFO lib-ver")))),
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("DEBUG")
.hasKind(SpanKind.CLIENT)
.hasAttributesSatisfyingExactly(
equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"),
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip),
equalTo(
NetworkAttributes.NETWORK_PEER_PORT,
containerConnection.port),
equalTo(ServerAttributes.SERVER_ADDRESS, host),
equalTo(ServerAttributes.SERVER_PORT, containerConnection.port),
equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"),
equalTo(DbIncubatingAttributes.DB_STATEMENT, "DEBUG SEGFAULT"))));
} else {
getInstrumentationExtension()
.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("DEBUG")
.hasKind(SpanKind.CLIENT)
.hasAttributesSatisfyingExactly(
equalTo(NetworkAttributes.NETWORK_TYPE, "ipv4"),
equalTo(NetworkAttributes.NETWORK_PEER_ADDRESS, ip),
equalTo(
NetworkAttributes.NETWORK_PEER_PORT,
containerConnection.port),
equalTo(ServerAttributes.SERVER_ADDRESS, host),
equalTo(ServerAttributes.SERVER_PORT, containerConnection.port),
equalTo(DbIncubatingAttributes.DB_SYSTEM, "redis"),
equalTo(DbIncubatingAttributes.DB_STATEMENT, "DEBUG SEGFAULT"))
// these are no longer recorded since Lettuce 6.1.6
.hasEventsSatisfyingExactly(
event -> event.hasName("redis.encode.start"),
event -> event.hasName("redis.encode.end"))));
}
} }
@Test @Test
@ -395,6 +446,12 @@ public abstract class AbstractLettuceSyncClientTest extends AbstractLettuceClien
ContainerConnection containerConnection = newContainerConnection(); ContainerConnection containerConnection = newContainerConnection();
RedisCommands<String, String> commands = containerConnection.connection.sync(); RedisCommands<String, String> commands = containerConnection.connection.sync();
if (Boolean.getBoolean("testLatestDeps")) {
// ignore CLIENT SETINFO traces
getInstrumentationExtension().waitForTraces(2);
getInstrumentationExtension().clearData();
}
commands.shutdown(false); commands.shutdown(false);
getInstrumentationExtension() getInstrumentationExtension()