myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject [myfaces-test] 21/24: MYFACESTEST-19 JUnit4 Runner that runs each Test method in a seperate classloader (thanks to Rudy De Busscher for this patch)
Date Thu, 03 May 2018 18:26:49 GMT
This is an automated email from the ASF dual-hosted git repository.

deki pushed a commit to branch 1_0_0_beta_4
in repository https://gitbox.apache.org/repos/asf/myfaces-test.git

commit a06f745f3d4fd50831fe4c361069fe07fb82e68d
Author: Leonardo Uribe <lu4242@apache.org>
AuthorDate: Tue Jul 13 04:14:17 2010 +0000

    MYFACESTEST-19 JUnit4 Runner that runs each Test method in a seperate classloader (thanks
to Rudy De Busscher for this patch)
---
 test12/pom.xml                                     |   8 +
 .../myfaces/test/base/AbstractJsfTestCase.java     |   4 +-
 .../apache/myfaces/test/runners/NamedRunner.java   | 123 ++++++++
 .../myfaces/test/runners/TestClassLoader.java      | 332 +++++++++++++++++++++
 .../test/runners/TestPerClassLoaderRunner.java     | 293 ++++++++++++++++++
 .../myfaces/test/runners/excluded.properties       |  12 +
 .../runner/TestPerCLassLoaderDefaultTestCase.java  |  71 +++++
 .../test/runner/TestPerClassLoaderTestCase.java    |  66 ++++
 .../myfaces/test/runner/WebXmlParameter.java       |  30 ++
 .../apache/myfaces/test/runner/WebXmlUtils.java    |  40 +++
 10 files changed, 978 insertions(+), 1 deletion(-)

diff --git a/test12/pom.xml b/test12/pom.xml
index 4484902..1838e31 100644
--- a/test12/pom.xml
+++ b/test12/pom.xml
@@ -95,6 +95,14 @@
     </dependencies>
 
     <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*properties</include>
+                </includes>
+            </resource>
+        </resources>
         <plugins>
             <plugin>
                 <artifactId>maven-compiler-plugin</artifactId>
