package com.tesora.dve.sql;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.tesora.dve.common.PEUrl;
import com.tesora.dve.common.catalog.CatalogEntity;
import com.tesora.dve.common.catalog.StorageSite;
import com.tesora.dve.common.catalog.TestCatalogHelper;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.exceptions.PENotFoundException;
import com.tesora.dve.server.bootstrap.BootstrapHost;
import com.tesora.dve.server.messaging.GetWorkerRequest;
import com.tesora.dve.siteprovider.SiteProviderPlugin;
import com.tesora.dve.siteprovider.SiteProviderPlugin.SiteProviderFactory;
import com.tesora.dve.siteprovider.onpremise.OnPremiseSiteProvider;
import com.tesora.dve.sql.transform.execution.PassThroughCommand.Command;
import com.tesora.dve.sql.util.PEDDL;
import com.tesora.dve.sql.util.Pair;
import com.tesora.dve.sql.util.ProjectDDL;
import com.tesora.dve.sql.util.ProxyConnectionResource;
import com.tesora.dve.sql.util.StorageGroupDDL;
import com.tesora.dve.standalone.PETest;
import com.tesora.dve.variables.ScopedVariableHandler;
import com.tesora.dve.variables.ScopedVariables;
import com.tesora.dve.worker.SiteManagerCommand;
public class GroupProviderDDLTest extends SchemaTest {
private static final ProjectDDL checkDDL =
new PEDDL("checkdb",
new StorageGroupDDL("check",1,"checkg"),"schema");
static GroupProviderDDLTest thisTest;
@BeforeClass
public static void setup() throws Exception {
PETest.projectSetup(checkDDL);
PETest.bootHost = BootstrapHost.startServices(PETest.class);
}
private static final String testProviderName = "floyd";
SiteManagerCommand lastPrepare = null;
SiteManagerCommand lastUpdate = null;
SiteManagerCommand lastShow = null;
SiteManagerCommand lastRollback = null;
String lastSetVariableName = null;
String lastSetVariableValue = null;
private ProxyConnectionResource conn = null;
@Before
public void before() throws Throwable {
conn = new ProxyConnectionResource();
checkDDL.create(conn);
thisTest = this;
}
@After
public void after() throws Throwable {
if(conn != null)
conn.disconnect();
conn = null;
thisTest = null;
SiteProviderFactory.deregister(testProviderName);
}
@Test
public void testGroupProviderDDL() throws Throwable {
update("CREATE DYNAMIC SITE PROVIDER " + testProviderName + " USING plugin='" + GroupProviderDDLTestProvider.class.getName() + "' other=1 other.another='ballyfoyle' crop=true",
Command.CREATE, testProviderName,
new Object[] {"other", new Long(1), "other.another", "ballyfoyle", "crop", Boolean.TRUE });
conn.assertResults("show dynamic site providers",
br(nr,"floyd",GroupProviderDDLTestProvider.class.getName(),"YES",
nr,OnPremiseSiteProvider.DEFAULT_NAME, OnPremiseSiteProvider.class.getCanonicalName(), "YES"));
update("ALTER DYNAMIC SITE PROVIDER " + testProviderName + " first='ballyfoyle' second='tinahely' third='paddy'",
Command.ALTER, testProviderName,
new Object[] { "first", "ballyfoyle", "second", "tinahely", "third", "paddy" });
Object[] rollBackOpts = new Object[] { "rollback", Boolean.FALSE, "rollback", Boolean.TRUE };
try {
update("ALTER DYNAMIC SITE PROVIDER " + testProviderName + " rollback=false rollback=true",
Command.ALTER, testProviderName, rollBackOpts);
fail("rollback exception not propagated");
} catch (PEException pe) {
assertPEException(pe, "Test rollback");
assertNotNull(lastRollback);
assertCommandBlock(Command.ALTER, testProviderName, rollBackOpts, lastRollback);
}
show("SHOW DYNAMIC SITE PROVIDER " + testProviderName + " cmd='sites'",
Command.SHOW, testProviderName, new Object[] { "cmd", "sites" });
// variable tests
conn.execute("alter dynamic site provider floyd set tic = 'ticklish'");
assertSetVariable("tic","ticklish");
conn.execute("alter dynamic site provider floyd set tac = 'spackling'");
assertSetVariable("tac","spackling");
conn.assertResults("show dynamic site provider variables floyd",
br(nr,"tac","spackling",
nr,"tic","ticklish"));
conn.assertResults("show dynamic site provider variables",
br(nr,"floyd","tac","spackling",
nr,"floyd","tic","ticklish"));
conn.assertResults("show dynamic site provider variables like '%ac'",
br(nr,"floyd","tac","spackling"));
try {
conn.execute("alter dynamic site provider floyd set dne = 'unknowable'");
} catch (PENotFoundException re) {
assertException(re,PENotFoundException.class,"Variable \"dne\" not found");
}
// make sure we can handle attributes with funny names
conn.execute("alter dynamic site provider floyd cmd='set status' site='inst1' pool='abc' count='15'");
conn.execute("alter dynamic site provider floyd cmd='set status' pool=null");
update("DROP DYNAMIC SITE PROVIDER " + testProviderName,
Command.DROP, testProviderName,
new Object[] {});
conn.assertResults("show dynamic site providers",
br( nr,OnPremiseSiteProvider.DEFAULT_NAME, OnPremiseSiteProvider.class.getCanonicalName(), "YES"));
String sl = PEUrl.stripUrlParameters(TestCatalogHelper.getInstance().getCatalogBaseUrl());
String ops = "OnPremise";
String local = "LOCAL";
Integer negone = new Integer(-1);
Integer zero = new Integer(0);
String n = "ONLINE";
// System.out.println(conn.printResults("show dynamic site providers sites"));
conn.assertResults("show dynamic site providers sites",
br(
nr, ops+"_"+local+"_dyn1", ops, local, "dyn1", sl, negone, zero, zero, n, SchemaTest.getIgnore(),
nr, ops+"_"+local+"_dyn2", ops, local, "dyn2", sl, negone, zero, zero, n, SchemaTest.getIgnore(),
nr, ops+"_"+local+"_dyn3", ops, local, "dyn3", sl, negone, zero, zero, n, SchemaTest.getIgnore(),
nr, ops+"_"+local+"_dyn4", ops, local, "dyn4", sl, negone, zero, zero, n, SchemaTest.getIgnore(),
nr, ops+"_"+local+"_dyn5", ops, local, "dyn5", sl, negone, zero, zero, n, SchemaTest.getIgnore()
));
}
private void clearLast() {
lastPrepare = null;
lastUpdate = null;
lastShow = null;
lastRollback = null;
}
protected void update(String sql, Command action, String providerName,
Object[] opts) throws Throwable {
clearLast();
SchemaTest.echo(conn.printResults(sql));
assertNotNull(lastUpdate);
SchemaTest.echo(" => " + lastUpdate);
assertCommandBlock(action, providerName, opts, lastUpdate);
assertNotNull(lastPrepare);
assertCommandBlock(action, providerName, opts, lastPrepare);
// only clearLast at the beginning - lets us further examine the called state
}
protected void show(String sql, Command action, String providerName, Object[] opts) throws Throwable {
clearLast();
SchemaTest.echo(conn.printResults(sql));
assertNotNull(lastShow);
SchemaTest.echo(" => " + lastShow);
assertCommandBlock(action, providerName, opts, lastShow);
}
// this is our test provider
public static class GroupProviderDDLTestProvider implements SiteProviderPlugin {
// we hold two variables, tic and tac
String tic;
String tac;
boolean isEnabled = true;
public GroupProviderDDLTestProvider() {
}
public String getProviderType()
{
return "GroupProviderDDLTestProvider";
}
@Override
public void initialize(SiteProviderContext ctxt, String name, boolean isEnabled1, String config) {
// TODO Auto-generated method stub
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public void provisionWorkerRequest(SiteProviderContext ctxt, GetWorkerRequest getWorkerRequest) throws PEException {
// TODO Auto-generated method stub
}
@Override
public void returnSitesByClass(SiteProviderContext ctxt, String siteClass, Collection<? extends StorageSite> sites) {
// TODO Auto-generated method stub
}
@Override
public List<CatalogEntity> show(SiteManagerCommand smc)
throws PEException {
thisTest.lastShow = smc;
return Collections.emptyList();
}
@Override
public SiteManagerCommand prepareUpdate(SiteManagerCommand smc)
throws PEException {
thisTest.lastPrepare = smc;
return smc;
}
@Override
public int update(SiteManagerCommand smc) throws PEException {
thisTest.lastUpdate = smc;
for(Pair<String,Object> kv : smc.getOptions()) {
if ("rollback".equals(kv.getFirst()) && Boolean.TRUE.equals(kv.getSecond()))
throw new PEException("Test rollback");
}
return 1;
}
@Override
public void rollback(SiteManagerCommand smc) throws PEException {
thisTest.lastRollback = smc;
}
@Override
public boolean isEnabled() {
return this.isEnabled;
}
@Override
public void setEnabled(boolean isEnabled) throws PEException {
this.isEnabled = isEnabled;
}
@Override
public String getProviderName() {
return this.getClass().getSimpleName();
}
@Override
public ScopedVariables getVariableConfiguration() {
return new ScopedVariables(testProviderName,
new GroupProviderDDLTestVariableHandler("tic",this) {
@Override
public void setValue(String value) throws PEException {
me.tic = value;
thisTest.lastSetVariableName = getName();
thisTest.lastSetVariableValue = value;
}
@Override
public String getValue() throws PEException {
return me.tic;
}
},
new GroupProviderDDLTestVariableHandler("tac",this) {
@Override
public void setValue(String value) throws PEException {
me.tac = value;
thisTest.lastSetVariableName = getName();
thisTest.lastSetVariableValue = value;
}
@Override
public String getValue() throws PEException {
return me.tac;
}
});
}
public abstract class GroupProviderDDLTestVariableHandler extends ScopedVariableHandler {
protected GroupProviderDDLTestProvider me;
public GroupProviderDDLTestVariableHandler(String name, GroupProviderDDLTestProvider enc) {
super(name);
me = enc;
}
}
@Override
public Collection<? extends StorageSite> getAllSites() {
// TODO Auto-generated method stub
return null;
}
}
private static void assertCommandBlock(Command expectedAction, String expectedName,
Object[] expectedOptions, SiteManagerCommand on) throws Throwable {
assertEquals("expected action",expectedAction,on.getAction());
assertEquals("expected provider name",expectedName,on.getTarget().getName());
assertOptions(expectedOptions, on);
}
private static void assertOptions(Object[] in, SiteManagerCommand on) throws Throwable {
List<Pair<String,Object>> opts = new ArrayList<Pair<String,Object>>();
int i = 0;
while(i < in.length) {
String key = (String)in[i];
if ((++i) >= in.length)
throw new Throwable("Missing value for key " + key);
Object value = in[i];
opts.add(new Pair<String,Object>(key,value));
i++;
}
assertEquals("command block should have matching opt size",opts.size(), on.getOptions().size());
for(i = 0; i < opts.size(); i++) {
Pair<String,Object> expected = opts.get(i);
Pair<String,Object> actual = on.getOptions().get(i);
assertEquals("same option should have same key",expected.getFirst(),actual.getFirst());
assertEquals("same option should have same value",expected.getSecond(),actual.getSecond());
}
}
private void assertSetVariable(String varName, String varValue) {
assertEquals("last set variable name should match",varName, lastSetVariableName);
assertEquals("last set variable value should match", varValue, lastSetVariableValue);
}
}