/* * This software is subject to the terms of the Eclipse Public License v1.0 * Agreement, available at the following URL: * http://www.eclipse.org/legal/epl-v10.html. * You must accept the terms of that agreement to use this software. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package mondrian.test; import mondrian.olap.Connection; import mondrian.olap.Util; import mondrian.spi.DynamicSchemaProcessor; import junit.framework.Assert; import junit.framework.TestCase; /** * Unit test DynamicSchemaProcessor. Tests availability of properties that DSP's * are called, and used to modify the resulting Mondrian schema * * @author ngoodman */ public class DynamicSchemaProcessorTest extends TestCase { public static final String FRAGMENT_ONE = "<?xml version=\"1.0\"?>\n" + "<Schema name=\""; public static final String FRAGMENT_TWO = "\">\n" + "<Cube name=\"Sales\">\n" + " <Table name=\"sales_fact_1997\">" + " <AggExclude name=\"agg_pl_01_sales_fact_1997\" />" + " <AggExclude name=\"agg_ll_01_sales_fact_1997\" />" + " <AggExclude name=\"agg_lc_100_sales_fact_1997\" />" + " <AggExclude name=\"agg_lc_06_sales_fact_1997\" />" + " <AggExclude name=\"agg_l_04_sales_fact_1997\" />" + " <AggExclude name=\"agg_l_03_sales_fact_1997\" />" + " <AggExclude name=\"agg_g_ms_pcat_sales_fact_1997\" />" + " <AggExclude name=\"agg_c_10_sales_fact_1997\" />" + "</Table>" + " <Dimension name=\"Fake\"><Hierarchy hasAll=\"true\">" + " <Level name=\"blah\" column=\"store_id\"/>" + " </Hierarchy></Dimension>" + " <Measure name=\"c\" column=\"store_id\" aggregator=\"count\"/>" + "</Cube>\n" + "</Schema>\n"; public static final String TEMPLATE_SCHEMA = FRAGMENT_ONE + "REPLACEME" + FRAGMENT_TWO; /** * Tests to make sure that our base DynamicSchemaProcessor works, with no * replacement. Does not test Mondrian is able to connect with the schema * definition. */ public void testDSPBasics() { DynamicSchemaProcessor dsp = new BaseDsp(); Util.PropertyList dummy = new Util.PropertyList(); String processedSchema = ""; try { processedSchema = dsp.processSchema("", dummy); } catch (Exception e) { // TODO some other assert failure message assertEquals(0, 1); } Assert.assertEquals(TEMPLATE_SCHEMA, processedSchema); } /** * Tests to make sure that our base DynamicSchemaProcessor works, and * Mondrian is able to parse and connect to FoodMart with it */ public void testFoodmartDsp() { final Connection monConnection = TestContext.instance() .withSchemaProcessor(BaseDsp.class) .getConnection(); assertEquals(monConnection.getSchema().getName(), "REPLACEME"); } /** * Our base, token replacing schema processor. * * @author ngoodman */ public static class BaseDsp implements DynamicSchemaProcessor { // Determines the "cubeName" protected String replaceToken = "REPLACEME"; public BaseDsp() {} public String processSchema( String schemaUrl, Util.PropertyList connectInfo) throws Exception { return getSchema(); } public String getSchema() throws Exception { return DynamicSchemaProcessorTest.TEMPLATE_SCHEMA.replaceAll( "REPLACEME", this.replaceToken); } } /** * Tests to ensure we have access to Connect properies in a DSP */ public void testProviderTestDSP() { Connection monConnection = TestContext.instance() .withSchemaProcessor(ProviderTestDSP.class) .getConnection(); assertEquals(monConnection.getSchema().getName(), "mondrian"); } /** * DSP that checks that replaces the Schema Name with the name of the * Provider property * * @author ngoodman * */ public static class ProviderTestDSP extends BaseDsp { public String processSchema( String schemaUrl, Util.PropertyList connectInfo) throws Exception { this.replaceToken = connectInfo.get("Provider"); return getSchema(); } } /** * Tests to ensure we have access to Connect properies in a DSP */ public void testDBInfoDSP() { Connection monConnection = TestContext.instance() .withSchemaProcessor(FoodMartCatalogDsp.class) .getConnection(); assertEquals( monConnection.getSchema().getName(), "FoodmartFoundInCatalogProperty"); } /** * Checks to make sure our Catalog property contains our FoodMart.xml VFS * URL * * @author ngoodman * */ public static class FoodMartCatalogDsp extends BaseDsp { public String processSchema( String schemaUrl, Util.PropertyList connectInfo) throws Exception { if (connectInfo.get("Catalog").indexOf("FoodMart.xml") <= 0) { this.replaceToken = "NoFoodmartFoundInCatalogProperty"; } else { this.replaceToken = "FoodmartFoundInCatalogProperty"; } return getSchema(); } } /** * Tests to ensure we have access to Connect properties in a DSP */ public void testCheckJdbcPropertyDsp() { Connection monConnection = TestContext.instance() .withSchemaProcessor(CheckJdbcPropertyDsp.class) .getConnection(); assertEquals( monConnection.getSchema().getName(), CheckJdbcPropertyDsp.RETURNTRUESTRING); } /** * Ensures we have access to the JDBC URL. Note, since Foodmart can run on * multiple databases all we check in schema name is the first four * characters (JDBC) * * @author ngoodman * */ public static class CheckJdbcPropertyDsp extends BaseDsp { public static String RETURNTRUESTRING = "true"; public static String RETURNFALSESTRING = "false"; public String processSchema( String schemaUrl, Util.PropertyList connectInfo) throws Exception { String dataSource = null; String jdbc = null; dataSource = connectInfo.get("DataSource"); jdbc = connectInfo.get("Jdbc"); // If we're using a DataSource we might not get a Jdbc= property // trivially return true. if (dataSource != null && dataSource.length() > 0) { this.replaceToken = RETURNTRUESTRING; return getSchema(); } // IF we're here, we don't have a DataSource and // our JDBC property should have jdbc: in the URL if (jdbc == null || !jdbc.startsWith("jdbc")) { this.replaceToken = RETURNFALSESTRING; return getSchema(); } else { // If we're here, we have a JDBC url this.replaceToken = RETURNTRUESTRING; return getSchema(); } } } } // End DynamicSchemaProcessorTest.java