Package org.voltdb.regressionsuites

Source Code of org.voltdb.regressionsuites.TestAntiCacheSuite

package org.voltdb.regressionsuites;

import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import junit.framework.Test;

import org.voltdb.BackendTarget;
import org.voltdb.CatalogContext;
import org.voltdb.SysProcSelector;
import org.voltdb.VoltSystemProcedure;
import org.voltdb.VoltTable;
import org.voltdb.client.Client;
import org.voltdb.client.ClientResponse;
import org.voltdb.sysprocs.AdHoc;
import org.voltdb.sysprocs.EvictHistory;
import org.voltdb.sysprocs.EvictTuples;
import org.voltdb.sysprocs.EvictedAccessHistory;
import org.voltdb.sysprocs.Statistics;
import org.voltdb.utils.VoltTableUtil;

import edu.brown.HStoreSiteTestUtil.LatchableProcedureCallback;
import edu.brown.benchmark.voter.VoterConstants;
import edu.brown.benchmark.voter.VoterProjectBuilder;
import edu.brown.benchmark.voter.procedures.Initialize;
import edu.brown.benchmark.voter.procedures.Vote;
import edu.brown.hstore.Hstoreservice.Status;
import edu.brown.profilers.AntiCacheManagerProfiler;
import edu.brown.utils.StringUtil;

/**
* Anti-Caching Test Suite
* @author pavlo
*/
public class TestAntiCacheSuite extends RegressionSuite {

    private static final String PREFIX = "anticache";
    private static final int NOTIFY_TIMEOUT = 2000; // ms
    private static final int NUM_VOTES = 100;

    private int readBackTracker;
   
    /**
     * 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 TestAntiCacheSuite(String name) {
        super(name);
    }
   
    // --------------------------------------------------------------------------------------------
    // UTILITY METHODS
    // --------------------------------------------------------------------------------------------
   
    private void initializeDatabase(Client client) throws Exception {
//        System.err.println("Initializing ...");
        Object params[] = {
            VoterConstants.NUM_CONTESTANTS,
            VoterConstants.CONTESTANT_NAMES_CSV
        };
       
        ClientResponse cresponse = client.callProcedure(Initialize.class.getSimpleName(), params);
        assertNotNull(cresponse);
        assertEquals(Status.OK, cresponse.getStatus());
//        System.err.println("done.");
    }
   
    private void loadVotes(Client client, int num_txns) throws Exception {
       
//        System.err.println("Loading data...");
       
        LatchableProcedureCallback callback = new LatchableProcedureCallback(num_txns);
        for (int i = 0; i < num_txns; i++) {
            Object params[] = { new Long(i),
                                TestVoterSuite.phoneNumber+i,
                                TestVoterSuite.contestantNumber,
                                num_txns+1 }
            client.callProcedure(callback, Vote.class.getSimpleName(), params);
        } // FOR

        // Wait until they all finish
        boolean result = callback.latch.await(NOTIFY_TIMEOUT, TimeUnit.MILLISECONDS);
        assertTrue(callback.toString(), result);
        for (ClientResponse cr : callback.responses) {
            assertEquals(cr.toString(), Status.OK, cr.getStatus());
        }
       
        // Make sure that our vote is actually in the real table and materialized views
        String query = "SELECT COUNT(*) FROM votes";
        String procName = VoltSystemProcedure.procCallName(AdHoc.class);
        ClientResponse cresponse = client.callProcedure(procName, query);
        assertEquals(Status.OK, cresponse.getStatus());
        VoltTable results[] = cresponse.getResults();
        assertEquals(1, results.length);
        assertEquals(num_txns, results[0].asScalarLong());
//        System.err.println("Finished Loading Data.");
    }
   
    private Map<Integer, VoltTable> evictData(Client client) throws Exception {
//        System.err.printf("Evicting data...");
        String procName = VoltSystemProcedure.procCallName(EvictTuples.class);
        CatalogContext catalogContext = this.getCatalogContext();
        String tableNames[] = { VoterConstants.TABLENAME_VOTES };
        LatchableProcedureCallback callback = new LatchableProcedureCallback(catalogContext.numberOfPartitions);
//        long evictBytes[] = { Integer.MAX_VALUE };
        long evictBytes[] = {10000};
        int numBlocks[] = { 1 };
        for (int partition : catalogContext.getAllPartitionIds()) {
//            System.err.printf("Evicting data at partition %d...\n", partition);
          String children[] = null;
            Object params[] = { partition, tableNames, children, evictBytes, numBlocks };
            boolean result = client.callProcedure(callback, procName, params);
            assertTrue(result);
        } // FOR
       
        // Wait until they all finish
        boolean result = callback.latch.await(NOTIFY_TIMEOUT, TimeUnit.MILLISECONDS);
        assertTrue(callback.toString(), result);
       
        // Construct a mapping BasePartition->VoltTable
        Map<Integer, VoltTable> m = new TreeMap<Integer, VoltTable>();
        for (ClientResponse cr : callback.responses) {
            assertEquals(cr.toString(), Status.OK, cr.getStatus());
            assertEquals(cr.toString(), 1, cr.getResults().length);
            m.put(cr.getBasePartition(), cr.getResults()[0]);
        } // FOR
        assertEquals(catalogContext.numberOfPartitions, m.size());
//        System.err.printf("Finished evicting data.");
        return (m);
    }
   
   
    private void checkEvictedAccess(String procName, Object params[], int expected) throws Exception {
        Client client = this.getClient();
        this.initializeDatabase(client);
        this.loadVotes(client, NUM_VOTES);
        int num_evicts = 5;
        for (int i = 0; i < num_evicts; i++) {
            this.evictData(client);
        } // FOR
       
        // Now force the system to fetch the block back in
        // long expected = 1;
        ClientResponse cresponse = client.callProcedure(procName, params);
        assertEquals(cresponse.toString(), Status.OK, cresponse.getStatus());
        assertEquals(cresponse.toString(), 1, cresponse.getResults().length);
        VoltTable result = cresponse.getResults()[0];
        // result.advanceRow();
        // assertEquals(cresponse.toString(), expected, result.getRowCount());
       
        // Our stats should now come back with one evicted access
        cresponse = client.callProcedure(VoltSystemProcedure.procCallName(EvictedAccessHistory.class));
        assertEquals(cresponse.toString(), Status.OK, cresponse.getStatus());
        assertEquals(cresponse.toString(), 1, cresponse.getResults().length);
        result = cresponse.getResults()[0];
        // assertEquals(1, result.getRowCount());
        System.err.println(VoltTableUtil.format(result));
       
        while (result.advanceRow()) {
            assertEquals(procName, result.getString("PROCEDURE"));
        } // WHILE       
    }
   
    // --------------------------------------------------------------------------------------------
    // TEST CASES
    // --------------------------------------------------------------------------------------------
   
   
    /**
     * testEvictEmptyTable
     */
    public void testEvictEmptyTable() throws Exception {
        Client client = this.getClient();
        this.initializeDatabase(client);
               
        // Force an eviction on a table before putting anything in it
        Map<Integer, VoltTable> evictResults = this.evictData(client);
        System.err.println(StringUtil.formatMaps(evictResults));
        System.err.println("-------------------------------");
    }
   
    /**
     * testProfiling
     */
    public void testProfiling() throws Exception {
        Client client = this.getClient();
        this.initializeDatabase(client);
        this.loadVotes(client, 100);

        // Force an eviction
        Map<Integer, VoltTable> evictResults = this.evictData(client);
        for (int partition : evictResults.keySet()) {
            System.err.println("Partition " + partition);
            System.err.println(StringUtil.prefix("  ", VoltTableUtil.format(evictResults.get(partition))));
        }
        System.err.println("-------------------------------");

        // Our stats should now come back with one eviction executed
        String procName = VoltSystemProcedure.procCallName(Statistics.class);
        Object params[] = { SysProcSelector.ANTICACHE.name(), 0 };
        ClientResponse cresponse = client.callProcedure(procName, params);
        assertEquals(cresponse.toString(), Status.OK, cresponse.getStatus());
        assertEquals(cresponse.toString(), 1, cresponse.getResults().length);
        VoltTable statsResult = cresponse.getResults()[0];

        System.err.println(VoltTableUtil.format(statsResult));

        // We need this just to get the name of the column
        AntiCacheManagerProfiler profiler = new AntiCacheManagerProfiler();
        String colName = profiler.eviction_time.getName().toUpperCase()+"_CNT";
        while (statsResult.advanceRow()) {
            System.err.println("colName: " + colName);
            int partition = (int)statsResult.getLong("PARTITION");
            VoltTable vt = evictResults.get(partition);
            boolean adv = vt.advanceRow();
            assert(adv);
            long expected = vt.getLong("ANTICACHE_BLOCKS_EVICTED");
            assertEquals("Partition "+partition, expected, statsResult.getLong(colName));
        } // WHILE
    }

    /**
     * testEvictHistory
     */
    public void testEvictHistory() throws Exception {
        CatalogContext catalogContext = this.getCatalogContext();
        Client client = this.getClient();
        this.initializeDatabase(client);
        this.loadVotes(client, 100);
        int num_evicts = 5;
        for (int i = 0; i < num_evicts; i++) {
            this.evictData(client);
        } // FOR
       
        // Our stats should now come back with one eviction executed
        String procName = VoltSystemProcedure.procCallName(EvictHistory.class);
        ClientResponse cresponse = client.callProcedure(procName);
        assertEquals(cresponse.toString(), Status.OK, cresponse.getStatus());
        assertEquals(cresponse.toString(), 1, cresponse.getResults().length);
        VoltTable result = cresponse.getResults()[0];
        assertEquals(num_evicts * catalogContext.numberOfPartitions, result.getRowCount());
        System.err.println(VoltTableUtil.format(result));
       
        while (result.advanceRow()) {
            long start = result.getLong("START");
            long stop = result.getLong("STOP");
            assert(start <= stop) : start + " <= " + stop;
        } // WHILE
    }
   
    /**
     * testEvictedAccessSeqScan
     */
    public void testEvictedAccessSeqScan() throws Exception {
        // Object params[] = { };
        // FIXME this.checkEvictedAccess("GetAllVotes", params, NUM_VOTES);
    }
   
    /**
     * testEvictedAccessIndexScan
     */
    public void testEvictedAccessIndexScan() throws Exception {
        Object params[] = { 1 };
        this.checkEvictedAccess("GetVote", params, 1);
    }
   
    /**
     * testEvictedAccessIndexJoin
     */
    public void testEvictedAccessIndexJoin() throws Exception {
        Object params[] = { 1 };
        this.checkEvictedAccess("GetVoteJoin", params, 1);
    }

    public static Test suite() {
        VoltServerConfig config = null;
        // the suite made here will all be using the tests from this class
        MultiConfigSuiteBuilder builder = new MultiConfigSuiteBuilder(TestAntiCacheSuite.class);
        builder.setGlobalConfParameter("site.exec_voltdb_procinfo", true);
        builder.setGlobalConfParameter("site.anticache_enable", true);
        builder.setGlobalConfParameter("site.anticache_profiling", true);
        builder.setGlobalConfParameter("site.anticache_reset", true);
        builder.setGlobalConfParameter("site.anticache_check_interval", Integer.MAX_VALUE);
        builder.setGlobalConfParameter("site.anticache_batching", false);

        // build up a project builder for the TPC-C app
        VoterProjectBuilder project = new VoterProjectBuilder();
        project.addAllDefaults();
        project.markTableEvictable(VoterConstants.TABLENAME_VOTES);
        project.markTableEvictable(VoterConstants.TABLENAME_CONTESTANTS);
        project.addStmtProcedure("GetVote",
                                 "SELECT * FROM " + VoterConstants.TABLENAME_VOTES + " WHERE vote_id = ?");
        project.addStmtProcedure("GetAllVotes",
                                 "SELECT * FROM " + VoterConstants.TABLENAME_VOTES);
        project.addStmtProcedure("GetVoteJoin",
                String.format("SELECT phone_number, contestant_number FROM %s, %s " +
                              " WHERE vote_id = ? " +
                              "   AND %s.contestant_number = %s.contestant_number",
                              VoterConstants.TABLENAME_VOTES, VoterConstants.TABLENAME_CONTESTANTS,
                              VoterConstants.TABLENAME_VOTES, VoterConstants.TABLENAME_CONTESTANTS));
       
        boolean success;
       
        /////////////////////////////////////////////////////////////
        // CONFIG #1: 1 Local Site/Partition running on JNI backend
        /////////////////////////////////////////////////////////////
        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;
    }

}
TOP

Related Classes of org.voltdb.regressionsuites.TestAntiCacheSuite

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.