public void testCatalogUpdateAfterRejoin() throws Exception {
    System.out.println("testCatalogUpdateAfterRejoin");
    VoltProjectBuilder builder = getBuilderForTest();

    LocalCluster cluster = new LocalCluster("rejoin.jar", 2, 2, 1, BackendTarget.NATIVE_EE_JNI);
    boolean success = cluster.compile(builder);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));

    try {
      cluster.startUp();

      for (int ii = 0; ii < 3; ii++) {
        cluster.shutDownSingleHost(1);
        Thread.sleep(1000);
        cluster.recoverOne(1, 0, "localhost");

        File newCatalog = new File(Configuration.getPathToCatalogForTest("rejoin.jar"));
        File deployment = new File(Configuration.getPathToCatalogForTest("rejoin.xml"));

        Client client = ClientFactory.createClient();
        client.createConnection("localhost");

        VoltTable[] results = client.updateApplicationCatalog(newCatalog, deployment).getResults();
        assertTrue(results.length == 1);
        client.close();
      }
    } finally {
      cluster.shutDown();
    }
  }
  public void testRejoinSysprocButFail() throws Exception {
    VoltProjectBuilder builder = getBuilderForTest();
    boolean success = builder.compile(Configuration.getPathToCatalogForTest("rejoin.jar"), 1, 1, 0);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = Configuration.getPathToCatalogForTest("rejoin.jar");
    config.m_pathToDeployment = Configuration.getPathToCatalogForTest("rejoin.xml");
    config.m_isRejoinTest = true;
    ServerThread localServer = new ServerThread(config);

    localServer.start();
    localServer.waitForInitialization();

    Client client = ClientFactory.createClient();
    client.createConnection("localhost");

    SyncCallback scb = new SyncCallback();
    success = false;
    while (!success) {
      success = client.callProcedure(scb, "@Rejoin", "localhost", config.m_internalPort + 1);
      if (!success) Thread.sleep(100);
    }

    scb.waitForResponse();
    ClientResponse response = scb.getResponse();
    assertTrue(response.getStatusString().contains("Unable to find down node"));

    client.close();
    localServer.shutdown();
    localServer.join();
  }
  public void testRejoinPropogateAdminMode() throws Exception {
    // Reset the VoltFile prefix that may have been set by previous tests in this suite
    org.voltdb.utils.VoltFile.resetSubrootForThisProcess();
    VoltProjectBuilder builder = getBuilderForTest();
    builder.setSecurityEnabled(true);

    LocalCluster cluster =
        new LocalCluster("rejoin.jar", 2, 3, 1, BackendTarget.NATIVE_EE_JNI, true);
    boolean success = cluster.compileWithAdminMode(builder, 9998, false);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));
    cluster.setHasLocalServer(false);

    cluster.startUp();

    ClientResponse response;
    Client client;

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost", 9997);

    response = client.callProcedure("@Pause");
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    client.close();

    cluster.shutDownSingleHost(0);
    Thread.sleep(100);

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = Configuration.getPathToCatalogForTest("rejoin.jar");
    config.m_pathToDeployment = Configuration.getPathToCatalogForTest("rejoin.xml");
    config.m_rejoinToHostAndPort = m_username + ":" + m_password + "@localhost:9996";
    config.m_isRejoinTest = true;
    ServerThread localServer = new ServerThread(config);

    localServer.start();
    localServer.waitForInitialization();

    Thread.sleep(1000);

    assertTrue(VoltDB.instance().getMode() == OperationMode.PAUSED);

    localServer.shutdown();
    cluster.shutDown();
  }
  public void testLocalClusterRecoveringMode() throws Exception {
    VoltProjectBuilder builder = getBuilderForTest();

    LocalCluster cluster =
        new LocalCluster(
            "rejoin.jar",
            2,
            2,
            1,
            BackendTarget.NATIVE_EE_JNI,
            LocalCluster.FailureState.ONE_FAILURE,
            false,
            true);
    boolean success = cluster.compile(builder);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));
    cluster.setHasLocalServer(false);

    cluster.startUp();
    Thread.sleep(100);

    cluster.shutDown();

    cluster =
        new LocalCluster(
            "rejoin.jar",
            2,
            3,
            1,
            BackendTarget.NATIVE_EE_JNI,
            LocalCluster.FailureState.ONE_RECOVERING,
            false,
            true);
    success = cluster.compile(builder);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));
    cluster.setHasLocalServer(false);

    cluster.startUp();
    Thread.sleep(100);

    cluster.shutDown();
  }
  public void testRejoinInlineStringBug() throws Exception {
    VoltProjectBuilder builder = getBuilderForTest();

    LocalCluster cluster =
        new LocalCluster("rejoin.jar", 1, 2, 1, BackendTarget.NATIVE_EE_JNI, true);
    boolean success = cluster.compile(builder);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));
    cluster.setHasLocalServer(false);

    cluster.startUp();
    Client client;

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost");

    ProcedureCallback callback =
        new ProcedureCallback() {

          @Override
          public void clientCallback(ClientResponse clientResponse) throws Exception {
            if (clientResponse.getStatus() != ClientResponse.SUCCESS) {
              System.out.println(clientResponse.getStatusString());
            }
          }
        };

    StringBuffer shortBuffer = new StringBuffer();
    for (int ii = 0; ii < 33; ii++) {
      shortBuffer.append('a');
    }
    String shortString = shortBuffer.toString();

    StringBuffer longBuffer = new StringBuffer();
    for (int ii = 0; ii < 17700; ii++) {
      longBuffer.append('a');
    }
    String longString = longBuffer.toString();

    for (int ii = 0; ii < 119; ii++) {
      client.callProcedure(callback, "InsertInlinedString", ii, shortString, longString);
    }

    shortBuffer.append("aaa");
    client.callProcedure(callback, "InsertInlinedString", 120, shortBuffer.toString(), longString);

    client.drain();
    client.close();

    cluster.shutDownSingleHost(0);
    cluster.recoverOne(0, 1, "localhost");

    cluster.shutDown();
  }
 /** Assuming given table has schema metadata, make a catalog containing that table on disk. */
 String catalogPathForTable(VoltTable t, String jarname) throws IOException {
   CatalogBuilder builder = new CatalogBuilder();
   String ddl = TableHelper.ddlForTable(t);
   builder.addLiteralSchema(ddl);
   String retval = Configuration.getPathToCatalogForTest(jarname);
   boolean success = builder.compile(retval);
   // good spot below for a breakpoint if compiling fails
   if (!success) {
     fail();
   }
   return retval;
 }
Exemple #7
0
  ServerThread startup() throws Exception {
    String simpleSchema =
        "create table dummy ("
            + "sval1 varchar(100) not null, "
            + "sval2 varchar(100) default 'foo', "
            + "sval3 varchar(100) default 'bar', "
            + "PRIMARY KEY(sval1));";

    File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
    String schemaPath = schemaFile.getPath();
    schemaPath = URLEncoder.encode(schemaPath, "UTF-8");

    VoltProjectBuilder builder = new VoltProjectBuilder();
    builder.addSchema(schemaPath);
    builder.addPartitionInfo("dummy", "sval1");
    builder.addStmtProcedure("Insert", "insert into dummy values (?,?,?);");
    builder.addStmtProcedure("Select", "select * from dummy;");
    builder.setHTTPDPort(8095);
    boolean success =
        builder.compile(Configuration.getPathToCatalogForTest("jsonperf.jar"), 1, 1, 0);
    assert (success);

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = Configuration.getPathToCatalogForTest("jsonperf.jar");
    config.m_pathToDeployment = builder.getPathToDeployment();
    ServerThread server = new ServerThread(config);
    server.start();
    server.waitForInitialization();

    Client client = ClientFactory.createClient();
    client.createConnection("localhost");

    ClientResponse response1;
    response1 = client.callProcedure("Insert", "FOO", "BAR", "BOO");
    assert (response1.getStatus() == ClientResponse.SUCCESS);

    return server;
  }
