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

org.tentackle.test.pdo.AbstractPdoTest Maven / Gradle / Ivy

Go to download

Test depdendency to support writing PDO-based tests. Also generates the SQL-scripts for the TT tables and contains some PDO tests. This artifact must be included in test-scope only!

There is a newer version: 21.16.1.0
Show newest version
/*
 * Tentackle - http://www.tentackle.org.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

package org.tentackle.test.pdo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import org.tentackle.pdo.DomainContext;
import org.tentackle.pdo.DomainContextProvider;
import org.tentackle.pdo.Pdo;
import org.tentackle.session.ModificationTracker;
import org.tentackle.session.PersistenceException;
import org.tentackle.session.Session;
import org.testng.Reporter;
import org.testng.SkipException;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;

import static org.testng.Assert.*;

/**
 * Base class for tests on PDO level.
 *
 * @author harald
 */
public abstract class AbstractPdoTest implements DomainContextProvider {

  /**
   * The transaction handling for the test class.
   */
  public enum TransactionType {
    /** transaction per test class. */
    CLASS,

    /** transaction per test method. */
    METHOD,

    /** no automatic transaction handling. */
    NONE
  }


  private static Session session;           // session for all methods in all test classes
  private DomainContext context;            // domain context for all methods in all test classes

  private final TransactionType txType;     // transaction handling
  private final boolean commit;             // true if commit transaction, else rollback (default)
  private long txVoucher;                   // transaction voucher for current test class


  /**
   * Creates a test.
   *
   * @param txType the transaction type
   * @param commit true if commit transaction, else rollback (default for regular tests)
   */
  public AbstractPdoTest(TransactionType txType, boolean commit) {
    this.txType = txType;
    this.commit = commit;
  }

  /**
   * Creates a test with rollback.
   *
   * @param txType the transaction type
   */
  public AbstractPdoTest(TransactionType txType) {
    this(txType, false);
  }

  /**
   * Creates a test with rollback and one transaction per class.
   */
  public AbstractPdoTest() {
    this(TransactionType.CLASS, false);    // per class
  }


  /**
   * Opens the sessions and starts the modification tracker.
   *
   * @throws Exception if failed
   */
  @BeforeSuite(alwaysRun = true)
  public void openSessionsAndStartModificationTracker() throws Exception {
    session = openSession();
    context = createDomainContext();

    ModificationTracker tracker = ModificationTracker.getInstance();
    tracker.setSession(session.clone());
    tracker.setSleepInterval(500);   // fast polling for tests
    tracker.start();
  }

  /**
   * Terminates the modification tracker and closes the sessions.
   *
   * @throws Exception if failed
   */
  @AfterSuite(alwaysRun = true)
  public void closeSessionsAndTerminateModificationTracker() throws Exception {
    if (session != null) {
      ModificationTracker.getInstance().terminate();
      session.close();
    }
  }

  /**
   * Begins the transaction if type is {@link TransactionType#CLASS}.
   *
   * @throws Exception if failed
   */
  @BeforeClass(alwaysRun = true)
  public void beforeClass() throws Exception {
    if (txType == TransactionType.CLASS) {
      beginTransaction();
    }
  }

  /**
   * Ends the transaction if type is {@link TransactionType#CLASS}.
   *
   * @throws Exception if failed
   */
  @AfterClass(alwaysRun = true)
  public void afterClass() throws Exception {
    if (txType == TransactionType.CLASS) {
      endTransaction();
    }
  }

  /**
   * Begins the transaction if type is {@link TransactionType#METHOD}.
   *
   * @throws Exception if failed
   */
  @BeforeMethod(alwaysRun = true)
  public void beforeMethod() throws Exception {
    if (txType == TransactionType.METHOD) {
      beginTransaction();
    }
  }

  /**
   * Ends the transaction if type is {@link TransactionType#METHOD}.
   *
   * @throws Exception if failed
   */
  @AfterMethod(alwaysRun = true)
  public void afterMethod() throws Exception {
    if (txType == TransactionType.METHOD) {
      endTransaction();
    }
  }


  /**
   * Gets the session.
   *
   * @return the session
   */
  public Session getSession() {
    return session;
  }

  /**
   * Returns whether the transaction should be commit or rolled back.
   *
   * @return true if commit, false if rollback (default for regular tests)
   */
  public boolean isCommit() {
    return commit;
  }

  /**
   * Gets the domain context.
   *
   * @return the domain context
   */
  @Override
  public DomainContext getDomainContext() {
    return context;
  }

  /**
   * Runs the given class in another JVM.
* The testclass must have a main method. * * @param testClass the test class * @return the exit value * @throws IOException if some IO operation failed */ public int runInOtherJVM(Class testClass) throws IOException { Process process = runClass(testClass); waitForProcess(process); return process.exitValue(); } /** * Opens the session. * * @return the thread-local session */ protected Session openSession() { Session s = Pdo.createSession(); try { s.open(); } catch (PersistenceException ex) { // no database? wrong database? whatever: testing environment incomplete throw new SkipException("no backend found -> no tests"); } s.makeCurrent(); return s; } /** * Creates the domain context. * * @return the context (usually thread-local) */ protected DomainContext createDomainContext() { return Pdo.createDomainContext(); // thread local } /** * Begins a transaction. */ protected void beginTransaction() { if (session != null) { txVoucher = session.begin("test"); } } /** * Commits or rolls back a transaction. */ protected void endTransaction() { if (session != null && session.isTxRunning()) { if (commit) { session.commit(txVoucher); } else { session.rollback(txVoucher); } txVoucher = 0; } } /** * Runs the given class in another JVM and waits for termination.
* The testclass must have a main method. * * @param testClass the test class * @param args optional arguments * @return the process object * @throws IOException if some IO operation failed */ public static Process runClass(Class testClass, String... args) throws IOException { // add node and key in other jvm String javaHome = System.getProperty("java.home"); String classPath = System.getProperty("java.class.path"); StringBuilder cmd = new StringBuilder(); cmd.append(javaHome).append("/bin/java -classpath ") .append(classPath).append(' ').append(testClass.getName()); if (args != null) { for (String arg: args) { cmd.append(' ').append(arg); } } Reporter.log("running: " + cmd + "
"); return Runtime.getRuntime().exec(cmd.toString()); } /** * Waits for process to terminate and write stdout and stderr to the reporter log. * * @param process the process * @throws IOException if some IO failed */ public static void waitForProcess(Process process) throws IOException { try { process.waitFor(); } catch (InterruptedException ex) { fail("executing " + process + " failed
", ex); } // collect stdout Reader r = new InputStreamReader(process.getInputStream()); try (BufferedReader in = new BufferedReader(r)) { String line; while ((line = in.readLine()) != null) { Reporter.log(line + "
"); } } // collect stderr r = new InputStreamReader(process.getErrorStream()); try (BufferedReader in = new BufferedReader(r)) { String line; while ((line = in.readLine()) != null) { Reporter.log(line + "
"); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy