From ba29a42943c8c82232c3eb28772e8db7fe6882c2 Mon Sep 17 00:00:00 2001 From: Julian Hyde Date: Wed, 21 Nov 2007 01:39:37 +0000 Subject: [PATCH] Move test parameters out of source code and into a file. 'test.properties' should be the only file you need to edit. Provided 'test.properties.example'. First cut README.txt. git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@42 c6a108a4-781c-0410-a6c6-c2d559e19af0 --- README.txt | 42 +++ build.properties | 17 +- build.xml | 12 +- .../mdx/parser/impl/DefaultMdxParser.cup | 1 - test.properties.example | 25 ++ testsrc/org/olap4j/ConnectionTest.java | 281 +++--------------- testsrc/org/olap4j/MetadataTest.java | 5 +- testsrc/org/olap4j/MondrianTester.java | 69 +++++ testsrc/org/olap4j/OlapTest.java | 1 - testsrc/org/olap4j/XmlaTester.java | 118 ++++++++ testsrc/org/olap4j/test/ParserTest.java | 10 +- testsrc/org/olap4j/test/TestContext.java | 166 +++++++---- 12 files changed, 438 insertions(+), 309 deletions(-) create mode 100644 README.txt create mode 100644 test.properties.example create mode 100644 testsrc/org/olap4j/MondrianTester.java create mode 100644 testsrc/org/olap4j/XmlaTester.java diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..a08878c --- /dev/null +++ b/README.txt @@ -0,0 +1,42 @@ +Contents of this distribution +----------------------------- + +This is a binary distribution of olap4j. +For version information, see VERSION.txt. +For licensing, see LICENSE.html. + +It contains the following external libraries: + +lib/asm-2.2.3.jar Part of retroweaver. +lib/asm-commons-2.2.3.jar Part of retroweaver. +lib/javacup.jar Javacup 0.10k +lib/log4j-1.2.9.jar +lib/mondrian-2.1.1.jar From mondrian project, change xxxx. (Not an + official release of mondrian.) +lib/pdfdoclet-1.0.2-all.jar PDF doclet is a utility to generate javadoc + in Adobe Acrobat format. +lib/retroweaver-1.2.4.jar Retroweaver 1.2.4, compile-time library +lib/retroweaver-rt-1.2.4.jar Retroweaver 1.2.4, runtime library +lib/spring.jar Spring. Used for code samples only +testlib/junit.jar Junit. Used for test +testlib/servlet.jar Servlet. Used for code samples only + +mondrian.jar + + +Running the test suite +---------------------- + +To run the test suite: + +1. create a test.properties file describing your environment. The easiest way + to this is to copy test.properties.example and customize it. +2. execute 'ant test' + +JDK 1.4 +------- + +This distribution does not include JDK 1.4-compatible binaries. To create them, +run 'ant retroweave'. + +End README.txt diff --git a/build.properties b/build.properties index 50215e1..e1ac8cf 100644 --- a/build.properties +++ b/build.properties @@ -1 +1,16 @@ -retroweaver.dir=E:/retroweaver-1.2.4 +# $Id: DefaultMdxParser.cup 40 2007-11-18 01:13:26Z jhyde $ +# This software is subject to the terms of the Common Public License +# Agreement, available at the following URL: +# http://www.opensource.org/licenses/cpl.html. +# Copyright (C) 2007-2007 Julian Hyde and others. +# All Rights Reserved. +# You must accept the terms of that agreement to use this software. +# +# Modify this file to override build settings. It is read by ant's build.xml. +# See also 'test.properties', which contains settings for the regression +# suite. +# + +# retroweaver.dir=E:/retroweaver-1.2.4 + +# End build.properties diff --git a/build.xml b/build.xml index a159886..2082528 100644 --- a/build.xml +++ b/build.xml @@ -41,6 +41,14 @@ + + + + @@ -73,9 +81,6 @@ - - - @@ -96,6 +101,7 @@ + diff --git a/src/org/olap4j/mdx/parser/impl/DefaultMdxParser.cup b/src/org/olap4j/mdx/parser/impl/DefaultMdxParser.cup index 1361429..1a4fbf6 100644 --- a/src/org/olap4j/mdx/parser/impl/DefaultMdxParser.cup +++ b/src/org/olap4j/mdx/parser/impl/DefaultMdxParser.cup @@ -1427,7 +1427,6 @@ axis_specification ::= // Legal axis ordinals run from 0 (COLUMS) to 4 (SECTIONS), // inclusive. if (index < 0 || index != d || index > Axis.MAX_ORDINAL) { - System.out.println("nleft=" + nleft + ", nright=" + nright); throw new MdxParseException( createRegion(nleft, nright), "Invalid axis specification. The axis number must be an integer between 0 and " + diff --git a/test.properties.example b/test.properties.example new file mode 100644 index 0000000..fdd2f46 --- /dev/null +++ b/test.properties.example @@ -0,0 +1,25 @@ +# $Id$ +# This software is subject to the terms of the Common Public License +# Agreement, available at the following URL: +# http://www.opensource.org/licenses/cpl.html. +# Copyright (C) 2007-2007 Julian Hyde and others. +# All Rights Reserved. +# You must accept the terms of that agreement to use this software. +# +# Sample "test.properties" file. Rename to "test.properties" and modify +# for your environment. + +# Connect string olap4j test suite should use to connect to the foodmart +# database. Examples are shown for mondrian connecting to Apache Derby on +# Linux, Oracle on Linux, and Microsoft Access on Windows. Must be specified; +# there is no default. +#org.olap4j.test.connectUrl=jdbc:mondrian:Jdbc='jdbc:derby:/home/jvs/open/mondrian/demo/derby/foodmart';JdbcUser=sa;JdbcPassword=sa;Catalog='file:///home/jvs/open/mondrian/demo/FoodMart.xml';JdbcDrivers=org.apache.derby.jdbc.EmbeddedDriver; +#org.olap4j.test.connectUrl=jdbc:mondrian:Jdbc=jdbc:oracle:thin:foodmart/foodmart@//marmalade.hydromatic.net:1521/XE;JdbcUser=foodmart;JdbcPassword=foodmart;Catalog=../mondrian/demo/FoodMart.xml;JdbcDrivers=oracle.jdbc.OracleDriver; +#org.olap4j.test.connectUrl=jdbc:mondrian:Jdbc='jdbc:odbc:MondrianFoodMart';Catalog='file://c:/open/mondrian/demo/FoodMart.xml';JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver; + +# Name of class which targets the olap4j test suite to a particular driver +# implementation. Must implement org.olap4j.test.TestContext.Tester interface. +# Default is "org.olap4j.MondrianTester". +org.olap4j.test.helperClassName=org.olap4j.MondrianTester + +# End test.properties.example diff --git a/testsrc/org/olap4j/ConnectionTest.java b/testsrc/org/olap4j/ConnectionTest.java index 3a049f0..130a72c 100644 --- a/testsrc/org/olap4j/ConnectionTest.java +++ b/testsrc/org/olap4j/ConnectionTest.java @@ -11,19 +11,14 @@ import junit.framework.AssertionFailedError; import junit.framework.TestCase; -import mondrian.tui.XmlaSupport; -import org.olap4j.driver.xmla.XmlaOlap4jDriver; import org.olap4j.mdx.*; import org.olap4j.mdx.parser.*; import org.olap4j.metadata.*; import org.olap4j.test.TestContext; import org.olap4j.type.*; -import org.xml.sax.SAXException; -import javax.servlet.ServletException; import java.io.*; import java.lang.reflect.InvocationTargetException; -import java.net.URL; import java.sql.*; import java.util.*; @@ -31,37 +26,14 @@ * Unit test for olap4j Driver and Connection classes. * *

The system property "org.olap4j.test.helperClassName" determines the - * name of the helper class. By default, uses {@link MondrianHelper}, which - * runs against mondrian; {@link XmlaHelper} is also available. + * name of the helper class. By default, uses {@link MondrianTester}, which + * runs against mondrian; {@link XmlaTester} is also available. * + * @author jhyde * @version $Id$ */ public class ConnectionTest extends TestCase { - private final Helper helper = createHelper(); - - /** - * Factory method for the {@link org.olap4j.ConnectionTest.Helper} - * object which determines which driver to test. - * - * @return a new Helper - */ - static Helper createHelper() { - String helperClassName = - System.getProperty("org.olap4j.test.helperClassName"); - if (helperClassName != null) { - try { - Class clazz = Class.forName(helperClassName); - return (Helper) clazz.newInstance(); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } - } - return new MondrianHelper(); - } + private final TestContext.Tester tester = TestContext.instance().getTester(); private static final boolean IS_JDK_16 = System.getProperty("java.version").startsWith("1.6."); @@ -70,18 +42,18 @@ static Helper createHelper() { * Driver basics. */ public void testDriver() throws ClassNotFoundException, SQLException { - Class clazz = Class.forName(helper.getDriverClassName()); + Class clazz = Class.forName(tester.getDriverClassName()); assertNotNull(clazz); assertTrue(Driver.class.isAssignableFrom(clazz)); // driver should have automatically registered itself - Driver driver = DriverManager.getDriver(helper.getDriverUrlPrefix()); + Driver driver = DriverManager.getDriver(tester.getDriverUrlPrefix()); assertNotNull(driver); // deregister driver DriverManager.deregisterDriver(driver); try { - Driver driver2 = DriverManager.getDriver(helper.getDriverUrlPrefix()); + Driver driver2 = DriverManager.getDriver(tester.getDriverUrlPrefix()); fail("expected error, got " + driver2); } catch (SQLException e) { assertEquals("No suitable driver", e.getMessage()); @@ -89,7 +61,7 @@ public void testDriver() throws ClassNotFoundException, SQLException { // register explicitly DriverManager.registerDriver(driver); - Driver driver3 = DriverManager.getDriver(helper.getDriverUrlPrefix()); + Driver driver3 = DriverManager.getDriver(tester.getDriverUrlPrefix()); assertNotNull(driver3); // test properties @@ -102,7 +74,7 @@ public void testDriver() throws ClassNotFoundException, SQLException { // We can't test individual properties in this non-driver-specific test. DriverPropertyInfo[] driverPropertyInfos = driver.getPropertyInfo( - helper.getDriverUrlPrefix(), + tester.getDriverUrlPrefix(), new Properties()); assertTrue(driverPropertyInfos.length > 0); } @@ -170,10 +142,10 @@ void assertIsClosed(Object o, boolean b) { } public void testConnection() throws ClassNotFoundException, SQLException { - Class.forName(helper.getDriverClassName()); + Class.forName(tester.getDriverClassName()); // connect using properties and no username/password - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); assertNotNull(connection); // check isClosed, isValid @@ -193,14 +165,14 @@ public void testConnection() throws ClassNotFoundException, SQLException { connection.close(); // connect using username/password - connection = helper.createConnectionWithUserPassword(); + connection = tester.createConnectionWithUserPassword(); assertNotNull(connection); connection.close(); assertTrue(connection.isClosed()); // connect with URL only - connection = DriverManager.getConnection(helper.getURL()); + connection = DriverManager.getConnection(tester.getURL()); assertNotNull(connection); connection.close(); @@ -208,7 +180,7 @@ public void testConnection() throws ClassNotFoundException, SQLException { } public void testConnectionUnwrap() throws SQLException { - java.sql.Connection connection = helper.createConnection(); + java.sql.Connection connection = tester.createConnection(); // Trivial unwrap assertTrue(((OlapWrapper) connection).isWrapperFor(Connection.class)); @@ -249,7 +221,7 @@ public void testConnectionUnwrap() throws SQLException { } // Unwrap the mondrian connection. - if (helper.isMondrian()) { + if (tester.isMondrian()) { final mondrian.olap.Connection mondrianConnection = ((OlapWrapper) connection).unwrap(mondrian.olap.Connection.class); assertNotNull(mondrianConnection); @@ -257,7 +229,7 @@ public void testConnectionUnwrap() throws SQLException { } public void testStatement() throws SQLException { - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); Statement statement = connection.createStatement(); // Closing a statement is idempotent. @@ -308,7 +280,7 @@ public void testStatement() throws SQLException { private enum Method { ClassName, Mode, Type, TypeName, OlapType } public void testPreparedStatement() throws SQLException { - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); PreparedOlapStatement pstmt = @@ -477,7 +449,7 @@ public void testPreparedStatement() throws SQLException { public void testCellSetMetaData() throws SQLException { // Metadata of prepared statement - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); @@ -547,7 +519,7 @@ private void checkCellSetMetaData( * @throws Exception on error */ public void testCellSetAxisMetaData() throws Exception { - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); final String mdx = "SELECT\n" @@ -592,7 +564,7 @@ private void checkAxisMetaData(CellSetAxisMetaData cellSetAxisMetaData) { } public void testCellSet() throws SQLException { - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); Statement statement = connection.createStatement(); final OlapStatement olapStatement = ((OlapWrapper) statement).unwrap(OlapStatement.class); @@ -625,7 +597,7 @@ public void testCellSet() throws SQLException { } public void testCell() throws Exception { - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); Statement statement = connection.createStatement(); final OlapStatement olapStatement = ((OlapWrapper) statement).unwrap(OlapStatement.class); @@ -806,7 +778,7 @@ public void testParsing() throws SQLException { // parse - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); MdxParser mdxParser = @@ -834,7 +806,7 @@ public void testParsing() throws SQLException { fail("expected exception, got " + select); } catch (Exception e) { assertTrue( - getStackTrace(e).indexOf("Duplicate axis name 'COLUMNS'.") + TestContext.getStackTrace(e).indexOf("Duplicate axis name 'COLUMNS'.") >= 0); } } @@ -937,8 +909,8 @@ public void testUnparsing() { * Tests the {@link Cube#lookupMember(String[])} method. */ public void testCubeLookupMember() throws Exception { - Class.forName(helper.getDriverClassName()); - Connection connection = helper.createConnection(); + Class.forName(tester.getDriverClassName()); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); Cube cube = olapConnection.getSchema().getCubes().get("Sales"); @@ -970,8 +942,8 @@ public void testCubeLookupMember() throws Exception { * Tests the {@link Cube#lookupMembers(java.util.Set, String[])} method. */ public void testCubeLookupMembers() throws Exception { - Class.forName(helper.getDriverClassName()); - Connection connection = helper.createConnection(); + Class.forName(tester.getDriverClassName()); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); Cube cube = olapConnection.getSchema().getCubes().get("Sales"); @@ -1048,8 +1020,8 @@ public void testCubeLookupMembers() throws Exception { * Tests metadata browsing. */ public void testMetadata() throws Exception { - Class.forName(helper.getDriverClassName()); - Connection connection = helper.createConnection(); + Class.forName(tester.getDriverClassName()); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); Cube cube = olapConnection.getSchema().getCubes().get("Sales"); @@ -1157,8 +1129,8 @@ public void testMetadata() throws Exception { * @throws Throwable on error */ public void testCubeType() throws Throwable { - Class.forName(helper.getDriverClassName()); - Connection connection = helper.createConnection(); + Class.forName(tester.getDriverClassName()); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); @@ -1220,10 +1192,10 @@ public void testCubeType() throws Throwable { * @throws Throwable on error */ public void testAxisType() throws Throwable { - Class.forName(helper.getDriverClassName()); + Class.forName(tester.getDriverClassName()); // connect using properties and no username/password - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); @@ -1306,8 +1278,8 @@ public void testAxisType() throws Throwable { } public void testParseQueryWithNoFilter() throws Exception { - Class.forName(helper.getDriverClassName()); - Connection connection = helper.createConnection(); + Class.forName(tester.getDriverClassName()); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); @@ -1337,7 +1309,7 @@ public void testParseQueryWithNoFilter() throws Exception { fail("expected parse error, got " + select); } catch (RuntimeException e) { assertTrue( - getStackTrace(e).indexOf( + TestContext.getStackTrace(e).indexOf( "Syntax error at [4:10], token ')'") >= 0); } } @@ -1346,17 +1318,6 @@ public void testParseQueryWithNoFilter() throws Exception { // TODO: test for DimensionType // TODO: test for LevelType - /** - * Converts a {@link Throwable} to a stack trace. - */ - static String getStackTrace(Throwable e) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - pw.flush(); - return sw.toString(); - } - /** * Converts a list of members to a string, one per line. */ @@ -1369,7 +1330,7 @@ static String memberListToString(List list) { } public void testStatementCancel() throws Throwable { - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); final OlapStatement olapStatement = olapConnection.createStatement(); @@ -1403,7 +1364,7 @@ public void run() { } public void testStatementTimeout() throws Throwable { - Connection connection = helper.createConnection(); + Connection connection = tester.createConnection(); OlapConnection olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); final OlapStatement olapStatement = olapConnection.createStatement(); @@ -1428,172 +1389,6 @@ public void testStatementTimeout() throws Throwable { } } - /** - * Abstracts the information about specific drivers and database instances - * needed by this test. This allows the same test suite to be used for - * multiple implementations of olap4j. - */ - interface Helper { - Connection createConnection() throws SQLException; - - String getDriverUrlPrefix(); - - String getDriverClassName(); - - Connection createConnectionWithUserPassword() throws SQLException; - - String getURL(); - - boolean isMondrian(); - } - - /** - * Implementation of {@link Helper} which speaks to the mondrian olap4j - * driver. - */ - public static class MondrianHelper implements Helper { - - public Connection createConnection() throws SQLException { - try { - Class.forName(DRIVER_CLASS_NAME); - } catch (ClassNotFoundException e) { - throw new RuntimeException("oops", e); - } - return - DriverManager.getConnection( - getURL(), - new Properties()); - } - - public Connection createConnectionWithUserPassword() throws SQLException { - return DriverManager.getConnection( - getURL(), USER, PASSWORD); - } - - public String getDriverUrlPrefix() { - return DRIVER_URL_PREFIX; - } - - public String getDriverClassName() { - return DRIVER_CLASS_NAME; - } - - public String getURL() { - return getDefaultConnectString(); - } - - public boolean isMondrian() { - return true; - } - - public static String getDefaultConnectString() { - if (false) { - return "jdbc:mondrian:Jdbc='jdbc:derby:/home/jvs/open/mondrian/demo/derby/foodmart';JdbcUser=sa;JdbcPassword=sa;Catalog='file:///home/jvs/open/mondrian/demo/FoodMart.xml';JdbcDrivers=org.apache.derby.jdbc.EmbeddedDriver;"; - } - if (true) { - return "jdbc:mondrian:Jdbc='jdbc:odbc:MondrianFoodMart';Catalog='file://c:/open/mondrian/demo/FoodMart.xml';JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver;"; - } else { - return "jdbc:mondrian:Jdbc=jdbc:oracle:thin:foodmart/foodmart@//marmalade.hydromatic.net:1521/XE;JdbcUser=foodmart;JdbcPassword=foodmart;Catalog=../mondrian/demo/FoodMart.xml;JdbcDrivers=oracle.jdbc.OracleDriver;"; - } - } - - public static final String DRIVER_CLASS_NAME = "mondrian.olap4j.MondrianOlap4jDriver"; - - public static final String DRIVER_URL_PREFIX = "jdbc:mondrian:"; - private static final String USER = "sa"; - private static final String PASSWORD = "sa"; - } - - /** - * Implementation of {@link Helper} which speaks to the XML/A olap4j - * driver. - */ - public static class XmlaHelper implements Helper { - XmlaOlap4jDriver.Proxy proxy = - new MondrianInprocProxy(); - - public Connection createConnection() throws SQLException { - try { - Class.forName(DRIVER_CLASS_NAME); - } catch (ClassNotFoundException e) { - throw new RuntimeException("oops", e); - } - try { - XmlaOlap4jDriver.THREAD_PROXY.set(proxy); - Properties info = new Properties(); - info.setProperty("UseThreadProxy", "true"); - return - DriverManager.getConnection( - getURL(), - info); - } finally { - XmlaOlap4jDriver.THREAD_PROXY.set(null); - } - } - - public Connection createConnectionWithUserPassword() throws SQLException { - try { - Class.forName(DRIVER_CLASS_NAME); - } catch (ClassNotFoundException e) { - throw new RuntimeException("oops", e); - } - try { - XmlaOlap4jDriver.THREAD_PROXY.set(proxy); - Properties info = new Properties(); - info.setProperty("UseThreadProxy", "true"); - return DriverManager.getConnection( - getURL(), USER, PASSWORD); - } finally { - XmlaOlap4jDriver.THREAD_PROXY.set(null); - } - } - - public String getDriverUrlPrefix() { - return DRIVER_URL_PREFIX; - } - - public String getDriverClassName() { - return DRIVER_CLASS_NAME; - } - - public String getURL() { - return "jdbc:xmla:Server=http://foo;UseThreadProxy=true"; - } - - public boolean isMondrian() { - return false; - } - - public static final String DRIVER_CLASS_NAME = - "org.olap4j.driver.xmla.XmlaOlap4jDriver"; - - public static final String DRIVER_URL_PREFIX = "jdbc:xmla:"; - private static final String USER = "user"; - private static final String PASSWORD = "password"; - - /** - * Proxy which implements XMLA requests by talking to mondrian - * in-process. This is more convenient to debug than an inter-process - * request using HTTP. - */ - private static class MondrianInprocProxy implements XmlaOlap4jDriver.Proxy { - public InputStream get(URL url, String request) throws IOException { - try { - Map map = new HashMap(); - String urlString = url.toString(); - byte[] bytes = XmlaSupport.processSoapXmla( - request, urlString, map, null); - return new ByteArrayInputStream(bytes); - } catch (ServletException e) { - throw new RuntimeException( - "Error while reading '" + url + "'", e); - } catch (SAXException e) { - throw new RuntimeException( - "Error while reading '" + url + "'", e); - } - } - } - } } // End ConnectionTest.java diff --git a/testsrc/org/olap4j/MetadataTest.java b/testsrc/org/olap4j/MetadataTest.java index 91bf95d..5ea53e4 100644 --- a/testsrc/org/olap4j/MetadataTest.java +++ b/testsrc/org/olap4j/MetadataTest.java @@ -23,7 +23,6 @@ public class MetadataTest extends TestCase { private static final String NL = System.getProperty("line.separator"); - private final ConnectionTest.Helper helper = ConnectionTest.createHelper(); private final Connection connection; private final String catalogName; private final OlapConnection olapConnection; @@ -48,7 +47,7 @@ public class MetadataTest extends TestCase { private static final List ACTIONS_COLUMN_NAMES = Arrays.asList("SCHEMA_NAME", "CUBE_NAME", "ACTION_NAME", "COORDINATE", "COORDINATE_TYPE"); public MetadataTest() throws SQLException { - connection = helper.createConnection(); + connection = TestContext.instance().getTester().createConnection(); catalogName = connection.getCatalog(); olapConnection = ((OlapWrapper) connection).unwrap(OlapConnection.class); @@ -255,7 +254,7 @@ public void testDatabaseMetaDataGetFunctions() throws SQLException { olapDatabaseMetaData.getOlapFunctions(null), FUNCTIONS_COLUMN_NAMES); assertContains("FUNCTION_NAME=Name, DESCRIPTION=Returns the name of a member., PARAMETER_LIST=Member, RETURN_TYPE=8, ORIGIN=1, INTERFACE_NAME=, LIBRARY_NAME=null, CAPTION=Name", s); - assertEquals(271, linecount(s)); + assertEquals(272, linecount(s)); s = checkResultSet( olapDatabaseMetaData.getOlapFunctions("%scendants"), diff --git a/testsrc/org/olap4j/MondrianTester.java b/testsrc/org/olap4j/MondrianTester.java new file mode 100644 index 0000000..4829d3f --- /dev/null +++ b/testsrc/org/olap4j/MondrianTester.java @@ -0,0 +1,69 @@ +/* +// This software is subject to the terms of the Common Public License +// Agreement, available at the following URL: +// http://www.opensource.org/licenses/cpl.html. +// Copyright (C) 2007-2007 Julian Hyde +// All Rights Reserved. +// You must accept the terms of that agreement to use this software. +*/ +package org.olap4j; + +import org.olap4j.test.TestContext; + +import java.sql.*; +import java.util.Properties; + +/** + * Implementation of {@link org.olap4j.test.TestContext.Tester} which speaks to + * the mondrian olap4j driver. + * + * @author jhyde + * @version $Id$ + */ +public class MondrianTester implements TestContext.Tester { + + public Connection createConnection() throws SQLException { + try { + Class.forName(DRIVER_CLASS_NAME); + } catch (ClassNotFoundException e) { + throw new RuntimeException("oops", e); + } + return + DriverManager.getConnection( + getURL(), + new Properties()); + } + + public Connection createConnectionWithUserPassword() throws SQLException { + return DriverManager.getConnection( + getURL(), USER, PASSWORD); + } + + public String getDriverUrlPrefix() { + return DRIVER_URL_PREFIX; + } + + public String getDriverClassName() { + return DRIVER_CLASS_NAME; + } + + public String getURL() { + // This property is usually defined in build.properties. See + // examples in that file. + return TestContext.getTestProperties().getProperty( + "org.olap4j.test.connectUrl"); + } + + public boolean isMondrian() { + return true; + } + + public static final String DRIVER_CLASS_NAME = + "mondrian.olap4j.MondrianOlap4jDriver"; + + public static final String DRIVER_URL_PREFIX = "jdbc:mondrian:"; + private static final String USER = "sa"; + private static final String PASSWORD = "sa"; +} + +// End MondrianTester.java diff --git a/testsrc/org/olap4j/OlapTest.java b/testsrc/org/olap4j/OlapTest.java index 6c00798..43d16bf 100644 --- a/testsrc/org/olap4j/OlapTest.java +++ b/testsrc/org/olap4j/OlapTest.java @@ -189,7 +189,6 @@ public void testModel() { } catch (Throwable t) { t.printStackTrace(); - System.exit(0); } } diff --git a/testsrc/org/olap4j/XmlaTester.java b/testsrc/org/olap4j/XmlaTester.java new file mode 100644 index 0000000..3777387 --- /dev/null +++ b/testsrc/org/olap4j/XmlaTester.java @@ -0,0 +1,118 @@ +/* +// This software is subject to the terms of the Common Public License +// Agreement, available at the following URL: +// http://www.opensource.org/licenses/cpl.html. +// Copyright (C) 2007-2007 Julian Hyde +// All Rights Reserved. +// You must accept the terms of that agreement to use this software. +*/ +package org.olap4j; + +import org.olap4j.driver.xmla.XmlaOlap4jDriver; +import org.olap4j.test.TestContext; +import org.xml.sax.SAXException; + +import java.sql.*; +import java.util.*; +import java.io.*; +import java.net.URL; + +import mondrian.tui.XmlaSupport; + +import javax.servlet.ServletException; + +/** + * Implementation of {@link org.olap4j.test.TestContext.Tester} which speaks + * to the olap4j driver for XML/A. + * + * @author jhyde + * @version $Id$ + */ +public class XmlaTester implements TestContext.Tester { + XmlaOlap4jDriver.Proxy proxy = + new MondrianInprocProxy(); + + public Connection createConnection() throws SQLException { + try { + Class.forName(DRIVER_CLASS_NAME); + } catch (ClassNotFoundException e) { + throw new RuntimeException("oops", e); + } + try { + XmlaOlap4jDriver.THREAD_PROXY.set(proxy); + Properties info = new Properties(); + info.setProperty("UseThreadProxy", "true"); + return + DriverManager.getConnection( + getURL(), + info); + } finally { + XmlaOlap4jDriver.THREAD_PROXY.set(null); + } + } + + public Connection createConnectionWithUserPassword() throws SQLException { + try { + Class.forName(DRIVER_CLASS_NAME); + } catch (ClassNotFoundException e) { + throw new RuntimeException("oops", e); + } + try { + XmlaOlap4jDriver.THREAD_PROXY.set(proxy); + Properties info = new Properties(); + info.setProperty("UseThreadProxy", "true"); + return DriverManager.getConnection( + getURL(), USER, PASSWORD); + } finally { + XmlaOlap4jDriver.THREAD_PROXY.set(null); + } + } + + public String getDriverUrlPrefix() { + return DRIVER_URL_PREFIX; + } + + public String getDriverClassName() { + return DRIVER_CLASS_NAME; + } + + public String getURL() { + return "jdbc:xmla:Server=http://foo;UseThreadProxy=true"; + } + + public boolean isMondrian() { + return false; + } + + public static final String DRIVER_CLASS_NAME = + "org.olap4j.driver.xmla.XmlaOlap4jDriver"; + + public static final String DRIVER_URL_PREFIX = "jdbc:xmla:"; + private static final String USER = "user"; + private static final String PASSWORD = "password"; + + /** + * Proxy which implements XMLA requests by talking to mondrian + * in-process. This is more convenient to debug than an inter-process + * request using HTTP. + */ + private static class MondrianInprocProxy implements XmlaOlap4jDriver.Proxy { + public InputStream get(URL url, String request) throws IOException { + try { + Map map = new HashMap(); + String urlString = url.toString(); + byte[] bytes = XmlaSupport.processSoapXmla( + request, urlString, map, null); + return new ByteArrayInputStream(bytes); + } catch (ServletException e) { + throw new RuntimeException( + "Error while reading '" + url + "'", e); + } catch (SAXException e) { + throw new RuntimeException( + "Error while reading '" + url + "'", e); + } + } + } +} + +// End XmlaTester.java diff --git a/testsrc/org/olap4j/test/ParserTest.java b/testsrc/org/olap4j/test/ParserTest.java index b009c0c..bd3fdfb 100644 --- a/testsrc/org/olap4j/test/ParserTest.java +++ b/testsrc/org/olap4j/test/ParserTest.java @@ -42,8 +42,10 @@ public ParserTest(String name) { private MdxParser createParser() { try { - OlapConnection olapConnection = TestContext.instance().getConnection(); - return olapConnection.getParserFactory().createMdxParser(olapConnection); + OlapConnection olapConnection = + TestContext.instance().getOlapConnection(); + return olapConnection.getParserFactory() + .createMdxParser(olapConnection); } catch (SQLException e) { throw new RuntimeException(e); } @@ -185,7 +187,7 @@ private void checkUnparse(String queryString, final String expected) { try { final TestContext testContext = TestContext.instance(); - OlapConnection olapConnection = testContext.getConnection(); + OlapConnection olapConnection = testContext.getOlapConnection(); MdxParser mdxParser = olapConnection.getParserFactory() .createMdxParser(olapConnection); @@ -526,7 +528,7 @@ public void testId() { // todo: enable this public void _testCloneQuery() throws SQLException { - OlapConnection olapConnection = TestContext.instance().getConnection(); + OlapConnection olapConnection = TestContext.instance().getOlapConnection(); MdxParser mdxParser = olapConnection.getParserFactory() .createMdxParser(olapConnection); diff --git a/testsrc/org/olap4j/test/TestContext.java b/testsrc/org/olap4j/test/TestContext.java index d0a3d96..64e444a 100644 --- a/testsrc/org/olap4j/test/TestContext.java +++ b/testsrc/org/olap4j/test/TestContext.java @@ -9,14 +9,12 @@ */ package org.olap4j.test; -import java.io.StringWriter; -import java.io.PrintWriter; +import java.io.*; import java.util.List; import java.util.ArrayList; import java.util.Properties; import java.util.regex.Pattern; -import java.sql.SQLException; -import java.sql.DriverManager; +import java.sql.*; import org.olap4j.metadata.Member; import org.olap4j.*; @@ -42,6 +40,15 @@ public class TestContext { private static final Pattern LineBreakPattern = Pattern.compile("\r\n|\r|\n"); private static final Pattern TabPattern = Pattern.compile("\t"); + public static Properties testProperties; + + private final Tester tester = createTester(); + + /** + * Intentionally private: use {@link #instance()}. + */ + private TestContext() { + } /** * Converts a string constant into environment-specific line endings. @@ -158,57 +165,11 @@ public static TestContext instance() { return INSTANCE; } - public OlapConnection getConnection() throws SQLException { - java.sql.Connection connection = createConnection(); - OlapConnection olapConnection = - ((OlapWrapper) connection).unwrap(OlapConnection.class); - return olapConnection; - } - - public java.sql.Connection createConnection() throws SQLException { - try { - Class.forName(DRIVER_CLASS_NAME); - } catch (ClassNotFoundException e) { - throw new RuntimeException("oops", e); - } - return - DriverManager.getConnection( - getURL(), - new Properties()); - } - - public java.sql.Connection createConnectionWithUserPassword() throws SQLException { - return DriverManager.getConnection( - getURL(), USER, PASSWORD); - } - - public String getDriverUrlPrefix() { - return DRIVER_URL_PREFIX; - } - - public String getDriverClassName() { - return DRIVER_CLASS_NAME; + public OlapConnection getOlapConnection() throws SQLException { + java.sql.Connection connection = tester.createConnection(); + return ((OlapWrapper) connection).unwrap(OlapConnection.class); } - public String getURL() { - return getDefaultConnectString(); - } - - public boolean isMondrian() { - return true; - } - - public static String getDefaultConnectString() { -// return "jdbc:mondrian:Jdbc='jdbc:odbc:MondrianFoodMart';Catalog='../mondrian/demo/FoodMart.xml';JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver;"; - return "jdbc:mondrian:Jdbc='jdbc:oracle:thin:foodmart/foodmart@//marmalade.hydromatic.net:1521/XE';Catalog='../mondrian/demo/FoodMart.xml';JdbcDrivers=oracle.jdbc.OracleDriver;"; - } - - public static final String DRIVER_CLASS_NAME = "mondrian.olap4j.MondrianOlap4jDriver"; - - public static final String DRIVER_URL_PREFIX = "jdbc:mondrian:"; - private static final String USER = "user"; - private static final String PASSWORD = "password"; - /** * Checks that an actual string matches an expected string. If they do not, * throws a {@link junit.framework.ComparisonFailure} and prints the @@ -317,6 +278,105 @@ public static String quotePattern(String s) s = s.replaceAll("\\]", "\\\\]"); return s; } + + /** + * Factory method for the {@link Tester} + * object which determines which driver to test. + * + * @return a new Tester + */ + private static Tester createTester() { + String helperClassName = + getTestProperties().getProperty("org.olap4j.test.helperClassName"); + if (helperClassName == null) { + helperClassName = "org.olap4j.MondrianTester"; + } + try { + Class clazz = Class.forName(helperClassName); + return (Tester) clazz.newInstance(); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } + } + + /** + * Returns an object containing all properties needed by the test suite. + * + *

Consists of system properties, overridden by the contents of + * "test.properties" in the current directory, if it exists, and + * in any parent or ancestor directory. This allows you to invoke the + * test from any sub-directory of the source root and still pick up the + * right test parameters. + * + * @return object containing properties needed by the test suite + */ + public static synchronized Properties getTestProperties() { + if (testProperties == null) { + testProperties = new Properties(System.getProperties()); + + File dir = new File(System.getProperty("user.dir")); + while (dir != null) { + File file = new File(dir, "test.properties"); + if (file.exists()) { + try { + testProperties.load(new FileInputStream(file)); + } catch (IOException e) { + // ignore + } + } + + file = new File(new File(dir, "olap4j"), "test.properties"); + if (file.exists()) { + try { + testProperties.load(new FileInputStream(file)); + } catch (IOException e) { + // ignore + } + } + + dir = dir.getParentFile(); + } + } + return testProperties; + } + + /** + * Converts a {@link Throwable} to a stack trace. + */ + public static String getStackTrace(Throwable e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + pw.flush(); + return sw.toString(); + } + + public Tester getTester() { + return tester; + } + + /** + * Abstracts the information about specific drivers and database instances + * needed by this test. This allows the same test suite to be used for + * multiple implementations of olap4j. + */ + public interface Tester { + Connection createConnection() throws SQLException; + + String getDriverUrlPrefix(); + + String getDriverClassName(); + + Connection createConnectionWithUserPassword() throws SQLException; + + String getURL(); + + boolean isMondrian(); + } } // End TestContext.java