Exemple #8
0
  ServerThread startup() throws UnsupportedEncodingException {
    String simpleSchema =
        "create table cjk ("
            + "sval1 varchar(1024) not null, "
            + "sval2 varchar(1024) default 'foo', "
            + "sval3 varchar(1024) default 'bar', "
            + "PRIMARY KEY(sval1));";

    /*String simpleSchema =
    "create table cjk (" +
    "sval1 varchar(20) not null, " +
    "sval2 varchar(20) default 'foo', " +
    "sval3 varchar(20) default 'bar', " +
    "PRIMARY KEY(sval1));";*/

    File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
    String schemaPath = schemaFile.getPath();
    schemaPath = URLEncoder.encode(schemaPath, "UTF-8");

    VoltProjectBuilder builder = new VoltProjectBuilder();
    builder.addSchema(schemaPath);
    builder.addPartitionInfo("cjk", "sval1");
    builder.addStmtProcedure("Insert", "insert into cjk values (?,?,?);");
    builder.addStmtProcedure("Select", "select * from cjk;");
    builder.setHTTPDPort(8095);
    boolean success = builder.compile(Configuration.getPathToCatalogForTest("cjk.jar"), 1, 1, 0);
    assertTrue(success);

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = Configuration.getPathToCatalogForTest("cjk.jar");
    config.m_pathToDeployment = builder.getPathToDeployment();
    ServerThread server = new ServerThread(config);
    server.start();
    server.waitForInitialization();

    return server;
  }
