HIVE-13589: beeline support prompt for password with '-p' option (Vihang 
Karajgaonkar, reviewed by Ferdinand Xu, Jia Ke)


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/749e8310
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/749e8310
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/749e8310

Branch: refs/heads/hive-14535
Commit: 749e831060381a8ae4775630efb72d5cd040652f
Parents: 7968e1e
Author: Ferdinand Xu <[email protected]>
Authored: Tue Oct 25 04:11:53 2016 +0800
Committer: Ferdinand Xu <[email protected]>
Committed: Tue Oct 25 04:11:53 2016 +0800

----------------------------------------------------------------------
 .../java/org/apache/hive/beeline/BeeLine.java   | 184 ++++++++---
 .../java/org/apache/hive/beeline/Commands.java  |  23 +-
 .../hive/beeline/TestBeelinePasswordOption.java | 328 +++++++++++++++++++
 3 files changed, 475 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/749e8310/beeline/src/java/org/apache/hive/beeline/BeeLine.java
----------------------------------------------------------------------
diff --git a/beeline/src/java/org/apache/hive/beeline/BeeLine.java 
b/beeline/src/java/org/apache/hive/beeline/BeeLine.java
index fdbe0a2..e9111c4 100644
--- a/beeline/src/java/org/apache/hive/beeline/BeeLine.java
+++ b/beeline/src/java/org/apache/hive/beeline/BeeLine.java
@@ -328,6 +328,7 @@ public class BeeLine implements Closeable {
         .hasArg()
         .withArgName("password")
         .withDescription("the password to connect as")
+        .hasOptionalArg()
         .create('p'));
 
     // -w (or) --password-file <file>
