/* * Copyright (C) 2015 LibreCCM Foundation. * * 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., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ package org.libreccm.testutils; import org.dbunit.DatabaseUnitException; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.DataSetException; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.operation.DatabaseOperation; import org.junit.Test; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import org.h2.tools.RunScript; import org.jboss.arquillian.persistence.dbunit.dataset.json.JsonDataSet; import org.junit.runners.Parameterized; import static org.libreccm.testutils.DatasetType.*; import org.dbunit.database.DatabaseConfig; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.jboss.arquillian.persistence.dbunit.dataset.yaml.YamlDataSet; import java.io.InputStream; import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.sql.ResultSet; /** * * For testing the CCM modules the Arquillian Persistence extension including * the DBUnit integration is used. Unfortunately there are some issues with * exception reporting if there errors in the datasets used for testing. * Therefore we provide this utility class which can be used to implement test * for the datasets outside of Arquillian. * * For testing an in-memory H2 database is used. The datasets are loaded into * the database using DBUnit classes. Before loading the dataset this class * creates the database schema. The SQL script for generating the schema is * loaded via {@code getClass().getResource(/sql/ddl/auto/h2.sql).toURI()}. * Therefore the utility expects to find the SQL for generating the database * schema in the classpath at th path {@code /sql/ddl/auto/h2.sql}. The default * {@code pom.xml} for modules take care of that. * * After each dataset the database is scrapped. To use this utility create a * JUnit test class using the {@link Parameterized} test runner from JUnit. An * example is the * DatasetsTest * in the {@code org.libreccm.core} package of the ccm-core module. * * @author Jens Pelzetter */ public class DatasetsVerifier { private final String datasetPath; public DatasetsVerifier(final String datasetsPath) { this.datasetPath = datasetsPath; } /** * Overwrite this method if you are using another schema than the default one. * * @return An string array contains the names of the database schemata used by * the datasets the test. */ public String[] getSchemas() { return new String[]{}; } public DatasetType getDatasetType() { return JSON; } @Test @edu.umd.cs.findbugs.annotations.SuppressWarnings( value = "DMI_EMPTY_DB_PASSWORD", justification = "H2 in mem database does not need a password") public void verifyDataset() throws SQLException, URISyntaxException, IOException, DatabaseUnitException { //Create database connection to an in memory h2 database. Placed in //try-with-resources block to ensure that the connection is closed. final StringBuffer buffer = new StringBuffer("jdbc:h2:mem:testdatabase"); //Create schema if necssary // if (getSchemas().length > 0) { // buffer.append(";INIT="); // for (final String schema : getSchemas()) { // if (buffer.length() > 0) { // buffer.append("\\;"); // } // buffer.append(String.format("CREATE SCHEMA IF NOT EXISTS %s", // schema)); // } // } final String connectionStr = buffer.toString(); try (final Connection connection = DriverManager .getConnection(connectionStr, "sa", "")) { final StringBuffer schemaCreateBuffer = new StringBuffer(); for (final String schema : getSchemas()) { schemaCreateBuffer.append(String .format("CREATE SCHEMA IF NOT EXISTS %s;%n", schema)); } try (final StringReader schemaCreateReader = new StringReader( schemaCreateBuffer.toString())) { RunScript.execute(connection, schemaCreateReader); } //Create DB tables etc for (final String ddlFile : getDdlFiles()) { processDdlFile(connection, ddlFile); } // final Path schemaPath = Paths.get(getClass().getResource( // "/sql/ddl/auto/h2.sql").toURI()); // RunScript.execute(connection, Files.newBufferedReader( // schemaPath, StandardCharsets.UTF_8)); connection.commit(); System.out.println("DB Info:"); System.out.println("Catalogs:"); try (ResultSet resultSet = connection.getMetaData().getCatalogs()) { while(resultSet.next()) { System.out.println(resultSet.getString("table_cat")); } } System.out.println("Schemas"); try(ResultSet resultSet = connection.getMetaData().getSchemas()) { while(resultSet.next()) { System.out.println(resultSet.getString("TABLE_SCHEM")); } } System.out.println("Tables"); try (ResultSet resultSet = connection.getMetaData().getTables("TESTDATABASE", "CCM_CORE", null, null)) { while(resultSet.next()) { System.out.println(resultSet.getString("table_name")); } } System.out.println("settings columns:"); try (ResultSet resultSet = connection.getMetaData().getColumns( "TESTDATABASE", "CCM_CORE", "SETTINGS", null )) { while (resultSet.next()) { System.out.printf("table_name = %s%n", resultSet.getString( "table_name")); System.out.printf("col_name = %s%n", resultSet.getString( "column_name")); } } //Get dataset to test final IDataSet dataSet; try (final InputStream inputStream = getClass().getResourceAsStream( datasetPath)) { switch (getDatasetType()) { case FLAT_XML: final FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder(); dataSet = builder.build(inputStream); break; case JSON: dataSet = new JsonDataSet(inputStream); break; case YAML: dataSet = new YamlDataSet(inputStream); break; default: throw new IllegalArgumentException(String.format( "Unsupported DatasetType \"%s\"", getDatasetType())); } } //Create DBUnit DB connection final IDatabaseConnection dbUnitConn = new DatabaseConnection(connection); dbUnitConn.getConfig().setProperty( "http://www.dbunit.org/features/qualifiedTableNames", true); //Check if dumping works the DB works before loading the dataset. System.out.println("Dump before loading dataset..."); verifyDumping(dbUnitConn); //Put dataset into DB DatabaseOperation.CLEAN_INSERT.execute(dbUnitConn, dataSet); //Check if dumping works after loading the dataset System.out.println("Dump after loading dataset..."); verifyDumping(dbUnitConn); } } protected String[] getDdlFiles() { return new String[]{"/sql/ddl/auto/libreccmh2.sql"}; } private void processDdlFile(final Connection connection, final String ddlFile) throws URISyntaxException, SQLException, IOException { final Path schemaPath = Paths.get(getClass().getResource(ddlFile) .toURI()); RunScript.execute(connection, Files.newBufferedReader(schemaPath, StandardCharsets.UTF_8)); } private void verifyDumping(final IDatabaseConnection connection) throws SQLException, IOException, DataSetException { final IDataSet data = connection.createDataSet(); FlatXmlDataSet.write(data, System.out); } }