Author: tomdz Date: Sun Oct 15 18:15:26 2006 New Revision: 464353 URL: http://svn.apache.org/viewvc?view=rev&rev=464353 Log: Fixed tests and junit ant target Added first version of the test summary task
Added: db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java Modified: db/ddlutils/trunk/build.xml db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java Modified: db/ddlutils/trunk/build.xml URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/build.xml?view=diff&rev=464353&r1=464352&r2=464353 ============================================================================== --- db/ddlutils/trunk/build.xml (original) +++ db/ddlutils/trunk/build.xml Sun Oct 15 18:15:26 2006 @@ -211,9 +211,9 @@ <!-- Runs the test cases --> <!-- ================================================================== --> <target name="junit" - description="Runs the test cases against the default database (Hsqldb)"> - <antcall target="junit-hsqldb"/> - </target> + description="Runs the test cases against no database or the one specified via -Djdbc.properties.file"> + <antcall target="-junit-internal"/> + </target> <!-- ================================================================== --> <!-- Runs the test cases against HsqlDb --> @@ -241,7 +241,7 @@ </target> <!-- ================================================================== --> - <!-- Runs the test cases against AxionDB --> + <!-- Runs the test cases against MySQL --> <!-- ================================================================== --> <target name="junit-mysql" description="Runs the test cases against mysql"> @@ -277,8 +277,9 @@ <classpath refid="compilation-classpath"/> <batchtest todir="${build.test.dir}"> <fileset dir="${src.test.dir}" includes="**/Test*.java"> - <exclude name="**/TestDatabaseWriterBase.java"/> - <exclude name="**/TestPlatformBase.java"/> + <exclude name="**/Test*Base.java"/> + <exclude name="**/TestPlatform.java"/> + <exclude name="**/TestSummaryCreatorTask.java"/> </fileset> </batchtest> </junit> @@ -296,6 +297,23 @@ <report format="frames" todir="${build.test.dir}"/> </junitreport> + </target> + + <!-- ================================================================== --> + <!-- Creates the test summary --> + <!-- ================================================================== --> + <target name="junit-summary" + depends="compile-tests" + description="Creates a test summary"> + <taskdef name="testSummary" + classname="org.apache.ddlutils.TestSummaryCreatorTask" + classpathref="compilation-classpath"/> + <testSummary> + <fileset dir="${build.test.dir}" + casesensitive="false"> + <include name="test*.xml"/> + </fileset> + </testSummary> </target> <!-- ================================================================== --> Added: db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java?view=auto&rev=464353 ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java (added) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java Sun Oct 15 18:15:26 2006 @@ -0,0 +1,415 @@ +package org.apache.ddlutils; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.sql.DataSource; + +import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.Node; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.SAXReader; +import org.dom4j.io.XMLWriter; +import org.xml.sax.InputSource; + +/** + * Creates a test summary snippet that can be put onto the DdlUtils web site. + * + * @version $Revision: $ + */ +public class TestSummaryCreatorTask extends Task +{ + /** The file to write the snippet to. */ + private File _outputFile = null; + /** The input files. */ + private ArrayList _fileSets = new ArrayList(); + + /** + * Set the output file. + * + * @param outputFile The output file + */ + public void setOutputFile(File outputFile) + { + _outputFile = outputFile; + } + + /** + * Adds a fileset. + * + * @param fileset The additional input files + */ + public void addConfiguredFileset(FileSet fileset) + { + _fileSets.add(fileset); + } + + /** + * Returns the list of input files ([EMAIL PROTECTED] java.io.File} objects) to process. + * Note that this does not check that the file is a valid and useful XML file. + * + * @return The input files + */ + private List getInputFiles() + { + ArrayList result = new ArrayList(); + + for (Iterator it = _fileSets.iterator(); it.hasNext();) + { + FileSet fileSet = (FileSet)it.next(); + File fileSetDir = fileSet.getDir(getProject()); + DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject()); + String[] files = scanner.getIncludedFiles(); + + for (int idx = 0; (files != null) && (idx < files.length); idx++) + { + File file = new File(fileSetDir, files[idx]); + + if (file.isFile() && file.canRead()) + { + result.add(file); + } + } + } + return result; + } + + /** + * Processes all input files and gathers the relevant data. + * + * @return The Dom4j document object containing the summary + */ + private Document processInputFiles() throws IOException + { + Document summaryDoc = DocumentHelper.createDocument(); + + summaryDoc.addElement("summary"); + + for (Iterator it = getInputFiles().iterator(); it.hasNext();) + { + processInputFile(summaryDoc, (File)it.next()); + } + return summaryDoc; + } + + /** + * Returns the value of the specified attribute of the node determined by the given xpath. + * + * @param doc The XML document + * @param xpath The xpath selecting the node whose attribute we want + * @param attrName The name of the attribute + * @return The attribute value + */ + private String getAttrValue(Document doc, String xpath, String attrName) + { + Node node = doc.selectSingleNode(xpath); + + if (node instanceof Attribute) + { + // we ignore the attribute name then + return ((Attribute)node).getValue(); + } + else + { + return node.valueOf("@" + attrName); + } + } + + /** + * Processes the given input file. + * + * @param summaryDoc The document object to add data to + * @param inputFile The input file + */ + private void processInputFile(Document summaryDoc, File inputFile) throws IOException + { + try + { + // First we check whether it is an XML file + SAXReader reader = new SAXReader(); + Document testDoc = reader.read(new InputSource(new FileReader(inputFile))); + + // Then we check whether it is one that we're interested in + if (testDoc.selectSingleNode("/testsuite") == null) + { + return; + } + + // Ok, it is, so lets extract the data that we want: + Element generalElement = (Element)summaryDoc.selectSingleNode("//general"); + int totalNumTests = 0; + int totalNumErrors = 0; + int totalNumFailures = 0; + + if (generalElement == null) + { + generalElement = summaryDoc.getRootElement().addElement("general"); + + // General run info (we only need this once) + generalElement.addAttribute("date", getAttrValue(testDoc, "//[EMAIL PROTECTED]'TODAY']", "value")); + generalElement.addAttribute("lang", getAttrValue(testDoc, "//[EMAIL PROTECTED]'env.LANG']", "value")); + generalElement.addAttribute("jre", + getAttrValue(testDoc, "//[EMAIL PROTECTED]'java.runtime.name']", "value") + " " + + getAttrValue(testDoc, "//[EMAIL PROTECTED]'java.runtime.version']", "value") + " (" + + getAttrValue(testDoc, "//[EMAIL PROTECTED]'java.vendor']", "value") + ")"); + generalElement.addAttribute("os", + getAttrValue(testDoc, "//[EMAIL PROTECTED]'os.name']", "value") + " " + + getAttrValue(testDoc, "//[EMAIL PROTECTED]'os.version']", "value") + ", arch " + + getAttrValue(testDoc, "//[EMAIL PROTECTED]'os.arch']", "value")); + addTargetDatabaseInfo(generalElement, getAttrValue(testDoc, "//[EMAIL PROTECTED]'jdbc.properties.file']", "value")); + } + else + { + totalNumTests = Integer.parseInt(generalElement.attributeValue("tests")); + totalNumErrors = Integer.parseInt(generalElement.attributeValue("errors")); + totalNumFailures = Integer.parseInt(generalElement.attributeValue("failures")); + } + + int numTests = Integer.parseInt(getAttrValue(testDoc, "/testsuite", "tests")); + int numErrors = Integer.parseInt(getAttrValue(testDoc, "/testsuite", "errors")); + int numFailures = Integer.parseInt(getAttrValue(testDoc, "/testsuite", "failures")); + + totalNumTests += numTests; + totalNumErrors += numErrors; + totalNumFailures += numFailures; + + generalElement.addAttribute("tests", String.valueOf(totalNumTests)); + generalElement.addAttribute("errors", String.valueOf(totalNumErrors)); + generalElement.addAttribute("failures", String.valueOf(totalNumErrors)); + + if ((numErrors > 0) || (numFailures > 0)) + { + Element testSuiteNode = (Element)testDoc.selectSingleNode("/testsuite"); + String testSuiteName = testSuiteNode.attributeValue("name"); + + // since tests have failed, we add it to the summary + for (Iterator it = testSuiteNode.elementIterator("testcase"); it.hasNext();) + { + Element failedTestElement = (Element)it.next(); + Element newTestElement = summaryDoc.getRootElement().addElement("failedTest"); + + // Test setup failure, so the test was not actually run ? + if (!failedTestElement.attributeValue("classname").startsWith("junit.framework.TestSuite")) + { + newTestElement.addAttribute("name", failedTestElement.attributeValue("classname") + "#" + failedTestElement.attributeValue("name")); + } + newTestElement.addAttribute("testsuite", testSuiteName); + } + } + } + catch (DocumentException ex) + { + // No, apparently it's not an XML document, so we ignore it + } + } + + /** + * Reads the database properties from the used properties file. + * + * @param element The element to add the relevant database properties to + * @param jdbcPropertiesFile The path of the properties file + */ + protected void addTargetDatabaseInfo(Element element, String jdbcPropertiesFile) throws IOException, BuildException + { + if (jdbcPropertiesFile == null) + { + return; + } + + Properties props = new Properties(); + Connection conn = null; + DatabaseMetaData metaData = null; + + try + { + props.load(getClass().getResourceAsStream(jdbcPropertiesFile)); + } + catch (Exception ex) + { + throw new BuildException("Cannot load database properties from file " + jdbcPropertiesFile); + } + + try + { + String dataSourceClass = props.getProperty(TestDatabaseWriterBase.DATASOURCE_PROPERTY_PREFIX + "class", BasicDataSource.class.getName()); + DataSource dataSource = (DataSource)Class.forName(dataSourceClass).newInstance(); + + for (Iterator it = props.entrySet().iterator(); it.hasNext();) + { + Map.Entry entry = (Map.Entry)it.next(); + String propName = (String)entry.getKey(); + + if (propName.startsWith(TestDatabaseWriterBase.DATASOURCE_PROPERTY_PREFIX) && !propName.equals(TestDatabaseWriterBase.DATASOURCE_PROPERTY_PREFIX +"class")) + { + BeanUtils.setProperty(dataSource, + propName.substring(TestDatabaseWriterBase.DATASOURCE_PROPERTY_PREFIX.length()), + entry.getValue()); + } + } + + String platformName = props.getProperty(TestDatabaseWriterBase.PLATFORM_PROPERTY); + + if (platformName == null) + { + platformName = new PlatformUtils().determineDatabaseType(dataSource); + if (platformName == null) + { + throw new BuildException("Could not determine platform from datasource, please specify it in the jdbc.properties via the ddlutils.platform property"); + } + } + + element.addAttribute("platform", platformName); + element.addAttribute("dataSourceClass", dataSourceClass); + + // TODO: we're also interested in the specific versions of the DB and the JDBC driver + // used as well as the used data source + conn = dataSource.getConnection(); + metaData = conn.getMetaData(); + + try + { + element.addAttribute("dbProductName", metaData.getDatabaseProductName()); + } + catch (Exception ex) + { + // we ignore it + } + try + { + element.addAttribute("dbProductVersion", metaData.getDatabaseProductVersion()); + } + catch (Exception ex) + { + // we ignore it + } + try + { + int databaseMajorVersion = metaData.getDatabaseMajorVersion(); + int databaseMinorVersion = metaData.getDatabaseMinorVersion(); + + element.addAttribute("dbVersion", databaseMajorVersion + "." + databaseMinorVersion); + } + catch (Exception ex) + { + // we ignore it + } + try + { + element.addAttribute("driverName", metaData.getDriverName()); + } + catch (Exception ex) + { + // we ignore it + } + try + { + element.addAttribute("driverVersion", metaData.getDriverVersion()); + } + catch (Exception ex) + { + // we ignore it + } + try + { + int jdbcMajorVersion = metaData.getJDBCMajorVersion(); + int jdbcMinorVersion = metaData.getJDBCMinorVersion(); + + element.addAttribute("jdbcVersion", jdbcMajorVersion + "." + jdbcMinorVersion); + } + catch (Exception ex) + { + // we ignore it + } + } + catch (Exception ex) + { + throw new BuildException(ex); + } + finally + { + if (conn != null) + { + try + { + conn.close(); + } + catch (SQLException ex) + { + // we ignore it + } + } + } + } + + /** + * [EMAIL PROTECTED] + */ + public void execute() throws BuildException + { + try + { + log("Processing test results", Project.MSG_INFO); + + Document doc = processInputFiles(); + XMLWriter writer = null; + + if (_outputFile != null) + { + writer = new XMLWriter(new FileWriter(_outputFile), OutputFormat.createPrettyPrint()); + } + else + { + writer = new XMLWriter(System.out, OutputFormat.createPrettyPrint()); + } + + writer.write(doc); + writer.close(); + + log("Processing finished", Project.MSG_INFO); + } + catch (Exception ex) + { + throw new BuildException("Error while processing the test results: "+ex.getLocalizedMessage(), ex); + } + } +} Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java?view=diff&rev=464353&r1=464352&r2=464353 ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java (original) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java Sun Oct 15 18:15:26 2006 @@ -151,14 +151,14 @@ } /** - * Retrieves all rows from the given table. - * - * @param tableName The table - * @return The rows + * Returns a "SELECT * FROM [table name]" statement. It also takes + * delimited identifier mode into account if enabled. + * + * @param table The table + * @return The statement */ - protected List getRows(String tableName) + protected String getSelectQueryForAllString(Table table) { - Table table = getModel().findTable(tableName, getPlatform().isDelimitedIdentifierModeOn()); StringBuffer query = new StringBuffer(); query.append("SELECT * FROM "); @@ -171,8 +171,20 @@ { query.append(getPlatformInfo().getDelimiterToken()); } + return query.toString(); + } + + /** + * Retrieves all rows from the given table. + * + * @param tableName The table + * @return The rows + */ + protected List getRows(String tableName) + { + Table table = getModel().findTable(tableName, getPlatform().isDelimitedIdentifierModeOn()); - return getPlatform().fetch(getModel(), query.toString(), new Table[] { table }); + return getPlatform().fetch(getModel(), getSelectQueryForAllString(table), new Table[] { table }); } /** Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java?view=diff&rev=464353&r1=464352&r2=464353 ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java (original) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatatypes.java Sun Oct 15 18:15:26 2006 @@ -124,14 +124,16 @@ dataWriter.writeDocumentStart(); for (int idx = 0; idx < getModel().getTableCount(); idx++) { - Table[] tables = { (Table)getModel().getTable(idx) }; + Table table = getModel().getTable(idx); - dataWriter.write(getPlatform().query(getModel(), "select * from " + tables[0].getName(), tables)); + dataWriter.write(getPlatform().query(getModel(), getSelectQueryForAllString(table), new Table[] { table })); } dataWriter.writeDocumentEnd(); String dataSql = stringWriter.toString(); + assertTrue((dataSql != null) && (dataSql.length() > 0)); + getPlatform().dropTables(getModel(), false); createDatabase(modelXml);