Make tests work for StatelessSession as well as Session
MODIFY
dd-java-agent/instrumentation/hibernate/src/test/groovy/SessionTest.groovy
dd-java-agent/instrumentation/hibernate/src/test/groovy/SessionTest.groovy
@@ -2,6 +2,7 @@ import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import io.opentracing.tag.Tags
+import lombok.NonNull
import org.hibernate.*
import org.hibernate.boot.MetadataSources
import org.hibernate.boot.registry.StandardServiceRegistry
@@ -31,33 +32,58 @@ class SessionTest extends AgentTestRunner {
}
}
+ @lombok.Value
+ static class SessionTypeTest {
+ // Lombok can't get the types right for the constructor.
+ SessionTypeTest(Closure fn) {
+ sessionBuilder = fn
+ }
+
+ @NonNull
+ Closure sessionBuilder
+ @NonNull
+ Value value = new Value("Hello :)")
+ }
+
def "test hibernate #testName"() {
setup:
- Session session = sessionFactory.openSession()
- session.beginTransaction()
- Value value = new Value("Hello :)")
- session.save(value)
- session.getTransaction().commit()
- session.close()
+ // Test two different types of Session. Groovy doesn't allow testing the cross-product/combinations of two data
+ // tables, so we get this hack instead.
+ Map<String, SessionTypeTest> sessionTests = new HashMap<>();
+ sessionTests.put("Session", new SessionTypeTest({ return sessionFactory.openSession() }))
+ sessionTests.put("StatelessSession", new SessionTypeTest({ return sessionFactory.openStatelessSession() }))
+ // Pre-populate the DB, so delete/update can be tested.
+ Session writer = sessionFactory.openSession()
+ writer.beginTransaction()
+ for (SessionTypeTest sessionTypeTest : sessionTests.values()) {
+ writer.save(sessionTypeTest.value)
+ }
+ writer.getTransaction().commit()
+ writer.close()
TEST_WRITER.waitForTraces(1)
TEST_WRITER.clear()
- session = sessionFactory.openSession()
+ // Test for each implementation of Session.
+ for (String sessionImplementation : sessionImplementations) {
+ SessionTypeTest sessionTypeTest = sessionTests.get(sessionImplementation)
+ def session = sessionTypeTest.getSessionBuilder().call()
session.beginTransaction()
try {
- sessionMethodTest.call(session, value)
+ sessionMethodTest.call(session, sessionTypeTest.getValue())
} catch (Exception e) {
// We expected this, we should see the error field set on the span.
}
session.getTransaction().commit()
session.close()
+ }
expect:
- assertTraces(1) {
- trace(0, 3) {
+ assertTraces(sessionImplementations.size()) {
+ for (int i = 0; i < sessionImplementations.size(); i++) {
+ trace(i, 3) {
span(0) {
serviceName "hibernate"
resourceName "hibernate.session"
@@ -103,56 +129,57 @@ class SessionTest extends AgentTestRunner {
}
}
}
+ }
where:
- testName | methodName | resource | isError | sessionMethodTest
- "replicate" | "replicate" | "Value" | false | { sesh, val ->
+ testName | methodName | resource | isError | sessionImplementations | sessionMethodTest
+ "replicate" | "replicate" | "Value" | false | ["Session"] | { sesh, val ->
Value replicated = new Value(val.getName() + " replicated")
replicated.setId(val.getId())
sesh.replicate(replicated, ReplicationMode.OVERWRITE)
}
- "replicate by entityName" | "replicate" | "Value" | false | { sesh, val ->
+ "replicate by entityName" | "replicate" | "Value" | false | ["Session"] | { sesh, val ->
Value replicated = new Value(val.getName() + " replicated")
replicated.setId(val.getId())
sesh.replicate("Value", replicated, ReplicationMode.OVERWRITE)
}
- "failed replicate" | "replicate" | "unknown object" | true | { sesh, val ->
+ "failed replicate" | "replicate" | "unknown object" | true | ["Session"] | { sesh, val ->
sesh.replicate(new Long(123) /* Not a valid entity */, ReplicationMode.OVERWRITE)
}
- "save" | "save" | "Value" | false | { sesh, val ->
+ "save" | "save" | "Value" | false | ["Session"] | { sesh, val ->
sesh.save(new Value("Another value"))
}
- "saveOrUpdate save" | "saveOrUpdate" | "Value" | false | { sesh, val ->
+ "saveOrUpdate save" | "saveOrUpdate" | "Value" | false | ["Session"] | { sesh, val ->
sesh.saveOrUpdate(new Value("Value"))
}
- "saveOrUpdate update" | "saveOrUpdate" | "Value" | false | { sesh, val ->
+ "saveOrUpdate update" | "saveOrUpdate" | "Value" | false | ["Session"] | { sesh, val ->
val.setName("New name")
sesh.saveOrUpdate(val)
}
- "update" | "update" | "Value" | false | { sesh, val ->
+ "update" | "update" | "Value" | false | ["Session", "StatelessSession"] | { sesh, val ->
val.setName("New name")
sesh.update(val)
}
- "update by entityName" | "update" | "Value" | false | { sesh, val ->
+ "update by entityName" | "update" | "Value" | false | ["Session", "StatelessSession"] | { sesh, val ->
val.setName("New name")
sesh.update("Value", val)
}
- "merge" | "merge" | "Value" | false | { sesh, val ->
+ "merge" | "merge" | "Value" | false | ["Session"] | { sesh, val ->
sesh.merge(new Value("merge me in"))
}
- "persist" | "persist" | "Value" | false | { sesh, val ->
+ "persist" | "persist" | "Value" | false | ["Session"] | { sesh, val ->
sesh.persist(new Value("merge me in"))
}
- "lock" | "lock" | "Value" | false | { sesh, val ->
+ "lock" | "lock" | "Value" | false | ["Session"] | { sesh, val ->
sesh.lock(val, LockMode.READ)
}
- "refresh" | "refresh" | "Value" | false | { sesh, val ->
+ "refresh" | "refresh" | "Value" | false | ["Session", "StatelessSession"] | { sesh, val ->
sesh.refresh(val)
}
- "delete" | "delete" | "Value" | false | { sesh, val ->
+ "delete" | "delete" | "Value" | false | ["Session", "StatelessSession"] | { sesh, val ->
sesh.delete(val)
}
- "get" | "get" | "Value" | false | { sesh, val ->
+ "get" | "get" | "Value" | false | ["Session", "StatelessSession"] | { sesh, val ->
sesh.get("Value", val.getId())
}
}

Make tests work for StatelessSession as well as Session