@@ -640,23 +641,45 @@ public class BeeLine implements Closeable {
 
 
   public class BeelineParser extends GnuParser {
+    private boolean isPasswordOptionSet = false;
 
     @Override
-    protected void processOption(final String arg, final ListIterator iter) 
throws  ParseException {
-      if ((arg.startsWith("--")) && !(arg.equals(HIVE_VAR_PREFIX) || 
(arg.equals(HIVE_CONF_PREFIX))
-          || (arg.equals("--help") || (arg.equals(PROP_FILE_PREFIX))))) {
-        String stripped = arg.substring(2, arg.length());
-        String[] parts = split(stripped, "=");
-        debug(loc("setting-prop", Arrays.asList(parts)));
-        if (parts.length >= 2) {
-          getOpts().set(parts[0], parts[1], true);
-        } else {
-          getOpts().set(parts[0], "true", true);
-        }
+    protected void processOption(String arg, final ListIterator iter) throws  
ParseException {
+      if (isBeeLineOpt(arg)) {
+        processBeeLineOpt(arg);
       } else {
+        //-p with the next argument being for BeeLineOpts
+        if ("-p".equals(arg)) {
+          isPasswordOptionSet = true;
+          if(iter.hasNext()) {
+            String next = (String) iter.next();
+            if(isBeeLineOpt(next)) {
+              processBeeLineOpt(next);
+              return;
+            } else {
+              iter.previous();
+            }
+          }
+        }
         super.processOption(arg, iter);
       }
     }
+
+    private void processBeeLineOpt(final String arg) {
+      String stripped = arg.substring(2, arg.length());
+      String[] parts = split(stripped, "=");
+      debug(loc("setting-prop", Arrays.asList(parts)));
+      if (parts.length >= 2) {
+        getOpts().set(parts[0], parts[1], true);
+      } else {
+        getOpts().set(parts[0], "true", true);
+      }
+    }
+
+    private boolean isBeeLineOpt(String arg) {
+      return arg.startsWith("--") && !(HIVE_VAR_PREFIX.equals(arg) || 
(HIVE_CONF_PREFIX.equals(arg))
+          || "--help".equals(arg) || PROP_FILE_PREFIX.equals(arg));
+    }
   }
 
   int initArgsFromCliVars(String[] args) {
@@ -735,7 +758,7 @@ public class BeeLine implements Closeable {
       return -1;
     }
 
-    boolean connSuccessful = connectUsingArgs(cl);
+    boolean connSuccessful = connectUsingArgs(beelineParser, cl);
     // checks if default hs2 connection configuration file is present
     // and uses it to connect if found
     // no-op if the file is not present
@@ -774,8 +797,8 @@ public class BeeLine implements Closeable {
    * possible ways to connect here 1. using the cmd line arguments like -u
    * or using !properties <property-file>
    */
-  private boolean connectUsingArgs(CommandLine cl) {
-    String driver = null, user = null, pass = null, url = null;
+  private boolean connectUsingArgs(BeelineParser beelineParser, CommandLine 
cl) {
+    String driver = null, user = null, pass = "", url = null;
     String auth = null;
 
 
@@ -802,7 +825,9 @@ public class BeeLine implements Closeable {
     if (cl.hasOption("w")) {
       pass = obtainPasswordFromFile(cl.getOptionValue("w"));
     } else {
-      pass = cl.getOptionValue("p");
+      if (beelineParser.isPasswordOptionSet) {
+        pass = cl.getOptionValue("p");
+      }
     }
     url = cl.getOptionValue("u");
     if ((url == null) && cl.hasOption("reconnect")){
@@ -814,31 +839,29 @@ public class BeeLine implements Closeable {
 
 
     if (url != null) {
-      if (user == null) {
-        user = Utils.parsePropertyFromUrl(url, JdbcConnectionParams.AUTH_USER);
-      }
-
-      if (pass == null) {
-        pass = Utils.parsePropertyFromUrl(url, 
JdbcConnectionParams.AUTH_PASSWD);
+      String com;
+      String comForDebug;
+      if(pass != null) {
+        com = constructCmd(url, user, pass, driver, false);
+        comForDebug = constructCmd(url, user, pass, driver, true);
+      } else {
+        com = constructCmdUrl(url, user, driver, false);
+        comForDebug = constructCmdUrl(url, user, driver, true);
       }
-
-      String com = constructCmd(url, user, pass, driver, false);
-      String comForDebug = constructCmd(url, user, pass, driver, true);
-      debug("issuing: " + comForDebug);
+      debug(comForDebug);
       return dispatch(com);
-    } else {
-      // load property file
-      String propertyFile = cl.getOptionValue("property-file");
-      if (propertyFile != null) {
-        try {
-          this.consoleReader = new ConsoleReader();
-        } catch (IOException e) {
-          handleException(e);
-        }
-        if (!dispatch("!properties " + propertyFile)) {
-          exit = true;
-          return false;
-        }
+    }
+    // load property file
+    String propertyFile = cl.getOptionValue("property-file");
+    if (propertyFile != null) {
+      try {
+        this.consoleReader = new ConsoleReader();
+      } catch (IOException e) {
+        handleException(e);
+      }
+      if (!dispatch("!properties " + propertyFile)) {
+        exit = true;
+        return false;
       }
     }
     return false;
@@ -852,17 +875,79 @@ public class BeeLine implements Closeable {
   }
 
   private String constructCmd(String url, String user, String pass, String 
driver, boolean stripPasswd) {
-    String com = "!connect "
-        + url + " "
-        + (user == null || user.length() == 0 ? "''" : user) + " ";
+    return new StringBuilder()
+       .append("!connect ")
+       .append(url)
+       .append(" ")
+       .append(user == null || user.length() == 0 ? "''" : user)
+       .append(" ")
+       .append(stripPasswd ? PASSWD_MASK : (pass.length() == 0 ? "''" : pass))
+       .append(" ")
+       .append((driver == null ? "" : driver))
+       .toString();
+  }
+
+  /**
+   * This is an internal method used to create !connect command when -p option 
is used without
+   * providing the password on the command line. Connect command returned 
should be ; separated
+   * key-value pairs along with the url. We cannot use space separated 
!connect url user [password]
+   * [driver] here since both password and driver are optional and there would 
be no way to
+   * distinguish if the last string is password or driver
+   *
+   * @param url connection url passed using -u argument on the command line
+   * @param user username passed through command line
+   * @param driver driver passed through command line -d option
+   * @param stripPasswd when set to true generates a !connect command which 
strips the password for
+   *          logging purposes
+   * @return !connect command
+   */
+  private String constructCmdUrl(String url, String user, String driver,
+      boolean stripPasswd)  {
+    StringBuilder command = new StringBuilder("!connect ");
+    command.append(url);
+    //if the url does not have a database name add the trailing '/'
+    if(isTrailingSlashNeeded(url)) {
+      command.append('/');
+    }
+    command.append(';');
+    // if the username is not already available in the URL add the one provided
+    if (Utils.parsePropertyFromUrl(url, JdbcConnectionParams.AUTH_USER) == 
null) {
+      command.append(JdbcConnectionParams.AUTH_USER);
+      command.append('=');
+      command.append((user == null || user.length() == 0 ? "''" : user));
+    }
     if (stripPasswd) {
-      com += PASSWD_MASK + " ";
-    } else {
-      com += (pass == null || pass.length() == 0 ? "''" : pass) + " ";
+      // if password is available in url it needs to be striped
+      int startIndex = command.indexOf(JdbcConnectionParams.AUTH_PASSWD + "=")
+          + JdbcConnectionParams.AUTH_PASSWD.length() + 2;
+      if(startIndex != -1) {
+        int endIndex = command.toString().indexOf(";", startIndex);
+        command.replace(startIndex, (endIndex == -1 ? command.length() : 
endIndex),
+          BeeLine.PASSWD_MASK);
+      }
     }
-    com += (driver == null ? "" : driver);
-    return com;
+    // if the driver is not already available in the URL add the one provided
+    if (Utils.parsePropertyFromUrl(url, JdbcConnectionParams.PROPERTY_DRIVER) 
== null
+        && driver != null) {
+      command.append(';');
+      command.append(JdbcConnectionParams.PROPERTY_DRIVER);
+      command.append("=");
+      command.append(driver);
+    }
+    return command.toString();
   }
+
+  /*
+   * Returns true if trailing slash is needed to be appended to the url
+   */
+  private boolean isTrailingSlashNeeded(String url) {
+    if (url.toLowerCase().startsWith("jdbc:hive2://")) {
+      return url.indexOf('/', "jdbc:hive2://".length()) < 0;
+    }
+    return false;
+  }
+
+
   /**
    * Obtains a password from the passed file path.
    */
@@ -899,6 +984,9 @@ public class BeeLine implements Closeable {
     }
 
     try {
+      //this method also initializes the consoleReader which is
+      //needed by initArgs for certain execution paths
+      ConsoleReader reader = initializeConsoleReader(inputStream);
       if (isBeeLine) {
         int code = initArgs(args);
         if (code != 0) {
@@ -923,7 +1011,6 @@ public class BeeLine implements Closeable {
       } catch (Exception e) {
         // ignore
       }
-      ConsoleReader reader = initializeConsoleReader(inputStream);
       return execute(reader, false);
     } finally {
         close();
@@ -938,13 +1025,12 @@ public class BeeLine implements Closeable {
   private boolean defaultBeelineConnect() {
     String url;
     try {
-      initializeConsoleReader(null);
       url = getDefaultConnectionUrl();
       if (url == null) {
         debug("Default hs2 connection config file not found");
         return false;
       }
-    } catch (BeelineHS2ConnectionFileParseException | IOException e) {
+    } catch (BeelineHS2ConnectionFileParseException e) {
       error(e);
       return false;
     }

http://git-wip-us.apache.org/repos/asf/hive/blob/749e8310/beeline/src/java/org/apache/hive/beeline/Commands.java
----------------------------------------------------------------------
diff --git a/beeline/src/java/org/apache/hive/beeline/Commands.java 
b/beeline/src/java/org/apache/hive/beeline/Commands.java
index 6c3e7f7..748546d 100644
--- a/beeline/src/java/org/apache/hive/beeline/Commands.java
+++ b/beeline/src/java/org/apache/hive/beeline/Commands.java
@@ -1036,9 +1036,12 @@ public class Commands {
     return true;
   }
 
+  /*
+   * Check if the input line is a multi-line command which needs to read 
further
+   */
   public String handleMultiLineCmd(String line) throws IOException {
+    //When using -e, console reader is not initialized and command is always a 
single line
     while (isMultiLine(line) && beeLine.getOpts().isAllowMultiLineCommand()) {
-
       StringBuilder prompt = new StringBuilder(beeLine.getPrompt());
       if (!beeLine.getOpts().isSilent()) {
         for (int i = 0; i < prompt.length() - 1; i++) {
@@ -1048,6 +1051,11 @@ public class Commands {
         }
       }
       String extra;
+      //avoid NPE below if for some reason -e argument has multi-line command
+      if (beeLine.getConsoleReader() == null) {
+        throw new RuntimeException("Console reader not initialized. This could 
happen when there "
+            + "is a multi-line command using -e option and which requires 
further reading from console");
+      }
       if (beeLine.getOpts().isSilent() && beeLine.getOpts().getScriptFile() != 
null) {
         extra = beeLine.getConsoleReader().readLine(null, 
jline.console.ConsoleReader.NULL_MASK);
       } else {
@@ -1070,15 +1078,12 @@ public class Commands {
   //assumes line would never be null when this method is called
   private boolean isMultiLine(String line) {
     line = line.trim();
-    if (line.endsWith(";")) {
-      return false;
-    }
-    if (beeLine.isComment(line)) {
+    if (line.endsWith(";") || beeLine.isComment(line)) {
       return false;
     }
     // handles the case like line = show tables; --test comment
     List<String> cmds = getCmdList(line, false);
-    if(!cmds.isEmpty() && cmds.get(cmds.size()-1).trim().startsWith("--")) {
+    if (!cmds.isEmpty() && cmds.get(cmds.size() - 1).trim().startsWith("--")) {
       return false;
     }
     return true;
@@ -1426,10 +1431,6 @@ public class Commands {
       value = Utils.parsePropertyFromUrl(url, 
JdbcConnectionParams.AUTH_PASSWD);
       if (value != null) {
         props.setProperty(JdbcConnectionParams.AUTH_PASSWD, value);
-      } else {
-        //if the password is not provided, beeline assumes a empty string as
-        //password
-        props.setProperty(JdbcConnectionParams.AUTH_PASSWD, "");
       }
     }
 
@@ -1534,7 +1535,7 @@ public class Commands {
       props.setProperty(JdbcConnectionParams.AUTH_USER, username);
       if (password == null) {
         password = beeLine.getConsoleReader().readLine("Enter password for " + 
urlForPrompt + ": ",
-            new Character('*'));
+          new Character('*'));
       }
       props.setProperty(JdbcConnectionParams.AUTH_PASSWD, password);
     }

http://git-wip-us.apache.org/repos/asf/hive/blob/749e8310/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeelinePasswordOption.java
----------------------------------------------------------------------
diff --git 
a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeelinePasswordOption.java
 
b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeelinePasswordOption.java
new file mode 100644
index 0000000..5dc1465
--- /dev/null
+++ 
b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeelinePasswordOption.java
@@ -0,0 +1,328 @@
+/**
+ * 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.beeline;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hive.jdbc.miniHS2.MiniHS2;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestBeelinePasswordOption {
+  private static final Logger LOG = 
LoggerFactory.getLogger(TestBeelinePasswordOption.class);
+  private static final String tableName = "TestBeelineTable1";
+  private static final String tableComment = "Test table comment";
+  private static MiniHS2 miniHS2;
+
+  /**
+   * Start up a local Hive Server 2 for these tests
+   */
+  @BeforeClass
+  public static void preTests() throws Exception {
+    HiveConf hiveConf = new HiveConf();
+    // 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");
+    miniHS2 = new MiniHS2(hiveConf);
+    miniHS2.start(new HashMap<String, String>());
+    createTable();
+  }
+
+  /**
+   * Test if beeline prompts for a password when optional password option is 
at the beginning of
+   * arguments
+   */
+  @Test
+  public void testPromptPasswordOptionAsFirst() throws Throwable {
+    List<String> argList = new ArrayList<>();
+    argList.add("-p");
+    argList.addAll(getBaseArgs(miniHS2.getBaseJdbcURL()));
+    argList.add("-n");
+    argList.add("hive");
+    connectBeelineWithUserPrompt(argList, "hivepassword");
+  }
+
+  /**
+   * Test if beeline prompts for a password when optional password option is 
at the end of arguments
+   */
+  @Test
+  public void testPromptPasswordOptionLast() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("-n");
+    argList.add("hive");
+    argList.add("-p");
+    connectBeelineWithUserPrompt(argList, "hivepassword");
+  }
+
+  /**
+   * Test if beeline prompts for a password when optional password option is 
at the middle of
+   * arguments
+   */
+  @Test
+  public void testPromptPasswordOptionMiddle() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("-p");
+    argList.add("-n");
+    argList.add("hive");
+    connectBeelineWithUserPrompt(argList, "hivepassword");
+  }
+
+  /**
+   * Test if beeline prompts for a password when optional password option is 
used in conjunction
+   * with additional commandLine options after -p
+   */
+  @Test
+  public void testPromptPasswordOptionWithOtherOptions() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("-p");
+    argList.add("-n");
+    argList.add("hive");
+    argList.add("-e");
+    argList.add("show tables;");
+    String output = connectBeelineWithUserPrompt(argList, "hivepassword");
+    Assert.assertTrue("Table name " + tableName + " not found in the output",
+        output.contains(tableName.toLowerCase()));
+  }
+
+  /**
+   * Test if beeline prompts for a password when optional password option is 
used in conjunction
+   * with additional BeeLineOpts options after -p
+   */
+  @Test
+  public void testPromptPasswordOptionWithBeelineOpts() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("-n");
+    argList.add("hive");
+    argList.add("-p");
+    argList.add("--force=true");
+    argList.add("-e");
+    argList.add("show tables;");
+    String output = connectBeelineWithUserPrompt(argList, "hivepassword");
+    Assert.assertTrue("Table name " + tableName + " not found in the output",
+        output.contains(tableName.toLowerCase()));
+  }
+
+  /**
+   * Test if beeline prompts for a password when optional password option is 
used in conjunction
+   * with additional BeeLineOpts options after -p. Also, verifies the 
beelineOpt value is set as
+   * expected
+   */
+  @Test
+  public void testPromptPasswordVerifyBeelineOpts() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("-n");
+    argList.add("hive");
+    argList.add("-p");
+    argList.add("--maxColumnWidth=57");
+    argList.add("-e");
+    argList.add("show tables;");
+    String output = connectWithPromptAndVerify(argList, "hivepassword", true, 
57, null, null);
+    Assert.assertTrue("Table name " + tableName + " not found in the output",
+        output.contains(tableName.toLowerCase()));
+  }
+
+  /**
+   * Tests if beeline prompts for a password and also confirms that --hiveconf
+   * argument works when given immediately after -p with no password
+   * @throws Exception
+   */
+  @Test
+  public void testPromptPasswordWithHiveConf() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("-n");
+    argList.add("hive");
+    argList.add("-p");
+    argList.add("--hiveconf");
+    argList.add("hive.cli.print.header=true");
+    argList.add("-e");
+    argList.add("show tables;");
+    String output = connectWithPromptAndVerify(argList, "hivepassword", false, 
null,
+        "hive.cli.print.header", "true");
+    Assert.assertTrue("Table name " + tableName + " not found in the output",
+        output.contains(tableName.toLowerCase()));
+  }
+
+  /**
+   * Tests if beeline doesn't prompt for a password and connects with empty 
password
+   * when no password option provided
+   */
+  @Test
+  public void testNoPasswordPrompt() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("-n");
+    argList.add("hive");
+    argList.add("--force=true");
+    argList.add("-e");
+    argList.add("show tables;");
+    String output = connectBeelineWithUserPrompt(argList);
+    Assert.assertTrue("Table name " + tableName + " not found in the output",
+        output.contains(tableName.toLowerCase()));
+  }
+
+  /**
+   * Tests if beeline doesn't prompt for a password and connects with no 
password/username option
+   * provided
+   */
+  @Test
+  public void testNoPasswordPrompt2() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("--force=true");
+    argList.add("-e");
+    argList.add("show tables;");
+    String output = connectBeelineWithUserPrompt(argList);
+    Assert.assertTrue("Table name " + tableName + " not found in the output",
+        output.contains(tableName.toLowerCase()));
+  }
+
+  /**
+   * Tests if Beeline prompts for password when -p is the last argument and 
argList has CommandLine
+   * options as well as BeelineOpts
+   */
+  @Test
+  public void testPromptPassOptionLastWithBeelineOpts() throws Exception {
+    List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+    argList.add("-n");
+    argList.add("hive");
+    argList.add("--force=true");
+    argList.add("-e");
+    argList.add("show tables;");
+    argList.add("-p");
+    String output = connectBeelineWithUserPrompt(argList, "hivepassword");
+    Assert.assertTrue("Table name " + tableName + " not found in the output",
+        output.contains(tableName.toLowerCase()));
+  }
+
+  /**
+   * 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
+   *
+   * @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 output of beeline from outputstream
+   * @throws Exception
+   */
+  private String connectWithPromptAndVerify(List<String> argList, String 
prompt,
+    boolean testMaxColumnWidthOption, Integer expectedMaxColumnWidth, String 
hiveConfKey,
+    String expectedHiveConfValue) throws Exception {
+    BeeLine beeLine = null;
+    InputStream inputStream = null;
+    try {
+      beeLine = new BeeLine();
+      ByteArrayOutputStream os = new ByteArrayOutputStream();
+      PrintStream beelineOutputStream = new PrintStream(os);
+      beeLine.setOutputStream(beelineOutputStream);
+      beeLine.setErrorStream(beelineOutputStream);
+      String[] args = argList.toArray(new String[argList.size()]);
+      if (prompt != null) {
+        inputStream = new ByteArrayInputStream(prompt.getBytes());
+      }
+      Assert.assertTrue(beeLine.begin(args, inputStream) == 0);
+      if (testMaxColumnWidthOption) {
+        int maxColumnWidth = beeLine.getOpts().getMaxColumnWidth();
+        Assert.assertTrue(
+          "Expected max columnWidth to be " + expectedMaxColumnWidth + " found 
" + maxColumnWidth,
+          maxColumnWidth == expectedMaxColumnWidth);
+      }
+      if (hiveConfKey != null) {
+        String hiveConfValue = 
beeLine.getOpts().getHiveConfVariables().get(hiveConfKey);
+        Assert.assertTrue(
+          "Expected " + expectedHiveConfValue + " got " + hiveConfValue + " 
for " + hiveConfKey,
+          expectedHiveConfValue.equalsIgnoreCase(hiveConfValue));
+      }
+      String output = os.toString("UTF-8");
+      LOG.debug(output);
+      return output;
+    } finally {
+      if (beeLine != null) {
+        beeLine.close();
+      }
+      if(inputStream != null) {
+        inputStream.close();
+      }
+    }
+  }
+
+  private String connectBeelineWithUserPrompt(List<String> argList) throws 
Exception {
+    return connectBeelineWithUserPrompt(argList, null);
+  }
+
+  private String connectBeelineWithUserPrompt(List<String> argList, String 
prompt)
+      throws Exception {
+    return connectWithPromptAndVerify(argList, prompt, false, null, null, 
null);
+  }
+
+  /**
+   * Create table for use by tests
+   *
+   * @throws ClassNotFoundException
+   * @throws SQLException
+   */
+  private static void createTable() throws ClassNotFoundException, 
SQLException {
+    Class.forName(BeeLine.BEELINE_DEFAULT_JDBC_DRIVER);
+    Connection con = DriverManager.getConnection(miniHS2.getBaseJdbcURL(), "", 
"");
+
+    assertNotNull("Connection is null", con);
+    assertFalse("Connection should not be closed", con.isClosed());
+    Statement stmt = con.createStatement();
+    assertNotNull("Statement is null", stmt);
+
+    stmt.execute("set hive.support.concurrency = false");
+    try {
+      stmt.execute("drop table if exists " + tableName);
+    } catch (Exception ex) {
+      LOG.error("Failed due to exception ", ex);
+      fail("Unable to create setup table " + tableName + ex.toString());
+    }
+    // create table
+    stmt.execute("create table " + tableName
+        + " (under_col int comment 'the under column', value string) comment 
'" + tableComment
+        + "'");
+  }
+
+  private List<String> getBaseArgs(String jdbcUrl) {
+    List<String> argList = new ArrayList<String>(8);
+    argList.add("-d");
+    argList.add(BeeLine.BEELINE_DEFAULT_JDBC_DRIVER);
+    argList.add("-u");
+    argList.add(jdbcUrl);
+    return argList;
+  }
+}

Reply via email to