commit 28f82b1241de1dc892346e63c08fdcb6fdb0abe1 Author: Andrew Sherman Date: Tue Oct 10 11:58:23 2017 -0700 HIVE-17760: Create a unit test which validates HIVE-9423 does not regress Refactor connectWithPromptAndVerify() to create a method which does not automatically close a BeeLine connection. Use this to connect twice to the MiniHS2. The second connection will timeout with a error message that is understandable by humans. This ensures the fix for HIVE-9423 will no regress. ADDED: verbose option for debugging Change-Id: I7d1ce8ffcec5b914cdf4154071c15046d5151298 diff --git itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeelinePasswordOption.java itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeelinePasswordOption.java index 5dc1465d64bb81c1a7affe7a5382b74ce53cf519..975b7f8c0167069bcf0055f831e6197cdf09404d 100644 --- itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeelinePasswordOption.java +++ itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeelinePasswordOption.java @@ -19,10 +19,12 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.sql.Connection; @@ -56,6 +58,11 @@ public static void preTests() throws Exception { // Set to non-zk lock manager to prevent HS2 from trying to connect hiveConf.setVar(HiveConf.ConfVars.HIVE_LOCK_MANAGER, "org.apache.hadoop.hive.ql.lockmgr.EmbeddedLockManager"); + // Set the min and max threads so we can test what happens when there aren't enough threads + hiveConf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_THRIFT_MIN_WORKER_THREADS, 1); + hiveConf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_THRIFT_MAX_WORKER_THREADS, 2); + // Set the login timeout so our timeout test is not too slow + hiveConf.setVar(HiveConf.ConfVars.HIVE_SERVER2_THRIFT_LOGIN_TIMEOUT, "4s"); miniHS2 = new MiniHS2(hiveConf); miniHS2.start(new HashMap()); createTable(); @@ -226,6 +233,38 @@ public void testPromptPassOptionLastWithBeelineOpts() throws Exception { } /** + * Test that if the Thrift server pool is exhausted then the Beeline connection times out, + * and provides a meaningful error message + */ + @Test(timeout = 20000) + public void testMultiConnect() throws Throwable { + List argList = new ArrayList<>(); + argList.add("-p"); + argList.addAll(getBaseArgs(miniHS2.getBaseJdbcURL())); + argList.add("-n"); + argList.add("hive"); + argList.add("--verbose=true"); + + try (BeeLine beeLine1 = new BeeLine(); + BeeLine beeLine2 = new BeeLine()) { + // the first connection should work OK + String output1 = getBeelineOutput(beeLine1, argList, "password", false, + 100, null, null); + System.out.println("output1 = " + output1); + assertTrue(output1.contains("Connected to: Apache Hive")); + + // the second connection should time out + String output2 = getBeelineOutput(beeLine2, argList, "password", false, + 100, null, null); + System.out.println("output2 = " + output2); + assertFalse(output2.contains("Connected to: Apache Hive")); + assertTrue(output2.contains("The root cause might be too many concurrent connections")); + assertTrue(output2.contains("adjust hive.server2.thrift.max.worker.threads")); + } + } + + + /** * Connects to miniHS2 using beeline with the given string value for the prompt if the prompt is * null, uses beeline with null inputstream in which this method expects that the argList is * sufficient to make a successful Beeline connection with no prompt required from user @@ -242,10 +281,34 @@ public void testPromptPassOptionLastWithBeelineOpts() throws Exception { private String connectWithPromptAndVerify(List argList, String prompt, boolean testMaxColumnWidthOption, Integer expectedMaxColumnWidth, String hiveConfKey, String expectedHiveConfValue) throws Exception { - BeeLine beeLine = null; + try (BeeLine beeLine = new BeeLine()) { + return getBeelineOutput(beeLine, argList, prompt, testMaxColumnWidthOption, expectedMaxColumnWidth, + hiveConfKey, expectedHiveConfValue); + } + } + + + /** + * Connects to miniHS2 using beeline with the given string value for the + * prompt. If the prompt is null then beeline is created with a null + * inputstream, in which case this method expects that the argList is + * sufficient to make a successful Beeline connection without a prompt + * being required from the user. + * + * @param beeLine - the BeeLine object to use for the connection + * @param argList - arguments list for the beeline + * @param prompt - String value to be given to beeline prompt during connection + * @param beelineOptName - Name of BeelineOpt to be verified + * @param beelineOptValue - Expected value of value of BeeLineOpt + * @param hiveConfKey - hive conf variable name to verify + * @param expectedHiveConfValue - Expected value of hive conf variable + * @return the output printed by beeline + */ + private String getBeelineOutput(BeeLine beeLine, List argList, String prompt, + boolean testMaxColumnWidthOption, Integer expectedMaxColumnWidth, String hiveConfKey, + String expectedHiveConfValue) throws IOException { InputStream inputStream = null; try { - beeLine = new BeeLine(); ByteArrayOutputStream os = new ByteArrayOutputStream(); PrintStream beelineOutputStream = new PrintStream(os); beeLine.setOutputStream(beelineOutputStream); @@ -271,10 +334,7 @@ private String connectWithPromptAndVerify(List argList, String prompt, LOG.debug(output); return output; } finally { - if (beeLine != null) { - beeLine.close(); - } - if(inputStream != null) { + if (inputStream != null) { inputStream.close(); } }