Return-Path: X-Original-To: apmail-hive-commits-archive@www.apache.org Delivered-To: apmail-hive-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C9FF3109FB for ; Tue, 16 Dec 2014 20:36:25 +0000 (UTC) Received: (qmail 3270 invoked by uid 500); 16 Dec 2014 20:36:25 -0000 Delivered-To: apmail-hive-commits-archive@hive.apache.org Received: (qmail 3226 invoked by uid 500); 16 Dec 2014 20:36:25 -0000 Mailing-List: contact commits-help@hive.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: hive-dev@hive.apache.org Delivered-To: mailing list commits@hive.apache.org Received: (qmail 3214 invoked by uid 99); 16 Dec 2014 20:36:25 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Dec 2014 20:36:25 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id 0A850AC0935; Tue, 16 Dec 2014 20:36:24 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1646067 - in /hive/trunk/service/src: java/org/apache/hive/service/cli/HiveSQLException.java test/org/apache/hive/service/cli/TestHiveSQLException.java Date: Tue, 16 Dec 2014 20:36:24 -0000 To: commits@hive.apache.org From: brock@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20141216203625.0A850AC0935@hades.apache.org> Author: brock Date: Tue Dec 16 20:36:23 2014 New Revision: 1646067 URL: http://svn.apache.org/r1646067 Log: HIVE-9091 - Add additional unit tests for HiveSQLException (Aihua Xu via Brock) Modified: hive/trunk/service/src/java/org/apache/hive/service/cli/HiveSQLException.java hive/trunk/service/src/test/org/apache/hive/service/cli/TestHiveSQLException.java Modified: hive/trunk/service/src/java/org/apache/hive/service/cli/HiveSQLException.java URL: http://svn.apache.org/viewvc/hive/trunk/service/src/java/org/apache/hive/service/cli/HiveSQLException.java?rev=1646067&r1=1646066&r2=1646067&view=diff ============================================================================== --- hive/trunk/service/src/java/org/apache/hive/service/cli/HiveSQLException.java (original) +++ hive/trunk/service/src/java/org/apache/hive/service/cli/HiveSQLException.java Tue Dec 16 20:36:23 2014 @@ -109,6 +109,10 @@ public class HiveSQLException extends SQ } } + /** + * Converts current object to a {@link TStatus} object + * @return a {@link TStatus} object + */ public TStatus toTStatus() { // TODO: convert sqlState, etc. TStatus tStatus = new TStatus(TStatusCode.ERROR_STATUS); @@ -119,6 +123,11 @@ public class HiveSQLException extends SQ return tStatus; } + /** + * Converts the specified {@link Exception} object into a {@link TStatus} object + * @param e a {@link Exception} object + * @return a {@link TStatus} object + */ public static TStatus toTStatus(Exception e) { if (e instanceof HiveSQLException) { return ((HiveSQLException)e).toTStatus(); @@ -129,11 +138,18 @@ public class HiveSQLException extends SQ return tStatus; } + /** + * Converts a {@link Throwable} object into a flattened list of texts including its stack trace + * and the stack traces of the nested causes. + * @param ex a {@link Throwable} object + * @return a flattened list of texts including the {@link Throwable} object's stack trace + * and the stack traces of the nested causes. + */ public static List toString(Throwable ex) { return toString(ex, null); } - static List toString(Throwable cause, StackTraceElement[] parent) { + private static List toString(Throwable cause, StackTraceElement[] parent) { StackTraceElement[] trace = cause.getStackTrace(); int m = trace.length - 1; if (parent != null) { @@ -150,7 +166,7 @@ public class HiveSQLException extends SQ return detail; } - static List enroll(Throwable ex, StackTraceElement[] trace, int max) { + private static List enroll(Throwable ex, StackTraceElement[] trace, int max) { List details = new ArrayList(); StringBuilder builder = new StringBuilder(); builder.append('*').append(ex.getClass().getName()).append(':'); @@ -169,11 +185,18 @@ public class HiveSQLException extends SQ return details; } + /** + * Converts a flattened list of texts including the stack trace and the stack + * traces of the nested causes into a {@link Throwable} object. + * @param details a flattened list of texts including the stack trace and the stack + * traces of the nested causes + * @return a {@link Throwable} object + */ public static Throwable toCause(List details) { return toStackTrace(details, null, 0); } - static Throwable toStackTrace(List details, StackTraceElement[] parent, int index) { + private static Throwable toStackTrace(List details, StackTraceElement[] parent, int index) { String detail = details.get(index++); if (!detail.startsWith("*")) { return null; // should not be happened. ignore remaining Modified: hive/trunk/service/src/test/org/apache/hive/service/cli/TestHiveSQLException.java URL: http://svn.apache.org/viewvc/hive/trunk/service/src/test/org/apache/hive/service/cli/TestHiveSQLException.java?rev=1646067&r1=1646066&r2=1646067&view=diff ============================================================================== --- hive/trunk/service/src/test/org/apache/hive/service/cli/TestHiveSQLException.java (original) +++ hive/trunk/service/src/test/org/apache/hive/service/cli/TestHiveSQLException.java Tue Dec 16 20:36:23 2014 @@ -18,27 +18,164 @@ package org.apache.hive.service.cli; +import java.util.List; + import junit.framework.Assert; + +import org.apache.commons.lang.StringUtils; +import org.apache.hive.service.cli.thrift.TStatus; +import org.apache.hive.service.cli.thrift.TStatusCode; import org.junit.Test; public class TestHiveSQLException { + /** + * Tests the conversion from a regular exception to the TStatus object + */ + @Test + public void testExceptionToTStatus() { + Exception ex1 = createException(); + ex1.initCause(createSimpleCause()); + TStatus status = HiveSQLException.toTStatus(ex1); + + Assert.assertEquals(TStatusCode.ERROR_STATUS, status.getStatusCode()); + Assert.assertEquals(ex1.getMessage(), status.getErrorMessage()); + Assert.assertEquals(HiveSQLException.toString(ex1), status.getInfoMessages()); + } + + /** + * Tests the conversion from a HiveSQLException exception to the TStatus object + */ + @Test + public void testHiveSQLExceptionToTStatus() { + String expectedMessage = "reason"; + String expectedSqlState = "sqlState"; + int expectedVendorCode = 10; + + Exception ex1 = new HiveSQLException(expectedMessage, expectedSqlState, expectedVendorCode, createSimpleCause()); + TStatus status = HiveSQLException.toTStatus(ex1); + + Assert.assertEquals(TStatusCode.ERROR_STATUS, status.getStatusCode()); + Assert.assertEquals(expectedSqlState, status.getSqlState()); + Assert.assertEquals(expectedMessage, status.getErrorMessage()); + Assert.assertEquals(HiveSQLException.toString(ex1), status.getInfoMessages()); + } + + /** + * Tests the conversion between the exception text with the simple cause and the + * Throwable object + */ @Test public void testExceptionMarshalling() throws Exception { - Exception ex1 = ex1(); - ex1.initCause(ex2()); + Exception ex1 = createException(); + ex1.initCause(createSimpleCause()); Throwable ex = HiveSQLException.toCause(HiveSQLException.toString(ex1)); + + Assert.assertSame(RuntimeException.class, ex.getClass()); + Assert.assertEquals("exception1", ex.getMessage()); + Assert.assertSame(UnsupportedOperationException.class, ex.getCause().getClass()); + Assert.assertEquals("exception2", ex.getCause().getMessage()); + } + + /** + * Tests the conversion between the exception text with nested cause and + * the Throwable object + */ + @Test + public void testNestedException() { + Exception ex1 = createException(); + ex1.initCause(createNestedCause()); + Throwable ex = HiveSQLException.toCause(HiveSQLException.toString(ex1)); + + Assert.assertSame(RuntimeException.class, ex.getClass()); + Assert.assertEquals("exception1", ex.getMessage()); + + Assert.assertSame(UnsupportedOperationException.class, ex.getCause().getClass()); + Assert.assertEquals("exception2", ex.getCause().getMessage()); + + Assert.assertSame(Exception.class, ex.getCause().getCause().getClass()); + Assert.assertEquals("exception3", ex.getCause().getCause().getMessage()); + } + + /** + * Tests the conversion of the exception with unknown source + */ + @Test + public void testExceptionWithUnknownSource() { + Exception ex1 = createException(); + ex1.initCause(createSimpleCause()); + List details = HiveSQLException.toString(ex1); + + // Simulate the unknown source + String[] tokens = details.get(1).split(":"); + tokens[2] = null; + tokens[3] = "-1"; + details.set(1, StringUtils.join(tokens, ":")); + + Throwable ex = HiveSQLException.toCause(details); + Assert.assertSame(RuntimeException.class, ex.getClass()); Assert.assertEquals("exception1", ex.getMessage()); Assert.assertSame(UnsupportedOperationException.class, ex.getCause().getClass()); Assert.assertEquals("exception2", ex.getCause().getMessage()); } - private static Exception ex1() { + /** + * Tests the conversion of the exception that the class type of one of the causes + * doesn't exist. The stack trace text is generated on the server and passed to JDBC + * client. It's possible that some cause types don't exist on the client and HiveSQLException + * can't convert them and use RunTimeException instead. + */ + @Test + public void testExceptionWithMissingTypeOnClient() { + Exception ex1 = new UnsupportedOperationException(); + ex1.initCause(createSimpleCause()); + List details = HiveSQLException.toString(ex1); + + // Simulate an unknown type + String[] tokens = details.get(0).split(":"); + tokens[0] = "*DummyException"; + details.set(0, StringUtils.join(tokens, ":")); + + Throwable ex = HiveSQLException.toCause(details); + Assert.assertEquals(RuntimeException.class, ex.getClass()); + } + + /** + * Tests the conversion of the exception from anonymous class + */ + @Test + public void testExceptionFromAnonymousClass() { + Dummy d = new Dummy() { + + public void testExceptionConversion() { + Exception ex1 = createException(); + ex1.initCause(createSimpleCause()); + Throwable ex = HiveSQLException.toCause(HiveSQLException.toString(ex1)); + + Assert.assertSame(RuntimeException.class, ex.getClass()); + Assert.assertEquals("exception1", ex.getMessage()); + Assert.assertSame(UnsupportedOperationException.class, ex.getCause().getClass()); + Assert.assertEquals("exception2", ex.getCause().getMessage()); + } + }; + + d.testExceptionConversion(); + } + + interface Dummy { + void testExceptionConversion(); + } + + private static Exception createException() { return new RuntimeException("exception1"); } - private static Exception ex2() { + private static Exception createSimpleCause() { return new UnsupportedOperationException("exception2"); } + + private static Exception createNestedCause() { + return new UnsupportedOperationException("exception2", new Exception("exception3")); + } }