Exemple #9
0
  @BeforeClass
  public static void startDatabase() throws Exception {
    prepare();

    String pathToCatalog = Configuration.getPathToCatalogForTest("csv.jar");
    String pathToDeployment = Configuration.getPathToCatalogForTest("csv.xml");
    VoltProjectBuilder builder = new VoltProjectBuilder();

    builder.addLiteralSchema(
        "create table BLAH ("
            + "clm_integer integer not null, "
            + "clm_tinyint tinyint default 0, "
            + "clm_smallint smallint default 0, "
            + "clm_bigint bigint default 0, "
            + "clm_string varchar(20) default null, "
            + "clm_decimal decimal default null, "
            + "clm_float float default null, "
            + "clm_timestamp timestamp default null, "
            + "PRIMARY KEY(clm_integer) "
            + ");");
    builder.addPartitionInfo("BLAH", "clm_integer");
    boolean success = builder.compile(pathToCatalog, 2, 1, 0);
    assertTrue(success);
    MiscUtils.copyFile(builder.getPathToDeployment(), pathToDeployment);
    Configuration config = new Configuration();
    config.m_pathToCatalog = pathToCatalog;
    config.m_pathToDeployment = pathToDeployment;
    localServer = new ServerThread(config);
    client = null;

    localServer.start();
    localServer.waitForInitialization();

    client = ClientFactory.createClient(new ClientConfig());
    client.createConnection("localhost");
  }
  public void testBasicCreateStatementProc() throws Exception {
    String pathToCatalog = Configuration.getPathToCatalogForTest("adhocddl.jar");
    String pathToDeployment = Configuration.getPathToCatalogForTest("adhocddl.xml");

    VoltProjectBuilder builder = new VoltProjectBuilder();
    builder.addLiteralSchema(
        "create table FOO ("
            + "ID integer not null,"
            + "VAL bigint, "
            + "constraint PK_TREE primary key (ID)"
            + ");\n"
            + "create table FOO_R ("
            + "ID integer not null,"
            + "VAL bigint, "
            + "constraint PK_TREE_R primary key (ID)"
            + ");\n");
    builder.addPartitionInfo("FOO", "ID");
    builder.setUseDDLSchema(true);
    boolean success = builder.compile(pathToCatalog, 2, 1, 0);
    assertTrue("Schema compilation failed", success);
    MiscUtils.copyFile(builder.getPathToDeployment(), pathToDeployment);

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = pathToCatalog;
    config.m_pathToDeployment = pathToDeployment;

    try {
      startSystem(config);
      // Procedure shouldn't exist
      boolean threw = false;
      assertFalse(findProcedureInSystemCatalog("FOOCOUNT"));
      try {
        m_client.callProcedure("FOOCOUNT", 1000L);
      } catch (ProcCallException pce) {
        assertTrue(pce.getMessage().contains("Procedure FOOCOUNT was not found"));
        threw = true;
      }
      assertTrue("FOOCOUNT procedure shouldn't exist", threw);
      try {
        m_client.callProcedure(
            "@AdHoc", "create procedure FOOCOUNT as select * from FOO where ID=?;");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to create statement procedure");
      }
      assertTrue(findProcedureInSystemCatalog("FOOCOUNT"));
      assertFalse(verifySinglePartitionProcedure("FOOCOUNT"));
      // Make sure we can call it
      try {
        m_client.callProcedure("FOOCOUNT", 1000L);
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to call procedure FOOCOUNT");
      }
      // partition that sucker
      try {
        m_client.callProcedure(
            "@AdHoc", "partition procedure FOOCOUNT on table FOO column ID parameter 0;");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to partition the procedure FOOCOUNT");
      }
      // Make sure we can call it
      assertTrue(verifySinglePartitionProcedure("FOOCOUNT"));
      try {
        m_client.callProcedure("FOOCOUNT", 1000L);
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to call procedure FOOCOUNT");
      }

      // now drop it
      try {
        m_client.callProcedure("@AdHoc", "drop procedure FOOCOUNT");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to drop procedure FOOCOUNT");
      }
      assertFalse(findProcedureInSystemCatalog("FOOCOUNT"));

      // Can't drop it twice
      threw = false;
      try {
        m_client.callProcedure("@AdHoc", "drop procedure FOOCOUNT");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        threw = true;
      }
      assertTrue("Can't vanilla drop procedure FOOCOUNT twice", threw);

      // unless we use if exists
      try {
        m_client.callProcedure("@AdHoc", "drop procedure FOOCOUNT if exists");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to drop procedure FOOCOUNT twice with if exists");
      }

      // Create it again so we can destroy it with drop with if exists, just to be sure
      try {
        m_client.callProcedure(
            "@AdHoc", "create procedure FOOCOUNT as select * from FOO where ID=?;");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to create statement procedure");
      }
      assertTrue(findProcedureInSystemCatalog("FOOCOUNT"));

      // now drop it
      try {
        m_client.callProcedure("@AdHoc", "drop procedure FOOCOUNT if exists");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to drop procedure FOOCOUNT");
      }
      assertFalse(findProcedureInSystemCatalog("FOOCOUNT"));
    } finally {
      teardownSystem();
    }
  }
  public void testBasic() throws Exception {
    System.out.println("\n\n-----\n testBasic \n-----\n\n");

    String pathToCatalog = Configuration.getPathToCatalogForTest("adhocddl.jar");
    String pathToDeployment = Configuration.getPathToCatalogForTest("adhocddl.xml");
    VoltProjectBuilder builder = new VoltProjectBuilder();
    // Need to parallel dbuilder as we modify builder
    DeploymentBuilder dbuilder = new DeploymentBuilder(2, 1, 0);
    builder.addLiteralSchema(
        "create table FOO ("
            + "ID integer not null,"
            + "VAL bigint, "
            + "constraint PK_TREE primary key (ID)"
            + ");\n"
            + "create table FOO_R ("
            + "ID integer not null,"
            + "VAL bigint, "
            + "constraint PK_TREE_R primary key (ID)"
            + ");\n");
    builder.addPartitionInfo("FOO", "ID");
    dbuilder.setUseDDLSchema(true);
    // Use random caps in role names to check case-insensitivity
    dbuilder.addUsers(
        new DeploymentBuilder.UserInfo[] {
          new DeploymentBuilder.UserInfo("admin", "admin", new String[] {"Administrator"})
        });
    dbuilder.setSecurityEnabled(true);
    dbuilder.setEnableCommandLogging(false);
    boolean success = builder.compile(pathToCatalog, 2, 1, 0);
    assertTrue("Schema compilation failed", success);
    dbuilder.writeXML(pathToDeployment);
    // MiscUtils.copyFile(builder.getPathToDeployment(), pathToDeployment);

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = pathToCatalog;
    config.m_pathToDeployment = pathToDeployment;

    try {
      startServer(config);
      ClientConfig adminConfig = new ClientConfig("admin", "admin");
      Client adminClient = ClientFactory.createClient(adminConfig);
      ClientConfig userConfig = new ClientConfig("user", "user");
      Client userClient = ClientFactory.createClient(userConfig);

      adminClient.createConnection("localhost");
      // Can't connect a user which doesn't exist
      boolean threw = false;
      try {
        userClient.createConnection("localhost");
      } catch (IOException ioe) {
        threw = true;
        assertTrue(ioe.getMessage().contains("Authentication rejected"));
      }
      assertTrue("Connecting bad user should have failed", threw);

      // Add the user with the new role
      dbuilder.addUsers(new UserInfo[] {new UserInfo("user", "user", new String[] {"NEWROLE"})});
      dbuilder.writeXML(pathToDeployment);
      try {
        adminClient.updateApplicationCatalog(null, new File(pathToDeployment));
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to add a user even with a role that doesn't exist");
      }

      // Check that we can connect the new user
      try {
        userClient.createConnection("localhost");
      } catch (IOException ioe) {
        ioe.printStackTrace();
        fail("Should have been able to connect 'user'");
      }

      // Make sure the user doesn't actually have DEFAULTPROC permissions yet
      threw = false;
      try {
        userClient.callProcedure("FOO.insert", 0, 0);
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        threw = true;
      }
      assertTrue("'user' shouldn't be able to call procedures yet", threw);

      // Okay, it's showtime.  Let's add the role through live DDL
      try {
        adminClient.callProcedure("@AdHoc", "create role NEWROLE with DEFAULTPROC");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Creating role should have succeeded");
      }

      try {
        adminClient.updateApplicationCatalog(null, new File(pathToDeployment));
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Adding 'user' should have succeeded this time");
      }

      // Make sure the user now has DEFAULTPROC permissions
      try {
        userClient.callProcedure("FOO.insert", 0, 0);
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("'user' should be able to call default procs now");
      }

      threw = false;
      try {
        adminClient.callProcedure("@AdHoc", "create role NEWROLE with ALLPROC");
      } catch (ProcCallException pce) {
        assertTrue(pce.getMessage().contains("already exists"));
        threw = true;
      }
      assertTrue("Shouldn't be able to 'create' same role twice", threw);

      threw = false;
      try {
        // Use random caps in role names to check case-insensitivity
        adminClient.callProcedure("@AdHoc", "create role aDministrator with ALLPROC");
      } catch (ProcCallException pce) {
        assertTrue(pce.getMessage().contains("already exists"));
        threw = true;
      }
      assertTrue("Shouldn't be able to 'create' ADMINISTRATOR role", threw);

      threw = false;
      try {
        adminClient.callProcedure("@AdHoc", "create role USER with ALLPROC");
      } catch (ProcCallException pce) {
        assertTrue(pce.getMessage().contains("already exists"));
        threw = true;
      }
      assertTrue("Shouldn't be able to 'create' USER role", threw);

      try {
        adminClient.callProcedure("@AdHoc", "drop role NEWROLE;");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to drop role NEWROLE");
      }

      // Can't drop twice
      try {
        adminClient.callProcedure("@AdHoc", "drop role NEWROLE;");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        threw = true;
      }
      assertTrue("Can't vanilla DROP a role which doesn't exist", threw);

      // unless you use IF EXISTS
      try {
        adminClient.callProcedure("@AdHoc", "drop role NEWROLE if exists;");
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        fail("Should be able to drop role NEWROLE if exists");
      }

      // Make sure the user doesn't actually have DEFAULTPROC permissions any more
      threw = false;
      try {
        userClient.callProcedure("FOO.insert", 0, 0);
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        threw = true;
      }
      assertTrue("'user' shouldn't be able to call procedures yet", threw);

      threw = false;
      try {
        adminClient.callProcedure("@AdHoc", "drop role USER;");
      } catch (ProcCallException pce) {
        threw = true;
        assertTrue(pce.getMessage().contains("You may not drop the built-in role"));
        pce.printStackTrace();
      }
      assertTrue("Shouldn't be able to drop role USER", threw);

      // CHeck the administrator error message, there should end up being multiple
      // reasons why we can't get rid of this role (like, we will require you to always
      // have a user with this role)
      threw = false;
      try {
        // Use random caps in role names to check case-insensitivity
        adminClient.callProcedure("@AdHoc", "drop role adMinistrator;");
      } catch (ProcCallException pce) {
        threw = true;
        assertTrue(pce.getMessage().contains("You may not drop the built-in role"));
        pce.printStackTrace();
      }
      assertTrue("Shouldn't be able to drop role ADMINISTRATOR", threw);

      // Make sure that we can't get rid of the administrator user
      dbuilder.removeUser("admin");
      dbuilder.writeXML(pathToDeployment);
      threw = false;
      try {
        adminClient.updateApplicationCatalog(null, new File(pathToDeployment));
      } catch (ProcCallException pce) {
        pce.printStackTrace();
        threw = true;
      }
      assertTrue("Shouldn't be able to remove the last remaining ADMINSTRATOR user", threw);
    } finally {
      teardownSystem();
    }
  }
