diff --git a/instrumentation/jedis/jedis-1.4/javaagent/build.gradle.kts b/instrumentation/jedis/jedis-1.4/javaagent/build.gradle.kts index 2e446ca8b53a..a8351d07e963 100644 --- a/instrumentation/jedis/jedis-1.4/javaagent/build.gradle.kts +++ b/instrumentation/jedis/jedis-1.4/javaagent/build.gradle.kts @@ -19,12 +19,25 @@ dependencies { implementation(project(":instrumentation:jedis:jedis-common:javaagent")) + testImplementation(project(":instrumentation:jedis:jedis-1.4:testing")) + testInstrumentation(project(":instrumentation:jedis:jedis-3.0:javaagent")) testInstrumentation(project(":instrumentation:jedis:jedis-4.0:javaagent")) latestDepTestLibrary("redis.clients:jedis:2.+") // see jedis-3.0 module } +testing { + suites { + val version272 by registering(JvmTestSuite::class) { + dependencies { + implementation("redis.clients:jedis:2.7.2") + implementation(project(":instrumentation:jedis:jedis-1.4:testing")) + } + } + } +} + tasks { test { usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service) diff --git a/instrumentation/jedis/jedis-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jedis/v1_4/JedisConnectionInstrumentation.java b/instrumentation/jedis/jedis-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jedis/v1_4/JedisConnectionInstrumentation.java index c2386d5821e7..fcd6822e99bb 100644 --- a/instrumentation/jedis/jedis-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jedis/v1_4/JedisConnectionInstrumentation.java +++ b/instrumentation/jedis/jedis-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jedis/v1_4/JedisConnectionInstrumentation.java @@ -11,6 +11,7 @@ import static net.bytebuddy.matcher.ElementMatchers.is; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; @@ -21,6 +22,7 @@ import io.opentelemetry.javaagent.instrumentation.jedis.JedisRequestContext; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.matcher.ElementMatcher; import redis.clients.jedis.Connection; import redis.clients.jedis.Protocol; @@ -37,13 +39,23 @@ public void transform(TypeTransformer transformer) { isMethod() .and(named("sendCommand")) .and(takesArguments(1)) - .and(takesArgument(0, named("redis.clients.jedis.Protocol$Command"))), + .and( + takesArgument( + 0, + namedOneOf( + "redis.clients.jedis.Protocol$Command", + "redis.clients.jedis.ProtocolCommand"))), this.getClass().getName() + "$SendCommandNoArgsAdvice"); transformer.applyAdviceToMethod( isMethod() .and(named("sendCommand")) .and(takesArguments(2)) - .and(takesArgument(0, named("redis.clients.jedis.Protocol$Command"))) + .and( + takesArgument( + 0, + namedOneOf( + "redis.clients.jedis.Protocol$Command", + "redis.clients.jedis.ProtocolCommand"))) .and(takesArgument(1, is(byte[][].class))), this.getClass().getName() + "$SendCommandWithArgsAdvice"); } @@ -54,7 +66,7 @@ public static class SendCommandNoArgsAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void onEnter( @Advice.This Connection connection, - @Advice.Argument(0) Protocol.Command command, + @Advice.Argument(value = 0, typing = Assigner.Typing.DYNAMIC) Protocol.Command command, @Advice.Local("otelJedisRequest") JedisRequest request, @Advice.Local("otelContext") Context context, @Advice.Local("otelScope") Scope scope) { @@ -89,7 +101,7 @@ public static class SendCommandWithArgsAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void onEnter( @Advice.This Connection connection, - @Advice.Argument(0) Protocol.Command command, + @Advice.Argument(value = 0, typing = Assigner.Typing.DYNAMIC) Protocol.Command command, @Advice.Argument(1) byte[][] args, @Advice.Local("otelJedisRequest") JedisRequest request, @Advice.Local("otelContext") Context context, diff --git a/instrumentation/jedis/jedis-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v1_4/JedisClientTest.java b/instrumentation/jedis/jedis-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v1_4/JedisClientTest.java index 1a4aafef54a1..99b5bfc6272d 100644 --- a/instrumentation/jedis/jedis-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v1_4/JedisClientTest.java +++ b/instrumentation/jedis/jedis-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v1_4/JedisClientTest.java @@ -5,129 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.jedis.v1_4; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; -import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.javaagent.instrumentation.jedis.AbstractJedisTest; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; -import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import io.opentelemetry.semconv.SemanticAttributes; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.testcontainers.containers.GenericContainer; -import redis.clients.jedis.Jedis; - -class JedisClientTest { - @RegisterExtension - static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); - - static GenericContainer redisServer = - new GenericContainer<>("redis:6.2.3-alpine").withExposedPorts(6379); - - static int port; - - static Jedis jedis; - - @BeforeAll - static void setup() { - redisServer.start(); - port = redisServer.getMappedPort(6379); - jedis = new Jedis("localhost", port); - } - - @AfterAll - static void cleanup() { - redisServer.stop(); - } - - @BeforeEach - void reset() { - jedis.flushAll(); - testing.clearData(); - } - - @Test - void setCommand() { - jedis.set("foo", "bar"); - - testing.waitAndAssertTraces( - trace -> - trace.hasSpansSatisfyingExactly( - span -> - span.hasName("SET") - .hasKind(SpanKind.CLIENT) - .hasAttributesSatisfyingExactly( - equalTo(SemanticAttributes.DB_SYSTEM, "redis"), - equalTo(SemanticAttributes.DB_STATEMENT, "SET foo ?"), - equalTo(SemanticAttributes.DB_OPERATION, "SET"), - equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), - equalTo(SemanticAttributes.SERVER_PORT, port)))); - } - - @Test - void getCommand() { - jedis.set("foo", "bar"); - String value = jedis.get("foo"); - - assertThat(value).isEqualTo("bar"); - - testing.waitAndAssertTraces( - trace -> - trace.hasSpansSatisfyingExactly( - span -> - span.hasName("SET") - .hasKind(SpanKind.CLIENT) - .hasAttributesSatisfyingExactly( - equalTo(SemanticAttributes.DB_SYSTEM, "redis"), - equalTo(SemanticAttributes.DB_STATEMENT, "SET foo ?"), - equalTo(SemanticAttributes.DB_OPERATION, "SET"), - equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), - equalTo(SemanticAttributes.SERVER_PORT, port))), - trace -> - trace.hasSpansSatisfyingExactly( - span -> - span.hasName("GET") - .hasKind(SpanKind.CLIENT) - .hasAttributesSatisfyingExactly( - equalTo(SemanticAttributes.DB_SYSTEM, "redis"), - equalTo(SemanticAttributes.DB_STATEMENT, "GET foo"), - equalTo(SemanticAttributes.DB_OPERATION, "GET"), - equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), - equalTo(SemanticAttributes.SERVER_PORT, port)))); - } - - @Test - void commandWithNoArguments() { - jedis.set("foo", "bar"); - String value = jedis.randomKey(); - - assertThat(value).isEqualTo("foo"); - - testing.waitAndAssertTraces( - trace -> - trace.hasSpansSatisfyingExactly( - span -> - span.hasName("SET") - .hasKind(SpanKind.CLIENT) - .hasAttributesSatisfyingExactly( - equalTo(SemanticAttributes.DB_SYSTEM, "redis"), - equalTo(SemanticAttributes.DB_STATEMENT, "SET foo ?"), - equalTo(SemanticAttributes.DB_OPERATION, "SET"), - equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), - equalTo(SemanticAttributes.SERVER_PORT, port))), - trace -> - trace.hasSpansSatisfyingExactly( - span -> - span.hasName("RANDOMKEY") - .hasKind(SpanKind.CLIENT) - .hasAttributesSatisfyingExactly( - equalTo(SemanticAttributes.DB_SYSTEM, "redis"), - equalTo(SemanticAttributes.DB_STATEMENT, "RANDOMKEY"), - equalTo(SemanticAttributes.DB_OPERATION, "RANDOMKEY"), - equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), - equalTo(SemanticAttributes.SERVER_PORT, port)))); - } -} +class JedisClientTest extends AbstractJedisTest {} diff --git a/instrumentation/jedis/jedis-1.4/javaagent/src/version272/java/io/opentelemetry/javaagent/instrumentation/jedis/v2_7_2/JedisClientTest.java b/instrumentation/jedis/jedis-1.4/javaagent/src/version272/java/io/opentelemetry/javaagent/instrumentation/jedis/v2_7_2/JedisClientTest.java new file mode 100644 index 000000000000..15d1e5d01084 --- /dev/null +++ b/instrumentation/jedis/jedis-1.4/javaagent/src/version272/java/io/opentelemetry/javaagent/instrumentation/jedis/v2_7_2/JedisClientTest.java @@ -0,0 +1,10 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jedis.v2_7_2; + +import io.opentelemetry.javaagent.instrumentation.jedis.AbstractJedisTest; + +class JedisClientTest extends AbstractJedisTest {} diff --git a/instrumentation/jedis/jedis-1.4/testing/build.gradle.kts b/instrumentation/jedis/jedis-1.4/testing/build.gradle.kts new file mode 100644 index 000000000000..38876e40dcf8 --- /dev/null +++ b/instrumentation/jedis/jedis-1.4/testing/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("otel.java-conventions") +} + +dependencies { + compileOnly("redis.clients:jedis:1.4.0") + api(project(":testing-common")) + implementation("org.testcontainers:testcontainers") +} diff --git a/instrumentation/jedis/jedis-1.4/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/jedis/AbstractJedisTest.java b/instrumentation/jedis/jedis-1.4/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/jedis/AbstractJedisTest.java new file mode 100644 index 000000000000..8e22b8d638a5 --- /dev/null +++ b/instrumentation/jedis/jedis-1.4/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/jedis/AbstractJedisTest.java @@ -0,0 +1,133 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jedis; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.semconv.SemanticAttributes; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.testcontainers.containers.GenericContainer; +import redis.clients.jedis.Jedis; + +public abstract class AbstractJedisTest { + @RegisterExtension + private static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private static final GenericContainer REDIS_SERVER = + new GenericContainer<>("redis:6.2.3-alpine").withExposedPorts(6379); + + private static int port; + + private static Jedis jedis; + + @BeforeAll + static void setup() { + REDIS_SERVER.start(); + port = REDIS_SERVER.getMappedPort(6379); + jedis = new Jedis("localhost", port); + } + + @AfterAll + static void cleanup() { + REDIS_SERVER.stop(); + } + + @BeforeEach + void reset() { + jedis.flushAll(); + testing.clearData(); + } + + @Test + void setCommand() { + jedis.set("foo", "bar"); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("SET") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "redis"), + equalTo(SemanticAttributes.DB_STATEMENT, "SET foo ?"), + equalTo(SemanticAttributes.DB_OPERATION, "SET"), + equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), + equalTo(SemanticAttributes.SERVER_PORT, port)))); + } + + @Test + void getCommand() { + jedis.set("foo", "bar"); + String value = jedis.get("foo"); + + assertThat(value).isEqualTo("bar"); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("SET") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "redis"), + equalTo(SemanticAttributes.DB_STATEMENT, "SET foo ?"), + equalTo(SemanticAttributes.DB_OPERATION, "SET"), + equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), + equalTo(SemanticAttributes.SERVER_PORT, port))), + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("GET") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "redis"), + equalTo(SemanticAttributes.DB_STATEMENT, "GET foo"), + equalTo(SemanticAttributes.DB_OPERATION, "GET"), + equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), + equalTo(SemanticAttributes.SERVER_PORT, port)))); + } + + @Test + void commandWithNoArguments() { + jedis.set("foo", "bar"); + String value = jedis.randomKey(); + + assertThat(value).isEqualTo("foo"); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("SET") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "redis"), + equalTo(SemanticAttributes.DB_STATEMENT, "SET foo ?"), + equalTo(SemanticAttributes.DB_OPERATION, "SET"), + equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), + equalTo(SemanticAttributes.SERVER_PORT, port))), + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("RANDOMKEY") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "redis"), + equalTo(SemanticAttributes.DB_STATEMENT, "RANDOMKEY"), + equalTo(SemanticAttributes.DB_OPERATION, "RANDOMKEY"), + equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"), + equalTo(SemanticAttributes.SERVER_PORT, port)))); + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 00a34d0c372e..3a5bf1b4298a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -309,6 +309,7 @@ include(":instrumentation:jdbc:javaagent") include(":instrumentation:jdbc:library") include(":instrumentation:jdbc:testing") include(":instrumentation:jedis:jedis-1.4:javaagent") +include(":instrumentation:jedis:jedis-1.4:testing") include(":instrumentation:jedis:jedis-3.0:javaagent") include(":instrumentation:jedis:jedis-4.0:javaagent") include(":instrumentation:jedis:jedis-common:javaagent")