/*
* 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