001/* 002 * #%L 003 * Netarchivesuite - common - test 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.testutils.preconfigured; 024 025import java.security.Permission; 026 027import dk.netarkivet.common.exceptions.UnknownID; 028 029/** 030 * Configures the test environment to block calls to System.exit(), throwing a PermissionDenied instead. 031 */ 032public class PreventSystemExit implements TestConfigurationIF { 033 /** Saves the original security manager, so that it can be restored in tearDown() */ 034 private SecurityManager originalManager; 035 /** Saves latest value given to System.exit() for inspection */ 036 int exitValue; 037 /** Indicates whether System.exit() has been called after setUp(). */ 038 boolean exitCalled = false; 039 040 /** 041 * Stores original SecurityManager and set a new one blocking System.exit() Calls reset(). 042 */ 043 public void setUp() { 044 originalManager = System.getSecurityManager(); 045 SecurityManager manager = new DisallowSystemExitSecurityManager(); 046 System.setSecurityManager(manager); 047 } 048 049 /** 050 * Resets internal state. 051 */ 052 public void reset() { 053 exitCalled = false; 054 } 055 056 /** 057 * Restores original SecurityManager. 058 */ 059 public void tearDown() { 060 System.setSecurityManager(originalManager); 061 } 062 063 /** 064 * Checks whether System.exit() has been called after reset(). 065 * 066 * @return true if and only if System.exit() has been called after reset(). 067 */ 068 public boolean getExitCalled() { 069 return exitCalled; 070 } 071 072 /** 073 * Looks up the value given to the latest invocation of System.exit() 074 * 075 * @return The int value. Throws UnknownID if System.exit() has not been called after reset(). 076 */ 077 public int getExitValue() { 078 if (!exitCalled) { 079 throw new UnknownID("System.exit() was never called"); 080 } 081 return exitValue; 082 } 083 084 /** 085 * A SecurityManager that makes System.exit() throw PermissionDenied. Also stores the value given to System.exit() 086 * for subsequent inspection. 087 */ 088 private class DisallowSystemExitSecurityManager extends SecurityManager { 089 public void checkExit(int status) { 090 exitValue = status; 091 exitCalled = true; 092 super.checkExit(status); 093 } 094 095 public void checkPermission(Permission perm) { 096 if (perm.getName().startsWith("exitVM")) { // represents exitVM, exitVM.* 097 throw new SecurityException("System.exit() disallowed during this unit test."); 098 } 099 100 } 101 } 102}