/**
* 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.hive.service.cli.session;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.ql.QueryDisplay;
import org.apache.hadoop.hive.ql.QueryInfo;
import org.apache.hadoop.hive.ql.plan.api.StageType;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.hive.service.cli.OperationHandle;
import org.apache.hive.service.cli.SessionHandle;
import org.apache.hive.service.rpc.thrift.TProtocolVersion;
import org.apache.hive.service.server.HiveServer2;
import org.apache.hive.tmpl.QueryProfileTmpl;
import org.junit.Assert;
import org.junit.Before;
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 {
private HiveConf conf;
private 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<String, String>(), false, "");
SessionState.start(conf);
OperationHandle opHandle1 = session.executeStatement("show databases", null);
SessionState.start(conf);
OperationHandle opHandle2 = session.executeStatement("show tables", null);
List<QueryInfo> liveSqlOperations, historicSqlOperations;
liveSqlOperations = sessionManager.getOperationManager().getLiveQueryInfos();
historicSqlOperations = sessionManager.getOperationManager().getHistoricalQueryInfos();
Assert.assertEquals(liveSqlOperations.size(), 2);
Assert.assertEquals(historicSqlOperations.size(), 0);
verifyDDL(liveSqlOperations.get(0), "show databases", opHandle1.getHandleIdentifier().toString(), false);
verifyDDL(liveSqlOperations.get(1),"show tables", opHandle2.getHandleIdentifier().toString(), false);
session.closeOperation(opHandle1);
liveSqlOperations = sessionManager.getOperationManager().getLiveQueryInfos();
historicSqlOperations = sessionManager.getOperationManager().getHistoricalQueryInfos();
Assert.assertEquals(liveSqlOperations.size(), 1);
Assert.assertEquals(historicSqlOperations.size(), 1);
verifyDDL(historicSqlOperations.get(0),"show databases", opHandle1.getHandleIdentifier().toString(), true);
verifyDDL(liveSqlOperations.get(0),"show tables", opHandle2.getHandleIdentifier().toString(), false);
session.closeOperation(opHandle2);
liveSqlOperations = sessionManager.getOperationManager().getLiveQueryInfos();
historicSqlOperations = sessionManager.getOperationManager().getHistoricalQueryInfos();
Assert.assertEquals(liveSqlOperations.size(), 0);
Assert.assertEquals(historicSqlOperations.size(), 2);
verifyDDL(historicSqlOperations.get(1),"show databases", opHandle1.getHandleIdentifier().toString(), true);
verifyDDL(historicSqlOperations.get(0),"show tables", opHandle2.getHandleIdentifier().toString(), true);
session.close();
}
/**
* 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<String, String>(), false, "");
SessionState.start(conf);
OperationHandle opHandle1 = session.executeStatement("show databases", null);
SessionState.start(conf);
OperationHandle opHandle2 = session.executeStatement("show tables", null);
verifyDDLHtml("show databases", opHandle1.getHandleIdentifier().toString());
verifyDDLHtml("show tables", opHandle2.getHandleIdentifier().toString());
session.closeOperation(opHandle1);
session.closeOperation(opHandle2);
verifyDDLHtml("show databases", opHandle1.getHandleIdentifier().toString());
verifyDDLHtml("show tables", opHandle2.getHandleIdentifier().toString());
session.close();
}
private void verifyDDL(QueryInfo queryInfo, String stmt, String handle, boolean finished) {
Assert.assertEquals(queryInfo.getUserName(), "testuser");
Assert.assertEquals(queryInfo.getExecutionEngine(), "mr");
Assert.assertEquals(queryInfo.getOperationId(), handle);
Assert.assertTrue(queryInfo.getBeginTime() > 0 && queryInfo.getBeginTime() <= System.currentTimeMillis());
if (finished) {
Assert.assertTrue(queryInfo.getEndTime() > 0 && queryInfo.getEndTime() >= queryInfo.getBeginTime()
&& queryInfo.getEndTime() <= System.currentTimeMillis());
Assert.assertTrue(queryInfo.getRuntime() > 0);
} else {
Assert.assertNull(queryInfo.getEndTime());
//For runtime, query may have finished.
}
QueryDisplay qDisplay1 = queryInfo.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.getTaskDisplays().size(), 1);
QueryDisplay.TaskDisplay tInfo1 = qDisplay1.getTaskDisplays().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();
QueryInfo queryInfo = sessionManager.getOperationManager().getQueryInfo(
opHandle);
new QueryProfileTmpl().render(sw, queryInfo);
String html = sw.toString();
Assert.assertTrue(html.contains(stmt));
Assert.assertTrue(html.contains("testuser"));
}
}