Convert hibernate-4.0 groovy tests - part 2 (#9249)

This commit is contained in:
Jay DeLuca 2023-08-21 17:24:00 -04:00 committed by GitHub
parent eb3ded15e6
commit aca29defb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 447 additions and 319 deletions

View File

@ -1,84 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import io.opentelemetry.javaagent.instrumentation.hibernate.v4_0.Value
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.hibernate.Criteria
import org.hibernate.Session
import org.hibernate.criterion.Order
import org.hibernate.criterion.Restrictions
import static io.opentelemetry.api.trace.SpanKind.CLIENT
import static io.opentelemetry.api.trace.SpanKind.INTERNAL
class CriteriaTest extends AbstractHibernateTest {
def "test criteria.#methodName"() {
setup:
runWithSpan("parent") {
Session session = sessionFactory.openSession()
session.beginTransaction()
Criteria criteria = session.createCriteria(Value)
.add(Restrictions.like("name", "Hello"))
.addOrder(Order.desc("name"))
interaction.call(criteria)
session.getTransaction().commit()
session.close()
}
expect:
def sessionId
assertTraces(1) {
trace(0, 4) {
span(0) {
name "parent"
kind INTERNAL
hasNoParent()
attributes {
}
}
span(1) {
name "Criteria.$methodName $Value.name"
kind INTERNAL
childOf span(0)
attributes {
"hibernate.session_id" {
sessionId = it
it instanceof String
}
}
}
span(2) {
name "SELECT db1.Value"
kind CLIENT
childOf span(1)
attributes {
"$SemanticAttributes.DB_SYSTEM" "h2"
"$SemanticAttributes.DB_NAME" "db1"
"$SemanticAttributes.DB_USER" "sa"
"$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:"
"$SemanticAttributes.DB_STATEMENT" ~/^select /
"$SemanticAttributes.DB_OPERATION" "SELECT"
"$SemanticAttributes.DB_SQL_TABLE" "Value"
}
}
span(3) {
name "Transaction.commit"
kind INTERNAL
childOf span(0)
attributes {
"hibernate.session_id" sessionId
}
}
}
}
where:
methodName | interaction
"list" | { c -> c.list() }
"uniqueResult" | { c -> c.uniqueResult() }
"scroll" | { c -> c.scroll() }
}
}

View File

@ -1,235 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import io.opentelemetry.javaagent.instrumentation.hibernate.v4_0.Value
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import spock.lang.Shared
import spock.lang.Unroll
import javax.persistence.EntityManager
import javax.persistence.EntityManagerFactory
import javax.persistence.EntityTransaction
import javax.persistence.LockModeType
import javax.persistence.Persistence
import javax.persistence.Query
import static io.opentelemetry.api.trace.SpanKind.CLIENT
import static io.opentelemetry.api.trace.SpanKind.INTERNAL
class EntityManagerTest extends AbstractHibernateTest {
@Shared
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test-pu")
@Unroll
def "test hibernate action #testName"() {
setup:
EntityManager entityManager = entityManagerFactory.createEntityManager()
EntityTransaction entityTransaction = entityManager.getTransaction()
entityTransaction.begin()
def entity = prepopulated.get(0)
if (attach) {
entity = runWithSpan("setup") {
entityManager.merge(prepopulated.get(0))
}
ignoreTracesAndClear(1)
}
when:
runWithSpan("parent") {
try {
sessionMethodTest.call(entityManager, entity)
} catch (Exception e) {
// We expected this, we should see the error field set on the span.
}
entityTransaction.commit()
entityManager.close()
}
then:
boolean isPersistTest = "persist" == testName
def sessionId
assertTraces(1) {
trace(0, 4 + (isPersistTest ? 1 : 0)) {
span(0) {
name "parent"
kind INTERNAL
hasNoParent()
attributes {
}
}
span(1) {
name ~/Session.$methodName $resource/
kind INTERNAL
childOf span(0)
attributes {
"hibernate.session_id" {
sessionId = it
it instanceof String
}
}
}
def offset = 0
if (isPersistTest) {
// persist test has an extra query for getting id of inserted element
offset = 1
span(2) {
name "SELECT db1.Value"
childOf span(1)
kind CLIENT
attributes {
"$SemanticAttributes.DB_SYSTEM" "h2"
"$SemanticAttributes.DB_NAME" "db1"
"$SemanticAttributes.DB_USER" "sa"
"$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:"
"$SemanticAttributes.DB_STATEMENT" String
"$SemanticAttributes.DB_OPERATION" String
"$SemanticAttributes.DB_SQL_TABLE" "Value"
}
}
}
if (!flushOnCommit) {
span(2 + offset) {
childOf span(1)
kind CLIENT
attributes {
"$SemanticAttributes.DB_SYSTEM" "h2"
"$SemanticAttributes.DB_NAME" "db1"
"$SemanticAttributes.DB_USER" "sa"
"$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:"
"$SemanticAttributes.DB_STATEMENT" String
"$SemanticAttributes.DB_OPERATION" String
"$SemanticAttributes.DB_SQL_TABLE" "Value"
}
}
span(3 + offset) {
name "Transaction.commit"
kind INTERNAL
childOf span(0)
attributes {
"hibernate.session_id" sessionId
}
}
} else {
span(2 + offset) {
name "Transaction.commit"
kind INTERNAL
childOf span(0)
attributes {
"hibernate.session_id" sessionId
}
}
span(3 + offset) {
childOf span(2 + offset)
kind CLIENT
attributes {
"$SemanticAttributes.DB_SYSTEM" "h2"
"$SemanticAttributes.DB_NAME" "db1"
"$SemanticAttributes.DB_USER" "sa"
"$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:"
"$SemanticAttributes.DB_STATEMENT" String
"$SemanticAttributes.DB_OPERATION" String
"$SemanticAttributes.DB_SQL_TABLE" "Value"
}
}
}
}
}
where:
testName | methodName | resource | attach | flushOnCommit | sessionMethodTest
"lock" | "lock" | Value.name | true | false | { em, val ->
em.lock(val, LockModeType.PESSIMISTIC_READ)
}
"refresh" | "refresh" | Value.name | true | false | { em, val ->
em.refresh(val)
}
"find" | "(get|find)" | Value.name | false | false | { em, val ->
em.find(Value, val.getId())
}
"persist" | "persist" | Value.name | false | true | { em, val ->
em.persist(new Value("insert me"))
}
"merge" | "merge" | Value.name | true | true | { em, val ->
val.setName("New name")
em.merge(val)
}
"remove" | "delete" | Value.name | true | true | { em, val ->
em.remove(val)
}
}
@Unroll
def "test attaches State to query created via #queryMethodName"() {
setup:
runWithSpan("parent") {
EntityManager entityManager = entityManagerFactory.createEntityManager()
EntityTransaction entityTransaction = entityManager.getTransaction()
entityTransaction.begin()
Query query = queryBuildMethod(entityManager)
query.getResultList()
entityTransaction.commit()
entityManager.close()
}
expect:
def sessionId
assertTraces(1) {
trace(0, 4) {
span(0) {
name "parent"
kind INTERNAL
hasNoParent()
attributes {
}
}
span(1) {
name resource
kind INTERNAL
childOf span(0)
attributes {
"hibernate.session_id" {
sessionId = it
it instanceof String
}
}
}
span(2) {
name "SELECT db1.Value"
kind CLIENT
childOf span(1)
attributes {
"$SemanticAttributes.DB_SYSTEM" "h2"
"$SemanticAttributes.DB_NAME" "db1"
"$SemanticAttributes.DB_USER" "sa"
"$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:"
"$SemanticAttributes.DB_STATEMENT" String
"$SemanticAttributes.DB_OPERATION" "SELECT"
"$SemanticAttributes.DB_SQL_TABLE" "Value"
}
}
span(3) {
name "Transaction.commit"
kind INTERNAL
childOf span(0)
attributes {
"hibernate.session_id" sessionId
}
}
}
}
where:
queryMethodName | resource | queryBuildMethod
"createQuery" | "SELECT Value" | { em -> em.createQuery("from Value") }
"getNamedQuery" | "SELECT Value" | { em -> em.createNamedQuery("TestNamedQuery") }
"createSQLQuery" | "SELECT Value" | { em -> em.createNativeQuery("SELECT * FROM Value") }
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.hibernate.v4_0;
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.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.function.Consumer;
import java.util.stream.Stream;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class CriteriaTest extends AbstractHibernateTest {
@ParameterizedTest
@MethodSource("provideArguments")
@SuppressWarnings("deprecation") // createCriteria(Class) has been deprecated in v5
void testCriteria(String methodName, Consumer<Criteria> interaction) {
testing.runWithSpan(
"parent",
() -> {
Session session = sessionFactory.openSession();
session.beginTransaction();
Criteria criteria =
session
.createCriteria(Value.class)
.add(Restrictions.like("name", "Hello"))
.addOrder(Order.desc("name"));
interaction.accept(criteria);
session.getTransaction().commit();
session.close();
});
testing.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("parent")
.hasKind(INTERNAL)
.hasNoParent()
.hasAttributes(Attributes.empty()),
span ->
span.hasName("Criteria." + methodName + " " + Value.class.getName())
.hasKind(INTERNAL)
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
satisfies(
stringKey("hibernate.session_id"),
val -> val.isInstanceOf(String.class))),
span ->
span.hasName("SELECT db1.Value")
.hasKind(CLIENT)
.hasParent(trace.getSpan(1))
.hasAttributesSatisfyingExactly(
equalTo(SemanticAttributes.DB_SYSTEM, "h2"),
equalTo(SemanticAttributes.DB_NAME, "db1"),
equalTo(SemanticAttributes.DB_USER, "sa"),
equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"),
satisfies(
SemanticAttributes.DB_STATEMENT,
stringAssert -> stringAssert.startsWith("select")),
equalTo(SemanticAttributes.DB_OPERATION, "SELECT"),
equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")),
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"))))));
}
private static Stream<Arguments> provideArguments() {
return Stream.of(
Arguments.of("list", (Consumer<Criteria>) Criteria::list),
Arguments.of("uniqueResult", (Consumer<Criteria>) Criteria::uniqueResult),
Arguments.of("scroll", (Consumer<Criteria>) Criteria::scroll));
}
}

View File

@ -0,0 +1,350 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.hibernate.v4_0;
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.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
import static org.junit.jupiter.api.Named.named;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Stream;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.LockModeType;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.hibernate.Version;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class EntityManagerTest extends AbstractHibernateTest {
static final EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("test-pu");
@ParameterizedTest
@MethodSource("provideArgumentsHibernateActionParameters")
void testHibernateActions(Parameter parameter) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
Value entity;
if (parameter.attach) {
entity = testing.runWithSpan("setup", () -> entityManager.merge(prepopulated.get(0)));
testing.clearData();
} else {
entity = prepopulated.get(0);
}
String version = Version.getVersionString();
boolean isHibernate4 = version.startsWith("4.");
boolean isLatestDep = version.startsWith("5.0");
String action;
if ((isHibernate4 || isLatestDep) && "find".equals(parameter.methodName)) {
action = "get";
} else {
action = parameter.methodName;
}
testing.runWithSpan(
"parent",
() -> {
parameter.sessionMethodTest.accept(entityManager, entity);
entityTransaction.commit();
entityManager.close();
});
testing.waitAndAssertTraces(
trace -> {
if (parameter.flushOnCommit) {
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("parent")
.hasKind(INTERNAL)
.hasNoParent()
.hasAttributes(Attributes.empty()),
span ->
span.hasName("Session." + action + " " + Value.class.getName())
.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(
equalTo(
stringKey("hibernate.session_id"),
trace
.getSpan(1)
.getAttributes()
.get(stringKey("hibernate.session_id")))),
span ->
span.hasKind(CLIENT)
.hasParent(trace.getSpan(2))
.hasAttributesSatisfyingExactly(
equalTo(SemanticAttributes.DB_SYSTEM, "h2"),
equalTo(SemanticAttributes.DB_NAME, "db1"),
equalTo(SemanticAttributes.DB_USER, "sa"),
equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"),
satisfies(
SemanticAttributes.DB_STATEMENT,
val -> val.isInstanceOf(String.class)),
satisfies(
SemanticAttributes.DB_OPERATION,
val -> val.isInstanceOf(String.class)),
equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")));
} else {
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("parent")
.hasKind(INTERNAL)
.hasNoParent()
.hasAttributes(Attributes.empty()),
span ->
span.hasName("Session." + action + " " + Value.class.getName())
.hasKind(INTERNAL)
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
satisfies(
stringKey("hibernate.session_id"),
val -> val.isInstanceOf(String.class))),
span ->
span.hasKind(CLIENT)
.hasParent(trace.getSpan(1))
.hasAttributesSatisfyingExactly(
equalTo(SemanticAttributes.DB_SYSTEM, "h2"),
equalTo(SemanticAttributes.DB_NAME, "db1"),
equalTo(SemanticAttributes.DB_USER, "sa"),
equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"),
satisfies(
SemanticAttributes.DB_STATEMENT,
val -> val.isInstanceOf(String.class)),
satisfies(
SemanticAttributes.DB_OPERATION,
val -> val.isInstanceOf(String.class)),
equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")),
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")))));
}
});
}
private static Stream<Arguments> provideArgumentsHibernateActionParameters() {
return Stream.of(
Arguments.of(
named(
"lock",
new Parameter(
"lock", true, false, (em, v) -> em.lock(v, LockModeType.PESSIMISTIC_READ)))),
Arguments.of(
named("refresh", new Parameter("refresh", true, false, EntityManager::refresh))),
Arguments.of(
named(
"find",
new Parameter("find", false, false, (em, v) -> em.find(Value.class, v.getId())))),
Arguments.of(
named(
"merge",
new Parameter(
"merge",
true,
true,
(em, v) -> {
v.setName("New name");
em.merge(v);
}))),
Arguments.of(named("remove", new Parameter("delete", true, true, EntityManager::remove))));
}
@Test
void testHibernatePersist() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
testing.runWithSpan(
"parent",
() -> {
entityManager.persist(new Value("insert me"));
entityTransaction.commit();
entityManager.close();
});
testing.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("parent")
.hasKind(INTERNAL)
.hasNoParent()
.hasAttributes(Attributes.empty()),
span ->
span.hasName("Session.persist " + Value.class.getName())
.hasKind(INTERNAL)
.hasParent(trace.getSpan(0)),
// persist test has an extra query for getting id of inserted element
span ->
span.hasName("SELECT db1.Value")
.hasKind(CLIENT)
.hasParent(trace.getSpan(1))
.hasAttributesSatisfyingExactly(
equalTo(SemanticAttributes.DB_SYSTEM, "h2"),
equalTo(SemanticAttributes.DB_NAME, "db1"),
equalTo(SemanticAttributes.DB_USER, "sa"),
equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"),
satisfies(
SemanticAttributes.DB_STATEMENT,
val -> val.isInstanceOf(String.class)),
satisfies(
SemanticAttributes.DB_OPERATION,
val -> val.isInstanceOf(String.class)),
equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")),
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.hasKind(CLIENT)
.hasParent(trace.getSpan(3))
.hasAttributesSatisfyingExactly(
equalTo(SemanticAttributes.DB_SYSTEM, "h2"),
equalTo(SemanticAttributes.DB_NAME, "db1"),
equalTo(SemanticAttributes.DB_USER, "sa"),
equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"),
satisfies(
SemanticAttributes.DB_STATEMENT,
val -> val.isInstanceOf(String.class)),
satisfies(
SemanticAttributes.DB_OPERATION,
val -> val.isInstanceOf(String.class)),
equalTo(SemanticAttributes.DB_SQL_TABLE, "Value"))));
}
@ParameterizedTest
@MethodSource("provideArgumentsAttachesState")
void testAttachesStateToQuery(Function<EntityManager, Query> queryBuildMethod) {
testing.runWithSpan(
"parent",
() -> {
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
queryBuildMethod.apply(entityManager).getResultList();
entityTransaction.commit();
entityManager.close();
});
testing.waitAndAssertTraces(
trace ->
trace.hasSpansSatisfyingExactly(
span ->
span.hasName("parent")
.hasKind(INTERNAL)
.hasNoParent()
.hasAttributes(Attributes.empty()),
span ->
span.hasName("SELECT Value")
.hasKind(INTERNAL)
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
satisfies(
stringKey("hibernate.session_id"),
val -> val.isInstanceOf(String.class))),
span ->
span.hasName("SELECT db1.Value")
.hasKind(CLIENT)
.hasParent(trace.getSpan(1))
.hasAttributesSatisfyingExactly(
equalTo(SemanticAttributes.DB_SYSTEM, "h2"),
equalTo(SemanticAttributes.DB_NAME, "db1"),
equalTo(SemanticAttributes.DB_USER, "sa"),
equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"),
satisfies(
SemanticAttributes.DB_STATEMENT,
val -> val.isInstanceOf(String.class)),
satisfies(
SemanticAttributes.DB_OPERATION,
val -> val.isInstanceOf(String.class)),
equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")),
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"))))));
}
private static Stream<Arguments> provideArgumentsAttachesState() {
return Stream.of(
Arguments.of(
named(
"createQuery",
(Function<EntityManager, Query>) em -> em.createQuery("from Value"))),
Arguments.of(
named(
"getNamedQuery",
(Function<EntityManager, Query>) em -> em.createNamedQuery("TestNamedQuery"))),
Arguments.of(
named(
"createSQLQuery",
(Function<EntityManager, Query>)
em -> em.createNativeQuery("SELECT * FROM Value"))));
}
private static class Parameter {
public final String methodName;
public final boolean attach;
public final boolean flushOnCommit;
public final BiConsumer<EntityManager, Value> sessionMethodTest;
public Parameter(
String methodName,
boolean attach,
boolean flushOnCommit,
BiConsumer<EntityManager, Value> sessionMethodTest) {
this.methodName = methodName;
this.attach = attach;
this.flushOnCommit = flushOnCommit;
this.sessionMethodTest = sessionMethodTest;
}
}
}