Convert rediscala test to scala (#12616)
This commit is contained in:
parent
647fc45914
commit
3d5492184f
|
@ -1,5 +1,6 @@
|
|||
plugins {
|
||||
id("otel.javaagent-instrumentation")
|
||||
id("otel.scala-conventions")
|
||||
}
|
||||
|
||||
muzzle {
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue