package edu.brown.markov; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Vector; import java.util.Map.Entry; import org.json.JSONObject; import org.junit.Test; import org.voltdb.VoltProcedure; import org.voltdb.benchmark.tpcc.procedures.neworder; import org.voltdb.catalog.Procedure; import weka.core.Instances; import edu.brown.BaseTestCase; import edu.brown.markov.FeatureSet.Type; import edu.brown.markov.features.AbstractFeature; import edu.brown.markov.features.BasePartitionFeature; import edu.brown.markov.features.ParamArrayLengthFeature; import edu.brown.markov.features.ParamHashEqualsBasePartitionFeature; import edu.brown.statistics.Histogram; import edu.brown.statistics.ObjectHistogram; import edu.brown.utils.CollectionUtil; import edu.brown.utils.ProjectType; import edu.brown.workload.TransactionTrace; import edu.brown.workload.Workload; import edu.brown.workload.filters.Filter; import edu.brown.workload.filters.ProcedureLimitFilter; import edu.brown.workload.filters.ProcedureNameFilter; public class TestFeatureSet extends BaseTestCase { private static final Class<? extends VoltProcedure> TARGET_PROCEDURE = neworder.class; private static final int WORKLOAD_XACT_LIMIT = 10; private static Workload workload; private Procedure catalog_proc; private final Random rand = new Random(); private FeatureSet fset; private TransactionTrace txn_trace; @Override protected void setUp() throws Exception { super.setUp(ProjectType.TPCC); if (workload == null) { File file = this.getWorkloadFile(ProjectType.TPCC); workload = new Workload(catalog); Filter filter = new ProcedureNameFilter(false).include(TARGET_PROCEDURE.getSimpleName()) .attach(new ProcedureLimitFilter(WORKLOAD_XACT_LIMIT)); workload.load(file, catalog_db, filter); } this.catalog_proc = this.getProcedure(TARGET_PROCEDURE); this.fset = new FeatureSet(); this.txn_trace = CollectionUtil.first(workload.getTransactions()); } /** * testAddFeature */ @Test public void testAddFeature() throws Exception { List<String> orig_keys = new ArrayList<String>(); orig_keys.add("KEY1"); orig_keys.add("KEY2"); orig_keys.add("KEY3"); for (String k : orig_keys) { Integer val = rand.nextInt(); this.fset.addFeature(this.txn_trace, k, val); } // FOR List<String> features = fset.getFeatures(); assert(features.isEmpty() == false); assertEquals(orig_keys.size(), features.size()); assertEquals(orig_keys, features); } /** * testExport */ @Test public void testExport() throws Exception { List<String> orig_keys = new ArrayList<String>(); orig_keys.add("KEY1"); orig_keys.add("KEY2"); orig_keys.add("KEY3"); for (String k : orig_keys) { Integer val = rand.nextInt(); this.fset.addFeature(this.txn_trace, k, val); } // FOR Instances data = this.fset.export(TARGET_PROCEDURE.getSimpleName()); assertNotNull(data); String contents = data.toString(); assertNotNull(contents); assertFalse(contents.isEmpty()); for (String k : orig_keys) { assert(contents.contains(k)); } } /** * testAddBooleanFeature */ @Test public void testAddBooleanFeature() { Object values[] = { true, false, new Boolean(true) }; for (int i = 0; i < values.length; i++) { String key = "KEY" + i; this.fset.addFeature(this.txn_trace, key, values[i]); } // FOR for (int i = 0; i < values.length; i++) { String key = "KEY" + i; assertEquals(FeatureSet.Type.BOOLEAN, this.fset.getFeatureType(key)); } } /** * testAddNumericFeature */ @Test public void testAddNumericFeature() { Object values[] = { 1.0d, 1l, 1 }; for (int i = 0; i < values.length; i++) { String key = "KEY" + i; this.fset.addFeature(this.txn_trace, key, values[i]); } // FOR for (int i = 0; i < values.length; i++) { String key = "KEY" + i; assertEquals(FeatureSet.Type.NUMERIC, this.fset.getFeatureType(key)); } // FOR } /** * testSerialization */ @Test public void testSerialization() throws Exception { AbstractFeature features[] = new AbstractFeature[] { new BasePartitionFeature(p_estimator, catalog_proc), new ParamArrayLengthFeature(p_estimator, catalog_proc), new ParamHashEqualsBasePartitionFeature(p_estimator, catalog_proc), }; for (TransactionTrace txn_trace : workload.getTransactions()) { for (AbstractFeature f : features) { f.extract(this.fset, txn_trace); } // FOR } // FOR String json = this.fset.toJSONString(); assertNotNull(json); assertFalse(json.isEmpty()); // System.err.println(JSONUtil.format(json)); FeatureSet clone = new FeatureSet(); clone.fromJSON(new JSONObject(json), catalog_db); for (Entry<String, Type> e : this.fset.attributes.entrySet()) { assertEquals(e.getKey(), e.getValue(), clone.attributes.get(e.getKey())); } // FOR for (Entry<String, ObjectHistogram> e : this.fset.attribute_histograms.entrySet()) { ObjectHistogram<?> clone_h = clone.attribute_histograms.get(e.getKey()); // System.err.println(e.getValue()); // System.err.println(); // System.err.println(clone_h.isEmpty() ? "<EMPTY>" : clone_h.toString()); // // System.err.println("\nEQUALS = " + e.getValue().equals(clone_h)); // System.err.println("-------------------------------------------\n"); // // for (Object o : e.getValue().values()) { // System.err.println("ORIG " + o + ": " + o.getClass()); // } // for (Object o : clone_h.values()) { // System.err.println("CLONE " + o + ": " + o.getClass()); // } assertEquals(e.getKey(), e.getValue(), clone_h); } // FOR for (Entry<Long, Vector<Object>> e : this.fset.txn_values.entrySet()) { Vector<Object> clone_v = clone.txn_values.get(e.getKey()); assertNotNull(e.getKey().toString(), clone_v); assertEquals(e.getValue().size(), clone_v.size()); // System.err.println("ORIG: " + e.getValue()); // System.err.println("CLONE: " + clone_v); assert(e.getValue().containsAll(clone_v)); } // FOR assertEquals(this.fset.last_num_attributes, clone.last_num_attributes); } }