001: /*
002: *
003: * Derby - Class org.apache.derbyTesting.functionTests.util.SecurityManagerSetup
004: *
005: * Licensed to the Apache Software Foundation (ASF) under one or more
006: * contributor license agreements. See the NOTICE file distributed with
007: * this work for additional information regarding copyright ownership.
008: * The ASF licenses this file to You under the Apache License, Version 2.0
009: * (the "License"); you may not use this file except in compliance with
010: * the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
017: * either express or implied. See the License for the specific
018: * language governing permissions and limitations under the License.
019: */
020: package org.apache.derbyTesting.junit;
021:
022: import java.net.URL;
023: import java.security.AccessController;
024: import java.security.PrivilegedActionException;
025: import java.util.Enumeration;
026: import java.util.Properties;
027:
028: import junit.extensions.TestSetup;
029: import junit.framework.Test;
030: import junit.framework.TestSuite;
031:
032: /**
033: * Setup for running Derby JUnit tests with the SecurityManager
034: * which is the default for tests.
035: *
036: */
037: public final class SecurityManagerSetup extends TestSetup {
038:
039: private static final Properties classPathSet = new Properties();
040:
041: /**
042: * True if the classes are loaded from jars.
043: */
044: static boolean isJars;
045:
046: /**
047: * True if a security manager was installed outside of the
048: * control of this class and BaseTestCase.
049: */
050: private static final boolean externalSecurityManagerInstalled;
051:
052: static {
053: // Determine what the set of properties
054: // describing the environment is.
055: externalSecurityManagerInstalled = determineClasspath();
056:
057: }
058:
059: private final String decoratorPolicyResource;
060:
061: private SecurityManagerSetup(Test test, String policyResource) {
062: super (test);
063: this .decoratorPolicyResource = policyResource;
064: }
065:
066: /**
067: * Get a decorator that will ensure no security manger
068: * is installed to run a test. Not supported for suites.
069: * <BR>
070: * An empty suite is returned if a security manager was installed
071: * externally, i.e. not under the control of the BaseTestCase
072: * and this code. In this case the code can not support the
073: * mode of no security manager as it may not have enough information
074: * to re-install the security manager. So the passed in test
075: * will be skipped.
076: */
077: public static Test noSecurityManager(BaseTestCase test) {
078: if (externalSecurityManagerInstalled)
079: return new TestSuite();
080: return new SecurityManagerSetup(test, "<NONE>");
081: }
082:
083: /**
084: * Install a SecurityManager with the default test policy
085: * file:
086: * org/apache/derbyTesting/functionTests/util/derby_tests.policy
087: *
088: */
089: static void noSecurityManager() throws PrivilegedActionException {
090: installSecurityManager("<NONE>");
091: }
092:
093: /**
094: * Install specific polciy file with the security manager
095: * including the special case of no security manager.
096: */
097: protected void setUp() throws PrivilegedActionException {
098: installSecurityManager(decoratorPolicyResource);
099: }
100:
101: /**
102: * Install a SecurityManager with the default test policy
103: * file:
104: * org/apache/derbyTesting/functionTests/util/derby_tests.policy
105: *
106: */
107: static void installSecurityManager()
108: throws PrivilegedActionException {
109: installSecurityManager("org/apache/derbyTesting/functionTests/util/derby_tests.policy");
110:
111: }
112:
113: private static void installSecurityManager(String policyFile)
114: throws PrivilegedActionException {
115:
116: if (externalSecurityManagerInstalled)
117: return;
118:
119: Properties set = new Properties(classPathSet);
120: setSecurityPolicy(set, policyFile);
121:
122: SecurityManager sm = System.getSecurityManager();
123: if (sm != null) {
124: // SecurityManager installed, see if it has the same settings.
125:
126: if (set.getProperty("java.security.policy").equals(
127: BaseTestCase
128: .getSystemProperty("java.security.policy")))
129: return;
130:
131: // Uninstall the current manager.
132: AccessController
133: .doPrivileged(new java.security.PrivilegedAction() {
134:
135: public Object run() {
136: System.setSecurityManager(null);
137: return null;
138: }
139: });
140: }
141:
142: // Set the system properties from the desired set.
143: for (Enumeration e = set.propertyNames(); e.hasMoreElements();) {
144: String key = (String) e.nextElement();
145: BaseTestCase.setSystemProperty(key, set.getProperty(key));
146: }
147:
148: // Check indicator for no security manager
149: if ("<NONE>".equals(set.getProperty("java.security.policy")))
150: return;
151:
152: // and install
153: AccessController
154: .doPrivileged(new java.security.PrivilegedAction() {
155:
156: public Object run() {
157: System
158: .setSecurityManager(new SecurityManager());
159: return null;
160: }
161: });
162:
163: }
164:
165: private static void setSecurityPolicy(Properties set,
166: String policyResource) throws PrivilegedActionException {
167: if ("<NONE>".equals(policyResource)) {
168: set.setProperty("java.security.policy", policyResource);
169: return;
170: }
171: URL policyURL = BaseTestCase.getTestResource(policyResource);
172:
173: if (policyURL != null)
174: set.setProperty("java.security.policy", policyURL
175: .toExternalForm());
176: }
177:
178: /**
179: * Determine the settings of the classpath in order to configure
180: * the variables used in the testing policy files.
181: * Looks for three items:
182: *
183: * Location of derbyTesting.jar via this class
184: * Location of derby.jar via org.apache.derby.jdbc.EmbeddedSimpleDataSource
185: * Location of derbyclient.jar via org.apache.derby.jdbc.ClientDataSource
186: *
187: * Two options are supported, either all are in jar files or
188: * all are on the classpath. Properties are set as follows:
189: *
190: * <P>
191: * Classpath:
192: * <BR>
193: * derbyTesting.codeclasses set to location of classes folder
194: * <P>
195: * Jar files:
196: * <BR>
197: * derbyTesting.codejar - location of derby.jar,
198: * derbynet.jar and derbytools.jar, all assumed to be in the
199: * same location.
200: * <BR>
201: * derbyTesting.clientjar - location of derbyclient.jar (FUTURE)
202: * <BR>
203: * derbyTesting.testjar - location of derbyTesting.jar (FUTURE)
204: *
205: */
206: private static boolean determineClasspath() {
207: // Security manager already installed, assume that
208: // it is set up correctly.
209: if (System.getSecurityManager() != null) {
210: return true;
211: }
212:
213: URL testing = getURL(SecurityManagerSetup.class);
214:
215: boolean isClasspath = testing.toExternalForm().endsWith("/");
216: if (isClasspath) {
217: classPathSet.setProperty("derbyTesting.codeclasses",
218: testing.toExternalForm());
219: isJars = false;
220: return false;
221: }
222: classPathSet.setProperty("derbyTesting.testjar",
223: stripJar(testing));
224: isJars = true;
225:
226: URL derby = null;
227: try {
228: derby = getURL(org.apache.derby.jdbc.EmbeddedSimpleDataSource.class);
229: } catch (java.lang.NoClassDefFoundError e) {
230: derby = testing;
231: }
232: classPathSet.setProperty("derbyTesting.codejar",
233: stripJar(derby));
234:
235: URL client = null;
236: try {
237: client = getURL(org.apache.derby.jdbc.ClientDataSource.class);
238: } catch (java.lang.NoClassDefFoundError e) {
239: client = derby;
240: }
241:
242: classPathSet.setProperty("derbyTesting.clientjar",
243: stripJar(client));
244:
245: return false;
246: }
247:
248: /**
249: * Return the policy file system properties for use
250: * by the old test harness. This ensures a consistent
251: * approach to setting the properties. There are the
252: * properties used to define the jar file location in
253: * any policy files.
254: * @return
255: */
256: public static Properties getPolicyFilePropertiesForOldHarness() {
257: return classPathSet;
258: }
259:
260: /**
261: * Strip of the last token which will be the jar name.
262: * The returned string includes the trailing slash.
263: * @param url
264: * @return
265: */
266: private static String stripJar(URL url) {
267: String ef = url.toExternalForm();
268: return ef.substring(0, ef.lastIndexOf('/') + 1);
269: }
270:
271: /**
272: * Get the URL of the code base from a class.
273: */
274: private static URL getURL(final Class cl) {
275: return (URL) AccessController
276: .doPrivileged(new java.security.PrivilegedAction() {
277:
278: public Object run() {
279: return cl.getProtectionDomain().getCodeSource()
280: .getLocation();
281: }
282: });
283: }
284: }
|