Class TestHelper

java.lang.Object
com.orchestranetworks.service.extensions.TestHelper

public class TestHelper extends Object
This class can be used to write JUnit tests for EBX®.

Like BatchLauncher, it provides a "serverless" environment for executing EBX® (the Java Virtual Machine does not require a running application server). The main difference compared to BatchLauncher, is that TestHelper does not execute tests on the repository that is specified by 'ebx.properties' file. Each test runs on its own newly created repository.

General Configuration:

In order to be used, the environment must conform to the following principles:

  • The EBX® root module and all specific modules needed for running the tests must be expanded under the expected directory (see prepareEnvironment(File, File)).
  • The default EBX® repository, specified in ebx.properties, cannot be used (it is not initialized): a sandbox repository must be used instead, it is provided by the method getNewRepository(File).
  • The default directory is also not accessible (because it is based on the default repository): a specific user directory must be specified in ebx.properties, so that sessions can be authenticated through at least one defined user (see DirectoryFactory); a hard-coded directory can be used.

Code example:

Here, a JUnit test class performs some updates on the EBX® repository and checks those updates:

public class TestSimple extends junit.framework.TestCase
{
    protected void setUp() throws Exception
    {
        TestHelper.prepareEnvironment(new File(".."), new File("./ebx.properties"));
    }
    public void testSimple() throws Exception
    {
        File tempDir = TestHelper.createTemporaryDirectory(this.getClass().getName() + "."
            + this.getName());
        Repository repository = TestHelper.getNewRepository(tempDir);
        //Directory must specify the following user with admin rights.
        Session session = repository.createSessionFromLoginPassword(
            "testAdministrator",
            "testAdministratorPassword");

        AdaptationHome home = this.createWorkingHome(repository, session);
        ProgrammaticService ps = ProgrammaticService.createForSession(session, home);

        AdaptationReference name = this.createAdaptation(ps);
        Adaptation adaptation = home.findAdaptationOrNull(name);
        assertNotNull(adaptation);

        AdaptationTable aTable = adaptation.getTable(Path.parse("/root/structuresAndTypes/simpleTypesInTable1"));
        RequestResult result = aTable.createRequest().execute();
        assertTrue(result.isEmpty());

        this.createRecords(aTable, ps);

        result = aTable.createRequest().execute();
        assertEquals(10, result.getSize());

        //Needed to clean the repository before other tests
        TestHelper.shutdownRepository(true, repository);
    }

    private void createRecords(
        final AdaptationTable aTable,
        ProgrammaticService aProgrammaticService)
    {
        Procedure createRecords = new Procedure()
        {
            public void execute(ProcedureContext context) throws Exception
            {
                context.setAllPrivileges(true);
                for (int i = 0; i < 10; i++)
                {
                    ValueContextForUpdate vc = context.getContextForNewOccurrence(aTable);
                    vc.setValue("key" + i, Path.parse("/string"));
                    context.doCreateOccurrence(vc, aTable);
                }
            }
        };
        aProgrammaticService.execute(createRecords);
    }

    private AdaptationHome createWorkingHome(Repository repository, final Session session)
        throws OperationException
    {
        HomeCreationSpec aSpec = new HomeCreationSpec();
        aSpec.setParent(repository.getReferenceBranch());
        aSpec.setKey(HomeKey.forBranchName("child"));
        aSpec.setOwner(session.getUserReference());
        AdaptationHome home = repository.createHome(aSpec, session);
        return home;
    }

    private AdaptationReference createAdaptation(ProgrammaticService aProgrammaticService)
    {
        final SchemaLocation location = SchemaLocation.forPathInModule(
            "/WEB-INF/ebx/schema/sample-many-simple-tables-100.xsd",
            "module-sample");
        final AdaptationReference name = AdaptationReference.forPersistentName("test");

        assertNull(aProgrammaticService.getCurrentHome().findAdaptationOrNull(name));

        Procedure createInstance = new Procedure()
        {
            public void execute(ProcedureContext aContext) throws Exception
            {
                aContext.doCreateOccurrence(location, name, aContext.getSession().getUserReference());
            }
        };
        aProgrammaticService.execute(createInstance);
        return name;
    }

}

