/** * 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; import java.util.List; import junit.framework.Assert; import org.apache.commons.lang.StringUtils; import org.apache.hive.service.rpc.thrift.TStatus; import org.apache.hive.service.rpc.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 = 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<String> 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()); } /** * 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<String> 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 createSimpleCause() { return new UnsupportedOperationException("exception2"); } private static Exception createNestedCause() { return new UnsupportedOperationException("exception2", new Exception("exception3")); } }