/* * Copyright 2011-2013 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 kr.debop4j.data.ogm.test.simpleentity; import kr.debop4j.data.ogm.test.utils.GridDialectType; import kr.debop4j.data.ogm.test.utils.SkipByGridDialect; import kr.debop4j.data.ogm.test.utils.TestHelper; import lombok.extern.slf4j.Slf4j; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.annotations.common.util.StringHelper; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.ogm.cfg.OgmConfiguration; import org.hibernate.search.FullTextSession; import org.hibernate.search.Search; import org.hibernate.search.SearchFactory; import org.hibernate.search.engine.spi.SearchFactoryImplementor; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Map; import static org.fest.assertions.Assertions.assertThat; /** * OgmTestBase * * @author 배성혁 ( sunghyouk.bae@gmail.com ) * 13. 3. 29. 오후 4:22 */ @Slf4j public abstract class OgmTestBase { // static { // TestHelper.initializeHelpers(); // } @BeforeClass public static void beforeClass() { TestHelper.initializeHelpers(); } @Before public void before() throws Exception { doBefore(); } @After public void after() throws Exception { doAfter(); } public void doBefore() throws Exception { if (cfg == null || lastTestClass != getClass()) { buildConfiguration(); lastTestClass = getClass(); } } public void doAfter() throws Exception { handleUnclosedResources(); closeResources(); } protected SessionFactory sessions; private Session session; protected static Configuration cfg; private static Class<?> lastTestClass; protected String[] getXmlFiles() { return new String[] { }; } protected static void setCfg(Configuration cfg) { OgmTestBase.cfg = cfg; } protected static Configuration getCfg() { return cfg; } protected void configure(Configuration cfg) { } protected abstract Class<?>[] getAnnotatedClasses(); protected boolean recreateSchema() { return true; } protected String[] getAnnotatedPackages() { return new String[] { }; } protected SearchFactoryImplementor getSearchFactoryImpl() { if (log.isDebugEnabled()) log.debug("SearchFactoryImplementor 를 생성합니다."); FullTextSession fts = Search.getFullTextSession(openSession()); fts.close(); SearchFactory searchFactory = fts.getSearchFactory(); return (SearchFactoryImplementor) searchFactory; } private void reportSkip(Skip skip) { reportSkip(skip.reason, skip.testDescription); } protected void reportSkip(String reason, String testDescription) { StringBuilder builder = new StringBuilder(); builder.append("*** skipping test ["); builder.append(fullTestName()); builder.append("] - "); builder.append(testDescription); builder.append(" : "); builder.append(reason); OgmTestBase.log.warn(builder.toString()); } protected Skip buildSkip(GridDialectType dialect, String comment) { StringBuilder buffer = new StringBuilder(); buffer.append("skipping database-specific test ["); buffer.append(fullTestName()); buffer.append("] for dialect ["); buffer.append(dialect.name()); buffer.append(']'); if (StringHelper.isNotEmpty(comment)) { buffer.append("; ").append(comment); } return new Skip(buffer.toString(), null); } protected <T extends Annotation> T locateAnnotation(Class<T> annotationClass, Method runMethod) { T annotation = runMethod.getAnnotation(annotationClass); if (annotation == null) { annotation = getClass().getAnnotation(annotationClass); } if (annotation == null) { annotation = runMethod.getDeclaringClass().getAnnotation(annotationClass); } return annotation; } protected final Skip determineSkipByGridDialect(Method runMethod) throws Exception { SkipByGridDialect skipForDialectAnn = locateAnnotation(SkipByGridDialect.class, runMethod); if (skipForDialectAnn != null) { for (GridDialectType gridDialectType : skipForDialectAnn.value()) { if (gridDialectType.equals(TestHelper.getCurrentDialectType())) { return buildSkip(gridDialectType, skipForDialectAnn.comment()); } } } return null; } protected static class Skip { private final String reason; private final String testDescription; public Skip(String reason, String testDescription) { this.reason = reason; this.testDescription = testDescription; } } // @Override // protected void runTest() throws Throwable { // Method runMethod = findTestMethod(); // FailureExpected failureExpected = locateAnnotation(FailureExpected.class, runMethod); // try { // super.runTest(); // if (failureExpected != null) { // throw new FailureExpectedTestPassedException(); // } // } catch (FailureExpectedTestPassedException t) { // closeResources(); // throw t; // } catch (Throwable t) { // if (t instanceof InvocationTargetException) { // t = ((InvocationTargetException) t).getTargetException(); // } // if (t instanceof IllegalAccessException) { // t.fillInStackTrace(); // } // closeResources(); // if (failureExpected != null) { // StringBuilder builder = new StringBuilder(); // if (StringHelper.isNotEmpty(failureExpected.message())) { // builder.append(failureExpected.message()); // } else { // builder.append("ignoring @FailureExpected test"); // } // builder.append(" (") // .append(failureExpected.jiraKey()) // .append(")"); // OgmTestBase.log.warn(builder.toString(), t); // } else { // throw t; // } // } // } // // @Override // public void runBare() throws Throwable { // Method runMethod = findTestMethod(); // // final Skip skip = determineSkipByGridDialect(runMethod); // if (skip != null) { // reportSkip(skip); // return; // } // // setUp(); // try { // runTest(); // } finally { // tearDown(); // } // } public String fullTestName() { return this.getClass().getName(); // + "#" + this.getName(); } // // private Method findTestMethod() { // String fName = getName(); // assertNotNull(fName); // Method runMethod = null; // try { // runMethod = getClass().getMethod(fName); // } catch (NoSuchMethodException e) { // fail("Method \"" + fName + "\" not found"); // } // if (!Modifier.isPublic(runMethod.getModifiers())) { // fail("Method \"" + fName + "\" should be public"); // } // return runMethod; // } private static class FailureExpectedTestPassedException extends Exception { public FailureExpectedTestPassedException() { super("Test marked as @FailureExpected, but did not fail!"); } } public Session openSession() throws HibernateException { rebuildSessionFactory(); session = getSessions().openSession(); return session; } private void rebuildSessionFactory() { if (sessions == null) { try { buildConfiguration(); } catch (Exception e) { throw new HibernateException(e); } } } protected void setSessions(SessionFactory sessions) { this.sessions = sessions; } protected SessionFactory getSessions() { return sessions; } protected SessionFactoryImplementor sfi() { return (SessionFactoryImplementor) getSessions(); } //FIXME clear cache when this happens protected void runSchemaGeneration() { } protected void runSchemaDrop() { TestHelper.dropSchemaAndDatabase(session); } protected void buildConfiguration() throws Exception { try { setCfg(new OgmConfiguration()); //Other configurations // by default use the new id generator scheme... getCfg().setProperty(Configuration.USE_NEW_ID_GENERATOR_MAPPINGS, "true"); for (Map.Entry<String, String> entry : TestHelper.getEnvironmentProperties().entrySet()) { getCfg().setProperty(entry.getKey(), entry.getValue()); } configure(cfg); if (recreateSchema()) { getCfg().setProperty(Environment.HBM2DDL_AUTO, "none"); } for (String aPackage : getAnnotatedPackages()) { getCfg().addPackage(aPackage); } for (Class<?> aClass : getAnnotatedClasses()) { getCfg().addAnnotatedClass(aClass); } for (String xmlFile : getXmlFiles()) { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlFile); getCfg().addInputStream(is); } // TODO: hibernate-search-orm 4.3.0 SNAPSHOT 에 있습니다. // getCfg().setProperty(MassIndexerFactoryIntegrator.MASS_INDEXER_FACTORY_CLASSNAME, // OgmMassIndexerFactory.class.getName()); setSessions(getCfg().buildSessionFactory( /* new TestInterceptor() */)); } catch (Exception e) { e.printStackTrace(); throw e; } } protected void handleUnclosedResources() { if (session != null && session.isOpen()) { if (session.isConnected()) { if (session.getTransaction().isActive()) { session.getTransaction().rollback(); } } session.close(); session = null; // fail("unclosed session"); // Assert.fail("unclosed session"); } else { session = null; } closeSessionFactory(); } private void closeSessionFactory() { if (sessions != null) { if (!sessions.isClosed()) { log.info("SessionFactory를 close 합니다."); TestHelper.dropSchemaAndDatabase(sessions); sessions.close(); sessions = null; } else { sessions = null; } } } protected void closeResources() { try { if (session != null && session.isOpen()) { if (session.isConnected()) { if (session.getTransaction().isActive()) { session.getTransaction().rollback(); } } session.close(); } } catch (Exception ignore) { } try { closeSessionFactory(); } catch (Exception ignore) { } } public void checkCleanCache() { assertThat(TestHelper.assertNumberOfEntities(0, sessions)) .as("Entity cache should be empty") .isTrue(); assertThat(TestHelper.assertNumberOfAssociations(0, sessions)) .as("Association cache should be empty") .isTrue(); } }