Exemple #12
0
  public void testSimple() throws Exception {
    String simpleSchema =
        "create table BLAH ("
            + "IVAL bigint default 0 not null, "
            + "TVAL timestamp default null,"
            + "DVAL decimal default null,"
            + "PRIMARY KEY(IVAL));";

    VoltProjectBuilder builder = new VoltProjectBuilder();
    builder.addLiteralSchema(simpleSchema);
    builder.addPartitionInfo("BLAH", "IVAL");
    builder.addStmtProcedure("Insert", "insert into blah values (?, ?, ?);", null);
    builder.addStmtProcedure(
        "InsertWithDate",
        "INSERT INTO BLAH VALUES (974599638818488300, '2011-06-24 10:30:26.002', 5);");
    boolean success = builder.compile(Configuration.getPathToCatalogForTest("adhoc.jar"), 2, 1, 0);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("adhoc.xml"));

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = Configuration.getPathToCatalogForTest("adhoc.jar");
    config.m_pathToDeployment = Configuration.getPathToCatalogForTest("adhoc.xml");
    ServerThread localServer = new ServerThread(config);
    localServer.start();
    localServer.waitForInitialization();

    // do the test
    Client client = ClientFactory.createClient();
    client.createConnection("localhost");

    VoltTable modCount =
        client.callProcedure("@AdHoc", "INSERT INTO BLAH VALUES (1, 1, 1);").getResults()[0];
    assertTrue(modCount.getRowCount() == 1);
    assertTrue(modCount.asScalarLong() == 1);

    VoltTable result = client.callProcedure("@AdHoc", "SELECT * FROM BLAH;").getResults()[0];
    assertTrue(result.getRowCount() == 1);
    System.out.println(result.toString());

    // test single-partition stuff
    result = client.callProcedure("@AdHoc", "SELECT * FROM BLAH;", 0).getResults()[0];
    assertTrue(result.getRowCount() == 0);
    System.out.println(result.toString());
    result = client.callProcedure("@AdHoc", "SELECT * FROM BLAH;", 1).getResults()[0];
    assertTrue(result.getRowCount() == 1);
    System.out.println(result.toString());

    try {
      client.callProcedure("@AdHoc", "INSERT INTO BLAH VALUES (0, 0, 0);", 1);
      fail("Badly partitioned insert failed to throw expected exception");
    } catch (Exception e) {
    }

    try {
      client.callProcedure("@AdHoc", "SLEECT * FROOM NEEEW_OOORDERERER;");
      fail("Bad SQL failed to throw expected exception");
    } catch (Exception e) {
    }

    // try a huge bigint literal
    modCount =
        client.callProcedure(
                "@AdHoc",
                "INSERT INTO BLAH VALUES (974599638818488300, '2011-06-24 10:30:26.123012', 5);")
            .getResults()[0];
    modCount =
        client.callProcedure(
                "@AdHoc", "INSERT INTO BLAH VALUES (974599638818488301, '2011-06-24 10:30:28', 5);")
            .getResults()[0];
    assertTrue(modCount.getRowCount() == 1);
    assertTrue(modCount.asScalarLong() == 1);
    result =
        client.callProcedure("@AdHoc", "SELECT * FROM BLAH WHERE IVAL = 974599638818488300;")
            .getResults()[0];
    assertTrue(result.getRowCount() == 1);
    System.out.println(result.toString());
    result =
        client.callProcedure(
                "@AdHoc", "SELECT * FROM BLAH WHERE TVAL = '2011-06-24 10:30:26.123012';")
            .getResults()[0];
    assertTrue(result.getRowCount() == 1);
    System.out.println(result.toString());
    result =
        client.callProcedure("@AdHoc", "SELECT * FROM BLAH WHERE TVAL > '2011-06-24 10:30:25';")
            .getResults()[0];
    assertEquals(2, result.getRowCount());
    System.out.println(result.toString());
    result =
        client.callProcedure("@AdHoc", "SELECT * FROM BLAH WHERE TVAL < '2011-06-24 10:30:27';")
            .getResults()[0];
    System.out.println(result.toString());
    // We inserted a 1,1,1 row way earlier
    assertEquals(2, result.getRowCount());

    // try something like the queries in ENG-1242
    try {
      client.callProcedure(
          "@AdHoc", "select * from blah; dfvsdfgvdf select * from blah WHERE IVAL = 1;");
      fail("Bad SQL failed to throw expected exception");
    } catch (Exception e) {
    }
    client.callProcedure("@AdHoc", "select\n* from blah;");

    // try a decimal calculation (ENG-1093)
    modCount =
        client.callProcedure(
                "@AdHoc", "INSERT INTO BLAH VALUES (2, '2011-06-24 10:30:26', 1.12345*1);")
            .getResults()[0];
    assertTrue(modCount.getRowCount() == 1);
    assertTrue(modCount.asScalarLong() == 1);
    result = client.callProcedure("@AdHoc", "SELECT * FROM BLAH WHERE IVAL = 2;").getResults()[0];
    assertTrue(result.getRowCount() == 1);
    System.out.println(result.toString());

    localServer.shutdown();
    localServer.join();
  }
  public void testRejoinDataTransfer() throws Exception {
    System.out.println("testRejoinDataTransfer");
    VoltProjectBuilder builder = getBuilderForTest();
    builder.setSecurityEnabled(true);

    LocalCluster cluster =
        new LocalCluster("rejoin.jar", 2, 2, 1, BackendTarget.NATIVE_EE_JNI, true);
    boolean success = cluster.compile(builder);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));
    cluster.setHasLocalServer(false);

    cluster.startUp();

    ClientResponse response;
    Client client;

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost");

    response = client.callProcedure("InsertSinglePartition", 0);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("Insert", 1);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("InsertReplicated", 0);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());

    cluster.shutDownSingleHost(0);
    Thread.sleep(1000);

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = Configuration.getPathToCatalogForTest("rejoin.jar");
    config.m_pathToDeployment = Configuration.getPathToCatalogForTest("rejoin.xml");
    config.m_rejoinToHostAndPort = m_username + ":" + m_password + "@localhost:21213";
    config.m_isRejoinTest = true;
    ServerThread localServer = new ServerThread(config);

    localServer.start();
    localServer.waitForInitialization();

    Thread.sleep(2000);

    client.close();

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost", 21213);

    //
    // Check that the recovery data transferred
    //
    response = client.callProcedure("SelectBlahSinglePartition", 0);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 0);

    response = client.callProcedure("SelectBlah", 1);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 1);

    response = client.callProcedure("SelectBlahReplicated", 0);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 0);

    //
    //  Try to insert new data
    //
    response = client.callProcedure("InsertSinglePartition", 2);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("Insert", 3);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("InsertReplicated", 1);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());

    //
    // See that it was inserted
    //
    response = client.callProcedure("SelectBlahSinglePartition", 2);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 2);
    response = client.callProcedure("SelectBlah", 3);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 3);

    response = client.callProcedure("SelectBlahReplicated", 1);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 1);

    //
    // Kill one of the old ones (not the recovered partition)
    //
    cluster.shutDownSingleHost(1);
    Thread.sleep(1000);

    client.close();

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost", 21212);

    //
    // See that the cluster is available and the data is still there.
    //
    response = client.callProcedure("SelectBlahSinglePartition", 2);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 2);

    response = client.callProcedure("SelectBlah", 3);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 3);

    response = client.callProcedure("SelectBlahReplicated", 1);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 1);

    client.close();

    localServer.shutdown();
    cluster.shutDown();
  }
  public void testRejoinWithExport() throws Exception {
    VoltProjectBuilder builder = getBuilderForTest();
    // builder.setTableAsExportOnly("blah", false);
    // builder.setTableAsExportOnly("blah_replicated", false);
    // builder.setTableAsExportOnly("PARTITIONED", false);
    // builder.setTableAsExportOnly("PARTITIONED_LARGE", false);
    builder.addExport(
        "org.voltdb.export.processors.RawProcessor",
        true, // enabled
        null); // authGroups (off)

    LocalCluster cluster =
        new LocalCluster("rejoin.jar", 2, 3, 1, BackendTarget.NATIVE_EE_JNI, true);
    boolean success = cluster.compile(builder);
    assertTrue(success);
    MiscUtils.copyFile(
        builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));
    cluster.setHasLocalServer(false);

    cluster.startUp();

    ClientResponse response;
    Client client;

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost");

    response = client.callProcedure("InsertSinglePartition", 0);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("Insert", 1);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("InsertReplicated", 0);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    client.close();

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost", 21213);
    response = client.callProcedure("InsertSinglePartition", 2);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("Insert", 3);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    client.close();

    TrivialExportClient exportClient = new TrivialExportClient();
    exportClient.work();
    exportClient.work();

    Thread.sleep(4000);

    exportClient.work();

    Thread.sleep(4000);

    exportClient.work();

    cluster.shutDownSingleHost(0);
    Thread.sleep(100);

    VoltDB.Configuration config = new VoltDB.Configuration();
    config.m_pathToCatalog = Configuration.getPathToCatalogForTest("rejoin.jar");
    config.m_pathToDeployment = Configuration.getPathToCatalogForTest("rejoin.xml");
    config.m_rejoinToHostAndPort = m_username + ":" + m_password + "@localhost:21213";
    config.m_isRejoinTest = true;
    ServerThread localServer = new ServerThread(config);

    localServer.start();
    localServer.waitForInitialization();

    Thread.sleep(1000);
    while (VoltDB.instance().recovering()) {
      Thread.sleep(100);
    }

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost");

    response = client.callProcedure("InsertSinglePartition", 5);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("Insert", 6);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("InsertReplicated", 7);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    client.close();

    client = ClientFactory.createClient(m_cconfig);
    client.createConnection("localhost", 21213);
    response = client.callProcedure("InsertSinglePartition", 8);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    response = client.callProcedure("Insert", 9);
    assertEquals(ClientResponse.SUCCESS, response.getStatus());
    client.close();

    exportClient = new TrivialExportClient();
    exportClient.work();

    Thread.sleep(4000);

    exportClient.work();

    Thread.sleep(4000);

    exportClient.work();

    localServer.shutdown();
    cluster.shutDown();
  }
  public void testRejoinWithMultipartLoad() throws Exception {
    ExecutionSite.m_recoveryPermit.drainPermits();
    ExecutionSite.m_recoveryPermit.release();
    try {
      System.out.println("testRejoinWithMultipartLoad");
      VoltProjectBuilder builder = getBuilderForTest();
      builder.setSecurityEnabled(true);

      LocalCluster cluster =
          new LocalCluster(
              "rejoin.jar",
              2,
              2,
              1,
              BackendTarget.NATIVE_EE_JNI,
              LocalCluster.FailureState.ALL_RUNNING,
              true,
              true);
      boolean success = cluster.compile(builder);
      assertTrue(success);
      MiscUtils.copyFile(
          builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));
      cluster.setHasLocalServer(false);

      cluster.startUp();

      ClientResponse response;
      Client client;

      client = ClientFactory.createClient(m_cconfig);
      client.createConnection("localhost", 21213);

      response = client.callProcedure("InsertSinglePartition", 33);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      response = client.callProcedure("Insert", 1);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      response = client.callProcedure("InsertReplicated", 34);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());

      cluster.shutDownSingleHost(0);
      Thread.sleep(1000);

      final Client clientForLoadThread = client;
      final java.util.concurrent.atomic.AtomicBoolean shouldContinue =
          new java.util.concurrent.atomic.AtomicBoolean(true);
      Thread loadThread =
          new Thread("Load Thread") {
            @Override
            public void run() {
              try {
                final long startTime = System.currentTimeMillis();
                while (shouldContinue.get()) {
                  try {
                    clientForLoadThread.callProcedure(
                        new org.voltdb.client.ProcedureCallback() {

                          @Override
                          public void clientCallback(ClientResponse clientResponse)
                              throws Exception {
                            if (clientResponse.getStatus() != ClientResponse.SUCCESS) {
                              //
                              // System.err.println(clientResponse.getStatusString());
                            }
                          }
                        },
                        "@Statistics",
                        "MANAGEMENT",
                        1);
                    // clientForLoadThread.callProcedure("@Statistics", );
                    Thread.sleep(1);
                    final long now = System.currentTimeMillis();
                    if (now - startTime > 1000 * 10) {
                      break;
                    }
                  } catch (Exception e) {
                    e.printStackTrace();
                    break;
                  }
                }
              } finally {
                try {
                  clientForLoadThread.close();
                } catch (Exception e) {
                  e.printStackTrace();
                }
              }
            }
          };
      loadThread.start();

      Thread.sleep(2000);

      ServerThread localServer = null;
      try {
        VoltDB.Configuration config = new VoltDB.Configuration();
        config.m_pathToCatalog = Configuration.getPathToCatalogForTest("rejoin.jar");
        config.m_pathToDeployment = Configuration.getPathToCatalogForTest("rejoin.xml");
        config.m_rejoinToHostAndPort = m_username + ":" + m_password + "@localhost:21213";
        config.m_isRejoinTest = true;
        localServer = new ServerThread(config);

        localServer.start();
        localServer.waitForInitialization();

        Thread.sleep(2000);

        client = ClientFactory.createClient(m_cconfig);
        client.createConnection("localhost", 21213);

        //
        // Check that the recovery data transferred
        //
        response = client.callProcedure("SelectBlahSinglePartition", 33);
        assertEquals(ClientResponse.SUCCESS, response.getStatus());
        assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 33);

      } finally {
        shouldContinue.set(false);
      }

      response = client.callProcedure("SelectBlah", 1);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 1);

      response = client.callProcedure("SelectBlahReplicated", 34);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 34);

      //
      //  Try to insert new data
      //
      response = client.callProcedure("InsertSinglePartition", 2);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      response = client.callProcedure("Insert", 3);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      response = client.callProcedure("InsertReplicated", 1);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());

      //
      // See that it was inserted
      //
      response = client.callProcedure("SelectBlahSinglePartition", 2);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 2);
      response = client.callProcedure("SelectBlah", 3);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 3);

      response = client.callProcedure("SelectBlahReplicated", 1);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 1);

      //
      // Kill one of the old ones (not the recovered partition)
      //
      cluster.shutDownSingleHost(1);
      Thread.sleep(1000);

      client.close();

      client = ClientFactory.createClient(m_cconfig);
      client.createConnection("localhost", 21212);

      //
      // See that the cluster is available and the data is still there.
      //
      response = client.callProcedure("SelectBlahSinglePartition", 2);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 2);

      response = client.callProcedure("SelectBlah", 3);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 3);

      response = client.callProcedure("SelectBlahReplicated", 1);
      assertEquals(ClientResponse.SUCCESS, response.getStatus());
      assertEquals(response.getResults()[0].fetchRow(0).getLong(0), 1);

      client.close();

      localServer.shutdown();
      cluster.shutDown();
    } finally {
      ExecutionSite.m_recoveryPermit.drainPermits();
      ExecutionSite.m_recoveryPermit.release(Integer.MAX_VALUE);
    }
  }
