Convert rediscala test to scala (#12616)

This commit is contained in:
Lauri Tulmin 2024-11-13 00:00:03 +02:00 committed by GitHub
parent 647fc45914
commit 3d5492184f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 190 additions and 145 deletions

View File

@ -1,5 +1,6 @@
plugins {
id("otel.javaagent-instrumentation")
id("otel.scala-conventions")
}
muzzle {

View File

@ -1,145 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
import io.opentelemetry.semconv.incubating.DbIncubatingAttributes
import org.testcontainers.containers.GenericContainer
import redis.ByteStringDeserializerDefault
import redis.ByteStringSerializerLowPriority
import redis.RedisClient
import redis.RedisDispatcher
import scala.Option
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import spock.lang.Shared
import static io.opentelemetry.api.trace.SpanKind.CLIENT
import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable
class RediscalaClientTest extends AgentInstrumentationSpecification {
private static GenericContainer redisServer = new GenericContainer<>("redis:6.2.3-alpine").withExposedPorts(6379)
@Shared
int port
@Shared
def system
@Shared
RedisClient redisClient
def setupSpec() {
redisServer.start()
String host = redisServer.getHost()
port = redisServer.getMappedPort(6379)
// latest has separate artifacts for akka an pekko, currently latestDepTestLibrary picks the
// pekko one
try {
def clazz = Class.forName("akka.actor.ActorSystem")
system = clazz.getMethod("create").invoke(null)
} catch (ClassNotFoundException exception) {
def clazz = Class.forName("org.apache.pekko.actor.ActorSystem")
system = clazz.getMethod("create").invoke(null)
}
// latest RedisClient constructor takes username as argument
if (RedisClient.metaClass.getMetaMethod("username") != null) {
redisClient = new RedisClient(host,
port,
Option.apply(null),
Option.apply(null),
Option.apply(null),
"RedisClient",
Option.apply(null),
system,
new RedisDispatcher("rediscala.rediscala-client-worker-dispatcher"))
} else {
redisClient = new RedisClient(host,
port,
Option.apply(null),
Option.apply(null),
"RedisClient",
Option.apply(null),
system,
new RedisDispatcher("rediscala.rediscala-client-worker-dispatcher"))
}
}
def cleanupSpec() {
redisServer.stop()
system?.terminate()
}
def "set command"() {
when:
def value = redisClient.set("foo",
"bar",
Option.apply(null),
Option.apply(null),
false,
false,
new ByteStringSerializerLowPriority.String$())
then:
Await.result(value, Duration.apply("3 second")) == true
assertTraces(1) {
trace(0, 1) {
span(0) {
name "SET"
kind CLIENT
attributes {
"$DbIncubatingAttributes.DB_SYSTEM" "redis"
"${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "SET"
}
}
}
}
}
def "get command"() {
when:
def (write, value) = runWithSpan("parent") {
def w = redisClient.set("bar",
"baz",
Option.apply(null),
Option.apply(null),
false,
false,
new ByteStringSerializerLowPriority.String$())
def v = redisClient.get("bar", new ByteStringDeserializerDefault.String$())
return new Tuple(w, v)
}
then:
Await.result(write, Duration.apply("3 second")) == true
Await.result(value, Duration.apply("3 second")) == Option.apply("baz")
assertTraces(1) {
trace(0, 3) {
span(0) {
name "parent"
}
span(1) {
name "SET"
kind CLIENT
childOf span(0)
attributes {
"$DbIncubatingAttributes.DB_SYSTEM" "redis"
"${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "SET"
}
}
span(2) {
name "GET"
kind CLIENT
childOf span(0)
attributes {
"$DbIncubatingAttributes.DB_SYSTEM" "redis"
"${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "GET"
}
}
}
}
}
}

View File

@ -0,0 +1,189 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package rediscala
import io.opentelemetry.api.trace.SpanKind.CLIENT
import io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension
import io.opentelemetry.instrumentation.testing.util.ThrowingSupplier
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo
import io.opentelemetry.sdk.testing.assertj.{SpanDataAssert, TraceAssert}
import io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION
import io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM
import io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DbSystemIncubatingValues.REDIS
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.{AfterAll, BeforeAll, Test, TestInstance}
import org.junit.jupiter.api.extension.RegisterExtension
import org.testcontainers.containers.GenericContainer
import redis.{RedisClient, RedisDispatcher}
import java.util.function.Consumer
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class RediscalaClientTest {
@RegisterExtension val testing = AgentInstrumentationExtension.create
var system: Object = null
var redisServer: GenericContainer[_] = null
var redisClient: RedisClient = null
@BeforeAll
def setUp(): Unit = {
redisServer =
new GenericContainer("redis:6.2.3-alpine").withExposedPorts(6379)
redisServer.start()
val host: String = redisServer.getHost
val port: Integer = redisServer.getMappedPort(6379)
try {
val clazz = Class.forName("akka.actor.ActorSystem")
system = clazz.getMethod("create").invoke(null)
} catch {
case _: ClassNotFoundException =>
val clazz = Class.forName("org.apache.pekko.actor.ActorSystem")
system = clazz.getMethod("create").invoke(null)
}
try {
// latest RedisClient constructor takes username as argument
classOf[RedisClient].getMethod("username")
redisClient = classOf[RedisClient]
.getConstructors()(0)
.newInstance(
host,
port,
Option.apply(null),
Option.apply(null),
Option.apply(null),
"RedisClient",
Option.apply(null),
system,
RedisDispatcher("rediscala.rediscala-client-worker-dispatcher")
)
.asInstanceOf[RedisClient]
} catch {
case _: Exception =>
redisClient = classOf[RedisClient]
.getConstructors()(0)
.newInstance(
host,
port,
Option.apply(null),
Option.apply(null),
"RedisClient",
Option.apply(null),
system,
RedisDispatcher("rediscala.rediscala-client-worker-dispatcher")
)
.asInstanceOf[RedisClient]
}
}
@AfterAll
def tearDown(): Unit = {
if (system != null) {
system.getClass.getMethod("terminate").invoke(system)
}
redisServer.stop()
}
@Test def testSetCommand(): Unit = {
val value = testing.runWithSpan(
"parent",
new ThrowingSupplier[Future[Boolean], Exception] {
override def get(): Future[Boolean] = {
redisClient.set("foo", "bar")
}
}
)
assertThat(Await.result(value, Duration.apply("3 second"))).isTrue
testing.waitAndAssertTraces(new Consumer[TraceAssert] {
override def accept(trace: TraceAssert): Unit =
trace.hasSpansSatisfyingExactly(
new Consumer[SpanDataAssert] {
override def accept(span: SpanDataAssert): Unit = {
span.hasName("parent").hasNoParent
}
},
new Consumer[SpanDataAssert] {
override def accept(span: SpanDataAssert): Unit = {
span
.hasName("SET")
.hasKind(CLIENT)
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
equalTo(DB_SYSTEM, REDIS),
equalTo(SemconvStabilityUtil.maybeStable(DB_OPERATION), "SET")
)
}
}
)
})
}
@Test def testGetCommand(): Unit = {
val (write, value) = testing.runWithSpan(
"parent",
new ThrowingSupplier[
(Future[Boolean], Future[Option[String]]),
Exception
] {
override def get(): (Future[Boolean], Future[Option[String]]) = {
val write = redisClient.set("bar", "baz")
val value = redisClient.get[String]("bar")
(write, value)
}
}
)
assertThat(Await.result(write, Duration.apply("3 second"))).isTrue
assertThat(
Await
.result(value, Duration.apply("3 second"))
.get
).isEqualTo("baz")
testing.waitAndAssertTraces(new Consumer[TraceAssert] {
override def accept(trace: TraceAssert): Unit =
trace.hasSpansSatisfyingExactly(
new Consumer[SpanDataAssert] {
override def accept(span: SpanDataAssert): Unit = {
span.hasName("parent").hasNoParent
}
},
new Consumer[SpanDataAssert] {
override def accept(span: SpanDataAssert): Unit = {
span
.hasName("SET")
.hasKind(CLIENT)
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
equalTo(DB_SYSTEM, REDIS),
equalTo(SemconvStabilityUtil.maybeStable(DB_OPERATION), "SET")
)
}
},
new Consumer[SpanDataAssert] {
override def accept(span: SpanDataAssert): Unit = {
span
.hasName("GET")
.hasKind(CLIENT)
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
equalTo(DB_SYSTEM, REDIS),
equalTo(SemconvStabilityUtil.maybeStable(DB_OPERATION), "GET")
)
}
}
)
})
}
}