diff --git a/test12/src/main/java/org/apache/myfaces/test/base/AbstractJsfTestCase.java b/test12/src/main/java/org/apache/myfaces/test/base/AbstractJsfTestCase.java
index fbe30cb..54e444e 100644
--- a/test12/src/main/java/org/apache/myfaces/test/base/AbstractJsfTestCase.java
+++ b/test12/src/main/java/org/apache/myfaces/test/base/AbstractJsfTestCase.java
@@ -202,7 +202,9 @@ public abstract class AbstractJsfTestCase extends TestCase {
         application = null;
         config = null;
         externalContext = null;
-        facesContext.release();
+        if (facesContext != null) {
+            facesContext.release();
+        }
         facesContext = null;
         lifecycle = null;
         lifecycleFactory = null;
diff --git a/test12/src/main/java/org/apache/myfaces/test/runners/NamedRunner.java b/test12/src/main/java/org/apache/myfaces/test/runners/NamedRunner.java
new file mode 100644
index 0000000..5493027
--- /dev/null
+++ b/test12/src/main/java/org/apache/myfaces/test/runners/NamedRunner.java
@@ -0,0 +1,123 @@
+/*
+ * 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.myfaces.test.runners;
+
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * A Junit 4 runner that stores the name of the method that runs.  The methods marked with
@After and @Before 
+ * (but also the Test method itself) can request this name for which it is running.
+ * 
+ * @author Rudy De Busscher
+ */
+public class NamedRunner extends BlockJUnit4ClassRunner
+{
+
+    /** The Constant PREFIX_KEY. */
+    private static final String PREFIX_KEY = "ClassLoaderRunner_TestMethodName_";
+
+    /** The Constant NO_NAME. */
+    private static final String NO_NAME = "null";
+
+    /**
+     * Instantiates a new named runner.
+     * 
+     * @param klass the klass
+     * 
+     * @throws InitializationError the initialization error
+     */
+    public NamedRunner(Class<?> klass) throws InitializationError
+    {
+        super(klass);
+    }
+
+    @Override
+    protected void runChild(FrameworkMethod method, RunNotifier notifier)
+
+    {
+        storeTestMethodName(method.getName());
+        super.runChild(method, notifier);
+        removeTestMethodName();
+    }
+
+    /**
+     * Gets the test method name.
+     * 
+     * @return the test method name
+     */
+    public static String getTestMethodName()
+    {
+        return retrieveTestMethodName();
+    }
+
+    /**
+     * Retrieve test method name.
+     * 
+     * @return the string
+     */
+    private static String retrieveTestMethodName()
+    {
+        // We can't use a ThreadLocal variable in the case the TestPerClassLoader runner
is used.  Then this
+        // Method is accessed from another classloader and thus reinitialized variables.
+        String result = null;
+        String storedName = System.getProperty(getKey());
+        if (!NO_NAME.equals(storedName))
+        {
+            result = storedName;
+        }
+        return result;
+    }
+
+    /**
+     * Removes the test method name.
+     */
+    private static void removeTestMethodName()
+    {
+        // We can't use a ThreadLocal variable in the case the TestPerClassLoader runner
is used.  Then this
+        // Method is accessed from another classloader and thus reinitialized variables.
+        System.setProperty(getKey(), NO_NAME);
+
+    }
+
+    /**
+     * Store test method name.
+     * 
+     * @param name the name
+     */
+    private static void storeTestMethodName(String name)
+    {
+
+        // We can't use a ThreadLocal variable in the case the TestPerClassLoader runner
is used.  Then this
+        // Method is accessed from another classloader and thus reinitialized variables.
+        System.setProperty(getKey(), name);
+    }
+
+    /**
+     * Gets the key.
+     * 
+     * @return the key
+     */
+    private static String getKey()
+    {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(PREFIX_KEY).append(Thread.currentThread().getName());
+        return buffer.toString();
+    }
+}
diff --git a/test12/src/main/java/org/apache/myfaces/test/runners/TestClassLoader.java b/test12/src/main/java/org/apache/myfaces/test/runners/TestClassLoader.java
new file mode 100644
index 0000000..036f1f0
--- /dev/null
+++ b/test12/src/main/java/org/apache/myfaces/test/runners/TestClassLoader.java
@@ -0,0 +1,332 @@
+/*
+ * 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.myfaces.test.runners;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * A Classloader that delegates the loading of the classes to the parent if it is in the

+ * excluded list or does it itself otherwise.
+ * Useful for a system that sets up a classloader per Test system.
+ *  
+ * @author Rudy De Busscher
+ */
+public class TestClassLoader extends ClassLoader
+{
+    /** scanned class path */
+    private Vector<String> fPathItems;
+    /** default excluded paths */
+    private String[] defaultExclusions = { "junit.framework.",
+            "junit.extensions.", "junit.runner." };
+    /** name of excluded properties file */
+    static final String EXCLUDED_FILE = "excluded.properties";
+    /** excluded paths */
+    private Vector<String> fExcluded;
+
+    /**
+     * Constructs a TestCaseLoader. It scans the class path
+     * and the excluded package paths
+     */
+    public TestClassLoader()
+    {
+        this(System.getProperty("java.class.path"));
+    }
+
+    /**
+     * Constructs a TestCaseLoader. It scans the class path
+     * and the excluded package paths
+     */
+    public TestClassLoader(String classPath)
+    {
+        scanPath(classPath);
+        readExcludedPackages();
+    }
+
+    private void scanPath(String classPath)
+    {
+        String separator = System.getProperty("path.separator");
+        fPathItems = new Vector<String>(10);
+        StringTokenizer st = new StringTokenizer(classPath, separator);
+        while (st.hasMoreTokens())
+        {
+            fPathItems.addElement(st.nextToken());
+        }
+    }
+
+    @Override
+    public URL getResource(String name)
+    {
+        return ClassLoader.getSystemResource(name);
+    }
+
+    @Override
+    public InputStream getResourceAsStream(String name)
+    {
+        return ClassLoader.getSystemResourceAsStream(name);
+    }
+
+    /**
+     * Checks if path is excluded.
+     * 
+     * @param name the name
+     * 
+     * @return true, if is excluded
+     */
+    public boolean isExcluded(String name)
+    {
+        for (int i = 0; i < fExcluded.size(); i++)
+        {
+            if (name.startsWith((String) fExcluded.elementAt(i)))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public synchronized Class loadClass(String name, boolean resolve)
+            throws ClassNotFoundException
+    {
+
+        Class c = findLoadedClass(name);
+        if (c != null)
+            return c;
+        //
+        // Delegate the loading of excluded classes to the
+        // standard class loader.
+        //
+        if (isExcluded(name))
+        {
+            try
+            {
+                c = findSystemClass(name);
+                return c;
+            }
+            catch (ClassNotFoundException e)
+            {
+                // keep searching
+            }
+        }
+        if (c == null)
+        {
+            byte[] data = lookupClassData(name);
+            if (data == null)
+                throw new ClassNotFoundException();
+            c = defineClass(name, data, 0, data.length);
+        }
+        if (resolve)
+            resolveClass(c);
+        return c;
+    }
+
+    /**
+     * Lookup class data in one of the classpath elements configured.
+     * 
+     * @param className the class name
+     * 
+     * @return the bytes making up the class
+     * 
+     * @throws ClassNotFoundException when class can't be found on the classpath elements.
+     */
+    private byte[] lookupClassData(String className)
+            throws ClassNotFoundException
+    {
+        byte[] data = null;
+        for (int i = 0; i < fPathItems.size(); i++)
+        {
+            String path = (String) fPathItems.elementAt(i);
+            String fileName = className.replace('.', '/') + ".class";
+            if (isJar(path))
+            {
+                data = loadJarData(path, fileName);
+            }
+            else
+            {
+                data = loadFileData(path, fileName);
+            }
+            if (data != null)
+                return data;
+        }
+        throw new ClassNotFoundException(className);
+    }
+
+    /**
+     * Checks if is jar.
+     * 
+     * @param pathEntry the path entry
+     * 
+     * @return true, if is jar
+     */
+    boolean isJar(String pathEntry)
+    {
+        return pathEntry.endsWith(".jar") || pathEntry.endsWith(".zip");
+    }
+
+    /**
+     * Load class bytes from file.
+     * 
+     * @param path the path
+     * @param fileName the file name
+     * 
+     * @return the bytes making up the class
+     */
+    private byte[] loadFileData(String path, String fileName)
+    {
+        File file = new File(path, fileName);
+        if (file.exists())
+        {
+            return getClassData(file);
+        }
+        return null;
+    }
+
+    private byte[] getClassData(File f)
+    {
+        try
+        {
+            FileInputStream stream = new FileInputStream(f);
+            ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
+            byte[] b = new byte[1000];
+            int n;
+            while ((n = stream.read(b)) != -1)
+                out.write(b, 0, n);
+            stream.close();
+            out.close();
+            return out.toByteArray();
+
+        }
+        catch (IOException e)
+        {
+        }
+        return null;
+    }
+
+    /**
+     * Load class bytes from jar.
+     * 
+     * @param path the path
+     * @param fileName the file name
+     * 
+     * @return the bytes making up the class
+     */
+    private byte[] loadJarData(String path, String fileName)
+    {
+        ZipFile zipFile = null;
+        InputStream stream = null;
+        File archive = new File(path);
+        if (!archive.exists())
+            return null;
+        try
+        {
+            zipFile = new ZipFile(archive);
+        }
+        catch (IOException io)
+        {
+            return null;
+        }
+        ZipEntry entry = zipFile.getEntry(fileName);
+        if (entry == null)
+            return null;
+        int size = (int) entry.getSize();
+        try
+        {
+            stream = zipFile.getInputStream(entry);
+            byte[] data = new byte[size];
+            int pos = 0;
+            while (pos < size)
+            {
+                int n = stream.read(data, pos, data.length - pos);
+                pos += n;
+            }
+            zipFile.close();
+            return data;
+        }
+        catch (IOException e)
+        {
+        }
+        finally
+        {
+            try
+            {
+                if (stream != null)
+                    stream.close();
+            }
+            catch (IOException e)
+            {
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Read excluded packages for which classes are read by the parent class loader.
+     */
+    private void readExcludedPackages()
+    {
+        fExcluded = new Vector<String>(10);
+        for (int i = 0; i < defaultExclusions.length; i++)
+            fExcluded.addElement(defaultExclusions[i]);
+
+        InputStream is = getClass().getResourceAsStream(EXCLUDED_FILE);
+        if (is == null)
+            return;
+        Properties p = new Properties();
+        try
+        {
+            p.load(is);
+        }
+        catch (IOException e)
+        {
+            return;
+        }
+        finally
+        {
+            try
+            {
+                is.close();
+            }
+            catch (IOException e)
+            {
+            }
+        }
+        for (Enumeration e = p.propertyNames(); e.hasMoreElements();)
+        {
+            String key = (String) e.nextElement();
+            if (key.startsWith("excluded."))
+            {
+                String path = p.getProperty(key);
+                path = path.trim();
+                if (path.endsWith("*"))
+                    path = path.substring(0, path.length() - 1);
+                if (path.length() > 0)
+                    fExcluded.addElement(path);
+            }
+        }
+    }
+}
diff --git a/test12/src/main/java/org/apache/myfaces/test/runners/TestPerClassLoaderRunner.java
b/test12/src/main/java/org/apache/myfaces/test/runners/TestPerClassLoaderRunner.java
new file mode 100644
index 0000000..32e2c12
--- /dev/null
+++ b/test12/src/main/java/org/apache/myfaces/test/runners/TestPerClassLoaderRunner.java
@@ -0,0 +1,293 @@
+/*
+ * 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.myfaces.test.runners;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.internal.runners.statements.Fail;
+import org.junit.internal.runners.statements.RunAfters;
+import org.junit.internal.runners.statements.RunBefores;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+
+/**
+ * A Junit 4 runner that executes each Test method with a new Custom classloader so that
all variables, 
+ * also the final ones, are reinitialized.
+ * 
+ * @author Rudy De Busscher
+
+ */
+public class TestPerClassLoaderRunner extends NamedRunner
+{
+    private static final Logger LOGGER = Logger
+            .getLogger(TestPerClassLoaderRunner.class.getName());
+
+    // The classpath is needed because the custom class loader looks there to find the classes.
+    private static String classPath;
+    private static boolean classPathDetermined = false;
+
+    // Some data related to the class from the custom class loader.
+    private TestClass testClassFromClassLoader;
+    private Object beforeFromClassLoader;
+    private Object afterFromClassLoader;
+
+    /**
+     * Instantiates a new test per class loader runner.
+     * 
+     * @param klass the klass
+     * 
+     * @throws InitializationError the initialization error
+     */
+    public TestPerClassLoaderRunner(Class<?> klass) throws InitializationError
+    {
+        super(klass);
+    }
+
+    @Override
+    protected Object createTest() throws Exception
+    {
+        // Need an instance now from the class loaded by the custom loader.
+        return testClassFromClassLoader.getJavaClass().newInstance();
+    }
+
+    /**
+     * Load classes (TestCase, @Before and @After with custom class loader.
+     * 
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void loadClassesWithCustomClassLoader()
+            throws ClassNotFoundException
+    {
+        ClassLoader classLoader;
+
+        // We need the classpath so that our custom loader can search for the requested classes.
+        String testPath = getClassPath();
+        if (testPath != null)
+        {
+            classLoader = new TestClassLoader(testPath);
+        }
+
+        else
+        {
+            classLoader = new TestClassLoader();
+
+        }
+
+        testClassFromClassLoader = new TestClass(classLoader
+                .loadClass(getTestClass().getJavaClass().getName()));
+        // See withAfters and withBefores for the reason.
+        beforeFromClassLoader = classLoader.loadClass(Before.class.getName());
+        afterFromClassLoader = classLoader.loadClass(After.class.getName());
+    }
+
+    @Override
+    protected Statement methodBlock(FrameworkMethod method)
+    {
+        FrameworkMethod newMethod = null;
+        try
+        {
+            // Need the class frmo the custom loader now, so lets load the class.
+            loadClassesWithCustomClassLoader();
+            // The method as parameter is frmo the original class and thus not found in our
+            // class loaded by the custom name (reflection is class loader sensitive)
+            // So find the same method but now in the class frmo the class Loader.
+            Method methodFromNewlyLoadedClass = testClassFromClassLoader
+                    .getJavaClass().getMethod(method.getName());
+            newMethod = new FrameworkMethod(methodFromNewlyLoadedClass);
+        }
+        catch (ClassNotFoundException e)
+        {
+            // Show any problem nicely as a JUnit Test failure.
+            return new Fail(e);
+        }
+        catch (SecurityException e)
+        {
+            return new Fail(e);
+        }
+        catch (NoSuchMethodException e)
+        {
+            return new Fail(e);
+        }
+
+        // We can carry out the normal JUnit functionality with our newly discoverd method
now. 
+        return super.methodBlock(newMethod);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected Statement withAfters(FrameworkMethod method, Object target,
+            Statement statement)
+    {
+        // We now to need to search in the class from the custom loader.
+        //We also need to search with the annotation loaded by the custom class loader or
otherwise we don't find any method.
+        List<FrameworkMethod> afters = testClassFromClassLoader
+                .getAnnotatedMethods((Class<? extends Annotation>) afterFromClassLoader);
+        return new RunAfters(statement, afters, target);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected Statement withBefores(FrameworkMethod method, Object target,
+            Statement statement)
+    {
+        // We now to need to search in the class from the custom loader.
+        //We also need to search with the annotation loaded by the custom class loader or
otherwise we don't find any method.
+        List<FrameworkMethod> befores = testClassFromClassLoader
+                .getAnnotatedMethods((Class<? extends Annotation>) beforeFromClassLoader);
+        return new RunBefores(statement, befores, target);
+    }
+
+    /**
+     * Gets the class path. This value is cached in a static variable for performance reasons.
+     * 
+     * @return the class path
+     */
+    private static String getClassPath()
+    {
+        if (classPathDetermined)
+        {
+            return classPath;
+        }
+
+        classPathDetermined = true;
+        // running from maven, we have the classpath in this property.
+        classPath = System.getProperty("surefire.test.class.path");
+        if (classPath != null)
+        {
+            return classPath;
+        }
+
+        // For a multi module project, running it from the top we have to find it using another
way.
+        // We also need to set useSystemClassLoader=true in the POM so that we gets a jar
with the classpath in it.
+        String booterClassPath = System.getProperty("java.class.path");
+        Vector<String> pathItems = null;
+        if (booterClassPath != null)
+        {
+            pathItems = scanPath(booterClassPath);
+        }
+        // Do we have just 1 entry as classpath which is a jar?
+        if (pathItems != null && pathItems.size() == 1
+                && isJar((String) pathItems.get(0)))
+        {
+            classPath = loadJarManifestClassPath((String) pathItems.get(0),
+                    "META-INF/MANIFEST.MF");
+        }
+        return classPath;
+
+    }
+
+    /**
+     * Load jar manifest class path.
+     * 
+     * @param path the path
+     * @param fileName the file name
+     * 
+     * @return the string
+     */
+    private static String loadJarManifestClassPath(String path, String fileName)
+    {
+        File archive = new File(path);
+        if (!archive.exists())
+        {
+            return null;
+        }
+        ZipFile zipFile = null;
+
+        try
+        {
+            zipFile = new ZipFile(archive);
+        }
+        catch (IOException io)
+        {
+            return null;
+        }
+
+        ZipEntry entry = zipFile.getEntry(fileName);
+        if (entry == null)
+        {
+            return null;
+        }
+        try
+        {
+            Manifest mf = new Manifest();
+            mf.read(zipFile.getInputStream(entry));
+
+            return mf.getMainAttributes().getValue(Attributes.Name.CLASS_PATH)
+                    .replaceAll(" ", System.getProperty("path.separator"))
+                    .replaceAll("file:/", "");
+        }
+        catch (MalformedURLException e)
+        {
+            LOGGER.throwing("ClassLoaderTestSuite", "loadJarManifestClassPath",
+                    e);
+        }
+        catch (IOException e)
+        {
+            LOGGER.throwing("ClassLoaderTestSuite", "loadJarManifestClassPath",
+                    e);
+        }
+        return null;
+    }
+
+    /**
+     * Checks if is jar.
+     * 
+     * @param pathEntry the path entry
+     * 
+     * @return true, if is jar
+     */
+    private static boolean isJar(String pathEntry)
+    {
+        return pathEntry.endsWith(".jar") || pathEntry.endsWith(".zip");
+    }
+
+    /**
+     * Scan path for all directories.
+     * 
+     * @param classPath the class path
+     * 
+     * @return the vector< string>
+     */
+    private static Vector<String> scanPath(String classPath)
+    {
+        String separator = System.getProperty("path.separator");
+        Vector<String> pathItems = new Vector<String>(10);
+        StringTokenizer st = new StringTokenizer(classPath, separator);
+        while (st.hasMoreTokens())
+        {
+            pathItems.addElement(st.nextToken());
+        }
+        return pathItems;
+    }
+
+}
diff --git a/test12/src/main/resources/org/apache/myfaces/test/runners/excluded.properties
b/test12/src/main/resources/org/apache/myfaces/test/runners/excluded.properties
new file mode 100644
index 0000000..a936e9a
--- /dev/null
+++ b/test12/src/main/resources/org/apache/myfaces/test/runners/excluded.properties
@@ -0,0 +1,12 @@
+#
+# The list of excluded package paths for the TestCaseClassLoader
+#
+excluded.0=sun.*
+excluded.1=com.sun.*
+excluded.2=org.omg.*
+excluded.3=javax.*
+excluded.4=sunw.*
+excluded.5=java.*
+excluded.6=org.w3c.dom.*
+excluded.7=org.xml.sax.*
+excluded.8=net.jini.*
diff --git a/test12/src/test/java/org/apache/myfaces/test/runner/TestPerCLassLoaderDefaultTestCase.java
b/test12/src/test/java/org/apache/myfaces/test/runner/TestPerCLassLoaderDefaultTestCase.java
new file mode 100644
index 0000000..9106b8d
--- /dev/null
+++ b/test12/src/test/java/org/apache/myfaces/test/runner/TestPerCLassLoaderDefaultTestCase.java
@@ -0,0 +1,71 @@
+/*
+ * 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.myfaces.test.runner;
+
+import junit.framework.Assert;
+
+import org.apache.myfaces.test.base.junit4.AbstractJsfConfigurableMockTestCase;
+import org.apache.myfaces.test.runners.NamedRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * 
+ * @author Rudy De Busscher
+ */
+@RunWith(value = NamedRunner.class)
+public class TestPerCLassLoaderDefaultTestCase extends
+        AbstractJsfConfigurableMockTestCase
+{
+
+    @Override
+    protected void setUpExternalContext() throws Exception
+    {
+
+        super.setUpExternalContext();
+
+        if (needXmlParameters())
+        {
+            servletContext
+                    .addInitParameter(WebXmlParameter.PARAMETER_KEY, "60");
+        }
+
+    }
+
+    @Test
+    public void testGetParameterDefault()
+    {
+        Assert.assertNull(WebXmlParameter.PARAMETER);
+    }
+
+    @Test
+    public void testGetParameterWebXml()
+    {
+
+        Assert.assertNull(WebXmlParameter.PARAMETER);
+        // Although the parameter is set, the final variable keeps it value
+        // Since we aren't running with the TestPerClassLoader Test case.
+        Assert.assertNotNull(servletContext
+                .getInitParameter(WebXmlParameter.PARAMETER_KEY));
+    }
+
+    // These methods can be placed in a common super class.
+    protected boolean needXmlParameters()
+    {
+        return NamedRunner.getTestMethodName().contains("Xml");
+    }
+}
diff --git a/test12/src/test/java/org/apache/myfaces/test/runner/TestPerClassLoaderTestCase.java
b/test12/src/test/java/org/apache/myfaces/test/runner/TestPerClassLoaderTestCase.java
new file mode 100644
index 0000000..86fe9ed
--- /dev/null
+++ b/test12/src/test/java/org/apache/myfaces/test/runner/TestPerClassLoaderTestCase.java
@@ -0,0 +1,66 @@
+/*
+ * 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.myfaces.test.runner;
+
+import junit.framework.Assert;
+
+import org.apache.myfaces.test.base.junit4.AbstractJsfConfigurableMockTestCase;
+import org.apache.myfaces.test.runners.TestPerClassLoaderRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * 
+ * @author Rudy De Busscher
+ */
+@RunWith(value = TestPerClassLoaderRunner.class)
+public class TestPerClassLoaderTestCase extends
+        AbstractJsfConfigurableMockTestCase
+{
+
+    @Override
+    protected void setUpExternalContext() throws Exception
+    {
+
+        super.setUpExternalContext();
+
+        if (needXmlParameters())
+        {
+            servletContext
+                    .addInitParameter(WebXmlParameter.PARAMETER_KEY, "60");
+        }
+
+    }
+
+    @Test
+    public void testGetParameterDefault()
+    {
+        Assert.assertNull(WebXmlParameter.PARAMETER);
+    }
+
+    @Test
+    public void testGetParameterWebXml()
+    {
+        Assert.assertEquals("60", WebXmlParameter.PARAMETER);
+    }
+
+    // These methods can be placed in a common super class.
+    protected boolean needXmlParameters()
+    {
+        return TestPerClassLoaderRunner.getTestMethodName().contains("Xml");
+    }
+}
diff --git a/test12/src/test/java/org/apache/myfaces/test/runner/WebXmlParameter.java b/test12/src/test/java/org/apache/myfaces/test/runner/WebXmlParameter.java
new file mode 100644
index 0000000..455fb58
--- /dev/null
+++ b/test12/src/test/java/org/apache/myfaces/test/runner/WebXmlParameter.java
@@ -0,0 +1,30 @@
+/*
+ * 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.myfaces.test.runner;
+
+/**
+ * 
+ * @author Rudy De Busscher
+ */
+public class WebXmlParameter
+{
+    public static final String PARAMETER_KEY = "PARAMETER";
+    
+    static final String PARAMETER = WebXmlUtils
+            .getInitParameter(PARAMETER_KEY);
+
+}
diff --git a/test12/src/test/java/org/apache/myfaces/test/runner/WebXmlUtils.java b/test12/src/test/java/org/apache/myfaces/test/runner/WebXmlUtils.java
new file mode 100644
index 0000000..f122dfc
--- /dev/null
+++ b/test12/src/test/java/org/apache/myfaces/test/runner/WebXmlUtils.java
@@ -0,0 +1,40 @@
+/*
+ * 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.myfaces.test.runner;
+
+import javax.faces.context.FacesContext;
+
+/**
+ * 
+ * @author Rudy De Busscher
+ */
+public final class WebXmlUtils
+{
+
+    private WebXmlUtils()
+    {
+
+    }
+
+    public static String getInitParameter(String parameterName)
+    {
+        String value = FacesContext.getCurrentInstance().getExternalContext()
+                .getInitParameter(parameterName);
+        return (value != null) ? value.replace(" ", "").trim() : null;
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
deki@apache.org.

Mime
View raw message