All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ch.inftec.ju.testing.db.AbstractDbTest Maven / Gradle / Ivy

There is a newer version: 4.5.1-11
Show newest version
package ch.inftec.ju.testing.db;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;

import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.inftec.ju.db.EmfWork;
import ch.inftec.ju.db.JuConnUtil;
import ch.inftec.ju.db.JuConnUtil.DbType;
import ch.inftec.ju.db.JuConnUtil.MetaDataInfo.SchemaInfo;
import ch.inftec.ju.db.JuConnUtils;
import ch.inftec.ju.db.JuEmUtil;
import ch.inftec.ju.db.JuEmfUtil;
import ch.inftec.ju.util.JuUtils;
import ch.inftec.ju.util.TestUtils;

/**
 * Base class for DB tests.
 * 

* Provides a machanism to evaluate the test DB at runtime, thus enabling DB tests * targeting various DB implementations. * @author Martin * */ public class AbstractDbTest { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); protected JuConnUtil connUtil; protected EntityManager em; protected JuEmUtil emUtil; private JuEmfUtil emfUtil; private EmfWork emfWork; /** * Helper method that allows us to prepare a Schema as defined in the DB test profile. *

* This method can be called multiple time, it will only create the Schema the first time. *

* TODO: Whole Schema handling should be refactored... */ public static void prepareSchemaByProfile() { new DbInitializerRule(null).prepareSchemaByProfile(); } /** * Rule to initialize DB fields. We need to use a rule so we can evaluate the method * annotation. */ @Rule public DbInitializerRule dbInitializer = new DbInitializerRule(this); @After public void cleanupDb() { if (this.emfWork != null) { this.emfWork.close(); this.emfWork = null; this.em = null; } } /** * Sets the transaction to rollback. */ protected final void setRollbackOnly() { this.emfWork.setRollbackOnly(); } /** * Starts a new EmfWork. The caller is responsible to close the work. * @return EmfWork with a new transaction */ protected final EmfWork startNewWork() { return this.emfUtil.startWork(); } /** * This method can be overridden by extending classes to run DB initialization scripts before the test is * actually run. *

* The method is self-responsible to release any resources aquired from the provided JuEmtUtil instance. *

* The default implementation is empty. * @param emfUtil JuEmfUtil instance that can be used to access the DB */ protected void runDbInitializationScripts(JuEmfUtil emfUtil) { } private static class DbInitializerRule implements TestRule { private Logger logger = LoggerFactory.getLogger(DbInitializerRule.class); private static final Set createdSchemas = new HashSet<>(); private final AbstractDbTest dbTest; DbInitializerRule(AbstractDbTest dbTest) { this.dbTest = dbTest; } private void prepareSchemaByProfile() { String profile = JuUtils.getJuPropertyChain().get("ju-dbutil-test.profile", true); // Check if we have an admin profile set as well. In this case, we'll support creating // the user/schema if it's missing. String adminPassword = JuUtils.getJuPropertyChain().get(String.format("ju-dbutil-test.%sAdmin.password", profile), false); String schemaName = JuUtils.getJuPropertyChain().get(String.format("ju-dbutil-test.%s.schema", profile), false); String userName = JuUtils.getJuPropertyChain().get(String.format("ju-dbutil-test.%s.user", profile), false); if (StringUtils.isEmpty(schemaName)) { schemaName = userName; } if (!createdSchemas.contains(schemaName) && !StringUtils.isEmpty(adminPassword)) { String adminProfile = profile + "Admin"; logger.info("Admin-Profile defined: {}. Creating Schema '{}' if necessary", adminProfile, schemaName); JuConnUtil adminConnUtil = JuConnUtils.build() .profile(adminProfile) .create(); // Check if the Schema exists and if we should delete it if so boolean createSchema = true; if (adminConnUtil.getMetaDataInfo().getSchemaInfos().getSchemaNames().contains(schemaName)) { boolean dropExistingSchema = JuUtils.getJuPropertyChain().get( String.format("ju-dbutil-test.%s.dropExistingSchema", adminProfile), Boolean.class, "false"); if (dropExistingSchema) { logger.info("Schema {} already exists. Dropping and recreating.", schemaName); List schemaInfos = adminConnUtil.getMetaDataInfo().getSchemaInfos() .getSchemaInfos(schemaName, null); Assert.assertEquals("Catalogs not supported yet", 1, schemaInfos.size()); if (adminConnUtil.getDbType() == DbType.MYSQL) { // For MySQL, drop the user as well adminConnUtil.getDbHandler().dropSchema(schemaInfos.get(0), userName); } else { adminConnUtil.getDbHandler().dropSchema(schemaInfos.get(0)); } } else { createSchema = false; logger.info( "Schema {} already exists. Skipping creation. Set dropExistingSchema for adminProfile to true if Schema should be dropped and recreated.", schemaName); } } if (createSchema) { logger.info("Creating Schema {}", schemaName); String schemaPassword = JuUtils.getJuPropertyChain().get(String.format("ju-dbutil-test.%s.password", profile), false); boolean jtaRecoveryGrants = JuUtils.getJuPropertyChain().get( String.format("ju-dbutil-test.%s.jtaRecoveryGrants", profile), Boolean.class, "false"); adminConnUtil.getDbHandler().createSchema() .name(schemaName) .user(userName) // Ignored for DBs that don't have users .password(schemaPassword) .jtaRecoveryGrants(jtaRecoveryGrants) .create(); createdSchemas.add(schemaName); } } } @Override public Statement apply(final Statement base, final Description description) { final Method method = TestUtils.getTestMethod(description); // Evaluate Persistence Unit name String persistenceUnit = "ju-pu-test"; String profile = null; // Check if the persistenceUnit is overwritten by an annotation (method overrules // class annotation) JuDbTest juDbTest = method.getAnnotation(JuDbTest.class); if (juDbTest == null) { juDbTest = this.dbTest.getClass().getAnnotation(JuDbTest.class); } if (juDbTest != null) { persistenceUnit = juDbTest.persistenceUnit(); profile = juDbTest.profile(); } if (StringUtils.isEmpty(profile)) { profile = JuUtils.getJuPropertyChain().get("ju-dbutil-test.profile", true); this.prepareSchemaByProfile(); } this.dbTest.connUtil = JuConnUtils.build() .profile(profile) .create(); this.dbTest.emfUtil = new EmfUtilProvider().createEmfUtil(persistenceUnit, profile); return new Statement() { @Override public void evaluate() throws Throwable { // Run dbInitializationScripts dbTest.runDbInitializationScripts(dbTest.emfUtil); DbTestAnnotationHandler annotationHandler = new DbTestAnnotationHandler(method, description); // Run preAnnotations in own transaction try (EmfWork ew = dbTest.emfUtil.startWork()) { annotationHandler.executePreTestAnnotations(ew.getEmUtil()); } // Initialize protected fields of test class dbTest.emfWork = dbTest.emfUtil.startWork(); dbTest.em = dbTest.emfWork.getEm(); dbTest.emUtil = new JuEmUtil(dbTest.em); // Run test method base.evaluate(); // Run post server code in own transaction try (EmfWork ew = dbTest.emfUtil.startWork()) { annotationHandler.executePostServerCode(ew.getEmUtil()); } // Run postAnnotations in own transaction try (EmfWork ew = dbTest.emfUtil.startWork()) { annotationHandler.executePostTestAnnotations(ew.getEmUtil()); } } }; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy