http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestSimpleParser.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestSimpleParser.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestSimpleParser.java new file mode 100644 index 0000000..69bf30a --- /dev/null +++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestSimpleParser.java @@ -0,0 +1,286 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.cli.tsql; + +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class TestSimpleParser { + + @Test + public final void testSpecialCases() throws InvalidStatementException { + List<ParsedResult> res1 = SimpleParser.parseScript(""); + assertEquals(0, res1.size()); + + List<ParsedResult> res2 = SimpleParser.parseScript("a"); + assertEquals(1, res2.size()); + + List<ParsedResult> res3 = SimpleParser.parseScript("?"); + assertEquals(0, res3.size()); + + List<ParsedResult> res4 = SimpleParser.parseScript("\\"); + assertEquals(1, res4.size()); + } + + @Test + public final void testMetaCommands() throws InvalidStatementException { + List<ParsedResult> res1 = SimpleParser.parseScript("\\d"); + assertEquals(1, res1.size()); + assertEquals(ParsedResult.StatementType.META, res1.get(0).getType()); + assertEquals("\\d", res1.get(0).getHistoryStatement()); + + List<ParsedResult> res2 = SimpleParser.parseScript("\\d;\\c;\\f;"); + assertEquals(3, res2.size()); + assertEquals(ParsedResult.StatementType.META, res2.get(0).getType()); + assertEquals("\\d", res2.get(0).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.META, res2.get(1).getType()); + assertEquals("\\c", res2.get(1).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.META, res2.get(2).getType()); + assertEquals("\\f", res2.get(2).getHistoryStatement()); + + List<ParsedResult> res3 = SimpleParser.parseScript("\n\t\t \\d;\n\\c;\t\t\\f ;"); + assertEquals(3, res3.size()); + assertEquals(ParsedResult.StatementType.META, res3.get(0).getType()); + assertEquals("\\d", res3.get(0).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.META, res3.get(1).getType()); + assertEquals("\\c", res3.get(1).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.META, res3.get(2).getType()); + assertEquals("\\f", res3.get(2).getHistoryStatement()); + + List<ParsedResult> res4 = SimpleParser.parseScript("\\\td;"); + assertEquals(1, res4.size()); + assertEquals("\\\td", res4.get(0).getHistoryStatement()); + } + + @Test + public final void testParseScript() throws InvalidStatementException { + List<ParsedResult> res1 = SimpleParser.parseScript("select * from test;"); + assertEquals(1, res1.size()); + assertEquals(ParsedResult.StatementType.STATEMENT, res1.get(0).getType()); + assertEquals("select * from test", res1.get(0).getStatement()); + assertEquals("select * from test", res1.get(0).getHistoryStatement()); + + List<ParsedResult> res2 = SimpleParser.parseScript("select * from test;"); + assertEquals(1, res2.size()); + assertEquals(ParsedResult.StatementType.STATEMENT, res2.get(0).getType()); + assertEquals("select * from test", res2.get(0).getStatement()); + assertEquals("select * from test", res2.get(0).getHistoryStatement()); + + List<ParsedResult> res3 = SimpleParser.parseScript("select * from test1;select * from test2;"); + assertEquals(2, res3.size()); + assertEquals(ParsedResult.StatementType.STATEMENT, res3.get(0).getType()); + assertEquals("select * from test1", res3.get(0).getStatement()); + assertEquals("select * from test1", res3.get(0).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.STATEMENT, res3.get(1).getType()); + assertEquals("select * from test2", res3.get(1).getStatement()); + assertEquals("select * from test2", res3.get(1).getHistoryStatement()); + + List<ParsedResult> res4 = SimpleParser.parseScript("\t\t\n\rselect * from \ntest1;select * from test2\n;"); + assertEquals(2, res4.size()); + assertEquals(ParsedResult.StatementType.STATEMENT, res4.get(0).getType()); + assertEquals("select * from \ntest1", res4.get(0).getStatement()); + assertEquals("select * from test1", res4.get(0).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.STATEMENT, res4.get(1).getType()); + assertEquals("select * from test2", res4.get(1).getStatement()); + assertEquals("select * from test2", res4.get(1).getHistoryStatement()); + + List<ParsedResult> res5 = + SimpleParser.parseScript("\t\t\n\rselect * from \ntest1;\\d test;select * from test2;\n\nselect 1;"); + assertEquals(4, res5.size()); + assertEquals(ParsedResult.StatementType.STATEMENT, res5.get(0).getType()); + assertEquals("select * from \ntest1", res5.get(0).getStatement()); + assertEquals("select * from test1", res5.get(0).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.META, res5.get(1).getType()); + assertEquals("\\d test", res5.get(1).getStatement()); + assertEquals(ParsedResult.StatementType.STATEMENT, res5.get(2).getType()); + assertEquals("select * from test2", res5.get(2).getStatement()); + assertEquals("select * from test2", res5.get(2).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.STATEMENT, res5.get(3).getType()); + assertEquals("select 1", res5.get(3).getStatement()); + assertEquals("select 1", res5.get(3).getHistoryStatement()); + + List<ParsedResult> res6 = + SimpleParser.parseScript("select * from \n--test1; select * from test2;\ntest3;"); + assertEquals(1, res6.size()); + assertEquals("select * from test3", res6.get(0).getHistoryStatement()); + assertEquals("select * from \n--test1; select * from test2;\ntest3", res6.get(0).getStatement()); + + List<ParsedResult> res7 = + SimpleParser.parseScript("select * from --test1; select * from test2;\ntest3;"); + assertEquals(1, res7.size()); + assertEquals("select * from test3", res7.get(0).getHistoryStatement()); + assertEquals("select * from --test1; select * from test2;\ntest3", res7.get(0).getStatement()); + + List<ParsedResult> res8 = SimpleParser.parseScript("\\d test\nselect * \n--from test1;\nfrom test2;\\d test2;"); + assertEquals(3, res8.size()); + assertEquals(ParsedResult.StatementType.META, res8.get(0).getType()); + assertEquals("\\d test", res8.get(0).getStatement()); + assertEquals("\\d test", res8.get(0).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.STATEMENT, res8.get(1).getType()); + assertEquals("select * \n--from test1;\nfrom test2", res8.get(1).getStatement()); + assertEquals("select * from test2", res8.get(1).getHistoryStatement()); + assertEquals(ParsedResult.StatementType.META, res8.get(2).getType()); + assertEquals("\\d test2", res8.get(2).getStatement()); + assertEquals("\\d test2", res8.get(2).getHistoryStatement()); + } + + @Test + public final void testParseLines() throws InvalidStatementException { + SimpleParser simpleParser = new SimpleParser(); + List<ParsedResult> res1 = null; + + res1 = simpleParser.parseLines("select * from test1; select * from test2;"); + assertEquals(2, res1.size()); + assertEquals("select * from test1", res1.get(0).getStatement()); + assertEquals("select * from test2", res1.get(1).getStatement()); + assertEquals("select * from test1", res1.get(0).getHistoryStatement()); + assertEquals("select * from test2", res1.get(1).getHistoryStatement()); + + // select * from + // test1; select * from test2; + simpleParser = new SimpleParser(); + res1 = simpleParser.parseLines("select * from "); + assertEquals(0, res1.size()); + res1 = simpleParser.parseLines("test1; select * from test2;"); + assertEquals(2, res1.size()); + assertEquals("select * from \ntest1", res1.get(0).getStatement()); + assertEquals("select * from test2", res1.get(1).getStatement()); + assertEquals("select * from test1", res1.get(0).getHistoryStatement()); + assertEquals("select * from test2", res1.get(1).getHistoryStatement()); + + // select * from + // --test1; select * from test2; + // test3; + simpleParser = new SimpleParser(); + res1 = simpleParser.parseLines("select * from "); + assertEquals(0, res1.size()); + res1 = simpleParser.parseLines("--test1; select * from test2;"); + assertEquals(0, res1.size()); + res1 = simpleParser.parseLines("test3;"); + assertEquals(1, res1.size()); + assertEquals("select * from test3", res1.get(0).getHistoryStatement()); + assertEquals("select * from \n--test1; select * from test2;\ntest3", res1.get(0).getStatement()); + + // select * from + // test1 --select * from test2; + // where col1 = '123'; + simpleParser = new SimpleParser(); + res1 = simpleParser.parseLines("select * from "); + assertEquals(0, res1.size()); + res1 = simpleParser.parseLines("test1 --select * from test2;"); + assertEquals(0, res1.size()); + res1 = simpleParser.parseLines("where col1 = '123';"); + assertEquals(1, res1.size()); + assertEquals("select * from test1 where col1 = '123'", res1.get(0).getHistoryStatement()); + assertEquals("select * from \ntest1 --select * from test2;\nwhere col1 = '123'", res1.get(0).getStatement()); + + // Case for sql statement already including '\n' + // This test is important for tsql because CLI input always has '\n'. + simpleParser = new SimpleParser(); + res1 = simpleParser.parseLines("select\n"); + assertEquals(0, res1.size()); + res1 = simpleParser.parseLines("*\n"); + assertEquals(0, res1.size()); + res1 = simpleParser.parseLines("from\n"); + assertEquals(0, res1.size()); + res1 = simpleParser.parseLines("test1;\n"); + assertEquals(1, res1.size()); + assertEquals("select\n*\nfrom\ntest1", res1.get(0).getStatement()); + assertEquals("select * from test1", res1.get(0).getHistoryStatement()); + } + + @Test + public final void testQuoted() throws InvalidStatementException { + List<ParsedResult> res1 = SimpleParser.parseScript("select '\n;' from test;"); + assertEquals(1, res1.size()); + assertEquals(ParsedResult.StatementType.STATEMENT, res1.get(0).getType()); + assertEquals("select '\n;' from test", res1.get(0).getHistoryStatement()); + assertEquals("select '\n;' from test", res1.get(0).getStatement()); + + List<ParsedResult> res2 = SimpleParser.parseScript("select 'abc\nbbc\nddf' from test;"); + assertEquals(1, res2.size()); + assertEquals(ParsedResult.StatementType.STATEMENT, res2.get(0).getType()); + assertEquals("select 'abc\nbbc\nddf' from test", res2.get(0).getHistoryStatement()); + assertEquals("select 'abc\nbbc\nddf' from test", res2.get(0).getStatement()); + + List<ParsedResult> res3 = SimpleParser.parseScript("select '--test', \n'--test2' from test"); + assertEquals(1, res3.size()); + assertEquals(ParsedResult.StatementType.STATEMENT, res3.get(0).getType()); + assertEquals("select '--test', '--test2' from test", res3.get(0).getHistoryStatement()); + assertEquals("select '--test', \n'--test2' from test", res3.get(0).getStatement()); + + try { + SimpleParser.parseScript("select 'abc"); + assertTrue(false); + } catch (InvalidStatementException is) { + assertTrue(true); + } + } + + @Test + public final void testParseLines1() throws InvalidStatementException { + String [] lines = { + "select abc, ", + "bbc from test" + }; + SimpleParser parser = new SimpleParser(); + List<ParsedResult> result1 = parser.parseLines(lines[0]); + assertEquals(0, result1.size()); + List<ParsedResult> result2 = parser.parseLines(lines[1]); + assertEquals(0, result2.size()); + List<ParsedResult> result3 = parser.EOF(); + assertEquals(1, result3.size()); + assertEquals(lines[0] + lines[1], result3.get(0).getHistoryStatement()); + assertEquals(lines[0] + "\n" + lines[1], result3.get(0).getStatement()); + } + + @Test + public final void testParseLines2() throws InvalidStatementException { + String [] lines = { + "select abc, '", + "bbc' from test; select * from test3;" + }; + SimpleParser parser = new SimpleParser(); + List<ParsedResult> result1 = parser.parseLines(lines[0]); + assertEquals(0, result1.size()); + List<ParsedResult> result2 = parser.parseLines(lines[1]); + assertEquals(2, result2.size()); + assertEquals("select abc, 'bbc' from test", result2.get(0).getHistoryStatement()); + assertEquals("select * from test3", result2.get(1).getHistoryStatement()); + } + + @Test + public final void testParseLines3() throws InvalidStatementException { + String [] lines = { + "select abc, 'bbc", + "' from test; select * from test3;" + }; + SimpleParser parser = new SimpleParser(); + List<ParsedResult> result1 = parser.parseLines(lines[0]); + assertEquals(0, result1.size()); + List<ParsedResult> result2 = parser.parseLines(lines[1]); + assertEquals(2, result2.size()); + assertEquals("select abc, 'bbc' from test", result2.get(0).getHistoryStatement()); + assertEquals("select * from test3", result2.get(1).getHistoryStatement()); + } +}
http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCli.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCli.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCli.java new file mode 100644 index 0000000..e744631 --- /dev/null +++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCli.java @@ -0,0 +1,472 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.cli.tsql; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.PosixParser; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.tajo.ConfigKey; +import org.apache.tajo.SessionVars; +import org.apache.tajo.TajoTestingCluster; +import org.apache.tajo.TpchTestBase; +import org.apache.tajo.catalog.CatalogUtil; +import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.client.QueryStatus; +import org.apache.tajo.client.TajoClient; +import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.storage.StorageUtil; +import org.apache.tajo.storage.TablespaceManager; +import org.apache.tajo.util.FileUtil; +import org.junit.*; +import org.junit.rules.TestName; + +import java.io.*; +import java.net.URL; + +import static org.junit.Assert.*; + +public class TestTajoCli { + protected static final TpchTestBase testBase; + protected static final TajoTestingCluster cluster; + + /** the base path of result directories */ + protected static final Path resultBasePath; + static { + testBase = TpchTestBase.getInstance(); + cluster = testBase.getTestingCluster(); + URL resultBaseURL = ClassLoader.getSystemResource("results"); + resultBasePath = new Path(resultBaseURL.toString()); + } + + private TajoCli tajoCli; + private Path currentResultPath; + private ByteArrayOutputStream out; + + @Rule + public TestName name = new TestName(); + + public TestTajoCli() { + String className = getClass().getSimpleName(); + currentResultPath = new Path(resultBasePath, className); + } + + @Before + public void setUp() throws Exception { + out = new ByteArrayOutputStream(); + tajoCli = new TajoCli(cluster.getConfiguration(), new String[]{}, System.in, out); + } + + @After + public void tearDown() throws IOException { + out.close(); + if (tajoCli != null) { + tajoCli.close(); + } + } + + private static void setVar(TajoCli cli, ConfigKey key, String val) throws Exception { + cli.executeMetaCommand("\\set " + key.keyname() + " " + val); + } + + private static void assertSessionVar(TajoCli cli, String key, String expectedVal) { + assertEquals(cli.getContext().getCliSideVar(key), expectedVal); + } + + private void assertOutputResult(String actual) throws Exception { + assertOutputResult(name.getMethodName() + ".result", actual); + } + + private void assertOutputResult(String expectedResultFile, String actual) throws Exception { + assertOutputResult(expectedResultFile, actual, null, null); + } + + private void assertOutputResult(String expectedResultFile, String actual, String[] paramKeys, String[] paramValues) + throws Exception { + FileSystem fs = currentResultPath.getFileSystem(testBase.getTestingCluster().getConfiguration()); + Path resultFile = StorageUtil.concatPath(currentResultPath, expectedResultFile); + assertTrue(resultFile.toString() + " existence check", fs.exists(resultFile)); + + String expectedResult = FileUtil.readTextFile(new File(resultFile.toUri())); + + if (paramKeys != null) { + for (int i = 0; i < paramKeys.length; i++) { + if (i < paramValues.length) { + expectedResult = expectedResult.replace(paramKeys[i], paramValues[i]); + } + } + } + assertEquals(expectedResult.trim(), actual.trim()); + } + + @Test + public void testParseParam() throws Exception { + String[] args = new String[]{"-f", "test.sql", "--param", "test1=10", "--param", "test2=20"}; + + CommandLineParser parser = new PosixParser(); + CommandLine cmd = parser.parse(TajoCli.options, args); + + String fileName = cmd.getOptionValue("f"); + assertNotNull(fileName); + assertEquals(args[1], fileName); + + String[] paramValues = cmd.getOptionValues("param"); + + assertNotNull(paramValues); + assertEquals(2, paramValues.length); + + assertEquals("test1=10", paramValues[0]); + assertEquals("test2=20", paramValues[1]); + } + + @Test + public void testParseConf() throws Exception { + String[] args = new String[]{"--conf", "tajo.cli.print.pause=false", + "--conf", "tajo.executor.join.inner.in-memory-table-num=256"}; + + CommandLineParser parser = new PosixParser(); + CommandLine cmd = parser.parse(TajoCli.options, args); + String[] confValues = cmd.getOptionValues("conf"); + + assertNotNull(confValues); + assertEquals(2, confValues.length); + + assertEquals("tajo.cli.print.pause=false", confValues[0]); + assertEquals("tajo.executor.join.inner.in-memory-table-num=256", confValues[1]); + + TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration(); + TajoCli testCli = new TajoCli(tajoConf, args, System.in, System.out); + try { + assertEquals("false", testCli.getContext().get(SessionVars.CLI_PAGING_ENABLED)); + assertEquals("256", testCli.getContext().getConf().get("tajo.executor.join.inner.in-memory-table-num")); + } finally { + testCli.close(); + } + } + + @Test + public void testReplaceParam() throws Exception { + String sql = "select * from lineitem where l_tax > ${tax} and l_returnflag > '${returnflag}'"; + String[] params = new String[]{"tax=10", "returnflag=A"}; + + + String expected = "select * from lineitem where l_tax > 10 and l_returnflag > 'A'"; + assertEquals(expected, TajoCli.replaceParam(sql, params)); + } + + @Test + public void testLocalQueryWithoutFrom() throws Exception { + String sql = "select 'abc', '123'; select substr('123456', 1,3);"; + setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + tajoCli.executeScript(sql); + String consoleResult = new String(out.toByteArray()); + + assertOutputResult(consoleResult); + } + + @Test + public void testConnectDatabase() throws Exception { + String databaseName; + + if (cluster.isHiveCatalogStoreRunning()) { + databaseName = "TEST_CONNECTION_DATABASE".toLowerCase(); + } else { + databaseName = "TEST_CONNECTION_DATABASE"; + } + String sql = "create database \"" + databaseName + "\";"; + + tajoCli.executeScript(sql); + + tajoCli.executeMetaCommand("\\c " + databaseName); + assertEquals(databaseName, tajoCli.getContext().getCurrentDatabase()); + + tajoCli.executeMetaCommand("\\c default"); + assertEquals("default", tajoCli.getContext().getCurrentDatabase()); + + tajoCli.executeMetaCommand("\\c \"" + databaseName + "\""); + assertEquals(databaseName, tajoCli.getContext().getCurrentDatabase()); + } + + private void verifyDescTable(String sql, String tableName, String resultFileName) throws Exception { + setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + tajoCli.executeScript(sql); + + tajoCli.executeMetaCommand("\\d " + tableName); + tajoCli.executeMetaCommand("\\d \"" + tableName + "\""); + + String consoleResult = new String(out.toByteArray()); + + if (!cluster.isHiveCatalogStoreRunning()) { + assertOutputResult(resultFileName, consoleResult, new String[]{"${table.path}"}, + new String[]{TablespaceManager.getDefault().getTableUri("default", tableName).toString()}); + } + } + + @Test + public void testDescTable() throws Exception { + String tableName; + if (cluster.isHiveCatalogStoreRunning()) { + tableName = "TEST_DESC_TABLE".toLowerCase(); + } else { + tableName = "TEST_DESC_TABLE"; + } + + String sql = "create table \"" + tableName + "\" (col1 int4, col2 int4);"; + verifyDescTable(sql, tableName, "testDescTable.result"); + } + + @Test + public void testDescTableForNestedSchema() throws Exception { + String tableName; + if (cluster.isHiveCatalogStoreRunning()) { + tableName = "TEST_DESC_TABLE_NESTED".toLowerCase(); + } else { + tableName = "TEST_DESC_TABLE_NESTED"; + } + + String sql = "create table \"" + tableName + "\" (col1 int4, col2 int4, col3 record (col4 record (col5 text)));"; + verifyDescTable(sql, tableName, "testDescTableForNestedSchema.result"); + } + + @Test + public void testSelectResultWithNullFalse() throws Exception { + String sql = + "select\n" + + " c_custkey,\n" + + " orders.o_orderkey,\n" + + " orders.o_orderstatus \n" + + "from\n" + + " orders full outer join customer on c_custkey = o_orderkey\n" + + "order by\n" + + " c_custkey,\n" + + " orders.o_orderkey;\n"; + + setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + tajoCli.executeScript(sql); + + String consoleResult = new String(out.toByteArray()); + assertOutputResult(consoleResult); + } + + private void verifySelectResultWithNullTrue() throws Exception { + String sql = + "select\n" + + " c_custkey,\n" + + " orders.o_orderkey,\n" + + " orders.o_orderstatus \n" + + "from\n" + + " orders full outer join customer on c_custkey = o_orderkey\n" + + "order by\n" + + " c_custkey,\n" + + " orders.o_orderkey;\n"; + + + setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + assertSessionVar(tajoCli, SessionVars.CLI_NULL_CHAR.keyname(), "testnull"); + + tajoCli.executeScript(sql); + + String consoleResult = new String(out.toByteArray()); + assertOutputResult(consoleResult); + } + + @Test + public void testSelectResultWithNullTrueDeprecated() throws Exception { + setVar(tajoCli, TajoConf.ConfVars.$CLI_NULL_CHAR, "testnull"); + verifySelectResultWithNullTrue(); + } + + @Test + public void testSelectResultWithNullTrue() throws Exception { + setVar(tajoCli, SessionVars.CLI_NULL_CHAR, "testnull"); + verifySelectResultWithNullTrue(); + } + + private void verifyStopWhenError() throws Exception { + setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + + assertSessionVar(tajoCli, SessionVars.ON_ERROR_STOP.keyname(), "true"); + + tajoCli.executeScript("select count(*) from lineitem; " + + "select count(*) from lineitem2; " + + "select count(*) from orders"); + + String consoleResult = new String(out.toByteArray()); + assertOutputResult(consoleResult); + } + + @Test + public void testGetConf() throws Exception { + TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration(); + setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + TajoCli tajoCli = new TajoCli(tajoConf, new String[]{}, System.in, out); + try { + tajoCli.executeMetaCommand("\\getconf tajo.rootdir"); + + String consoleResult = new String(out.toByteArray()); + assertEquals(consoleResult, tajoCli.getContext().getConf().getVar(TajoConf.ConfVars.ROOT_DIR) + "\n"); + } finally { + tajoCli.close(); + } + } + + @Test + public void testShowMasters() throws Exception { + TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration(); + setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + TajoCli tajoCli = new TajoCli(tajoConf, new String[]{}, System.in, out); + tajoCli.executeMetaCommand("\\admin -showmasters"); + + String consoleResult = new String(out.toByteArray()); + + String masterAddress = tajoCli.getContext().getConf().getVar(TajoConf.ConfVars.TAJO_MASTER_UMBILICAL_RPC_ADDRESS); + String host = masterAddress.split(":")[0]; + tajoCli.close(); + assertEquals(consoleResult, host + "\n"); + } + + @Test + public void testStopWhenErrorDeprecated() throws Exception { + tajoCli.executeMetaCommand("\\set tajo.cli.error.stop true"); + verifyStopWhenError(); + } + + @Test + public void testStopWhenError() throws Exception { + tajoCli.executeMetaCommand("\\set ON_ERROR_STOP true"); + verifyStopWhenError(); + } + + @Test + public void testHelpSessionVars() throws Exception { + tajoCli.executeMetaCommand("\\help set"); + assertOutputResult(new String(out.toByteArray())); + } + + @Test + public void testTimeZoneSessionVars1() throws Exception { + tajoCli.executeMetaCommand("\\set TIMEZONE GMT+1"); + tajoCli.executeMetaCommand("\\set"); + String output = new String(out.toByteArray()); + assertTrue(output.contains("'TIMEZONE'='GMT+1'")); + } + + @Test + public void testTimeZoneSessionVars2() throws Exception { + tajoCli.executeScript("SET TIME ZONE 'GMT+2'"); + tajoCli.executeMetaCommand("\\set"); + String output = new String(out.toByteArray()); + assertTrue(output.contains("'TIMEZONE'='GMT+2'")); + } + + @Test + public void testTimeZoneTest1() throws Exception { + String tableName = "test1"; + tajoCli.executeMetaCommand("\\set TIMEZONE GMT+0"); + tajoCli.executeScript("create table " + tableName + " (col1 TIMESTAMP)"); + tajoCli.executeScript("insert into " + tableName + " select to_timestamp(0)"); + tajoCli.executeScript("select * from " + tableName); + String consoleResult = new String(out.toByteArray()); + tajoCli.executeScript("DROP TABLE " + tableName + " PURGE"); + assertTrue(consoleResult.contains("1970-01-01 00:00:00")); + } + + @Test + public void testTimeZoneTest2() throws Exception { + String tableName = "test1"; + tajoCli.executeMetaCommand("\\set TIMEZONE GMT+1"); + tajoCli.executeScript("create table " + tableName + " (col1 TIMESTAMP)"); + tajoCli.executeScript("insert into " + tableName + " select to_timestamp(0)"); + tajoCli.executeScript("select * from " + tableName); + String consoleResult = new String(out.toByteArray()); + tajoCli.executeScript("DROP TABLE " + tableName + " PURGE"); + assertTrue(consoleResult.contains("1970-01-01 01:00:00")); + } + + @Test(timeout = 3000) + public void testNonForwardQueryPause() throws Exception { + final String sql = "select * from default.lineitem"; + TajoCli cli = null; + try { + TableDesc tableDesc = cluster.getMaster().getCatalog().getTableDesc("default", "lineitem"); + assertNotNull(tableDesc); + assertEquals(0L, tableDesc.getStats().getNumRows().longValue()); + + InputStream testInput = new ByteArrayInputStream(new byte[]{(byte) DefaultTajoCliOutputFormatter.QUIT_COMMAND}); + cli = new TajoCli(cluster.getConfiguration(), new String[]{}, testInput, out); + setVar(cli, SessionVars.CLI_PAGE_ROWS, "2"); + setVar(cli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + + cli.executeScript(sql); + + String consoleResult; + consoleResult = new String(out.toByteArray()); + assertOutputResult(consoleResult); + } finally { + cli.close(); + } + } + + @Test + public void testAlterTableAddDropPartition() throws Exception { + String tableName = CatalogUtil.normalizeIdentifier("testAlterTableAddPartition"); + + tajoCli.executeScript("create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8)"); + tajoCli.executeScript("alter table " + tableName + " add partition (key2 = 0.1)"); + tajoCli.executeScript("alter table " + tableName + " add partition (key = 0.1)"); + tajoCli.executeScript("alter table " + tableName + " drop partition (key = 0.1)"); + tajoCli.executeScript("alter table " + tableName + " drop partition (key = 0.1)"); + + tajoCli.executeScript("drop table " + tableName); + tajoCli.executeScript("create table " + tableName + + " (col1 int4, col2 int4) partition by column(col3 float8, col4 int4)"); + + TajoClient client = testBase.getTestingCluster().newTajoClient(); + TableDesc tableDesc = client.getTableDesc(tableName); + + String partitionLocation = tableDesc.getUri().toString() + "/col5=0.1/col6=10"; + tajoCli.executeScript("alter table " + tableName + " add partition (col3 = 0.1, col4 = 10)" + + " location '" + partitionLocation + "'"); + + Path partitionPath = new Path(partitionLocation); + FileSystem fs = testBase.getTestingCluster().getDefaultFileSystem(); + assertTrue(fs.exists(partitionPath)); + + tajoCli.executeScript("alter table " + tableName + " drop partition (col3 = 0.1, col4 = 10)"); + + String consoleResult = new String(out.toByteArray()); + assertOutputResult(consoleResult); + } + + public static class TajoCliOutputTestFormatter extends DefaultTajoCliOutputFormatter { + @Override + protected String getResponseTimeReadable(float responseTime) { + return ""; + } + @Override + public void printProgress(PrintWriter sout, QueryStatus status) { + //nothing to do + } + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java new file mode 100644 index 0000000..edbeff6 --- /dev/null +++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/TestTajoCliNegatives.java @@ -0,0 +1,146 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.cli.tsql; + +import org.apache.hadoop.fs.Path; +import org.apache.tajo.ConfigKey; +import org.apache.tajo.QueryTestCaseBase; +import org.apache.tajo.SessionVars; +import org.apache.tajo.client.QueryStatus; +import org.apache.tajo.util.FileUtil; +import org.junit.*; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; + +import static org.junit.Assert.assertEquals; + +public class TestTajoCliNegatives extends QueryTestCaseBase { + private static TajoCli tajoCli; + private static ByteArrayOutputStream out; + + @BeforeClass + public static void setUp() throws Exception { + out = new ByteArrayOutputStream(); + tajoCli = new TajoCli(testingCluster.getConfiguration(), new String[]{}, System.in, out); + } + + @AfterClass + public static void tearDown() throws IOException { + out.close(); + if (tajoCli != null) { + tajoCli.close(); + } + } + + @Before + public void resetConsole() throws IOException { + out.reset(); + } + + public void assertMetaCommandFailures(String cmd) throws Exception { + Path resultFile = getResultFile(getMethodName() + ".result"); + String expected = FileUtil.readTextFile(new File(resultFile.toUri())); + + tajoCli.executeMetaCommand(cmd); + String consoleResult = new String(out.toByteArray()); + assertEquals(expected, consoleResult); + } + + public void assertMetaCommandFailure(String cmd, String expectedMsg) throws Exception { + tajoCli.executeMetaCommand(cmd); + String consoleResult = new String(out.toByteArray()); + assertEquals(expectedMsg, consoleResult); + } + + public void assertScriptFailure(String cmd) throws Exception { + Path resultFile = getResultFile(getMethodName() + ".result"); + String expected = FileUtil.readTextFile(new File(resultFile.toUri())); + + tajoCli.executeScript(cmd); + String consoleResult = new String(out.toByteArray()); + assertEquals(expected, consoleResult); + } + + public void assertScriptFailure(String cmd, String expectedMsg) throws Exception { + tajoCli.executeScript(cmd); + String consoleResult = new String(out.toByteArray()); + assertEquals(expectedMsg, consoleResult); + } + + @Test + public void testConnectDatabase() throws Exception { + assertMetaCommandFailure("\\c unknown_db", "ERROR: database 'unknown_db' does not exist"); + } + + @Test + public void testDescTable() throws Exception { + assertMetaCommandFailure("\\d unknown_table", "ERROR: relation 'unknown_table' does not exist\n"); + } + + @Test + public void testQueryVerification() throws Exception { + assertScriptFailure("select * from unknown_table", "ERROR: relation 'default.unknown_table' does not exist\n"); + } + + @Test + public void testQuerySyntax() throws Exception { + assertScriptFailure("select * from unknown-table"); + } + + private static void setVar(TajoCli cli, ConfigKey key, String val) throws Exception { + cli.executeMetaCommand("\\set " + key.keyname() + " " + val); + } + + public static class TajoCliOutputTestFormatter extends DefaultTajoCliOutputFormatter { + @Override + protected String getResponseTimeReadable(float responseTime) { + return ""; + } + @Override + public void printProgress(PrintWriter sout, QueryStatus status) { + //nothing to do + } + } + + @Test + public void testQueryNotImplementedFeature() throws Exception { + + try { + client.updateQuery("CREATE DATABASE TestTajoCliNegatives"); + client.updateQuery("CREATE TABLE TestTajoCliNegatives.table12u79 ( name RECORD(last TEXT, first TEXT) )"); + + assertScriptFailure("select name FROM TestTajoCliNegatives.table12u79", + "ERROR: not implemented feature: record field projection\n"); + + } finally { + client.updateQuery("DROP TABLE IF EXISTS TestTajoCliNegatives.table12u79"); + client.updateQuery("DROP DATABASE IF EXISTS TestTajoCliNegatives"); + } + } + + @Test + public void testQueryFailure() throws Exception { + setVar(tajoCli, SessionVars.CLI_FORMATTER_CLASS, TajoCliOutputTestFormatter.class.getName()); + assertScriptFailure("select fail(3, l_orderkey, 'testQueryFailure') from default.lineitem" , + "ERROR: No error message\n"); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestExecExternalShellCommand.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestExecExternalShellCommand.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestExecExternalShellCommand.java new file mode 100644 index 0000000..ed7ee4a --- /dev/null +++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestExecExternalShellCommand.java @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.cli.tsql.commands; + +import org.apache.tajo.TpchTestBase; +import org.apache.tajo.cli.tsql.TajoCli; +import org.apache.tajo.conf.TajoConf; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; + +import static org.junit.Assert.assertEquals; + +public class TestExecExternalShellCommand { + @Test + public void testCommand() throws Exception { + TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + TajoCli cli = new TajoCli(tajoConf, new String[]{}, null, out); + + cli.executeMetaCommand("\\! echo \"this is test\""); + String consoleResult = new String(out.toByteArray()); + assertEquals("this is test\n", consoleResult); + + assertEquals(-1, cli.executeMetaCommand("\\! error_command")); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestHdfsCommand.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestHdfsCommand.java b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestHdfsCommand.java new file mode 100644 index 0000000..496c7e3 --- /dev/null +++ b/tajo-core-tests/src/test/java/org/apache/tajo/cli/tsql/commands/TestHdfsCommand.java @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.cli.tsql.commands; + +import org.apache.tajo.TpchTestBase; +import org.apache.tajo.cli.tsql.TajoCli; +import org.apache.tajo.conf.TajoConf; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.Assert.assertEquals; + +public class TestHdfsCommand { + @Test + public void testHdfCommand() throws Exception { + TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + System.setOut(new PrintStream(out)); + System.setErr(new PrintStream(out)); + TajoCli cli = new TajoCli(tajoConf, new String[]{}, null, out); + + cli.executeMetaCommand("\\dfs -test"); + String consoleResult = new String(out.toByteArray()); + assertEquals("-test: Not enough arguments: expected 1 but got 0\n" + + "Usage: hadoop fs [generic options] -test -[defsz] <path>\n", consoleResult); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/client/TestCatalogAdminClientExceptions.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/client/TestCatalogAdminClientExceptions.java b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestCatalogAdminClientExceptions.java new file mode 100644 index 0000000..4b8000d --- /dev/null +++ b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestCatalogAdminClientExceptions.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.client; + +import org.apache.hadoop.fs.Path; +import org.apache.tajo.LocalTajoTestingUtility; +import org.apache.tajo.QueryTestCaseBase; +import org.apache.tajo.TajoTestingCluster; +import org.apache.tajo.TpchTestBase; +import org.apache.tajo.catalog.Schema; +import org.apache.tajo.catalog.TableMeta; +import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.exception.*; +import org.apache.tajo.util.KeyValueSet; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.net.URI; + +import static org.junit.Assert.assertFalse; + +public class TestCatalogAdminClientExceptions extends QueryTestCaseBase { + private static TajoTestingCluster cluster; + private static TajoClient client; + + @BeforeClass + public static void setUp() throws Exception { + cluster = TpchTestBase.getInstance().getTestingCluster(); + client = cluster.newTajoClient(); + } + + @AfterClass + public static void tearDown() throws Exception { + client.close(); + } + + @Test(expected = DuplicateDatabaseException.class) + public final void testCreateDatabase() throws TajoException { + client.createDatabase("default"); // duplicate database + } + + @Test + public final void testExistDatabase() { + assertFalse(client.existDatabase("unknown-database")); // unknown database + } + + @Test(expected = UndefinedDatabaseException.class) + public final void testDropDatabase() throws TajoException { + client.dropDatabase("unknown-database"); // unknown database + } + + @Test(expected = UnavailableTableLocationException.class) + public final void testCreateExternalTableUnavailableLocation() throws TajoException { + client.createExternalTable("table128237", new Schema(), URI.create("/tajo/test1bcd"), + new TableMeta("TEXT", new KeyValueSet())); + } + + @Test(expected = DuplicateTableException.class) + public final void testCreateExternalTableDuplicated() throws TajoException { + client.createExternalTable("default.lineitem", new Schema(), URI.create("/"), + new TableMeta("TEXT", new KeyValueSet())); + } + + @Test(expected = InsufficientPrivilegeException.class) + public final void testCreateExternalTableInsufficientPrivilege() throws TajoException { + Path p = TajoConf.getWarehouseDir(conf); + client.createExternalTable("information_schema.table1237891", new Schema(), p.toUri(), + new TableMeta("TEXT", new KeyValueSet())); + } + + @Test(expected = UndefinedTableException.class) + public final void testDropTableAbsent() throws UndefinedTableException, InsufficientPrivilegeException { + client.dropTable("unknown-table"); // unknown table + } + + @Test(expected = InsufficientPrivilegeException.class) + public final void testDropTableInsufficient() throws UndefinedTableException, InsufficientPrivilegeException { + client.dropTable("information_schema.tables"); // cannot be dropped + } + + @Test(expected = UndefinedTableException.class) + public final void testGetTableDesc() throws UndefinedTableException { + client.getTableDesc("unknown-table"); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/client/TestQueryClientExceptions.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/client/TestQueryClientExceptions.java b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestQueryClientExceptions.java new file mode 100644 index 0000000..0457e23 --- /dev/null +++ b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestQueryClientExceptions.java @@ -0,0 +1,121 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.client; + +import org.apache.tajo.LocalTajoTestingUtility; +import org.apache.tajo.TajoTestingCluster; +import org.apache.tajo.TpchTestBase; +import org.apache.tajo.annotation.NotThreadSafe; +import org.apache.tajo.error.Errors; +import org.apache.tajo.exception.*; +import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +@NotThreadSafe +public class TestQueryClientExceptions { + private static TajoTestingCluster cluster; + private static TajoClient client; + + @BeforeClass + public static void setUp() throws Exception { + cluster = TpchTestBase.getInstance().getTestingCluster(); + client = cluster.newTajoClient(); + } + + @AfterClass + public static void tearDown() throws Exception { + client.close(); + } + + @Test + public void testExecuteQuery() { + // This is just an error propagation unit test. Specified SQL errors will be addressed in other unit tests. + ReturnState state = client.executeQuery("select * from unknown_table").getState(); + assertEquals(Errors.ResultCode.UNDEFINED_TABLE, state.getReturnCode()); + + state = client.executeQuery("create table default.lineitem (name int);").getState(); + assertEquals(Errors.ResultCode.DUPLICATE_TABLE, state.getReturnCode()); + } + + @Test(expected = DuplicateTableException.class) + public void testUpdateQuery() throws TajoException { + client.updateQuery("create table default.lineitem (name int);"); + } + + @Test(expected = UndefinedTableException.class) + public void testExecuteQueryAndGetResult() throws TajoException { + // This is just an error propagation unit test. Specified SQL errors will be addressed in other unit tests. + client.executeQueryAndGetResult("select * from unknown_table"); + } + + @Test + public void testCloseQuery() { + // absent query id + client.closeQuery(LocalTajoTestingUtility.newQueryId()); + client.closeNonForwardQuery(LocalTajoTestingUtility.newQueryId()); + } + + @Test(expected = UndefinedDatabaseException .class) + public void testSelectDatabase() throws UndefinedDatabaseException { + // absent database name + client.selectDatabase("unknown_db"); + } + + @Test(expected = NoSuchSessionVariableException.class) + public void testGetSessionVar() throws NoSuchSessionVariableException { + // absent session variable + client.getSessionVariable("unknown-var"); + } + + @Test(expected = QueryNotFoundException.class) + public void testGetQueryResult() throws TajoException { + // absent query id + client.getQueryResult(LocalTajoTestingUtility.newQueryId()); + } + + @Test(expected = QueryNotFoundException.class) + public void testGetResultResponse() throws TajoException { + // absent query id + client.getResultResponse(LocalTajoTestingUtility.newQueryId()); + } + + @Test(expected = QueryNotFoundException.class) + public void testFetchNextQueryResult() throws TajoException { + client.fetchNextQueryResult(LocalTajoTestingUtility.newQueryId(), 100); + } + + @Test(expected = QueryNotFoundException.class) + public void testKillQuery() throws QueryNotFoundException { + client.killQuery(LocalTajoTestingUtility.newQueryId()); + } + + @Test(expected = QueryNotFoundException.class) + public void testGetQueryInfo() throws QueryNotFoundException { + client.getQueryInfo(LocalTajoTestingUtility.newQueryId()); + } + + @Test(expected = QueryNotFoundException.class) + public void testGetQueryHistory() throws QueryNotFoundException { + client.getQueryHistory(LocalTajoTestingUtility.newQueryId()); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/client/TestTajoClient.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/client/TestTajoClient.java b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestTajoClient.java new file mode 100644 index 0000000..93a48f0 --- /dev/null +++ b/tajo-core-tests/src/test/java/org/apache/tajo/client/TestTajoClient.java @@ -0,0 +1,775 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.client; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.tajo.*; +import org.apache.tajo.TajoProtos.QueryState; +import org.apache.tajo.annotation.NotThreadSafe; +import org.apache.tajo.catalog.CatalogUtil; +import org.apache.tajo.catalog.FunctionDesc; +import org.apache.tajo.catalog.TableDesc; +import org.apache.tajo.catalog.proto.CatalogProtos; +import org.apache.tajo.conf.TajoConf; +import org.apache.tajo.exception.TajoException; +import org.apache.tajo.exception.UnsupportedException; +import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.ipc.ClientProtos.QueryHistoryProto; +import org.apache.tajo.ipc.ClientProtos.QueryInfoProto; +import org.apache.tajo.ipc.ClientProtos.StageHistoryProto; +import org.apache.tajo.storage.StorageConstants; +import org.apache.tajo.storage.StorageUtil; +import org.apache.tajo.util.CommonTestingUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.IOException; +import java.io.InputStream; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +import static org.junit.Assert.*; + +@Category(IntegrationTest.class) +@NotThreadSafe +public class TestTajoClient { + private static TajoTestingCluster cluster; + private static TajoConf conf; + private static TajoClient client; + private static Path testDir; + + @BeforeClass + public static void setUp() throws Exception { + cluster = TpchTestBase.getInstance().getTestingCluster(); + conf = cluster.getConfiguration(); + client = cluster.newTajoClient(); + testDir = CommonTestingUtil.getTestDir(); + } + + @AfterClass + public static void tearDown() throws Exception { + client.close(); + } + + private static Path writeTmpTable(String tableName) throws IOException { + Path tablePath = StorageUtil.concatPath(testDir, tableName); + BackendTestingUtil.writeTmpTable(conf, tablePath); + return tablePath; + } + + @Test + public final void testCreateAndDropDatabases() throws TajoException { + int currentNum = client.getAllDatabaseNames().size(); + + String prefix = CatalogUtil.normalizeIdentifier("testCreateDatabase_"); + for (int i = 0; i < 10; i++) { + // test allDatabaseNames + assertEquals(currentNum + i, client.getAllDatabaseNames().size()); + + // test existence + assertFalse(client.existDatabase(prefix + i)); + client.createDatabase(prefix + i); + assertTrue(client.existDatabase(prefix + i)); + + // test allDatabaseNames + assertEquals(currentNum + i + 1, client.getAllDatabaseNames().size()); + assertTrue(client.getAllDatabaseNames().contains(prefix + i)); + } + + // test dropDatabase, existDatabase and getAllDatabaseNames() + for (int i = 0; i < 10; i++) { + assertTrue(client.existDatabase(prefix + i)); + assertTrue(client.getAllDatabaseNames().contains(prefix + i)); + client.dropDatabase(prefix + i); + assertFalse(client.existDatabase(prefix + i)); + assertFalse(client.getAllDatabaseNames().contains(prefix + i)); + } + + assertEquals(currentNum, client.getAllDatabaseNames().size()); + } + + @Test + public final void testCurrentDatabase() throws IOException, TajoException, InterruptedException { + int currentNum = client.getAllDatabaseNames().size(); + assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, client.getCurrentDatabase()); + + String databaseName = CatalogUtil.normalizeIdentifier("testcurrentdatabase"); + client.createDatabase(databaseName); + assertEquals(currentNum + 1, client.getAllDatabaseNames().size()); + assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, client.getCurrentDatabase()); + client.selectDatabase(databaseName); + assertEquals(databaseName, client.getCurrentDatabase()); + client.selectDatabase(TajoConstants.DEFAULT_DATABASE_NAME); + client.dropDatabase(databaseName); + + assertEquals(currentNum, client.getAllDatabaseNames().size()); + } + + @Test + public final void testSelectDatabaseToInvalidOne() throws IOException, TajoException, InterruptedException { + int currentNum = client.getAllDatabaseNames().size(); + assertFalse(client.existDatabase("invaliddatabase")); + + try { + client.selectDatabase("invaliddatabase"); + assertFalse(true); + } catch (Throwable t) { + assertFalse(false); + } + + assertEquals(currentNum, client.getAllDatabaseNames().size()); + } + + @Test + public final void testDropCurrentDatabase() throws IOException, TajoException, InterruptedException { + int currentNum = client.getAllDatabaseNames().size(); + String databaseName = CatalogUtil.normalizeIdentifier("testdropcurrentdatabase"); + client.createDatabase(databaseName); + client.selectDatabase(databaseName); + assertEquals(databaseName, client.getCurrentDatabase()); + + try { + client.dropDatabase(databaseName); + assertFalse(true); + } catch (Throwable t) { + assertFalse(false); + } + + client.selectDatabase(TajoConstants.DEFAULT_DATABASE_NAME); + client.dropDatabase(databaseName); + assertEquals(currentNum, client.getAllDatabaseNames().size()); + } + + @Test + public final void testSessionVariables() throws IOException, TajoException, InterruptedException { + String prefixName = "key_"; + String prefixValue = "val_"; + + List<String> unsetList = new ArrayList<>(); + for(Map.Entry<String, String> entry: client.getAllSessionVariables().entrySet()) { + unsetList.add(entry.getKey()); + } + client.unsetSessionVariables(unsetList); + + for (int i = 0; i < 10; i++) { + String key = prefixName + i; + String val = prefixValue + i; + + // Basically, + assertEquals(i + 4, client.getAllSessionVariables().size()); + assertFalse(client.getAllSessionVariables().containsKey(key)); + assertFalse(client.existSessionVariable(key)); + + Map<String, String> map = Maps.newHashMap(); + map.put(key, val); + client.updateSessionVariables(map); + + assertEquals(i + 5, client.getAllSessionVariables().size()); + assertTrue(client.getAllSessionVariables().containsKey(key)); + assertTrue(client.existSessionVariable(key)); + } + + int totalSessionVarNum = client.getAllSessionVariables().size(); + + for (int i = 0; i < 10; i++) { + String key = prefixName + i; + + assertTrue(client.getAllSessionVariables().containsKey(key)); + assertTrue(client.existSessionVariable(key)); + + client.unsetSessionVariables(Lists.newArrayList(key)); + + assertFalse(client.getAllSessionVariables().containsKey(key)); + assertFalse(client.existSessionVariable(key)); + } + + assertEquals(totalSessionVarNum - 10, client.getAllSessionVariables().size()); + } + + @Test + public final void testKillQuery() throws IOException, TajoException, InterruptedException { + ClientProtos.SubmitQueryResponse res = client.executeQuery("select sleep(1) from lineitem"); + Thread.sleep(1000); + QueryId queryId = new QueryId(res.getQueryId()); + client.killQuery(queryId); + assertEquals(TajoProtos.QueryState.QUERY_KILLED, client.getQueryStatus(queryId).getState()); + } + + @Test + public final void testUpdateQuery() throws IOException, TajoException { + final String tableName = CatalogUtil.normalizeIdentifier("testUpdateQuery"); + Path tablePath = writeTmpTable(tableName); + + assertFalse(client.existTable(tableName)); + String sql = + "create external table " + tableName + " (deptname text, score integer) " + + "using csv location '" + tablePath + "'"; + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + client.dropTable(tableName); + assertFalse(client.existTable(tableName)); + } + + @Test + public final void testCreateAndDropExternalTable() throws IOException, TajoException { + final String tableName = "testCreateAndDropExternalTable"; + Path tablePath = writeTmpTable(tableName); + LOG.error("Full path:" + tablePath.toUri().getRawPath()); + FileSystem fs = tablePath.getFileSystem(conf); + assertTrue(fs.exists(tablePath)); + + assertFalse(client.existTable(tableName)); + + client.createExternalTable(tableName, BackendTestingUtil.mockupSchema, tablePath.toUri(), BackendTestingUtil.mockupMeta); + assertTrue(client.existTable(tableName)); + client.dropTable(tableName); + assertFalse(client.existTable(tableName)); + fs = tablePath.getFileSystem(conf); + assertTrue(fs.exists(tablePath)); + } + + @Test + public final void testCreateAndPurgeExternalTable() throws IOException, TajoException { + final String tableName = "testCreateAndPurgeExternalTable"; + Path tablePath = writeTmpTable(tableName); + LOG.error("Full path:" + tablePath.toUri().getRawPath()); + FileSystem fs = tablePath.getFileSystem(conf); + assertTrue(fs.exists(tablePath)); + + assertFalse(client.existTable(tableName)); + + client.createExternalTable(tableName, BackendTestingUtil.mockupSchema, tablePath.toUri(), BackendTestingUtil.mockupMeta); + assertTrue(client.existTable(tableName)); + client.dropTable(tableName, true); + assertFalse(client.existTable(tableName)); + fs = tablePath.getFileSystem(conf); + assertFalse("Checking if table data exists", fs.exists(tablePath)); + } + + @Test + public final void testCreateAndDropExternalTableByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropExternalTableByExecuteQuery"); + + Path tablePath = writeTmpTable(tableName); + assertFalse(client.existTable(tableName)); + + String sql = "create external table " + tableName + " (deptname text, score int4) " + "using csv location '" + + tablePath + "'"; + + client.executeQueryAndGetResult(sql); + assertTrue(client.existTable(tableName)); + + client.updateQuery("drop table " + tableName); + assertFalse(client.existTable("tableName")); + FileSystem localFS = FileSystem.getLocal(conf); + assertTrue(localFS.exists(tablePath)); + } + + @Test + public final void testCreateAndPurgeExternalTableByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndPurgeExternalTableByExecuteQuery"); + + Path tablePath = writeTmpTable(tableName); + assertFalse(client.existTable(tableName)); + + String sql = "create external table " + tableName + " (deptname text, score int4) " + "using csv location '" + + tablePath + "'"; + + client.executeQueryAndGetResult(sql); + assertTrue(client.existTable(tableName)); + + client.updateQuery("drop table " + tableName + " purge"); + assertFalse(client.existTable(tableName)); + FileSystem localFS = FileSystem.getLocal(conf); + assertFalse(localFS.exists(tablePath)); + } + + @Test + public final void testCreateAndDropTableByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropTableByExecuteQuery"); + + assertFalse(client.existTable(tableName)); + + String sql = "create table " + tableName + " (deptname text, score int4)"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + Path tablePath = new Path(client.getTableDesc(tableName).getUri()); + FileSystem hdfs = tablePath.getFileSystem(conf); + assertTrue(hdfs.exists(tablePath)); + + client.updateQuery("drop table " + tableName); + assertFalse(client.existTable(tableName)); + assertTrue(hdfs.exists(tablePath)); + } + + @Test + public final void testCreateAndPurgeTableByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndPurgeTableByExecuteQuery"); + + assertFalse(client.existTable(tableName)); + + String sql = "create table " + tableName + " (deptname text, score int4)"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + Path tablePath = new Path(client.getTableDesc(tableName).getUri()); + FileSystem hdfs = tablePath.getFileSystem(conf); + assertTrue(hdfs.exists(tablePath)); + + client.updateQuery("drop table " + tableName + " purge"); + assertFalse(client.existTable(tableName)); + assertFalse(hdfs.exists(tablePath)); + } + + @Test + public final void testDDLByExecuteQuery() throws IOException, TajoException { + final String tableName = CatalogUtil.normalizeIdentifier("testDDLByExecuteQuery"); + Path tablePath = writeTmpTable(tableName); + + assertFalse(client.existTable(tableName)); + String sql = + "create external table " + tableName + " (deptname text, score int4) " + + "using csv location '" + tablePath + "'"; + client.executeQueryAndGetResult(sql); + assertTrue(client.existTable(tableName)); + } + + @Test + public final void testGetTableList() throws IOException, TajoException { + String tableName1 = "GetTableList1".toLowerCase(); + String tableName2 = "GetTableList2".toLowerCase(); + + assertFalse(client.existTable(tableName1)); + assertFalse(client.existTable(tableName2)); + client.updateQuery("create table GetTableList1 (age int, name text);"); + client.updateQuery("create table GetTableList2 (age int, name text);"); + + assertTrue(client.existTable(tableName1)); + assertTrue(client.existTable(tableName2)); + + Set<String> tables = Sets.newHashSet(client.getTableList(null)); + assertTrue(tables.contains(tableName1)); + assertTrue(tables.contains(tableName2)); + } + + Log LOG = LogFactory.getLog(TestTajoClient.class); + + @Test + public final void testGetTableDesc() throws IOException, TajoException { + final String tableName1 = CatalogUtil.normalizeIdentifier("table3"); + Path tablePath = writeTmpTable(tableName1); + LOG.error("Full path:" + tablePath.toUri().getRawPath()); + FileSystem fs = tablePath.getFileSystem(conf); + assertTrue(fs.exists(tablePath)); + + assertNotNull(tablePath); + assertFalse(client.existTable(tableName1)); + + client.createExternalTable("table3", BackendTestingUtil.mockupSchema, tablePath.toUri(), BackendTestingUtil.mockupMeta); + assertTrue(client.existTable(tableName1)); + + TableDesc desc = client.getTableDesc(tableName1); + assertNotNull(desc); + assertEquals(CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, tableName1), desc.getName()); + assertTrue(desc.getStats().getNumBytes() > 0); + } + + //@Test + public final void testCreateAndDropTablePartitionedHash1ByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = "testCreateAndDropTablePartitionedHash1ByExecuteQuery"; + + assertFalse(client.existTable(tableName)); + + String sql = "create table " + tableName + " (deptname text, score int4)"; + sql += " PARTITION BY HASH (deptname)"; + sql += " (PARTITION sub_part1, PARTITION sub_part2, PARTITION sub_part3)"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + Path tablePath = new Path(client.getTableDesc(tableName).getUri()); + FileSystem hdfs = tablePath.getFileSystem(conf); + assertTrue(hdfs.exists(tablePath)); + + client.updateQuery("drop table " + tableName); + assertFalse(client.existTable(tableName)); + assertTrue(hdfs.exists(tablePath)); + } + + //@Test + public final void testCreateAndPurgeTablePartitionedHash1ByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = "testCreateAndPurgeTablePartitionedHash1ByExecuteQuery"; + + assertFalse(client.existTable(tableName)); + + String sql = "create table " + tableName + " (deptname text, score int4)"; + sql += " PARTITION BY HASH (deptname)"; + sql += " (PARTITION sub_part1, PARTITION sub_part2, PARTITION sub_part3)"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + Path tablePath = new Path(client.getTableDesc(tableName).getUri()); + FileSystem hdfs = tablePath.getFileSystem(conf); + assertTrue(hdfs.exists(tablePath)); + + client.updateQuery("drop table " + tableName + " purge"); + assertFalse(client.existTable(tableName)); + assertFalse(hdfs.exists(tablePath)); + } + + //@Test + public final void testCreateAndDropTablePartitionedHash2ByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = "testCreateAndDropTablePartitionedHash2ByExecuteQuery"; + + assertFalse(client.existTable(tableName)); + + String sql = "create table " + tableName + " (deptname text, score int4)"; + sql += "PARTITION BY HASH (deptname)"; + sql += "PARTITIONS 2"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + Path tablePath = new Path(client.getTableDesc(tableName).getUri()); + FileSystem hdfs = tablePath.getFileSystem(conf); + assertTrue(hdfs.exists(tablePath)); + + client.updateQuery("drop table " + tableName + " purge"); + assertFalse(client.existTable(tableName)); + assertFalse(hdfs.exists(tablePath)); + } + + //@Test + public final void testCreateAndDropTablePartitionedListByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = "testCreateAndDropTablePartitionedListByExecuteQuery"; + + assertFalse(client.existTable(tableName)); + + String sql = "create table " + tableName + " (deptname text, score int4)"; + sql += "PARTITION BY LIST (deptname)"; + sql += "( PARTITION sub_part1 VALUES('r&d', 'design'),"; + sql += "PARTITION sub_part2 VALUES('sales', 'hr') )"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + Path tablePath = new Path(client.getTableDesc(tableName).getUri()); + FileSystem hdfs = tablePath.getFileSystem(conf); + assertTrue(hdfs.exists(tablePath)); + + client.updateQuery("drop table " + tableName + " purge"); + assertFalse(client.existTable(tableName)); + assertFalse(hdfs.exists(tablePath)); + } + + //@Test + public final void testCreateAndDropTablePartitionedRangeByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = "testCreateAndDropTablePartitionedRangeByExecuteQuery"; + + assertFalse(client.existTable(tableName)); + + String sql = "create table " + tableName + " (deptname text, score int4)"; + sql += "PARTITION BY RANGE (score)"; + sql += "( PARTITION sub_part1 VALUES LESS THAN (2),"; + sql += "PARTITION sub_part2 VALUES LESS THAN (5),"; + sql += "PARTITION sub_part2 VALUES LESS THAN (MAXVALUE) )"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + Path tablePath = new Path(client.getTableDesc(tableName).getUri()); + FileSystem hdfs = tablePath.getFileSystem(conf); + assertTrue(hdfs.exists(tablePath)); + + client.updateQuery("drop table " + tableName + " purge"); + assertFalse(client.existTable(tableName)); + assertFalse(hdfs.exists(tablePath)); + } + + @Test + public final void testFailCreateTablePartitionedOtherExceptColumn() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = "testFailCreateTablePartitionedOtherExceptColumn"; + + assertFalse(client.existTable(tableName)); + + String rangeSql = "create table " + tableName + " (deptname text, score int4)"; + rangeSql += "PARTITION BY RANGE (score)"; + rangeSql += "( PARTITION sub_part1 VALUES LESS THAN (2),"; + rangeSql += "PARTITION sub_part2 VALUES LESS THAN (5),"; + rangeSql += "PARTITION sub_part2 VALUES LESS THAN (MAXVALUE) )"; + + try { + client.updateQuery(rangeSql); + fail(); + } catch (UnsupportedException se) { + } + + String listSql = "create table " + tableName + " (deptname text, score int4)"; + listSql += "PARTITION BY LIST (deptname)"; + listSql += "( PARTITION sub_part1 VALUES('r&d', 'design'),"; + listSql += "PARTITION sub_part2 VALUES('sales', 'hr') )"; + + try { + assertFalse(client.updateQuery(listSql)); + fail(); + } catch (UnsupportedException se) { + } + + String hashSql = "create table " + tableName + " (deptname text, score int4)"; + hashSql += "PARTITION BY HASH (deptname)"; + hashSql += "PARTITIONS 2"; + + try { + assertFalse(client.updateQuery(hashSql)); + fail(); + } catch (UnsupportedException se) { + } + } + + @Test + public final void testCreateAndDropTablePartitionedColumnByExecuteQuery() throws IOException, TajoException { + TajoConf conf = cluster.getConfiguration(); + final String tableName = CatalogUtil.normalizeIdentifier("testCreateAndDropTablePartitionedColumnByExecuteQuery"); + + assertFalse(client.existTable(tableName)); + + String sql = "create table " + tableName + " (deptname text, score int4)"; + sql += "PARTITION BY COLUMN (key1 text)"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + Path tablePath = new Path(client.getTableDesc(tableName).getUri()); + FileSystem hdfs = tablePath.getFileSystem(conf); + assertTrue(hdfs.exists(tablePath)); + + client.updateQuery("drop table " + tableName + " purge"); + assertFalse(client.existTable(tableName)); + assertFalse(hdfs.exists(tablePath)); + } + + @Test + public final void testGetFunctions() throws IOException, TajoException { + Collection<FunctionDesc> catalogFunctions = cluster.getMaster().getCatalog().getFunctions(); + String functionName = "sum"; + int numFunctions = 0; + for(FunctionDesc eachFunction: catalogFunctions) { + if(functionName.equals(eachFunction.getFunctionName())) { + numFunctions++; + } + } + + List<CatalogProtos.FunctionDescProto> functions = client.getFunctions(functionName); + assertEquals(numFunctions, functions.size()); + + functions = client.getFunctions("notmatched"); + assertEquals(0, functions.size()); + + functions = client.getFunctions(null); + assertEquals(catalogFunctions.size(), functions.size()); + } + + @Test + public final void testGetFinishedQueryList() throws SQLException, TajoException { + final String tableName = CatalogUtil.normalizeIdentifier("testGetFinishedQueryList"); + String sql = "create table " + tableName + " (deptname text, score int4)"; + + client.updateQuery(sql); + assertTrue(client.existTable(tableName)); + + int numFinishedQueries = client.getFinishedQueryList().size(); + ResultSet resultSet = client.executeQueryAndGetResult("select * from " + tableName + " order by deptname"); + assertNotNull(resultSet); + + resultSet = client.executeQueryAndGetResult("select * from " + tableName + " order by deptname"); + assertNotNull(resultSet); + assertEquals(numFinishedQueries + 2, client.getFinishedQueryList().size()); + + resultSet.close(); + } + + /** + * The main objective of this test is to get the status of a query which is actually finished. + * Statuses of queries regardless of its status should be available for a specified time duration. + */ + @Test(timeout = 20 * 1000) + public final void testGetQueryStatusAndResultAfterFinish() throws Exception { + String sql = "select * from lineitem order by l_orderkey"; + ClientProtos.SubmitQueryResponse response = client.executeQuery(sql); + + assertNotNull(response); + QueryId queryId = new QueryId(response.getQueryId()); + + try { + while (true) { + Thread.sleep(100); + + List<ClientProtos.BriefQueryInfo> finishedQueries = client.getFinishedQueryList(); + boolean finished = false; + if (finishedQueries != null) { + for (ClientProtos.BriefQueryInfo eachQuery: finishedQueries) { + if (eachQuery.getQueryId().equals(queryId.getProto())) { + finished = true; + break; + } + } + } + + if (finished) { + break; + } + } + + QueryStatus queryStatus = client.getQueryStatus(queryId); + assertNotNull(queryStatus); + assertTrue(TajoClientUtil.isQueryComplete(queryStatus.getState())); + + ResultSet resultSet = client.getQueryResult(queryId); + assertNotNull(resultSet); + + int count = 0; + while(resultSet.next()) { + count++; + } + + assertEquals(5, count); + } finally { + client.closeQuery(queryId); + } + } + + @Test + public void testNullCharSessionInCTAS() throws Exception { + String sql = + "create table nullcharsession as select\n" + + " c_custkey,\n" + + " orders.o_orderkey,\n" + + " orders.o_orderstatus \n" + + "from\n" + + " orders full outer join customer on c_custkey = o_orderkey\n" + + "order by\n" + + " c_custkey,\n" + + " orders.o_orderkey;\n"; + + Map<String, String> variables = new HashMap<String, String>(); + variables.put(SessionVars.NULL_CHAR.keyname(), "\\\\T"); + client.updateSessionVariables(variables); + ResultSet res = client.executeQueryAndGetResult(sql); + res.close(); + + TableDesc resultDesc = client.getTableDesc("nullcharsession"); + assertNullCharSessionVar(resultDesc); + } + + + public void assertNullCharSessionVar(TableDesc resultDesc) throws Exception { + TajoConf tajoConf = TpchTestBase.getInstance().getTestingCluster().getConfiguration(); + + assertEquals(resultDesc.getMeta().getOption(StorageConstants.TEXT_NULL), "\\\\T"); + + Path path = new Path(resultDesc.getUri()); + FileSystem fs = path.getFileSystem(tajoConf); + + FileStatus[] files = fs.listStatus(path); + assertNotNull(files); + assertEquals(1, files.length); + + InputStream in = fs.open(files[0].getPath()); + byte[] buf = new byte[1024]; + + + int readBytes = in.read(buf); + assertTrue(readBytes > 0); + + // text type field's value is replaced with \T + String expected = "1|1|O\n" + + "2|2|O\n" + + "3|3|F\n" + + "4||\\T\n" + + "5||\\T\n"; + + String resultDatas = new String(buf, 0, readBytes); + + assertEquals(expected, resultDatas); + } + + @Test(timeout = 30000) + public void testGetQueryInfoAndHistory() throws Exception { + String sql = "select count(*) from lineitem"; + ClientProtos.SubmitQueryResponse response = client.executeQuery(sql); + + assertNotNull(response); + QueryId queryId = new QueryId(response.getQueryId()); + + QueryInfoProto queryInfo; + while (true) { + queryInfo = client.getQueryInfo(queryId); + + if (queryInfo != null && queryInfo.getQueryState() == QueryState.QUERY_SUCCEEDED) { + break; + } + Thread.sleep(100); + } + + assertNotNull(queryInfo); + assertEquals(queryId.toString(), queryInfo.getQueryId()); + + QueryHistoryProto queryHistory = client.getQueryHistory(queryId); + assertNotNull(queryHistory); + assertEquals(queryId.toString(), queryHistory.getQueryId()); + assertEquals(2, queryHistory.getStageHistoriesCount()); + + List<ClientProtos.StageHistoryProto> taskHistories = + new ArrayList<StageHistoryProto>(queryHistory.getStageHistoriesList()); + Collections.sort(taskHistories, new Comparator<StageHistoryProto>() { + @Override + public int compare(ClientProtos.StageHistoryProto o1, StageHistoryProto o2) { + return o1.getExecutionBlockId().compareTo(o2.getExecutionBlockId()); + } + }); + assertEquals(5, taskHistories.get(0).getTotalReadRows()); + assertEquals(1, taskHistories.get(0).getTotalWriteRows()); + assertEquals(1, taskHistories.get(1).getTotalReadRows()); + assertEquals(1, taskHistories.get(1).getTotalWriteRows()); + } +}