Exemple #16
0
@RunWith(value = Parameterized.class)
public class TestAdHocQueries extends AdHocQueryTester {

  @Parameters
  public static Collection<Object[]> useIv2() {
    return Arrays.asList(new Object[][] {{false}, {true}});
  }

  Client m_client;
  private static final boolean m_debug = false;

  protected final boolean m_useIv2;

  public TestAdHocQueries(boolean useIv2) {
    m_useIv2 = useIv2;
  }

  // IMPORTANT SAFETY TIP
  // The use of junit parameters to toggle between iv2 and non-iv2 cases
  // means that all test cases MUST BE annotated with @Test or THEY WILL NOT RUN.

  @Test
  public void testProcedureAdhoc() throws Exception {
    VoltDB.Configuration config = setUpSPDB(m_useIv2);
    ServerThread localServer = new ServerThread(config);

    try {
      localServer.start();
      localServer.waitForInitialization();

      // do the test
      m_client = ClientFactory.createClient();
      m_client.createConnection("localhost", config.m_port);

      m_client.callProcedure("@AdHoc", "insert into PARTED1 values ( 23, 3 )");

      /*
       * Test that a basic multipartition select works as well as a parameterized
       * query (it's in the procedure)
       */
      VoltTable results[] =
          m_client.callProcedure("executeSQLSP", 23, "select * from PARTED1").getResults();
      assertTrue(results[0].advanceRow());
      assertTrue(results[1].advanceRow());

      results =
          m_client.callProcedure("executeSQLMP", 23, "       select * from PARTED1").getResults();
      assertTrue(results[0].advanceRow());
      assertTrue(results[1].advanceRow());

      /*
       * Validate that doing an insert from a RO procedure fails
       */
      try {
        m_client.callProcedure("executeSQLSP", 24, "insert into parted1 values (24,5)");
        fail("Procedure call should not have succeded");
      } catch (ProcCallException e) {
      }

      try {
        m_client.callProcedure("executeSQLMP", 24, "insert into parted1 values (24,5)");
        fail("Procedure call should not have succeded");
      } catch (ProcCallException e) {
      }

      /*
       * Validate one sql statement per
       */
      try {
        m_client.callProcedure(
            "executeSQLSP", 24, "insert into parted1 values (24,5); select * from parted1;");
        fail("Procedure call should not have succeded");
      } catch (ProcCallException e) {
      }

      try {
        m_client.callProcedure("executeSQLSP", 24, "drop table parted1");
        fail("Procedure call should not have succeded");
      } catch (ProcCallException e) {
      }

      /*
       * Validate that an insert does work from a write procedure
       */
      m_client.callProcedure("executeSQLSPWRITE", 24, "insert into parted1 values (24, 4);");
      m_client.callProcedure("executeSQLMPWRITE", 25, "insert into parted1 values (25, 5);");

      /*
       * Query the inserts and all the rest do it once for singe and once for multi
       */
      results =
          m_client
              .callProcedure("executeSQLMP", 24, "select * from parted1 order by partval")
              .getResults();

      assertEquals(3, results[0].getRowCount());
      for (int ii = 3; ii < 6; ii++) {
        assertTrue(results[0].advanceRow());
        assertEquals(20 + ii, results[0].getLong(0));
        assertEquals(ii, results[0].getLong(1));
      }

      // Output from the first preplanned statement
      assertEquals(3, results[1].getRowCount());
      assertTrue(results[1].advanceRow());
      assertEquals(23, results[1].getLong(0));
      assertEquals(3, results[1].getLong(1));

      // Output from the second adhoc statement
      assertEquals(1, results[2].getRowCount());
      assertTrue(results[2].advanceRow());
      assertEquals(24, results[2].getLong(0));
      assertEquals(4, results[2].getLong(1));

      // Output from the second preplanned statement
      assertEquals(3, results[3].getRowCount());
      assertTrue(results[3].advanceRow());
      assertEquals(23, results[3].getLong(0));
      assertEquals(3, results[3].getLong(1));

      results =
          m_client
              .callProcedure("executeSQLSP", 24, "select * from parted1 order by partval")
              .getResults();

      assertEquals(1, results[0].getRowCount());
      assertTrue(results[0].advanceRow());
      assertEquals(24, results[0].getLong(0));
      assertEquals(4, results[0].getLong(1));

      // Output from the first preplanned statement
      assertEquals(1, results[1].getRowCount());
      assertTrue(results[1].advanceRow());
      assertEquals(24, results[1].getLong(0));
      assertEquals(4, results[1].getLong(1));

      // Output from the second adhoc statement
      assertEquals(1, results[2].getRowCount());
      assertTrue(results[2].advanceRow());
      assertEquals(24, results[2].getLong(0));
      assertEquals(4, results[2].getLong(1));

      // Output from the second preplanned statement
      assertEquals(1, results[3].getRowCount());
      assertTrue(results[3].advanceRow());
      assertEquals(24, results[3].getLong(0));
      assertEquals(4, results[3].getLong(1));
    } catch (Exception e) {
      e.printStackTrace();
      fail();
    } finally {
      if (m_client != null) m_client.close();
      m_client = null;

      if (localServer != null) {
        localServer.shutdown();
        localServer.join();
      }
      localServer = null;

      // no clue how helpful this is
      System.gc();
    }
  }

  @Test
  public void testSP() throws Exception {
    VoltDB.Configuration config = setUpSPDB(m_useIv2);
    ServerThread localServer = new ServerThread(config);

    try {
      localServer.start();
      localServer.waitForInitialization();

      // do the test
      m_client = ClientFactory.createClient();
      m_client.createConnection("localhost", config.m_port);

      VoltTable modCount;

      // Unlike TestAdHocPlans, TestAdHocQueries runs the queries against actual (minimal) data.
      // Load that, here.
      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO PARTED1 VALUES (0, 0);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO PARTED1 VALUES (1, 1);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO PARTED2 VALUES (0, 0);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO PARTED2 VALUES (2, 2);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO PARTED3 VALUES (0, 0);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO PARTED3 VALUES (3, 3);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO REPPED1 VALUES (0, 0);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO REPPED1 VALUES (1, 1);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO REPPED2 VALUES (0, 0);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      modCount =
          m_client.callProcedure("@AdHoc", "INSERT INTO REPPED2 VALUES (2, 2);").getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      runAllAdHocSPtests();
    } finally {
      if (m_client != null) m_client.close();
      m_client = null;

      if (localServer != null) {
        localServer.shutdown();
        localServer.join();
      }
      localServer = null;

      // no clue how helpful this is
      System.gc();
    }
  }

  /**
   * @param query
   * @param hashable - used to pick a single partition for running the query
   * @param spPartialSoFar - counts from prior SP queries to compensate for unpredictable hashing
   * @param expected - expected value of MP query (and of SP query, adjusting by spPartialSoFar, and
   *     only if validatingSPresult).
   * @param validatingSPresult - disables validation for non-deterministic SP results (so we don't
   *     have to second-guess the hashinator)
   * @return
   * @throws IOException
   * @throws NoConnectionsException
   * @throws ProcCallException
   */
  @Override
  public int runQueryTest(
      String query, int hashable, int spPartialSoFar, int expected, int validatingSPresult)
      throws IOException, NoConnectionsException, ProcCallException {
    VoltTable result;
    result = m_client.callProcedure("@AdHoc", query).getResults()[0];
    System.out.println(result.toString());
    assertEquals(expected, result.getRowCount());

    result = m_client.callProcedure("@AdHoc", query, hashable).getResults()[0];
    int spResult = result.getRowCount();
    System.out.println(result.toString());
    if (validatingSPresult != 0) {
      assertEquals(expected, spPartialSoFar + spResult);
    }

    return spResult;
  }

  String m_catalogJar = "adhoc.jar";
  String m_pathToCatalog = Configuration.getPathToCatalogForTest(m_catalogJar);
  String m_pathToDeployment = Configuration.getPathToCatalogForTest("adhoc.xml");

  @Test
  public void testSimple() throws Exception {
    TestEnv env = new TestEnv(m_catalogJar, m_pathToDeployment, 2, 2, 1, m_useIv2);
    try {
      env.setUp();

      VoltTable modCount =
          env.m_client.callProcedure("@AdHoc", "INSERT INTO BLAH VALUES (1, 1, 1);")
              .getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());

      VoltTable result =
          env.m_client.callProcedure("@AdHoc", "SELECT * FROM BLAH;").getResults()[0];
      assertEquals(1, result.getRowCount());
      System.out.println(result.toString());

      // test single-partition stuff
      result = env.m_client.callProcedure("@AdHoc", "SELECT * FROM BLAH;", 0).getResults()[0];
      assertEquals(0, result.getRowCount());
      System.out.println(result.toString());
      result = env.m_client.callProcedure("@AdHoc", "SELECT * FROM BLAH;", 1).getResults()[0];
      assertEquals(1, result.getRowCount());
      System.out.println(result.toString());

      try {
        env.m_client.callProcedure("@AdHoc", "INSERT INTO BLAH VALUES (0, 0, 0);", 1);
        fail("Badly partitioned insert failed to throw expected exception");
      } catch (Exception e) {
      }

      try {
        env.m_client.callProcedure("@AdHoc", "SLEECT * FROOM NEEEW_OOORDERERER;");
        fail("Bad SQL failed to throw expected exception");
      } catch (Exception e) {
      }

      // try a huge bigint literal
      modCount =
          env.m_client.callProcedure(
                  "@AdHoc",
                  "INSERT INTO BLAH VALUES (974599638818488300, '2011-06-24 10:30:26.123012', 5);")
              .getResults()[0];
      modCount =
          env.m_client.callProcedure(
                  "@AdHoc",
                  "INSERT INTO BLAH VALUES (974599638818488301, '2011-06-24 10:30:28', 5);")
              .getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());
      result =
          env.m_client.callProcedure(
                  "@AdHoc", "SELECT * FROM BLAH WHERE IVAL = 974599638818488300;")
              .getResults()[0];
      assertEquals(1, result.getRowCount());
      System.out.println(result.toString());
      result =
          env.m_client.callProcedure(
                  "@AdHoc", "SELECT * FROM BLAH WHERE TVAL = '2011-06-24 10:30:26.123012';")
              .getResults()[0];
      assertEquals(1, result.getRowCount());
      System.out.println(result.toString());
      result =
          env.m_client.callProcedure(
                  "@AdHoc", "SELECT * FROM BLAH WHERE TVAL > '2011-06-24 10:30:25';")
              .getResults()[0];
      assertEquals(2, result.getRowCount());
      System.out.println(result.toString());
      result =
          env.m_client.callProcedure(
                  "@AdHoc", "SELECT * FROM BLAH WHERE TVAL < '2011-06-24 10:30:27';")
              .getResults()[0];
      System.out.println(result.toString());
      // We inserted a 1,1,1 row way earlier
      assertEquals(2, result.getRowCount());

      // try something like the queries in ENG-1242
      try {
        env.m_client.callProcedure(
            "@AdHoc", "select * from blah; dfvsdfgvdf select * from blah WHERE IVAL = 1;");
        fail("Bad SQL failed to throw expected exception");
      } catch (Exception e) {
      }
      env.m_client.callProcedure("@AdHoc", "select\n* from blah;");

