package org.voltdb.regressionsuites;
import java.util.concurrent.CountDownLatch;
import junit.framework.Test;
import org.voltdb.BackendTarget;
import org.voltdb.CatalogContext;
import org.voltdb.StoredProcedureInvocationHints;
import org.voltdb.VoltSystemProcedure;
import org.voltdb.VoltTable;
import org.voltdb.benchmark.tpcc.TPCCConstants;
import org.voltdb.benchmark.tpcc.TPCCProjectBuilder;
import org.voltdb.benchmark.tpcc.procedures.neworder;
import org.voltdb.client.Client;
import org.voltdb.client.ClientResponse;
import org.voltdb.client.ProcedureCallback;
import org.voltdb.sysprocs.AdHoc;
import edu.brown.hstore.Hstoreservice.Status;
/**
* Simple test suite for HStoreSite features
* @author pavlo
*/
public class TestHStoreSiteSuite extends RegressionSuite {
private static final String PREFIX = "hstoresite";
private static final double SCALEFACTOR = 0.001;
private static final int NUM_WAREHOUSES = 4;
private static final int WAREHOUSE_ID = 1;
private static final int DISTRICT_ID = 1;
/**
* Constructor needed for JUnit. Should just pass on parameters to superclass.
* @param name The name of the method to test. This is just passed to the superclass.
*/
public TestHStoreSiteSuite(String name) {
super(name);
}
private void executeTestWorkload(Client client) throws Exception {
RegressionSuiteUtil.initializeTPCCDatabase(this.getCatalogContext(), client);
Object params[] = RegressionSuiteUtil.generateNewOrder(NUM_WAREHOUSES, false, WAREHOUSE_ID, DISTRICT_ID);
String procName = neworder.class.getSimpleName();
ClientResponse cresponse = client.callProcedure(procName, params);
assertNotNull(cresponse);
assertEquals(Status.OK, cresponse.getStatus());
}
/**
* testAdHocSQL
*/
public void testAdHocSQL() throws Exception {
// This was originally from org.voltdb.TestAdHocQueries
Client client = this.getClient();
String procName = VoltSystemProcedure.procCallName(AdHoc.class);
ClientResponse cr;
cr = client.callProcedure(procName, "INSERT INTO NEW_ORDER VALUES (1, 1, 1);");
VoltTable modCount = cr.getResults()[0];
assertTrue(modCount.getRowCount() == 1);
assertTrue(modCount.asScalarLong() == 1);
cr = client.callProcedure(procName, "SELECT * FROM NEW_ORDER;");
VoltTable result = cr.getResults()[0];
assertTrue(result.getRowCount() == 1);
// System.out.println(result.toString());
boolean caught = false;
try {
client.callProcedure("@AdHoc", "SLEECT * FROOM NEEEW_OOORDERERER;");
} catch (Exception e) {
caught = true;
}
assertTrue("Bad SQL failed to throw expected exception", caught);
}
/**
* testTransactionRedirect
*/
public void testTransactionRedirect() throws Exception {
CatalogContext catalogContext = this.getCatalogContext();
if (catalogContext.numberOfPartitions == 1) return;
// TODO
}
/**
* testNetworkThreadInitialization
*/
public void testNetworkThreadInitialization() throws Exception {
// Test transaction execution where the network processing threads are
// responsible for initializing the transactions.
Client client = this.getClient();
// RegressionSuiteUtil.setHStoreConf(client, "site.network_txn_initialization", true);
this.executeTestWorkload(client);
}
/**
* testStoredProcedureInvocationHints
*/
public void testStoredProcedureInvocationHints() throws Exception {
CatalogContext catalogContext = this.getCatalogContext();
Client client = this.getClient();
RegressionSuiteUtil.initializeTPCCDatabase(catalogContext, client, true);
final int repeat = 100;
final StoredProcedureInvocationHints hints = new StoredProcedureInvocationHints();
final ProcedureCallback callbacks[] = new ProcedureCallback[catalogContext.numberOfPartitions];
final CountDownLatch latch = new CountDownLatch(catalogContext.numberOfPartitions * repeat);
for (int p = 0; p < catalogContext.numberOfPartitions; p++) {
final int partition = p;
callbacks[p] = new ProcedureCallback() {
@Override
public void clientCallback(ClientResponse cresponse) {
assertEquals(Status.OK, cresponse.getStatus());
assertEquals(partition, cresponse.getBasePartition());
latch.countDown();
}
};
} // FOR
for (int i = 0; i < 100; i++) {
for (int p = 0; p < catalogContext.numberOfPartitions; p++) {
hints.basePartition = p;
// Once with a callback
client.callProcedure(callbacks[p], "GetItem", hints, 1);
// And once without a callback
ClientResponse cresponse = client.callProcedure("GetItem", hints, 1);
assertNotNull(cresponse);
assertEquals(Status.OK, cresponse.getStatus());
assertEquals(p, cresponse.getBasePartition());
} // FOR
} // FOR
latch.await();
}
public static Test suite() {
VoltServerConfig config = null;
// the suite made here will all be using the tests from this class
MultiConfigSuiteBuilder builder = new MultiConfigSuiteBuilder(TestHStoreSiteSuite.class);
builder.setGlobalConfParameter("client.scalefactor", SCALEFACTOR);
// build up a project builder for the TPC-C app
TPCCProjectBuilder project = new TPCCProjectBuilder();
project.addAllDefaults();
project.addStmtProcedure("GetItem", "SELECT * FROM " + TPCCConstants.TABLENAME_ITEM + " WHERE I_ID = ?");
boolean success;
/////////////////////////////////////////////////////////////
// CONFIG #1: 1 Local Site/Partition
/////////////////////////////////////////////////////////////
config = new LocalSingleProcessServer(PREFIX + "-1part.jar", 1, BackendTarget.NATIVE_EE_JNI);
success = config.compile(project);
assert(success);
builder.addServerConfig(config);
/////////////////////////////////////////////////////////////
// CONFIG #2: 1 Local Site with 2 Partitions running on JNI backend
/////////////////////////////////////////////////////////////
config = new LocalSingleProcessServer(PREFIX + "-2part.jar", 2, BackendTarget.NATIVE_EE_JNI);
success = config.compile(project);
assert(success);
builder.addServerConfig(config);
////////////////////////////////////////////////////////////
// CONFIG #3: cluster of 2 nodes running 2 site each, one replica
////////////////////////////////////////////////////////////
config = new LocalCluster(PREFIX + "-cluster.jar", 2, 2, 1, BackendTarget.NATIVE_EE_JNI);
success = config.compile(project);
assert(success);
builder.addServerConfig(config);
return builder;
}
}