From 219149faa092a6d24ee83bc273a6b291d4995bc5 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Sat, 30 Nov 2024 10:29:31 +0800 Subject: [PATCH] convert hibernate 6.0 test case from groovy to java (#12762) --- .../src/test/groovy/SpringJpaTest.groovy | 388 ------------------ .../test/java/spring/jpa/SpringJpaTest.java | 377 +++++++++++++++++ 2 files changed, 377 insertions(+), 388 deletions(-) delete mode 100644 instrumentation/hibernate/hibernate-6.0/spring-testing/src/test/groovy/SpringJpaTest.groovy create mode 100644 instrumentation/hibernate/hibernate-6.0/spring-testing/src/test/java/spring/jpa/SpringJpaTest.java diff --git a/instrumentation/hibernate/hibernate-6.0/spring-testing/src/test/groovy/SpringJpaTest.groovy b/instrumentation/hibernate/hibernate-6.0/spring-testing/src/test/groovy/SpringJpaTest.groovy deleted file mode 100644 index d0ffa8c6c36f..000000000000 --- a/instrumentation/hibernate/hibernate-6.0/spring-testing/src/test/groovy/SpringJpaTest.groovy +++ /dev/null @@ -1,388 +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.hibernate.Version -import org.springframework.context.annotation.AnnotationConfigApplicationContext -import spock.lang.Shared -import spring.jpa.Customer -import spring.jpa.CustomerRepository -import spring.jpa.PersistenceConfig - -import static io.opentelemetry.api.trace.SpanKind.CLIENT -import static io.opentelemetry.api.trace.SpanKind.INTERNAL -import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv -import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable - -class SpringJpaTest extends AgentInstrumentationSpecification { - - @Shared - def context = new AnnotationConfigApplicationContext(PersistenceConfig) - - @Shared - def repo = context.getBean(CustomerRepository) - - @SuppressWarnings("deprecation") // TODO DbIncubatingAttributes.DB_CONNECTION_STRING deprecation - def "test CRUD"() { - setup: - def isHibernate4 = Version.getVersionString().startsWith("4.") - def customer = new Customer("Bob", "Anonymous") - - expect: - customer.id == null - !runWithSpan("parent") { - repo.findAll().iterator().hasNext() - } - - def sessionId - assertTraces(1) { - trace(0, 4) { - span(0) { - name "parent" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "SELECT spring.jpa.Customer" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" { - sessionId = it - it instanceof String - } - } - } - span(2) { - name "SELECT test.Customer" - kind CLIENT - childOf span(1) - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" ~/select ([^.]+)\.id([^,]*),([^.]+)\.firstName([^,]*),([^.]+)\.lastName(.*)from Customer(.*)/ - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "SELECT" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" sessionId - } - } - } - } - clearExportedData() - - when: - runWithSpan("parent") { - repo.save(customer) - } - def savedId = customer.id - - then: - customer.id != null - def sessionId2 - assertTraces(1) { - trace(0, 4 + (isHibernate4 ? 0 : 1)) { - span(0) { - name "parent" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "Session.persist spring.jpa.Customer" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" { - sessionId2 = it - it instanceof String - } - } - } - if (!isHibernate4) { - span(2) { - name "CALL test" - kind CLIENT - childOf span(1) - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" "call next value for Customer_SEQ" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "CALL" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" sessionId2 - } - } - span(4) { - name "INSERT test.Customer" - kind CLIENT - childOf span(3) - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" ~/insert into Customer \(.*\) values \(.*\)/ - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "INSERT" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - } else { - span(2) { - name "INSERT test.Customer" - kind CLIENT - childOf span(1) - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" ~/insert into Customer \(.*\) values \(.*\)/ - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "INSERT" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" sessionId2 - } - } - } - } - } - clearExportedData() - - when: - customer.firstName = "Bill" - runWithSpan("parent") { - repo.save(customer) - } - - then: - customer.id == savedId - def sessionId3 - assertTraces(1) { - trace(0, 5) { - span(0) { - name "parent" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "Session.merge spring.jpa.Customer" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" { - sessionId3 = it - it instanceof String - } - } - } - span(2) { - name "SELECT test.Customer" - kind CLIENT - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" ~/select ([^.]+)\.id([^,]*),([^.]+)\.firstName([^,]*),([^.]+)\.lastName (.*)from Customer (.*)where ([^.]+)\.id( ?)=( ?)\?/ - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "SELECT" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" sessionId3 - } - } - span(4) { - name "UPDATE test.Customer" - kind CLIENT - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" ~/update Customer set firstName=\?,(.*)lastName=\? where id=\?/ - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "UPDATE" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - } - } - clearExportedData() - - when: - customer = runWithSpan("parent") { - repo.findByLastName("Anonymous")[0] - } - - then: - customer.id == savedId - customer.firstName == "Bill" - assertTraces(1) { - trace(0, 3) { - span(0) { - name "parent" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name { it == "SELECT spring.jpa.Customer" || it == "Hibernate Query" } - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" String - } - } - span(2) { - name "SELECT test.Customer" - kind CLIENT - childOf span(1) - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" ~/select ([^.]+)\.id([^,]*),([^.]+)\.firstName([^,]*),([^.]+)\.lastName (.*)from Customer (.*)(where ([^.]+)\.lastName( ?)=( ?)\?|)/ - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "SELECT" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - } - } - clearExportedData() - - when: - runWithSpan("parent") { - repo.delete(customer) - } - - then: - assertTraces(1) { - trace(0, 6 + (isHibernate4 ? 0 : 1)) { - span(0) { - name "parent" - kind INTERNAL - hasNoParent() - attributes { - } - } - def offset = 0 - if (!isHibernate4) { - offset = 2 - span(1) { - name ~/Session.(get|find) spring.jpa.Customer/ - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" String - } - } - span(2) { - name "SELECT test.Customer" - kind CLIENT - childOf span(1) - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" ~/select ([^.]+)\.id([^,]*),([^.]+)\.firstName([^,]*),([^.]+)\.lastName (.*)from Customer (.*)where ([^.]+)\.id( ?)=( ?)\?/ - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "SELECT" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - } - span(1 + offset) { - name "Session.merge spring.jpa.Customer" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" String - } - } - if (isHibernate4) { - offset = 1 - span(2) { - name "SELECT test.Customer" - kind CLIENT - childOf span(1) - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" ~/select ([^.]+)\.id([^,]*),([^.]+)\.firstName([^,]*),([^.]+)\.lastName (.*)from Customer (.*)where ([^.]+)\.id( ?)=( ?)\?/ - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "SELECT" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - } - span(2 + offset) { - name "Session.delete spring.jpa.Customer" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" String - } - } - span(3 + offset) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" String - } - } - span(4 + offset) { - name "DELETE test.Customer" - kind CLIENT - attributes { - "$DbIncubatingAttributes.DB_SYSTEM" "hsqldb" - "${maybeStable(DbIncubatingAttributes.DB_NAME)}" "test" - "$DbIncubatingAttributes.DB_USER" emitStableDatabaseSemconv() ? null : "sa" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" emitStableDatabaseSemconv() ? null : "hsqldb:mem:" - "${maybeStable(DbIncubatingAttributes.DB_STATEMENT)}" "delete from Customer where id=?" - "${maybeStable(DbIncubatingAttributes.DB_OPERATION)}" "DELETE" - "${maybeStable(DbIncubatingAttributes.DB_SQL_TABLE)}" "Customer" - } - } - } - } - } -} diff --git a/instrumentation/hibernate/hibernate-6.0/spring-testing/src/test/java/spring/jpa/SpringJpaTest.java b/instrumentation/hibernate/hibernate-6.0/spring-testing/src/test/java/spring/jpa/SpringJpaTest.java new file mode 100644 index 000000000000..becfe4aef79c --- /dev/null +++ b/instrumentation/hibernate/hibernate-6.0/spring-testing/src/test/java/spring/jpa/SpringJpaTest.java @@ -0,0 +1,377 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package spring.jpa; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.api.trace.SpanKind.CLIENT; +import static io.opentelemetry.api.trace.SpanKind.INTERNAL; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv; +import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_NAME; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SQL_TABLE; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DbSystemIncubatingValues.HSQLDB; +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +class SpringJpaTest { + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private static AnnotationConfigApplicationContext context; + private static CustomerRepository repo; + + @BeforeAll + static void setUp() { + context = new AnnotationConfigApplicationContext(PersistenceConfig.class); + repo = context.getBean(CustomerRepository.class); + } + + @AfterAll + static void tearDown() { + if (context != null) { + context.close(); + } + } + + @SuppressWarnings("deprecation") // DbIncubatingAttributes.DB_NAME has been deprecated + @Test + void testCrud() { + Customer customer = new Customer("Bob", "Anonymous"); + + assertThat(customer.getId()).isNull(); + assertThat(testing.runWithSpan("parent", () -> repo.findAll().iterator().hasNext())).isFalse(); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.hasName("SELECT spring.jpa.Customer") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("SELECT test.Customer") + .hasKind(CLIENT) + .hasParent(trace.getSpan(1)) + .hasAttributesSatisfyingExactly( + equalTo(DB_SYSTEM, HSQLDB), + equalTo(maybeStable(DB_NAME), "test"), + equalTo( + DbIncubatingAttributes.DB_USER, + emitStableDatabaseSemconv() ? null : "sa"), + equalTo( + DbIncubatingAttributes.DB_CONNECTION_STRING, + emitStableDatabaseSemconv() ? null : "hsqldb:mem:"), + satisfies( + maybeStable(DB_STATEMENT), + val -> + val.matches( + "select ([^.]+)\\.id([^,]*),([^.]+)\\.firstName([^,]*),([^.]+)\\.lastName(.*)from Customer(.*)")), + equalTo(maybeStable(DB_OPERATION), "SELECT"), + equalTo(maybeStable(DB_SQL_TABLE), "Customer")), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo( + stringKey("hibernate.session_id"), + trace + .getSpan(1) + .getAttributes() + .get(stringKey("hibernate.session_id")))))); + + testing.clearData(); + + testing.runWithSpan("parent", () -> repo.save(customer)); + Long savedId = customer.getId(); + + assertThat(customer.getId()).isNotNull(); + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.hasName("Session.persist spring.jpa.Customer") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("CALL test") + .hasKind(CLIENT) + .hasParent(trace.getSpan(1)) + .hasAttributesSatisfyingExactly( + equalTo(DB_SYSTEM, HSQLDB), + equalTo(maybeStable(DB_NAME), "test"), + equalTo( + DbIncubatingAttributes.DB_USER, + emitStableDatabaseSemconv() ? null : "sa"), + equalTo(maybeStable(DB_STATEMENT), "call next value for Customer_SEQ"), + equalTo( + DbIncubatingAttributes.DB_CONNECTION_STRING, + emitStableDatabaseSemconv() ? null : "hsqldb:mem:"), + equalTo(maybeStable(DB_OPERATION), "CALL")), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo( + stringKey("hibernate.session_id"), + trace + .getSpan(1) + .getAttributes() + .get(stringKey("hibernate.session_id")))), + span -> + span.hasName("INSERT test.Customer") + .hasKind(CLIENT) + .hasParent(trace.getSpan(3)) + .hasAttributesSatisfyingExactly( + equalTo(DB_SYSTEM, HSQLDB), + equalTo(maybeStable(DB_NAME), "test"), + equalTo( + DbIncubatingAttributes.DB_USER, + emitStableDatabaseSemconv() ? null : "sa"), + equalTo( + DbIncubatingAttributes.DB_CONNECTION_STRING, + emitStableDatabaseSemconv() ? null : "hsqldb:mem:"), + satisfies( + maybeStable(DB_STATEMENT), + val -> + val.matches("insert into Customer \\(.*\\) values \\(.*\\)")), + equalTo(maybeStable(DB_OPERATION), "INSERT"), + equalTo(maybeStable(DB_SQL_TABLE), "Customer")))); + + testing.clearData(); + + customer.setFirstName("Bill"); + testing.runWithSpan("parent", () -> repo.save(customer)); + + assertThat(customer.getId()).isEqualTo(savedId); + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.hasName("Session.merge spring.jpa.Customer") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("SELECT test.Customer") + .hasKind(CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(DB_SYSTEM, HSQLDB), + equalTo(maybeStable(DB_NAME), "test"), + equalTo( + DbIncubatingAttributes.DB_USER, + emitStableDatabaseSemconv() ? null : "sa"), + equalTo( + DbIncubatingAttributes.DB_CONNECTION_STRING, + emitStableDatabaseSemconv() ? null : "hsqldb:mem:"), + satisfies( + maybeStable(DB_STATEMENT), + val -> + val.matches( + "select ([^.]+)\\.id([^,]*),([^.]+)\\.firstName([^,]*),([^.]+)\\.lastName (.*)from Customer (.*)where ([^.]+)\\.id( ?)=( ?)\\?")), + equalTo(maybeStable(DB_OPERATION), "SELECT"), + equalTo(maybeStable(DB_SQL_TABLE), "Customer")), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo( + stringKey("hibernate.session_id"), + trace + .getSpan(1) + .getAttributes() + .get(stringKey("hibernate.session_id")))), + span -> + span.hasName("UPDATE test.Customer") + .hasKind(CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(DB_SYSTEM, HSQLDB), + equalTo(maybeStable(DB_NAME), "test"), + equalTo( + DbIncubatingAttributes.DB_USER, + emitStableDatabaseSemconv() ? null : "sa"), + equalTo( + DbIncubatingAttributes.DB_CONNECTION_STRING, + emitStableDatabaseSemconv() ? null : "hsqldb:mem:"), + satisfies( + maybeStable(DB_STATEMENT), + val -> + val.matches( + "update Customer set firstName=\\?,(.*)lastName=\\? where id=\\?")), + equalTo(maybeStable(DB_OPERATION), "UPDATE"), + equalTo(maybeStable(DB_SQL_TABLE), "Customer")))); + testing.clearData(); + Customer anonymousCustomer = + testing.runWithSpan("parent", () -> repo.findByLastName("Anonymous").get(0)); + + assertThat(anonymousCustomer.getId()).isEqualTo(savedId); + assertThat(anonymousCustomer.getFirstName()).isEqualTo("Bill"); + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.satisfies( + val -> + assertThat(val.getName()) + .isIn(asList("SELECT spring.jpa.Customer", "Hibernate Query"))) + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("SELECT test.Customer") + .hasKind(CLIENT) + .hasParent(trace.getSpan(1)) + .hasAttributesSatisfyingExactly( + equalTo(DB_SYSTEM, HSQLDB), + equalTo(maybeStable(DB_NAME), "test"), + equalTo( + DbIncubatingAttributes.DB_USER, + emitStableDatabaseSemconv() ? null : "sa"), + equalTo( + DbIncubatingAttributes.DB_CONNECTION_STRING, + emitStableDatabaseSemconv() ? null : "hsqldb:mem:"), + satisfies( + maybeStable(DB_STATEMENT), + val -> + val.matches( + "select ([^.]+)\\.id([^,]*),([^.]+)\\.firstName([^,]*),([^.]+)\\.lastName (.*)from Customer (.*)(where ([^.]+)\\.lastName( ?)=( ?)\\?|)")), + equalTo(maybeStable(DB_OPERATION), "SELECT"), + equalTo(maybeStable(DB_SQL_TABLE), "Customer")))); + testing.clearData(); + + testing.runWithSpan("parent", () -> repo.delete(anonymousCustomer)); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.satisfies( + val -> + assertThat(val.getName()) + .matches("Session.(get|find) spring.jpa.Customer")) + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("SELECT test.Customer") + .hasKind(CLIENT) + .hasParent(trace.getSpan(1)) + .hasAttributesSatisfyingExactly( + equalTo(DB_SYSTEM, HSQLDB), + equalTo(maybeStable(DB_NAME), "test"), + equalTo( + DbIncubatingAttributes.DB_USER, + emitStableDatabaseSemconv() ? null : "sa"), + equalTo( + DbIncubatingAttributes.DB_CONNECTION_STRING, + emitStableDatabaseSemconv() ? null : "hsqldb:mem:"), + satisfies( + maybeStable(DB_STATEMENT), + val -> + val.matches( + "select ([^.]+)\\.id([^,]*),([^.]+)\\.firstName([^,]*),([^.]+)\\.lastName (.*)from Customer (.*)(where ([^.]+)\\.lastName( ?)=( ?)\\?|)")), + equalTo(maybeStable(DB_OPERATION), "SELECT"), + equalTo(maybeStable(DB_SQL_TABLE), "Customer")), + span -> + span.hasName("Session.merge spring.jpa.Customer") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("Session.delete spring.jpa.Customer") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("DELETE test.Customer") + .hasKind(CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(DB_SYSTEM, HSQLDB), + equalTo(maybeStable(DB_NAME), "test"), + equalTo( + DbIncubatingAttributes.DB_USER, + emitStableDatabaseSemconv() ? null : "sa"), + equalTo( + DbIncubatingAttributes.DB_CONNECTION_STRING, + emitStableDatabaseSemconv() ? null : "hsqldb:mem:"), + equalTo(maybeStable(DB_STATEMENT), "delete from Customer where id=?"), + equalTo(maybeStable(DB_OPERATION), "DELETE"), + equalTo(maybeStable(DB_SQL_TABLE), "Customer")))); + } +}