Package org.voltdb.canonicalddl

Source Code of org.voltdb.canonicalddl.TestCanonicalDDLThroughSQLcmd

/* 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.
*/

/*
* This test is used for testing round trip DDL through Adhoc and SQLcmd.
* We first build a catalog and pull the canonical DDL from it.
* Then we feed this DDL to a bare server through Adhoc/SQLcmd,
* pull the canonical DDL again, and check whether it remains the same.
*/

package org.voltdb.canonicalddl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;

import org.junit.Test;
import org.voltcore.utils.PortGenerator;
import org.voltdb.AdhocDDLTestBase;
import org.voltdb.VoltDB;
import org.voltdb.VoltDB.Configuration;
import org.voltdb.compiler.VoltCompiler;
import org.voltdb.compiler.VoltProjectBuilder;
import org.voltdb.utils.MiscUtils;

public class TestCanonicalDDLThroughSQLcmd extends AdhocDDLTestBase {

    private String firstCanonicalDDL = null;
    private boolean triedSqlcmdDryRun = false;

    private String getFirstCanonicalDDL() throws Exception {
        String pathToCatalog = Configuration.getPathToCatalogForTest("fullDDL.jar");

        VoltCompiler compiler = new VoltCompiler();
        final URL url = TestCanonicalDDLThroughSQLcmd.class.getResource("fullDDL.sql");
        String pathToSchema = URLDecoder.decode(url.getPath(), "UTF-8");
        boolean success = compiler.compileFromDDL(pathToCatalog, pathToSchema);
        assertTrue(success);
        return compiler.getCanonicalDDL();
    }

    private void secondCanonicalDDLFromAdhoc() throws Exception {
        String pathToCatalog = Configuration.getPathToCatalogForTest("emptyDDL.jar");
        String pathToDeployment = Configuration.getPathToCatalogForTest("emptyDDL.xml");

        VoltCompiler compiler = new VoltCompiler();
        VoltProjectBuilder builder = new VoltProjectBuilder();

        builder.setUseDDLSchema(true);
        boolean success = builder.compile(pathToCatalog);
        assertTrue(success);
        MiscUtils.copyFile(builder.getPathToDeployment(), pathToDeployment);

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

        startSystem(config);

        m_client.callProcedure("@AdHoc", firstCanonicalDDL);

        assertEquals(compiler.getCanonicalDDL(), firstCanonicalDDL);

        teardownSystem();
    }

    private void secondCanonicalDDLFromSQLcmd() throws Exception {
        String pathToCatalog = Configuration.getPathToCatalogForTest("emptyDDL.jar");
        String pathToDeployment = Configuration.getPathToCatalogForTest("emptyDDL.xml");

        VoltProjectBuilder builder = new VoltProjectBuilder();

        builder.setUseDDLSchema(true);
        PortGenerator pg = new PortGenerator();
        int httpdPort = pg.next();
        builder.setHTTPDPort(httpdPort);
        boolean success = builder.compile(pathToCatalog);
        assertTrue(success);
        MiscUtils.copyFile(builder.getPathToDeployment(), pathToDeployment);

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

        startSystem(config);

        String roundtripDDL;

        assert(firstCanonicalDDL != null);

        if ( ! triedSqlcmdDryRun) {
            assertEquals("sqlcmd dry run failed -- maybe some sqlcmd component (the voltdb jar file?) needs to be rebuilt.",
                    0, callSQLcmd("\n"));
            triedSqlcmdDryRun = true;
        }

        assertEquals("sqlcmd failed on input:\n" + firstCanonicalDDL, 0, callSQLcmd(firstCanonicalDDL));
        roundtripDDL = getDDLFromHTTP(httpdPort);
        // IZZY: we force single statement SQL keywords to lower case, it seems
        assertTrue(firstCanonicalDDL.equalsIgnoreCase(roundtripDDL));

        assertEquals("sqlcmd failed on last call", 0, callSQLcmd("CREATE TABLE NONSENSE (id INTEGER);\n"));
        roundtripDDL = getDDLFromHTTP(httpdPort);
        assertFalse(firstCanonicalDDL.equals(roundtripDDL));

        teardownSystem();
    }

    private int callSQLcmd(String ddl) throws Exception {
        final String commandPath = "bin/sqlcmd";
        final long timeout = 60000; // 60,000 millis -- give up after 1 minute of trying.

        File f = new File("ddl.sql");
        f.deleteOnExit();
        FileOutputStream fos = new FileOutputStream(f);
        fos.write(ddl.getBytes());
        fos.close();

        File out = new File("out.log");

        File error = new File("error.log");

        ProcessBuilder pb = new ProcessBuilder(commandPath);
        pb.redirectInput(f);
        pb.redirectOutput(out);
        pb.redirectError(error);
        Process process = pb.start();

        // Set timeout to 1 minute
        long starttime = System.currentTimeMillis();
        long elapsedtime = 0;
        long pollcount = 0;
        do {
            Thread.sleep(1000);
            try {
                int exitValue = process.exitValue();
                // Only verbosely report the successful exit after verbosely reporting a delay.
                // Frequent false alarms might lead to raising the sleep time.
                if (pollcount > 0) {
                    elapsedtime = System.currentTimeMillis() - starttime;
                    System.err.println("External process (" + commandPath + ") exited after being polled " +
                            pollcount + " times over " + elapsedtime + "ms");
                }
                return exitValue;
            }
            catch (Exception e) {
                elapsedtime = System.currentTimeMillis() - starttime;
                ++pollcount;
                System.err.println("External process (" + commandPath + ") has not yet exited after " + elapsedtime + "ms");
            }
        } while (elapsedtime < timeout);

        fail("External process (" + commandPath + ") timed out after " + elapsedtime + "ms on input:\n" + ddl);
        return 0;
    }

    private String getDDLFromHTTP(int httpdPort) throws Exception {
        URL ddlURL = new URL(String.format("http://localhost:%d/ddl/", httpdPort));

        HttpURLConnection conn = (HttpURLConnection) ddlURL.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.connect();

        BufferedReader in = null;
        try {
            if (conn.getInputStream() != null) {
                in = new BufferedReader(
                        new InputStreamReader(
                        conn.getInputStream(), "UTF-8"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (in == null) {
            throw new Exception("Unable to read response from server");
        }

        String line;
        StringBuffer sb = new StringBuffer();
        while ((line = in.readLine()) != null) {
            sb.append(line + "\n");
        }

        return sb.toString();
    }

    @Test
    public void testCanonicalDDLRoundtrip() throws Exception {
        firstCanonicalDDL = getFirstCanonicalDDL();

        secondCanonicalDDLFromAdhoc();
        secondCanonicalDDLFromSQLcmd();
    }
}
TOP

Related Classes of org.voltdb.canonicalddl.TestCanonicalDDLThroughSQLcmd

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.