diff --git a/phoenix-core/src/test/java/org/apache/phoenix/SystemExitRule.java b/phoenix-core/src/test/java/org/apache/phoenix/SystemExitRule.java new file mode 100644 index 00000000000..0ec669ce845 --- /dev/null +++ b/phoenix-core/src/test/java/org/apache/phoenix/SystemExitRule.java @@ -0,0 +1,55 @@ +/* + * 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.phoenix; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +/** + * Test rule that prevents System.exit / JVM exit to error out the test runner, which manages + * JVM and providing test output files, and instead throw valid Exception to handle JVM exit + * gracefully + */ +public class SystemExitRule implements TestRule { + + private static final SecurityManager SECURITY_MANAGER = new TestSecurityManager(); + + @Override + public Statement apply(final Statement s, Description d) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + System.setSecurityManager(SECURITY_MANAGER); + s.evaluate(); + } finally { + System.setSecurityManager(null); + } + } + + }; + } + + // Exiting the JVM is not allowed in tests and this exception is thrown instead + // when it is done + public static class SystemExitInTestException extends SecurityException { + // empty + } + +} diff --git a/phoenix-core/src/test/java/org/apache/phoenix/TestJVMExit.java b/phoenix-core/src/test/java/org/apache/phoenix/TestJVMExit.java new file mode 100644 index 00000000000..1fd1b72fe6c --- /dev/null +++ b/phoenix-core/src/test/java/org/apache/phoenix/TestJVMExit.java @@ -0,0 +1,37 @@ +/* + * 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.phoenix; + +import org.junit.ClassRule; +import org.junit.Test; + +public class TestJVMExit { + + @ClassRule + public static final SystemExitRule SYSTEM_EXIT_RULE = new SystemExitRule(); + + @Test(expected = SystemExitRule.SystemExitInTestException.class) + public void testSystemExit() { + System.exit(10); + } + + @Test(expected = SystemExitRule.SystemExitInTestException.class) + public void testRuntimeHalt() { + Runtime.getRuntime().halt(10); + } + +} diff --git a/phoenix-core/src/test/java/org/apache/phoenix/TestSecurityManager.java b/phoenix-core/src/test/java/org/apache/phoenix/TestSecurityManager.java new file mode 100644 index 00000000000..643cea6dff0 --- /dev/null +++ b/phoenix-core/src/test/java/org/apache/phoenix/TestSecurityManager.java @@ -0,0 +1,139 @@ +/* + * 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.phoenix; + +import java.io.FileDescriptor; +import java.net.InetAddress; +import java.security.Permission; + +/** + * Custom SecurityManager impl used by SystemExitRule + */ +class TestSecurityManager extends SecurityManager { + + @Override + public void checkExit(int status) { + throw new SystemExitRule.SystemExitInTestException(); + } + + @Override + public void checkPermission(Permission permission) { + // no-op + } + + @Override + public void checkPermission(Permission var1, Object var2) { + // no-op + } + + @Override + public void checkSecurityAccess(String var1) { + // no-op + } + + @Override + public void checkConnect(String var1, int var2, Object var3) { + // no-op + } + + @Override + public void checkWrite(String var1) { + // no-op + } + + @Override + public void checkDelete(String var1) { + // no-op + } + + @Override + public void checkConnect(String var1, int var2) { + // no-op + } + + @Override + public void checkLink(String var1) { + // no-op + } + + @Override + public void checkRead(FileDescriptor var1) { + // no-op + } + + @Override + public void checkAccess(Thread var1) { + // no-op + } + + @Override + public void checkAccess(ThreadGroup var1) { + // no-op + } + + @Override + public void checkCreateClassLoader() { + // no-op + } + + @Override + public void checkListen(int var1) { + // no-op + } + + @Override + public void checkAccept(String var1, int var2) { + // no-op + } + + @Override + public void checkMulticast(InetAddress var1) { + // no-op + } + + @Override + public void checkMulticast(InetAddress var1, byte var2) { + // no-op + } + + @Override + public void checkPropertiesAccess() { + // no-op + } + + @Override + public void checkPropertyAccess(String var1) { + // no-op + } + + @Override + public void checkPackageAccess(String var1) { + // no-op + } + + @Override + public void checkPackageDefinition(String var1) { + // no-op + } + + @Override + public void checkSetFactory() { + // no-op + } + +} diff --git a/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java index 897bb5b49f5..809702a59b6 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java @@ -26,8 +26,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.phoenix.SystemExitRule; import org.apache.phoenix.coprocessor.GroupedAggregateRegionObserver; import org.apache.phoenix.memory.MemoryManager.MemoryChunk; +import org.junit.ClassRule; import org.junit.Test; /** @@ -39,6 +41,10 @@ * @since 0.1 */ public class MemoryManagerTest { + + @ClassRule + public static final SystemExitRule SYSTEM_EXIT_RULE = new SystemExitRule(); + @Test public void testOverGlobalMemoryLimit() throws Exception { GlobalMemoryManager gmm = new GlobalMemoryManager(250); diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java index 74fb75be61b..faf2a18d8ba 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java @@ -133,6 +133,7 @@ import org.apache.hadoop.hbase.regionserver.HRegionServer; import org.apache.hadoop.hbase.regionserver.RSRpcServices; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.SystemExitRule; import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT; import org.apache.phoenix.exception.SQLExceptionCode; import org.apache.phoenix.exception.SQLExceptionInfo; @@ -170,10 +171,10 @@ * client-time and hbase-time managed tests. * * For tests needing connectivity to a cluster, please use - * {@link BaseHBaseManagedTimeIT} or {@link BaseClientManagedTimeIT}. + * {@link BaseHBaseManagedTimeIT}. * * In the rare case when a test can't share the same mini cluster as the - * ones used by {@link BaseHBaseManagedTimeIT} or {@link BaseClientManagedTimeIT} + * ones used by {@link BaseHBaseManagedTimeIT}, * one could extend this class and spin up your own mini cluster. Please * make sure to shutdown the mini cluster in a method annotated by @AfterClass. * @@ -192,6 +193,9 @@ public abstract class BaseTest { private static final ExecutorService dropHTableService = Executors .newSingleThreadExecutor(factory); + @ClassRule + public static final SystemExitRule SYSTEM_EXIT_RULE = new SystemExitRule(); + static { ImmutableMap.Builder builder = ImmutableMap.builder(); builder.put(ENTITY_HISTORY_TABLE_NAME,"create table " + ENTITY_HISTORY_TABLE_NAME + diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionQueryServicesImplTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionQueryServicesImplTest.java index b411fceb993..df0e1b25f5d 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionQueryServicesImplTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionQueryServicesImplTest.java @@ -52,10 +52,12 @@ import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.hadoop.hbase.client.TableDescriptorBuilder; +import org.apache.phoenix.SystemExitRule; import org.apache.phoenix.exception.PhoenixIOException; import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData; import org.apache.phoenix.util.ReadOnlyProps; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; @@ -72,6 +74,9 @@ public class ConnectionQueryServicesImplTest { .build()) .build(); + @ClassRule + public static final SystemExitRule SYSTEM_EXIT_RULE = new SystemExitRule(); + @Mock private ConnectionQueryServicesImpl mockCqs; diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java index 8f40dad3b76..bf260ff2582 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java @@ -35,6 +35,7 @@ import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; +import org.apache.phoenix.SystemExitRule; import org.apache.phoenix.jdbc.PhoenixConnection; import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData; import org.apache.phoenix.jdbc.PhoenixDriver; @@ -46,6 +47,7 @@ import org.apache.phoenix.util.PhoenixRuntime; import org.apache.phoenix.util.StringUtil; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; @@ -73,7 +75,10 @@ public class ConnectionlessTest { private static String getUrl() { return PhoenixRuntime.JDBC_PROTOCOL + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + PhoenixRuntime.CONNECTIONLESS; } - + + @ClassRule + public static final SystemExitRule SYSTEM_EXIT_RULE = new SystemExitRule(); + @BeforeClass public static synchronized void verifyDriverRegistered() throws SQLException { assertTrue(DriverManager.getDriver(getUrl()) == PhoenixDriver.INSTANCE);