In order to run such a test, it is necessary for the classpath to include:

  • all of the libraries required to run a standard EBX® repository,
  • Ant 1.6 or greater.
  • Constructor Details

    • TestHelper

      public TestHelper()
  • Method Details

    • prepareEnvironment

      public static void prepareEnvironment(File modulesRootDir, File propertiesFile) throws Exception
      Prepares the environment for the test. This method must be called prior to any call to the method getNewRepository(File).
      Parameters:
      modulesRootDir - indicates the root directory in which to look for EBX® modules to be registered. The search is recursively executed under the specified directory, according to the following regexp: */webapps/*. This means that every required EBX® module, including the root module and the manager module, must be placed in a directory named webapps. Additionally, all modules must be expanded (they must not remain packaged as WAR files). Here is an example of a directory tree structure with two modules (predefined ebx-root-1.0, ebx-manager and specific module-sample) and where modulesRootDir is the "Root" directory :
           Root
              `-- test-project
                             `-- webapps
                                       |-- ebx-root-1.0
                                       |   |-- META-INF
                                       |   |   `-- MANIFEST.MF
                                       |   |-- WEB-INF
                                       |   |   |-- ebx
                                       |   |   |   |-- ...
                                       |   |   |   |-- module.xml
                                       |   |   |   `-- ...
                                       |   |   |-- lib
                                       |   |   |   `-- ebx-root-1.0.jar
                                       |   |   `-- web.xml
                                       |   `-- www
                                       |       `-- common
                                       |           `-- ...
                                       |-- ebx-manager
                                       |   `-- ...
                                       `-- module-sample
                                           `-- WEB-INF
                                               |-- ebx
                                               |   |-- module.xml
                                               |   `-- schema
                                               |       `-- sample-many-simple-tables-100.xsd
                                               `-- web.xml
                             
      propertiesFile - the path to the ebx.properties file.
      Throws:
      Exception
    • createTemporaryDirectory

      public static File createTemporaryDirectory(String aDirectoryPrefix) throws Exception
      Creates a new temporary directory.

      The actual location of the directory to be created is:

         ${ebx.temp.directory}/ebx.platform.test/${aDirectoryPrefix}/
       

      Where the property ebx.temp.directory is specified in the ebx.properties file. If that directory exists, it is deleted then recreated from scratch.

      Throws:
      Exception
    • getNewRepository

      public static Repository getNewRepository(File aTargetDirectory)
      Creates a new temporary repository for running tests with workflow API disabled.

      This method is equivalent to:

      TestHelper.getNewRepository(aTargetDirectory, false);
      See Also:
    • getNewRepository

      public static Repository getNewRepository(File aTargetDirectory, boolean isWorkflowEnabled)
      Creates a new temporary repository for running tests. This method must be called instead of Repository.getDefault().

      The created repository will be based on a standalone H2 database. The database files will have the following physical location:

         {aTargetDirectory}/h2/repository*
       

      Warning:

      1. If the database files already exist, all existing tables will be dropped upon the first repository access.
      2. When the test completes, it is required to shut down the repository. Invoking this method a second time without having shut down the first repository has unpredictable effects.
      Parameters:
      aTargetDirectory - location of the created H2 database. Tests will run on this database.
      isWorkflowEnabled - must be true to enable the workflow API. If false workflow will be disabled and repository initialization will be faster.
      Since:
      5.7.0 fix A
      See Also:
    • getRepositoryExistingH2StandaloneDB

      public static Repository getRepositoryExistingH2StandaloneDB(File aSourceDirectory, String aPrefix)
      Gets an existing H2 repository to use for running tests with workflow API disabled.

      This method is equivalent to:

      TestHelper.getRepositoryExistingH2StandaloneDB(aSourceDirectory, aPrefix, false);
      Since:
      5.3.0
    • getRepositoryExistingH2StandaloneDB

      public static Repository getRepositoryExistingH2StandaloneDB(File aSourceDirectory, String aPrefix, boolean isWorkflowEnabled)
      Gets an existing H2 repository to use for running tests.

      The H2 database files must exist at the following location:

         {aSourceDirectory}/h2/repository*
       

      Note: This will modify the existing database directly. To run tests on a copy of an existing database, use getRepositoryCopyOfExistingH2StandaloneDB(File, File, String).

      Parameters:
      aSourceDirectory - location of the existing H2 database.
      isWorkflowEnabled - must be true to enable the workflow API. If false workflow will be disabled and repository initialization will be faster.
      Since:
      5.7.0 fix A
    • getRepositoryCopyOfExistingH2StandaloneDB

      public static Repository getRepositoryCopyOfExistingH2StandaloneDB(File aSourceDirectory, File aTargetDirectory, String aPrefix)
      Creates a temporary copy of the specified existing repository for running tests with workflow API disabled.

      This method is equivalent to:

      TestHelper.getRepositoryCopyOfExistingH2StandaloneDB(aSourceDirectory, aTargetDirectory, aPrefix, false);
      Since:
      5.3.0
    • getRepositoryCopyOfExistingH2StandaloneDB

      public static Repository getRepositoryCopyOfExistingH2StandaloneDB(File aSourceDirectory, File aTargetDirectory, String aPrefix, boolean isWorkflowEnabled)
      Creates a temporary copy of the specified existing repository for running tests.
      Parameters:
      aSourceDirectory - location of the existing H2 database.
      aTargetDirectory - location to copy the existing H2 database. Tests will run on this database.
      aPrefix - prefix used in the provided source H2 database. Can be null.
      isWorkflowEnabled - must be true to enable the workflow API. If false workflow will be disabled and repository initialization will be faster.
      Returns:
      a repository using a copy of the specified database.
      Since:
      5.7.0 fix A
      See Also:
    • shutdownRepository

      public static void shutdownRepository(Repository aRepository)
      Shuts down the repository, and checks that all connections to the database have been closed.

      This method is equivalent to:

      TestHelper.shutdownRepository(true, aRepository);
      See Also:
    • shutdownRepository

      public static void shutdownRepository(boolean checkConnectionsHaveBeenClosed, Repository aRepository)
      Shuts down the specified repository.

      This method must be called for any test repository obtained using this class (one of the methods getNewRepository(File), getRepositoryCopyOfExistingH2StandaloneDB(File, File, String), or getRepositoryExistingH2StandaloneDB(File, String)).

      Parameters:
      checkConnectionsHaveBeenClosed - if true, verifies that all connections have been properly closed; if not, an exception is thrown.
      aRepository - the test repository to be shut down.
      Throws:
      IllegalStateException - if checkConnectionsHaveBeenClosed is set to true and connections to the database have not been closed properly.
      Since:
      5.3.1
      See Also: