Package org.voltdb.regressionsuites

Source Code of org.voltdb.regressionsuites.TestSystemProcedureSuite

/* This file is part of VoltDB.
* Copyright (C) 2008-2014 VoltDB Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package org.voltdb.regressionsuites;

import java.io.IOException;
import java.util.Random;

import junit.framework.Test;

import org.voltdb.BackendTarget;
import org.voltdb.VoltTable;
import org.voltdb.VoltType;
import org.voltdb.client.Client;
import org.voltdb.client.ClientResponse;
import org.voltdb.client.NoConnectionsException;
import org.voltdb.client.NullCallback;
import org.voltdb.client.ProcCallException;
import org.voltdb.compiler.VoltProjectBuilder;
import org.voltdb.utils.MiscUtils;
import org.voltdb_testprocs.regressionsuites.malicious.GoSleep;

public class TestSystemProcedureSuite extends RegressionSuite {

    private static int SITES = 3;
    private static int HOSTS = MiscUtils.isPro() ? 2 : 1;
    private static int KFACTOR = MiscUtils.isPro() ? 1 : 0;
    private static boolean hasLocalServer = false;

    static final Class<?>[] PROCEDURES =
    {
     GoSleep.class
    };

    public TestSystemProcedureSuite(String name) {
        super(name);
    }

    public void testPing() throws IOException, ProcCallException {
        Client client = getClient();
        ClientResponse cr = client.callProcedure("@Ping");
        assertEquals(ClientResponse.SUCCESS, cr.getStatus());
    }

    private void checkProSysprocError(Client client, String name, int paramCount)
            throws NoConnectionsException, IOException
    {
        // make some dummy params... real ones aren't needed for this test
        Object[] params = new Object[paramCount];
        for (int i = 0; i < paramCount; i++) {
            params[i] = i;
        }

        try {
            client.callProcedure(name, params);
            fail();
        }
        catch (ProcCallException e) {
            assertEquals(ClientResponse.GRACEFUL_FAILURE, e.getClientResponse().getStatus());
            if (!e.getClientResponse().getStatusString().contains("Enterprise Edition")) {
                System.out.println("sup");
                System.out.println("MESSAGE: " + e.getClientResponse().getStatusString());
            }
            assertTrue(e.getClientResponse().getStatusString().contains("Enterprise"));
        }
    }

    public void testProSysprocErrorOnCommunity() throws Exception {
        // this test only applies to community edition
        if (MiscUtils.isPro()) {
            return;
        }

        Client client = getClient();

        checkProSysprocError(client, "@SnapshotSave", 3);
        checkProSysprocError(client, "@SnapshotRestore", 2);
        checkProSysprocError(client, "@SnapshotStatus", 0);
        checkProSysprocError(client, "@SnapshotScan", 2);
        checkProSysprocError(client, "@SnapshotDelete", 2);
        // Turns out we don't flag @Promote as enterprise.  Not touching that right now. --izzy
        //checkProSysprocError(client, "@Promote", 0);
    }

    public void testInvalidProcedureName() throws IOException {
        Client client = getClient();
        try {
            client.callProcedure("@SomeInvalidSysProcName", "1", "2");
        }
        catch (Exception e2) {
            assertEquals("Procedure @SomeInvalidSysProcName was not found", e2.getMessage());
            return;
        }
        fail("Expected exception.");
    }

    private final String m_loggingConfig =
        "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" +
        "<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">" +
        "<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\">" +
            "<appender name=\"Console\" class=\"org.apache.log4j.ConsoleAppender\">" +
                "<param name=\"Target\" value=\"System.out\" />" +
                "<layout class=\"org.apache.log4j.TTCCLayout\">" +
                "</layout>" +
            "</appender>" +
            "<appender name=\"Async\" class=\"org.apache.log4j.AsyncAppender\">" +
                "<param name=\"Blocking\" value=\"true\" />" +
                "<appender-ref ref=\"Console\" /> " +
            "</appender>" +
            "<root>" +
               "<priority value=\"info\" />" +
               "<appender-ref ref=\"Async\" />" +
            "</root>" +
        "</log4j:configuration>";

    public void testUpdateLogging() throws Exception {
        Client client = getClient();
        VoltTable results[] = null;
        results = client.callProcedure("@UpdateLogging", m_loggingConfig).getResults();
        for (VoltTable result : results) {
            assertEquals( 0, result.asScalarLong());
        }
    }

    public void testPromoteMaster() throws Exception {
        Client client = getClient();
        try {
            client.callProcedure("@Promote");
            fail();
        }
        catch (ProcCallException pce) {
            assertEquals(ClientResponse.GRACEFUL_FAILURE, pce.getClientResponse().getStatus());
        }
    }

    // Pretty lame test but at least invoke the procedure.
    // "@Quiesce" is used more meaningfully in TestExportSuite.
    public void testQuiesce() throws IOException, ProcCallException {
        Client client = getClient();
        VoltTable results[] = client.callProcedure("@Quiesce").getResults();
        assertEquals(1, results.length);
        results[0].advanceRow();
        assertEquals(results[0].get(0, VoltType.BIGINT), new Long(0));
    }

    public void testLoadMultipartitionTableAndIndexStatsAndValidatePartitioning() throws Exception {
        Client client = getClient();

        /*
         * Load a little partitioned data for the mispartitioned check
         */
        Random r = new Random(0);
        for (int ii = 0; ii < 50; ii++) {
            client.callProcedure(new NullCallback(), "@AdHoc",
                    "INSERT INTO new_order values (" + (short)(r.nextDouble() * Short.MAX_VALUE) + ");");
        }

        // try the failure case first
        try {
            client.callProcedure("@LoadMultipartitionTable", "DOES_NOT_EXIST", null, 1);
            fail();
        } catch (ProcCallException ex) {}

        // make a TPCC warehouse table
        VoltTable partitioned_table = new VoltTable(
                new VoltTable.ColumnInfo("W_ID", org.voltdb.VoltType.SMALLINT),
                new VoltTable.ColumnInfo("W_NAME", org.voltdb.VoltType.get((byte)9)),
                new VoltTable.ColumnInfo("W_STREET_1", org.voltdb.VoltType.get((byte)9)),
                new VoltTable.ColumnInfo("W_STREET_2", org.voltdb.VoltType.get((byte)9)),
                new VoltTable.ColumnInfo("W_CITY", org.voltdb.VoltType.get((byte)9)),
                new VoltTable.ColumnInfo("W_STATE", org.voltdb.VoltType.get((byte)9)),
                new VoltTable.ColumnInfo("W_ZIP", org.voltdb.VoltType.get((byte)9)),
                new VoltTable.ColumnInfo("W_TAX",org.voltdb.VoltType.get((byte)8)),
                new VoltTable.ColumnInfo("W_YTD", org.voltdb.VoltType.get((byte)8))
        );

        for (int i = 1; i < 21; i++) {
            Object[] row = new Object[] {new Short((short) i),
                                         "name_" + i,
                                         "street1_" + i,
                                         "street2_" + i,
                                         "city_" + i,
                                         "ma",
                                         "zip_"  + i,
                                         new Double(i),
                                         new Double(i)};
            partitioned_table.addRow(row);
        }

        // make a TPCC item table
        VoltTable replicated_table =
            new VoltTable(new VoltTable.ColumnInfo("I_ID", VoltType.INTEGER),
                          new VoltTable.ColumnInfo("I_IM_ID", VoltType.INTEGER),
                          new VoltTable.ColumnInfo("I_NAME", VoltType.STRING),
                          new VoltTable.ColumnInfo("I_PRICE", VoltType.FLOAT),
                          new VoltTable.ColumnInfo("I_DATA", VoltType.STRING));

        for (int i = 1; i < 21; i++) {
            Object[] row = new Object[] {i,
                                         i,
                                         "name_" + i,
                                         new Double(i),
                                         "data_"  + i};

            replicated_table.addRow(row);
        }

        try {
            try {
                client.callProcedure("@LoadMultipartitionTable", "WAREHOUSE",
                                 partitioned_table);
                fail();
            } catch (ProcCallException e) {}
            client.callProcedure("@LoadMultipartitionTable", "ITEM",
                                 replicated_table);

            // 20 rows per site for the replicated table.  Wait for it...
            int rowcount = 0;
            VoltTable results[] = client.callProcedure("@Statistics", "table", 0).getResults();
            while (rowcount != (20 * SITES * HOSTS)) {
                rowcount = 0;
                results = client.callProcedure("@Statistics", "table", 0).getResults();
                // Check that tables loaded correctly
                while(results[0].advanceRow()) {
                    if (results[0].getString("TABLE_NAME").equals("ITEM"))
                    {
                        rowcount += results[0].getLong("TUPLE_COUNT");
                    }
                }
            }

            System.out.println(results[0]);

            // Check that tables loaded correctly
            int foundItem = 0;
            results = client.callProcedure("@Statistics", "table", 0).getResults();
            while(results[0].advanceRow()) {
                if (results[0].getString("TABLE_NAME").equals("ITEM"))
                {
                    ++foundItem;
                    //Different values depending on local cluster vs. single process hence ||
                    assertEquals(20, results[0].getLong("TUPLE_COUNT"));
                }
            }
            assertEquals(MiscUtils.isPro() ? 6 : 3, foundItem);

            // Table finally loaded fully should mean that index is okay on first read.
            VoltTable indexStats =
                    client.callProcedure("@Statistics", "INDEX", 0).getResults()[0];
            System.out.println(indexStats);
            long memorySum = 0;
            while (indexStats.advanceRow()) {
                memorySum += indexStats.getLong("MEMORY_ESTIMATE");
            }

            /*
             * It takes about a minute to spin through this 1000 times.
             * Should definitely give a 1 second tick time to fire
             */
            long indexMemorySum = 0;
            for (int ii = 0; ii < 1000; ii++) {
                indexMemorySum = 0;
                indexStats = client.callProcedure("@Statistics", "MEMORY", 0).getResults()[0];
                System.out.println(indexStats);
                while (indexStats.advanceRow()) {
                    indexMemorySum += indexStats.getLong("INDEXMEMORY");
                }
                boolean success = indexMemorySum != 120;//That is a row count, not memory usage
                if (success) {
                    success = memorySum == indexMemorySum;
                    if (success) {
                        break;
                    }
                }
                Thread.sleep(1);
            }
            assertTrue(indexMemorySum != 120);//That is a row count, not memory usage
            assertEquals(memorySum, indexMemorySum);

            /*
             * Test once using the current correct hash function,
             * expect no mispartitioned rows
             */
            ClientResponse cr = client.callProcedure("@ValidatePartitioning", 0, null);

            VoltTable hashinatorMatches = cr.getResults()[1];
            while (hashinatorMatches.advanceRow()) {
                assertEquals(1L, hashinatorMatches.getLong("HASHINATOR_MATCHES"));
            }

            VoltTable validateResult = cr.getResults()[0];
            System.out.println(validateResult);
            while (validateResult.advanceRow()) {
                assertEquals(0L, validateResult.getLong("MISPARTITIONED_ROWS"));
            }

            /*
             * Test again with a bad hash function, expect mispartitioned rows
             */
            cr = client.callProcedure("@ValidatePartitioning", 0, new byte[] { 0, 0, 0, 9 });

            hashinatorMatches = cr.getResults()[1];
            while (hashinatorMatches.advanceRow()) {
                assertEquals(0L, hashinatorMatches.getLong("HASHINATOR_MATCHES"));
            }

            validateResult = cr.getResults()[0];
            System.out.println(validateResult);
            while (validateResult.advanceRow()) {
                if (validateResult.getString("TABLE").equals("NEW_ORDER")) {
                    assertTrue(validateResult.getLong("MISPARTITIONED_ROWS") > 0);
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    // verify that these commands don't blow up
    public void testProfCtl() throws Exception {
        Client client = getClient();

        //
        // SAMPLER_START
        //
        ClientResponse resp = client.callProcedure("@ProfCtl", "SAMPLER_START");
        VoltTable vt = resp.getResults()[0];
        boolean foundResponse = false;
        while (vt.advanceRow()) {
            if (!vt.getString("Result").equalsIgnoreCase("sampler_start")) {
                fail();
            }
            foundResponse = true;
        }
        assertTrue(foundResponse);

        //
        // GPERF_ENABLE
        //
        resp = client.callProcedure("@ProfCtl", "GPERF_ENABLE");
        vt = resp.getResults()[0];
        foundResponse = false;
        while (vt.advanceRow()) {
            if (vt.getString("Result").equalsIgnoreCase("GPERF_ENABLE")) {
                foundResponse = true;
            }
            else {
                assertTrue(vt.getString("Result").equalsIgnoreCase("GPERF_NOOP"));
            }
        }
        assertTrue(foundResponse);

        //
        // GPERF_DISABLE
        //
        resp = client.callProcedure("@ProfCtl", "GPERF_DISABLE");
        vt = resp.getResults()[0];
        foundResponse = false;
        while (vt.advanceRow()) {
            if (vt.getString("Result").equalsIgnoreCase("gperf_disable")) {
                foundResponse = true;
            }
            else {
                assertTrue(vt.getString("Result").equalsIgnoreCase("GPERF_NOOP"));
            }
        }
        assertTrue(foundResponse);

        //
        // garbage
        //
        resp = client.callProcedure("@ProfCtl", "MakeAPony");
        vt = resp.getResults()[0];
        assertTrue(true);
    }

    //
    // Build a list of the tests to be run. Use the regression suite
    // helpers to allow multiple backends.
    // JUnit magic that uses the regression suite helper classes.
    //
    static public Test suite() throws IOException {
        VoltServerConfig config = null;

        MultiConfigSuiteBuilder builder =
            new MultiConfigSuiteBuilder(TestSystemProcedureSuite.class);

        // Not really using TPCC functionality but need a database.
        // The testLoadMultipartitionTable procedure assumes partitioning
        // on warehouse id.
        VoltProjectBuilder project = new VoltProjectBuilder();
        project.addLiteralSchema(
                        "CREATE TABLE WAREHOUSE (\n" +
                        "  W_ID SMALLINT DEFAULT '0' NOT NULL,\n" +
                        "  W_NAME VARCHAR(16) DEFAULT NULL,\n" +
                        "  W_STREET_1 VARCHAR(32) DEFAULT NULL,\n" +
                        "  W_STREET_2 VARCHAR(32) DEFAULT NULL,\n" +
                        "  W_CITY VARCHAR(32) DEFAULT NULL,\n" +
                        "  W_STATE VARCHAR(2) DEFAULT NULL,\n" +
                        "  W_ZIP VARCHAR(9) DEFAULT NULL,\n" +
                        "  W_TAX FLOAT DEFAULT NULL,\n" +
                        "  W_YTD FLOAT DEFAULT NULL,\n" +
                        "  CONSTRAINT W_PK_TREE PRIMARY KEY (W_ID)\n" +
                        ");\n" +
                        "CREATE TABLE ITEM (\n" +
                        "  I_ID INTEGER DEFAULT '0' NOT NULL,\n" +
                        "  I_IM_ID INTEGER DEFAULT NULL,\n" +
                        "  I_NAME VARCHAR(32) DEFAULT NULL,\n" +
                        "  I_PRICE FLOAT DEFAULT NULL,\n" +
                        "  I_DATA VARCHAR(64) DEFAULT NULL,\n" +
                        "  CONSTRAINT I_PK_TREE PRIMARY KEY (I_ID)\n" +
                        ");\n" +
                        "CREATE TABLE NEW_ORDER (\n" +
                        "  NO_W_ID SMALLINT DEFAULT '0' NOT NULL\n" +
                        ");\n");

        project.addPartitionInfo("WAREHOUSE", "W_ID");
        project.addPartitionInfo("NEW_ORDER", "NO_W_ID");
        project.addProcedures(PROCEDURES);

        /*config = new LocalCluster("sysproc-twosites.jar", 2, 1, 0,
                                  BackendTarget.NATIVE_EE_JNI);
        ((LocalCluster) config).setHasLocalServer(false);
        config.compile(project);
        builder.addServerConfig(config);*/

        /*
         * Add a cluster configuration for sysprocs too
         */
        config = new LocalCluster("sysproc-cluster.jar", TestSystemProcedureSuite.SITES, TestSystemProcedureSuite.HOSTS, TestSystemProcedureSuite.KFACTOR,
                                  BackendTarget.NATIVE_EE_JNI);
        ((LocalCluster) config).setHasLocalServer(hasLocalServer);
        boolean success = config.compile(project);
        assertTrue(success);
        builder.addServerConfig(config);

        return builder;
    }
}

TOP

Related Classes of org.voltdb.regressionsuites.TestSystemProcedureSuite

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.