/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.glowroot.agent.plugin.hibernate;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.glowroot.agent.it.harness.AppUnderTest;
import org.glowroot.agent.it.harness.Container;
import org.glowroot.agent.it.harness.Containers;
import org.glowroot.agent.it.harness.TransactionMarker;
import org.glowroot.wire.api.model.TraceOuterClass.Trace;
import static org.assertj.core.api.Assertions.assertThat;
public class SessionAspectIT {
private static Container container;
@BeforeClass
public static void setUp() throws Exception {
container = Containers.create();
}
@AfterClass
public static void tearDown() throws Exception {
container.close();
}
@After
public void afterEachTest() throws Exception {
container.checkAndReset();
}
@Test
public void shouldCaptureCriteriaQuery() throws Exception {
// when
Trace trace = container.execute(CriteriaQuery.class);
// then
Trace.Timer mainThreadRootTimer = trace.getHeader().getMainThreadRootTimer();
assertThat(mainThreadRootTimer.getChildTimerCount()).isEqualTo(1);
assertThat(mainThreadRootTimer.getChildTimer(0).getName()).isEqualTo("hibernate query");
assertThat(mainThreadRootTimer.getChildTimer(0).getChildTimerCount()).isZero();
assertThat(trace.getEntryList()).isEmpty();
}
// TODO add unit test for jpa criteria query
@Test
public void shouldCaptureSave() throws Exception {
// when
Trace trace = container.execute(SessionSave.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate save");
}
@Test
public void shouldCaptureSaveTwoArg() throws Exception {
// when
Trace trace = container.execute(SessionSaveTwoArg.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate save");
}
@Test
public void shouldCaptureSaveOrUpdate() throws Exception {
// when
Trace trace = container.execute(SessionSaveOrUpdate.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate saveOrUpdate");
}
@Test
public void shouldCaptureSaveOrUpdateTwoArg() throws Exception {
// when
Trace trace = container.execute(SessionSaveOrUpdateTwoArg.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate saveOrUpdate");
}
@Test
public void shouldCaptureUpdate() throws Exception {
// when
Trace trace = container.execute(SessionUpdate.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate update");
}
@Test
public void shouldCaptureUpdateTwoArg() throws Exception {
// when
Trace trace = container.execute(SessionUpdateTwoArg.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate update");
}
@Test
public void shouldCaptureMergeCommand() throws Exception {
// when
Trace trace = container.execute(SessionMerge.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate merge");
}
@Test
public void shouldCaptureMergeCommandTwoArg() throws Exception {
// when
Trace trace = container.execute(SessionMergeTwoArg.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate merge");
}
@Test
public void shouldCapturePersistCommand() throws Exception {
// when
Trace trace = container.execute(SessionPersist.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate persist");
}
@Test
public void shouldCapturePersistCommandTwoArg() throws Exception {
// when
Trace trace = container.execute(SessionPersistTwoArg.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate persist");
}
@Test
public void shouldCaptureDelete() throws Exception {
// when
Trace trace = container.execute(SessionDelete.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate delete");
}
@Test
public void shouldCaptureDeleteTwoArg() throws Exception {
// when
Trace trace = container.execute(SessionDeleteTwoArg.class);
// then
List<Trace.Timer> timers = trace.getHeader().getMainThreadRootTimer().getChildTimerList();
assertThat(timers).hasSize(1);
assertThat(timers.get(0).getName()).isEqualTo("hibernate delete");
}
@Test
public void shouldCaptureSessionFlush() throws Exception {
// when
Trace trace = container.execute(SessionFlush.class);
// then
Iterator<Trace.Entry> i = trace.getEntryList().iterator();
Trace.Entry entry = i.next();
assertThat(entry.getDepth()).isEqualTo(0);
assertThat(entry.getMessage()).isEqualTo("hibernate flush");
assertThat(i.hasNext()).isFalse();
}
@Test
public void shouldCaptureTransactionCommit() throws Exception {
// when
Trace trace = container.execute(TransactionCommit.class);
// then
Iterator<Trace.Entry> i = trace.getEntryList().iterator();
Trace.Entry entry = i.next();
assertThat(entry.getDepth()).isEqualTo(0);
assertThat(entry.getMessage()).isEqualTo("hibernate commit");
assertThat(i.hasNext()).isFalse();
}
@Test
public void shouldCaptureTransactionRollback() throws Exception {
// when
Trace trace = container.execute(TransactionRollback.class);
// then
Iterator<Trace.Entry> i = trace.getEntryList().iterator();
Trace.Entry entry = i.next();
assertThat(entry.getDepth()).isEqualTo(0);
assertThat(entry.getMessage()).isEqualTo("hibernate rollback");
assertThat(i.hasNext()).isFalse();
}
public abstract static class DoWithSession implements AppUnderTest, TransactionMarker {
Session session;
@Override
public void executeApp() throws Exception {
session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
initOutsideTransactionMarker();
transactionMarker();
transaction.commit();
session.close();
}
protected void initOutsideTransactionMarker() {}
}
public static class CriteriaQuery extends DoWithSession {
@Override
public void transactionMarker() {
session.createCriteria(Employee.class).list();
}
}
public static class SessionSave extends DoWithSession {
@Override
public void transactionMarker() {
session.save(new Employee("John"));
}
}
public static class SessionSaveTwoArg extends DoWithSession {
@Override
public void transactionMarker() {
session.save(null, new Employee("John"));
}
}
public static class SessionSaveOrUpdate extends DoWithSession {
@Override
public void transactionMarker() {
session.saveOrUpdate(new Employee("John"));
}
}
public static class SessionSaveOrUpdateTwoArg extends DoWithSession {
@Override
public void transactionMarker() {
session.saveOrUpdate(null, new Employee("John"));
}
}
public static class SessionUpdate extends DoWithSession {
private Employee employee;
@Override
public void transactionMarker() {
session.update(employee);
}
@Override
protected void initOutsideTransactionMarker() {
employee = (Employee) session.merge(new Employee("John"));
employee.setName("Hugh");
}
}
public static class SessionUpdateTwoArg extends DoWithSession {
private Employee employee;
@Override
public void transactionMarker() {
session.update(null, employee);
}
@Override
protected void initOutsideTransactionMarker() {
employee = (Employee) session.merge(new Employee("John"));
employee.setName("Hugh");
}
}
public static class SessionMerge extends DoWithSession {
@Override
public void transactionMarker() {
session.merge(new Employee("John"));
}
}
public static class SessionMergeTwoArg extends DoWithSession {
@Override
public void transactionMarker() {
session.merge(null, new Employee("John"));
}
}
public static class SessionPersist extends DoWithSession {
@Override
public void transactionMarker() {
session.persist(new Employee("John"));
}
}
public static class SessionPersistTwoArg extends DoWithSession {
@Override
public void transactionMarker() {
session.persist(null, new Employee("John"));
}
}
public static class SessionDelete extends DoWithSession {
private Employee employee;
@Override
public void transactionMarker() {
session.delete(employee);
}
@Override
protected void initOutsideTransactionMarker() {
employee = (Employee) session.merge(new Employee("John"));
employee.setName("Hugh");
}
}
public static class SessionDeleteTwoArg extends DoWithSession {
private Employee employee;
@Override
public void transactionMarker() {
session.delete(null, employee);
}
@Override
protected void initOutsideTransactionMarker() {
employee = (Employee) session.merge(new Employee("John"));
employee.setName("Hugh");
}
}
public static class SessionFlush extends DoWithSession {
@Override
public void transactionMarker() {
Employee employee = (Employee) session.merge(new Employee("John"));
employee.setEmail(new Email("john@example.org"));
session.flush();
}
}
public static class TransactionCommit implements AppUnderTest, TransactionMarker {
private Session session;
@Override
public void executeApp() throws Exception {
session = HibernateUtil.getSessionFactory().openSession();
transactionMarker();
session.close();
}
@Override
public void transactionMarker() throws Exception {
Transaction transaction = session.beginTransaction();
session.save(new Employee("John"));
transaction.commit();
}
}
public static class TransactionRollback implements AppUnderTest, TransactionMarker {
private Session session;
@Override
public void executeApp() throws Exception {
session = HibernateUtil.getSessionFactory().openSession();
transactionMarker();
session.close();
}
@Override
public void transactionMarker() throws Exception {
Transaction transaction = session.beginTransaction();
session.save(new Employee("John"));
transaction.rollback();
}
}
}