      // try a decimal calculation (ENG-1093)
      modCount =
          env.m_client.callProcedure(
                  "@AdHoc", "INSERT INTO BLAH VALUES (2, '2011-06-24 10:30:26', 1.12345*1);")
              .getResults()[0];
      assertEquals(1, modCount.getRowCount());
      assertEquals(1, modCount.asScalarLong());
      result =
          env.m_client.callProcedure("@AdHoc", "SELECT * FROM BLAH WHERE IVAL = 2;")
              .getResults()[0];
      assertEquals(1, result.getRowCount());
      System.out.println(result.toString());
    } finally {
      env.tearDown();
    }
  }

  @Test
  public void testAdHocBatches() throws Exception {
    TestEnv env = new TestEnv(m_catalogJar, m_pathToDeployment, 2, 1, 0, m_useIv2);
    try {
      env.setUp();
      Batcher batcher = new Batcher(env);

      // a few inserts (with a couple of ignored blank statements)
      batcher.add("INSERT INTO BLAH VALUES (100, '2012-05-21 12:00:00.000000', 1000)", 1);
      batcher.add("", null);
      batcher.add("INSERT INTO BLAH VALUES (101, '2012-05-21 12:01:00.000000', 1001)", 1);
      batcher.add("", null);
      batcher.add("INSERT INTO BLAH VALUES (102, '2012-05-21 12:02:00.000000', 1002)", 1);
      batcher.add("INSERT INTO BLAH VALUES (103, '2012-05-21 12:03:00.000000', 1003)", 1);
      batcher.add("INSERT INTO BLAH VALUES (104, '2012-05-21 12:04:00.000000', 1004)", 1);
      batcher.run();

      // a few selects using data inserted by previous batch
      batcher.add("SELECT * FROM BLAH WHERE IVAL = 102", 1);
      batcher.add("SELECT * FROM BLAH WHERE DVAL >= 1001 AND DVAL <= 1002", 2);
      batcher.add("SELECT * FROM BLAH WHERE DVAL >= 1002 AND DVAL <= 1004", 3);
      batcher.run();

      // mixed reads and writes (start from a clean slate)
      batcher.addUnchecked("DELETE FROM BLAH");
      batcher.run();
      batcher.add("INSERT INTO BLAH VALUES (100, '2012-05-21 12:00:00.000000', 1000)", 1);
      batcher.add("INSERT INTO BLAH VALUES (101, '2012-05-21 12:00:00.000000', 1001)", 1);
      batcher.add("INSERT INTO BLAH VALUES (102, '2012-05-21 12:00:00.000000', 1002)", 1);
      batcher.add("DELETE FROM BLAH WHERE IVAL = 100", 1);
      batcher.add("SELECT * FROM BLAH", 2);
      batcher.add("DELETE FROM BLAH WHERE IVAL = 101", 1);
      batcher.add("SELECT * FROM BLAH WHERE IVAL = 101", 0);
      batcher.add("UPDATE BLAH SET DVAL = 0 WHERE IVAL = 102", 1);
      batcher.run();

      // mix replicated and partitioned
      batcher.addUnchecked("DELETE FROM PARTED1");
      batcher.addUnchecked("DELETE FROM REPPED1");
      for (int i = 1; i <= 10; i++) {
        batcher.add(String.format("INSERT INTO PARTED1 VALUES (%d, %d)", i, 100 + i), 1);
        batcher.add(String.format("INSERT INTO REPPED1 VALUES (%d, %d)", i, 100 + i), 1);
      }
      batcher.run();
      batcher.add("SELECT * FROM PARTED1", 10);
      batcher.add("SELECT * FROM REPPED1", 10);
      batcher.add("DELETE FROM PARTED1 WHERE PARTVAL > 5", 5);
      batcher.add("DELETE FROM REPPED1 WHERE REPPEDVAL > 5", 5);
      batcher.add("SELECT * FROM PARTED1", 5);
      batcher.add("SELECT * FROM REPPED1", 5);
      batcher.run();

      // roll-back entire batch if one statement fails (start from a clean slate)
      batcher.addUnchecked("DELETE FROM BLAH");
      batcher.run();
      batcher.add("INSERT INTO BLAH VALUES (100, '2012-05-21 12:00:00.000000', 1000)", 1);
      batcher.run();
      // this should succeed, but won't due to the failure below
      batcher.add("INSERT INTO BLAH VALUES (101, '2012-05-21 12:00:00.000000', 1001)", 0);
      // this will fail the batch due to a PK constraint violation
      batcher.add("INSERT INTO BLAH VALUES (100, '2012-05-21 12:00:00.000000', 1000)", 0);
      batcher.runWithException();
      // expect 1 row, not 2.
      batcher.add("SELECT * FROM BLAH", 1);
      batcher.run();
    } finally {
      env.tearDown();
    }
  }

  /** Builds and validates query batch runs. */
  private static class Batcher {
    private final TestEnv m_env;
    private final List<Integer> m_expectedCounts = new ArrayList<Integer>();
    private final List<String> m_queries = new ArrayList<String>();

    public Batcher(final TestEnv env) {
      m_env = env;
    }

    void add(String query, Integer expectedCount) {
      m_queries.add(query);
      if (expectedCount != null) {
        m_expectedCounts.add(expectedCount);
      }
    }

    void addUnchecked(String query) {
      m_queries.add(query);
      m_expectedCounts.add(-1);
    }

    void run() throws Exception {
      runAndCheck(false);
    }

    void runWithException() throws Exception {
      runAndCheck(true);
    }

    private void runAndCheck(boolean expectException) throws Exception {
      try {
        VoltTable[] results =
            m_env.m_client.callProcedure("@AdHoc", StringUtils.join(m_queries, "; ")).getResults();
        int i = 0;
        assertEquals(m_expectedCounts.size(), results.length);
        for (String query : m_queries) {
          int expectedCount = m_expectedCounts.get(i);
          if (expectedCount >= 0) {
            String s = query.toLowerCase().trim();
            if (!s.isEmpty()) {
              if (s.startsWith("insert") || s.startsWith("update") || s.startsWith("delete")) {
                assertEquals(String.format("%s (row count):", query), 1, results[i].getRowCount());
                assertEquals(
                    String.format("%s (result count):", query),
                    expectedCount,
                    results[i].asScalarLong());
              } else {
                assertEquals(
                    String.format("%s (row count):", query),
                    expectedCount,
                    results[i].getRowCount());
              }
              i++;
            }
          }
        }
      } catch (ProcCallException e) {
        assertTrue("Unexpected exception for batch: " + e.getMessage(), expectException);
      } finally {
        m_queries.clear();
        m_expectedCounts.clear();
      }
    }
  }

  /** Test environment with configured schema and server. */
  private static class TestEnv {

    final VoltProjectBuilder m_builder;
    LocalCluster m_cluster;
    Client m_client = null;

    TestEnv(
        String pathToCatalog,
        String pathToDeployment,
        int siteCount,
        int hostCount,
        int kFactor,
        boolean enableIv2) {
      m_builder = new VoltProjectBuilder();
      try {
        m_builder.addLiteralSchema(
            "create table BLAH ("
                + "IVAL bigint default 0 not null, "
                + "TVAL timestamp default null,"
                + "DVAL decimal default null,"
                + "PRIMARY KEY(IVAL));");
        m_builder.addPartitionInfo("BLAH", "IVAL");
        m_builder.addStmtProcedure("Insert", "INSERT into BLAH values (?, ?, ?);", null);
        m_builder.addStmtProcedure(
            "InsertWithDate",
            "INSERT INTO BLAH VALUES (974599638818488300, '2011-06-24 10:30:26.002', 5);");

        // add more partitioned and replicated tables, PARTED[1-3] and REPED[1-2]
        AdHocQueryTester.setUpSchema(m_builder, pathToCatalog, pathToDeployment);
      } catch (Exception e) {
        e.printStackTrace();
        fail("Failed to set up schema");
      }

      m_cluster =
          new LocalCluster(
              pathToCatalog,
              siteCount,
              hostCount,
              kFactor,
              BackendTarget.NATIVE_EE_JNI,
              LocalCluster.FailureState.ALL_RUNNING,
              m_debug,
              false,
              enableIv2);
      boolean success = m_cluster.compile(m_builder);
      assert (success);

      try {
        MiscUtils.copyFile(m_builder.getPathToDeployment(), pathToDeployment);
      } catch (Exception e) {
        fail(
            String.format(
                "Failed to copy \"%s\" to \"%s\"",
                m_builder.getPathToDeployment(), pathToDeployment));
      }

      m_cluster.setHasLocalServer(true);
    }

    void setUp() {
      m_cluster.startUp();

      try {
        // do the test
        m_client = ClientFactory.createClient();
        m_client.createConnection("localhost", m_cluster.port(0));
      } catch (UnknownHostException e) {
        e.printStackTrace();
        fail(String.format("Failed to connect to localhost:%d", m_cluster.port(0)));
      } catch (IOException e) {
        e.printStackTrace();
        fail(String.format("Failed to connect to localhost:%d", m_cluster.port(0)));
      }
    }

    void tearDown() {
      if (m_client != null) {
        try {
          m_client.close();
        } catch (InterruptedException e) {
          e.printStackTrace();
          fail("Failed to close client");
        }
      }
      m_client = null;

      if (m_cluster != null) {
        try {
          m_cluster.shutDown();
        } catch (InterruptedException e) {
          e.printStackTrace();
          fail("Failed to shut down cluster");
        }
      }
      m_cluster = null;

      // no clue how helpful this is
      System.gc();
    }
  }
}
  public void testRestoreThenRejoinPropagatesRestore() throws Exception {
    System.out.println("testRestoreThenRejoinThenRestore");
    VoltProjectBuilder builder = getBuilderForTest();
    builder.setSecurityEnabled(true);

    LocalCluster cluster =
        new LocalCluster("rejoin.jar", 2, 2, 1, BackendTarget.NATIVE_EE_JNI, true);
    ServerThread localServer = null;
    try {
      boolean success = cluster.compileWithAdminMode(builder, 9998, false);
      assertTrue(success);
      MiscUtils.copyFile(
          builder.getPathToDeployment(), Configuration.getPathToCatalogForTest("rejoin.xml"));
      cluster.setHasLocalServer(false);

      cluster.startUp();

      Client client;

      client = ClientFactory.createClient(m_cconfig);
      client.createConnection("localhost");

      deleteTestFiles();

      client.callProcedure("@SnapshotSave", TMPDIR, TESTNONCE, (byte) 1).getResults();

      client.callProcedure("@SnapshotRestore", TMPDIR, TESTNONCE);

      cluster.shutDownSingleHost(0);
      Thread.sleep(1000);

      VoltDB.Configuration config = new VoltDB.Configuration();
      config.m_pathToCatalog = Configuration.getPathToCatalogForTest("rejoin.jar");
      config.m_pathToDeployment = Configuration.getPathToCatalogForTest("rejoin.xml");
      config.m_rejoinToHostAndPort = m_username + ":" + m_password + "@localhost:21213";
      config.m_isRejoinTest = true;
      localServer = new ServerThread(config);

      localServer.start();
      localServer.waitForInitialization();

      Thread.sleep(2000);

      client.close();

      assertTrue(org.voltdb.sysprocs.SnapshotRestore.m_haveDoneRestore);

      client = ClientFactory.createClient(m_cconfig);
      client.createConnection("localhost");

      // Also make sure a catalog update doesn't reset m_haveDoneRestore
      File newCatalog = new File(Configuration.getPathToCatalogForTest("rejoin.jar"));
      File deployment = new File(Configuration.getPathToCatalogForTest("rejoin.xml"));

      VoltTable[] results = client.updateApplicationCatalog(newCatalog, deployment).getResults();
      assertTrue(results.length == 1);

      client.close();

      assertTrue(org.voltdb.sysprocs.SnapshotRestore.m_haveDoneRestore);
    } finally {
      cluster.shutDown();
      if (localServer != null) {
        localServer.shutdown();
      }
    }
  }