diff --git itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestQueryDisplay.java itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestQueryDisplay.java new file mode 100644 index 0000000..fcc8dc0 --- /dev/null +++ itests/hive-unit/src/test/java/org/apache/hive/service/cli/session/TestQueryDisplay.java @@ -0,0 +1,165 @@ +package org.apache.hive.service.cli.session; + +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.ql.QueryDisplay; +import org.apache.hadoop.hive.ql.plan.api.StageType; +import org.apache.hive.service.cli.SessionHandle; +import org.apache.hive.service.cli.operation.ExecuteStatementOperation; +import org.apache.hive.service.cli.operation.SQLOperationDisplay; +import org.apache.hive.service.rpc.thrift.TProtocolVersion; +import org.apache.hive.service.server.HiveServer2; +import org.apache.hive.service.servlet.QueryProfileServlet; +import org.apache.hive.tmpl.QueryProfileTmpl; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.StringWriter; +import java.util.HashMap; +import java.util.List; + +/** + * Test QueryDisplay and its consumers like WebUI. + */ +public class TestQueryDisplay { + public HiveConf conf; + public SessionManager sessionManager; + + + @Before + public void setup() { + conf = new HiveConf(); + conf.set("hive.support.concurrency", "false"); + + HiveServer2 dummyHs2 = new HiveServer2(); + sessionManager = new SessionManager(dummyHs2); + sessionManager.init(conf); + } + + /** + * Test if query display captures information on current/historic SQL operations. + */ + @Test + public void testQueryDisplay() throws Exception { + HiveSession session = sessionManager.createSession( + new SessionHandle(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V8), + TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V8, + "testuser", "", "", new HashMap(), false, ""); + + ExecuteStatementOperation op = sessionManager.getOperationManager().newExecuteStatementOperation( + session, "show databases", null, false); + op.run(); + + ExecuteStatementOperation op2 = sessionManager.getOperationManager().newExecuteStatementOperation( + session, "show tables", null, false); + op2.run(); + + List liveSqlOperations, historicSqlOperations; + liveSqlOperations = sessionManager.getOperationManager().getLiveSqlOperations(); + historicSqlOperations = sessionManager.getOperationManager().getHistoricalSQLOperations(); + Assert.assertEquals(liveSqlOperations.size(), 2); + Assert.assertEquals(historicSqlOperations.size(), 0); + verifyDDL(liveSqlOperations.get(0), "show databases", op.getHandle().getHandleIdentifier().toString(), false); + verifyDDL(liveSqlOperations.get(1),"show tables", op2.getHandle().getHandleIdentifier().toString(), false); + + sessionManager.getOperationManager().closeOperation(op.getHandle()); + liveSqlOperations = sessionManager.getOperationManager().getLiveSqlOperations(); + historicSqlOperations = sessionManager.getOperationManager().getHistoricalSQLOperations(); + Assert.assertEquals(liveSqlOperations.size(), 1); + Assert.assertEquals(historicSqlOperations.size(), 1); + verifyDDL(historicSqlOperations.get(0),"show databases", op.getHandle().getHandleIdentifier().toString(), true); + verifyDDL(liveSqlOperations.get(0),"show tables", op2.getHandle().getHandleIdentifier().toString(), false); + + sessionManager.getOperationManager().closeOperation(op2.getHandle()); + liveSqlOperations = sessionManager.getOperationManager().getLiveSqlOperations(); + historicSqlOperations = sessionManager.getOperationManager().getHistoricalSQLOperations(); + Assert.assertEquals(liveSqlOperations.size(), 0); + Assert.assertEquals(historicSqlOperations.size(), 2); + verifyDDL(historicSqlOperations.get(0),"show databases", op.getHandle().getHandleIdentifier().toString(), true); + verifyDDL(historicSqlOperations.get(1),"show tables", op2.getHandle().getHandleIdentifier().toString(), true); + } + + /** + * Test if webui captures information on current/historic SQL operations. + */ + @Test + public void testWebUI() throws Exception { + HiveSession session = sessionManager.createSession( + new SessionHandle(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V8), + TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V8, + "testuser", "", "", new HashMap(), false, ""); + + ExecuteStatementOperation op = sessionManager.getOperationManager().newExecuteStatementOperation( + session, "show databases", null, false); + op.run(); + + ExecuteStatementOperation op2 = sessionManager.getOperationManager().newExecuteStatementOperation( + session, "show tables", null, false); + op2.run(); + + verifyDDLHtml("show databases", op.getHandle().getHandleIdentifier().toString()); + verifyDDLHtml("show tables", op2.getHandle().getHandleIdentifier().toString()); + + sessionManager.getOperationManager().closeOperation(op.getHandle()); + sessionManager.getOperationManager().closeOperation(op2.getHandle()); + + verifyDDLHtml("show databases", op.getHandle().getHandleIdentifier().toString()); + verifyDDLHtml("show tables", op2.getHandle().getHandleIdentifier().toString()); + } + + private void verifyDDL(SQLOperationDisplay display, String stmt, String handle, boolean finished) { + + Assert.assertEquals(display.getUserName(), "testuser"); + Assert.assertEquals(display.getExecutionEngine(), "mr"); + Assert.assertEquals(display.getOperationId(), handle); + Assert.assertTrue(display.getBeginTime() > 0 && display.getBeginTime() <= System.currentTimeMillis()); + + if (finished) { + Assert.assertTrue(display.getEndTime() > 0 && display.getEndTime() >= display.getBeginTime() + && display.getEndTime() <= System.currentTimeMillis()); + } else { + Assert.assertNull(display.getEndTime()); + } + + QueryDisplay qDisplay1 = display.getQueryDisplay(); + Assert.assertNotNull(qDisplay1); + Assert.assertEquals(qDisplay1.getQueryString(), stmt); + Assert.assertNotNull(qDisplay1.getExplainPlan()); + Assert.assertNull(qDisplay1.getErrorMessage()); + + Assert.assertTrue(qDisplay1.getHmsTimings(QueryDisplay.Phase.COMPILATION).size() > 0); + Assert.assertTrue(qDisplay1.getHmsTimings(QueryDisplay.Phase.EXECUTION).size() > 0); + + Assert.assertTrue(qDisplay1.getPerfLogStarts(QueryDisplay.Phase.COMPILATION).size() > 0); + Assert.assertTrue(qDisplay1.getPerfLogEnds(QueryDisplay.Phase.COMPILATION).size() > 0); + + Assert.assertTrue(qDisplay1.getPerfLogStarts(QueryDisplay.Phase.COMPILATION).size() > 0); + Assert.assertTrue(qDisplay1.getPerfLogEnds(QueryDisplay.Phase.COMPILATION).size() > 0); + + Assert.assertEquals(qDisplay1.getTaskInfos().size(), 1); + QueryDisplay.TaskInfo tInfo1 = qDisplay1.getTaskInfos().get(0); + Assert.assertEquals(tInfo1.getTaskId(), "Stage-0"); + Assert.assertEquals(tInfo1.getTaskType(), StageType.DDL); + Assert.assertTrue(tInfo1.getBeginTime() > 0 && tInfo1.getBeginTime() <= System.currentTimeMillis()); + Assert.assertTrue(tInfo1.getEndTime() > 0 && tInfo1.getEndTime() >= tInfo1.getBeginTime() && + tInfo1.getEndTime() <= System.currentTimeMillis()); + Assert.assertEquals(tInfo1.getStatus(), "Success, ReturnVal 0"); + } + + /** + * Sanity check if basic information is delivered in this html. Let's not go too crazy and + * assert each element, to make it easier to add UI improvements. + */ + private void verifyDDLHtml(String stmt, String opHandle) throws Exception { + StringWriter sw = new StringWriter(); + SQLOperationDisplay sod = sessionManager.getOperationManager().getSQLOperationDisplay( + opHandle); + new QueryProfileTmpl().render(sw, sod); + String html = sw.toString(); + + Assert.assertTrue(html.contains(stmt)); + Assert.assertTrue(html.contains("testuser")); + } + +}