You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by rw...@apache.org on 2009/04/25 00:44:37 UTC

svn commit: r768433 [1/3] - in /portals/jetspeed-2/portal/trunk/components: jetspeed-page-manager/src/test/java/org/apache/jetspeed/page/cache/ jetspeed-portal/ jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/ jetspeed-portal/src/test...

Author: rwatler
Date: Fri Apr 24 22:44:37 2009
New Revision: 768433

URL: http://svn.apache.org/viewvc?rev=768433&view=rev
Log:
adding multi-server PAM unit test for testing concurrency issues; PAM fails in the concurrent version of this test, so it is committed here executing serially

Added:
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/resources/log4j-stdout.properties
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/WEB-INF/
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/WEB-INF/portlet.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/WEB-INF/web.xml
Modified:
    portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/java/org/apache/jetspeed/page/cache/TestDatabasePageManagerCache.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/java/org/apache/jetspeed/page/cache/TestDatabasePageManagerCache.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/java/org/apache/jetspeed/page/cache/TestDatabasePageManagerCache.java?rev=768433&r1=768432&r2=768433&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/java/org/apache/jetspeed/page/cache/TestDatabasePageManagerCache.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-page-manager/src/test/java/org/apache/jetspeed/page/cache/TestDatabasePageManagerCache.java Fri Apr 24 22:44:37 2009
@@ -563,7 +563,7 @@
         
         private void logProcessLine(final String line)
         {
-            if (!line.contains("INFO") && (line.contains("ERROR") || line.contains("Exception") || line.startsWith("   at ")))
+            if (!line.contains("INFO") && (line.contains("ERROR") || line.contains("Exception") || line.matches("^\\s+at\\s")))
             {
                 log.error("{"+name+"} "+line);
             }

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml?rev=768433&r1=768432&r2=768433&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml Fri Apr 24 22:44:37 2009
@@ -237,6 +237,11 @@
             <artifactId>tyrex</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>commons-jexl</groupId>
+            <artifactId>commons-jexl</artifactId>
+            <scope>test</scope>
+        </dependency>
         
         <!-- Runtime Dependencies -->
         <dependency>

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java?rev=768433&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java Fri Apr 24 22:44:37 2009
@@ -0,0 +1,262 @@
+/*
+ * 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.jetspeed.tools.pamanager;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.jexl.JexlContext;
+import org.apache.commons.jexl.JexlHelper;
+import org.apache.commons.jexl.Script;
+import org.apache.commons.jexl.ScriptFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.components.JetspeedBeanDefinitionFilter;
+import org.apache.jetspeed.components.SpringComponentManager;
+import org.apache.jetspeed.components.jndi.JetspeedTestJNDIComponent;
+import org.apache.jetspeed.components.portletregistry.RegistryException;
+import org.apache.jetspeed.util.DirectoryHelper;
+
+/**
+ * PortletApplicationManagerServer
+ * 
+ * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
+ * @version $Id: $
+ */
+public class PortletApplicationManagerServer
+{
+    protected static Log log = LogFactory.getLog(PortletApplicationManagerServer.class);
+    
+    // Constants
+    
+    public static final String SCRIPT_RESULT_LINE_PREFIX = "> ";
+    
+    // Members
+    
+    private JetspeedTestJNDIComponent jndiDS;
+    private String baseDir;
+    private SpringComponentManager scm;
+    private JexlContext jexlContext;
+    private boolean exit;
+    private PortletApplicationManagement portletApplicationManager;    
+    
+    // Life cycle
+    
+    /**
+     * Initialize page manager server instance and script context.
+     * 
+     * @throws Exception
+     */
+    public void initialize() throws Exception
+    {
+        // setup jetspeed test datasource and component manager
+        jndiDS = new JetspeedTestJNDIComponent();
+        jndiDS.setup();
+        final JetspeedBeanDefinitionFilter beanDefinitionFilter = new JetspeedBeanDefinitionFilter("default,jdbcDS,xmlPageManager,security,dbSecurity");
+        final String [] bootConfigurations = new String[]{"boot/datasource.xml"};
+        final List<String> configurationsList = new ArrayList<String>();
+        configurationsList.add("transaction.xml");
+        configurationsList.add("cache.xml");
+        configurationsList.add("jetspeed-base.xml");
+        configurationsList.add("jetspeed-properties.xml");
+        configurationsList.add("page-manager.xml");
+        configurationsList.add("registry.xml");
+        configurationsList.add("rc2.xml");
+        configurationsList.add("deployment.xml");
+        if (TestPortletApplicationManager.TEST_USE_VERSIONED_PAM)
+        {
+            configurationsList.add("alternate/versioned-deployment/deployment.xml");
+        }
+        configurationsList.add("static-bean-references.xml");
+        configurationsList.add("security-managers.xml");
+        configurationsList.add("security-providers.xml");
+        configurationsList.add("security-spi-atn.xml");
+        configurationsList.add("security-spi.xml");
+        configurationsList.add("security-atn.xml");
+        configurationsList.add("security-atz.xml");
+        configurationsList.add("JETSPEED-INF/spring/JetspeedPrincipalManagerProviderOverride.xml");
+        configurationsList.add("search.xml");
+        configurationsList.add("cluster-node.xml");
+        final String[] configurations = configurationsList.toArray(new String[configurationsList.size()]);
+        baseDir = System.getProperty("basedir");
+        if ((baseDir == null) || (baseDir.length() == 0))
+        {
+            baseDir = System.getProperty("user.dir");
+        }
+        final String appRoot = baseDir+"/target/test-classes/webapp";
+        scm = new SpringComponentManager(beanDefinitionFilter, bootConfigurations, configurations, appRoot, false);
+        scm.start();
+
+        // access portal application manager
+        portletApplicationManager = (PortletApplicationManagement)scm.getComponent("PAM");
+        
+        // create jexl context
+        jexlContext = JexlHelper.createContext();
+        jexlContext.getVars().put("portletApplicationManagerServer", this);
+        
+        log.info( "PortalApplicationManager server initialized");
+    }
+    
+    /**
+     * Terminate page manager server instance.
+     * 
+     * @throws Exception
+     */
+    public void terminate() throws Exception
+    {
+        // tear down jetspeed component manager and test datasource
+        scm.stop();
+        jndiDS.tearDown();
+
+        log.info( "PortalApplicationManager server terminated");
+    }
+    
+    // Implementation
+    
+    /**
+     * Execute a single line script against page manager server context.
+     * 
+     * @param scriptLine jexl script
+     * @return script result line
+     */
+    public String execute(final String scriptLine)
+    {
+        // execute script line and return result line
+        String resultLine = scriptLine;
+        try
+        {
+            final Script jexlScript = ScriptFactory.createScript(scriptLine);
+            final Object result = jexlScript.execute(jexlContext);
+            if (result != null)
+            {
+                resultLine += " -> "+result;
+            }
+        }
+        catch (final Exception e)
+        {
+            resultLine += " -> "+e;            
+        }
+        return resultLine;
+    }
+
+    /**
+     * Start test portlet application.
+     * 
+     * @throws RegistryException
+     */
+    public void startPortletApplication() throws RegistryException
+    {
+        DirectoryHelper portletApplicationDir = new DirectoryHelper(new File(baseDir+"/src/test/testdata/"+TestPortletApplicationManager.CONTEXT_NAME));
+        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+        portletApplicationManager.startPortletApplication(TestPortletApplicationManager.CONTEXT_NAME, TestPortletApplicationManager.CONTEXT_PATH, portletApplicationDir, contextClassLoader);
+    }
+
+    /**
+     * Stop test portlet application.
+     * 
+     * @throws RegistryException
+     */
+    public void stopPortletApplication() throws RegistryException
+    {
+        portletApplicationManager.stopPortletApplication(TestPortletApplicationManager.CONTEXT_NAME);
+    }
+    
+    /**
+     * Unregister test portlet application.
+     * 
+     * @throws RegistryException
+     */
+    public void unregisterPortletApplication() throws RegistryException
+    {
+        portletApplicationManager.unregisterPortletApplication(TestPortletApplicationManager.CONTEXT_NAME);
+    }
+    
+    /**
+     * Sets server exit flag.
+     */
+    public void exit()
+    {
+        exit = true;
+    }
+    
+    // Data access
+    
+    /**
+     * @return server exit flag
+     */
+    public boolean isExit()
+    {
+        return exit;
+    }
+    
+    // Application entry point
+    
+    /**
+     * Server main entry point.
+     * 
+     * @param args not used
+     */
+    public static void main(final String [] args)
+    {
+        try
+        {
+            // create and initialize server
+            final PortletApplicationManagerServer server = new PortletApplicationManagerServer();
+            server.initialize();
+            
+            // simple server reads script lines from standard
+            // input and writes results on standard output
+            final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+            final PrintWriter out = new PrintWriter(System.out, true);
+            do
+            {
+                // read single line scripts to execute
+                String scriptLine = in.readLine();
+                if (scriptLine != null)
+                {
+                    scriptLine = scriptLine.trim();
+                    String resultLine = "";
+                    if (scriptLine.length() > 0)
+                    {
+                        // execute script
+                        resultLine = server.execute(scriptLine);
+                    }
+
+                    // write prefixed single line results
+                    out.println(SCRIPT_RESULT_LINE_PREFIX+resultLine);
+                }
+                else
+                {
+                    // exit server on input EOF
+                    server.exit();
+                }
+            }
+            while (!server.isExit());
+            
+            // terminate server
+            server.terminate();
+        }
+        catch (final Throwable t)
+        {
+            log.error( "Unexpected exception: "+t, t);
+        }
+    }
+}

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java?rev=768433&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java Fri Apr 24 22:44:37 2009
@@ -0,0 +1,520 @@
+/*
+ * 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.jetspeed.tools.pamanager;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.AbstractRequestContextTestCase;
+import org.apache.jetspeed.components.portletregistry.RegistryException;
+import org.apache.jetspeed.security.RoleManager;
+import org.apache.jetspeed.security.SecurityDomain;
+import org.apache.jetspeed.security.impl.SecurityDomainImpl;
+import org.apache.jetspeed.security.spi.SecurityDomainAccessManager;
+import org.apache.jetspeed.security.spi.SecurityDomainStorageManager;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+public class TestPortletApplicationManager extends AbstractRequestContextTestCase
+{
+    private static final Log log = LogFactory.getLog(TestPortletApplicationManager.class);
+
+    /*
+     * TODO: this test case is properly run with concurrent PAM access
+     * enabled, use of the versioned PAM, and with multiple restarts.
+     * Test will not pass with those settings, so these are being used
+     * temporarily until these issues are addressed.
+     */
+    public static final boolean TEST_CONCURRENT_PAM_ACCESS = false;
+    public static final boolean TEST_USE_VERSIONED_PAM = true;
+    public static final int TEST_PORTLET_APPLICATION_RESTARTS = 5;
+
+    public static final String CONTEXT_NAME = "test-pa";
+    public static final String CONTEXT_PATH = "/"+CONTEXT_NAME;
+
+    private String osExecutableExtension;
+    private String fileSeparator;
+    private File javaExecutablePath;
+    private String classPathSeparator;
+    private File projectDirectoryPath;
+    private Map<String,String> systemProperties;
+    private String classPath;
+
+    private String baseDir;
+    private PortletApplicationManagement portletApplicationManager;    
+    
+    /**
+     * Configure test methods.
+     * 
+     * @return test suite.
+     */
+    public static Test suite()
+    {
+        // All methods starting with "test" will be executed in the test suite.
+        return new TestSuite(TestPortletApplicationManager.class);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.AbstractRequestContextTestCase#getConfigurations()
+     */
+    protected String[] getConfigurations()
+    {
+        String[] confs = super.getConfigurations();
+        List<String> confList = new ArrayList<String>(Arrays.asList(confs));
+        confList.add("deployment.xml");
+        if (TEST_USE_VERSIONED_PAM)
+        {
+            confList.add("alternate/versioned-deployment/deployment.xml");
+        }
+        confList.add("search.xml");
+        confList.add("cluster-node.xml");
+        return (String[]) confList.toArray(new String[1]);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.test.AbstractSpringTestCase#getInitProperties()
+     */
+    protected Properties getInitProperties()
+    {
+        // setup dummy autodeployment properties
+        baseDir = System.getProperty("basedir", ".");
+        if ((baseDir == null) || (baseDir.length() == 0))
+        {
+            baseDir = System.getProperty("user.dir");
+        }
+        // set test properties
+        return setTestProperties(baseDir, super.getInitProperties());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.util.RegistrySupportedTestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        // environment setup
+        osExecutableExtension = (System.getProperty("os.name").startsWith("Windows") ? ".exe" : "");
+        fileSeparator = System.getProperty("file.separator");
+        javaExecutablePath = new File(System.getProperty("java.home")+fileSeparator+"bin"+fileSeparator+"java"+osExecutableExtension);
+        classPathSeparator = System.getProperty("path.separator");
+        projectDirectoryPath = new File(System.getProperty("basedir"));
+        systemProperties = new HashMap<String,String>();
+        for (final Map.Entry<Object,Object> systemProperty : System.getProperties().entrySet())
+        {
+            final String propertyName = systemProperty.getKey().toString();
+            final String propertyValue = systemProperty.getValue().toString();
+            if (propertyName.startsWith("org.apache.jetspeed.") || propertyName.startsWith("java.net.") || propertyName.equals("basedir"))
+            {
+                systemProperties.put(propertyName, propertyValue);
+            }
+        }
+        // construct launcher classpath from current class loader
+        final StringBuilder classPathBuilder = new StringBuilder();
+        final ClassLoader loader = this.getClass().getClassLoader();
+        assertTrue(loader instanceof URLClassLoader);
+        final URLClassLoader urlLoader = (URLClassLoader)loader;
+        assertNotNull(urlLoader.getURLs());
+        for (final URL pathURL : urlLoader.getURLs())
+        {
+            // convert path URL to file path
+            final String path = new File(pathURL.toURI()).getCanonicalPath();
+
+            // build class path
+            if (classPathBuilder.length() > 0)
+            {
+                classPathBuilder.append(classPathSeparator);
+            }
+            classPathBuilder.append(path);
+        }
+        classPath = classPathBuilder.toString();
+        assertTrue(classPath.length() > 0);
+
+        // setup test
+        super.setUp();
+        portletApplicationManager = (PortletApplicationManagement)scm.getComponent("PAM");
+        assertTrue(portletApplicationManager.isStarted());
+        Class<?> portletApplicationManagerClass = scm.getComponent("org.apache.jetspeed.tools.pamanager.PortletApplicationManager").getClass();
+        log.info("PortletApplicationManager class: "+portletApplicationManagerClass.getSimpleName());
+        // unregister portlet application
+        try
+        {
+            portletApplicationManager.unregisterPortletApplication(CONTEXT_NAME);
+        }
+        catch (RegistryException re)
+        {
+        }
+        // create standard default security domain and user role as necessary
+        // for portlet application permissions
+        SecurityDomainAccessManager domainAccessManager = (SecurityDomainAccessManager)scm.getComponent("org.apache.jetspeed.security.spi.SecurityDomainAccessManager");
+        if (domainAccessManager.getDomainByName(SecurityDomain.DEFAULT_NAME) == null)
+        {
+            SecurityDomainStorageManager domainStorageManager = (SecurityDomainStorageManager)scm.getComponent("org.apache.jetspeed.security.spi.SecurityDomainStorageManager");
+            SecurityDomainImpl defaultSecurityDomain = new SecurityDomainImpl();
+            defaultSecurityDomain.setName(SecurityDomain.DEFAULT_NAME);
+            domainStorageManager.addDomain(defaultSecurityDomain);
+        }
+        RoleManager roleManager = (RoleManager)scm.getComponent("org.apache.jetspeed.security.RoleManager");
+        if (!roleManager.roleExists("user"))
+        {
+            roleManager.addRole("user");
+        }
+    }   
+
+    /**
+     * Test basic PortletApplicationManager operation.
+     */
+    public void testPortletApplicationManager()
+    {
+        // start portlet application manager test servers
+        final TestProgram server0 = new TestProgram("server-0", PortletApplicationManagerServer.class);
+        final TestProgram server1 = new TestProgram("server-1", PortletApplicationManagerServer.class);
+        try
+        {
+            // start servers
+            server0.start();
+            server1.start();
+
+            // wait until servers have started
+            server0.execute("");
+            server1.execute("");
+            
+            // test starting and stopping portlet application
+            String result;
+            for (int i = 0; (i < TEST_PORTLET_APPLICATION_RESTARTS); i++)
+            {
+                // start portlet application
+                if (TEST_CONCURRENT_PAM_ACCESS)
+                {
+                    // start portlet application asynchronously in background threads per server
+                    TestExecuteThread startPortletApplication0 = new TestExecuteThread(server0, "portletApplicationManagerServer.startPortletApplication();");
+                    TestExecuteThread startPortletApplication1 = new TestExecuteThread(server1, "portletApplicationManagerServer.startPortletApplication();");
+                    startPortletApplication0.start();
+                    startPortletApplication1.start();
+                    result = startPortletApplication0.getResult();
+                    assertTrue(!result.contains("Exception"));
+                    result = startPortletApplication1.getResult();
+                    assertTrue(!result.contains("Exception"));
+                }
+                else
+                {
+                    // stop portlet application synchronously
+                    result = server0.execute("portletApplicationManagerServer.startPortletApplication();");
+                    assertTrue(!result.contains("Exception"));
+                    result = server1.execute("portletApplicationManagerServer.startPortletApplication();");
+                    assertTrue(!result.contains("Exception"));
+                }
+                // stop portlet application synchronously
+                result = server1.execute("portletApplicationManagerServer.stopPortletApplication();");
+                assertTrue(!result.contains("Exception"));
+                result = server0.execute("portletApplicationManagerServer.stopPortletApplication();");
+                assertTrue(!result.contains("Exception"));
+                // unregister portlet application
+                try
+                {
+                    portletApplicationManager.unregisterPortletApplication(CONTEXT_NAME);
+                }
+                catch (RegistryException re)
+                {
+                }
+            }
+        }
+        catch (final Exception e)
+        {
+            log.error("Server test exception: "+e, e);
+            fail("Server test exception: "+e);            
+        }        
+        finally
+        {
+            // silently shutdown servers
+            try
+            {
+                server0.shutdown();
+            }
+            catch (final Exception e)
+            {
+                log.error( "Server shutdown exception: "+e, e);
+            }
+            try
+            {
+                server1.shutdown();
+            }
+            catch (final Exception e)
+            {
+                log.error( "Server shutdown exception: "+e, e);
+            }
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.util.DatasourceEnabledSpringTestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {       
+        // unregister portlet application
+        try
+        {
+            portletApplicationManager.unregisterPortletApplication(CONTEXT_NAME);
+        }
+        catch (RegistryException re)
+        {
+        }
+        portletApplicationManager = null;
+        // teardown test
+        super.tearDown();
+    }   
+
+    /**
+     * TestProgram
+     * 
+     * Implementation of test program executables.
+     */
+    private class TestProgram
+    {
+        private String name;
+        private Class<?> mainClass;
+
+        private Process process;
+        private BufferedWriter processInput;
+        private BufferedReader processOutput;
+        
+        public TestProgram(final String name, final Class<?> mainClass)
+        {
+            this.name = name;
+            this.mainClass = mainClass;
+        }
+        
+        public synchronized void start() throws IOException
+        {
+            assertNull(process);
+
+            // configure launcher with paths and properties
+            final ProcessBuilder launcher = new ProcessBuilder();
+            final List<String> commandAndArgs = new ArrayList<String>();
+            commandAndArgs.add(javaExecutablePath.getCanonicalPath());
+            for (Map.Entry<String,String> systemProperty : systemProperties.entrySet())
+            {
+                final String propertyName = systemProperty.getKey();
+                final String propertyValue = systemProperty.getValue();
+                commandAndArgs.add( "-D"+propertyName+"="+propertyValue);
+            }
+            commandAndArgs.add("-Dlog4j.configuration=log4j-stdout.properties");
+            commandAndArgs.add("-classpath");
+            commandAndArgs.add(classPath);
+            commandAndArgs.add(mainClass.getName());
+            log.info("Launcher command for "+name+": "+commandAndArgs);
+            launcher.command(commandAndArgs);
+            launcher.directory(projectDirectoryPath);
+            launcher.redirectErrorStream(true);
+
+            // launch test programs
+            process = launcher.start();
+
+            // setup I/O for process
+            processInput = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
+            processOutput = new BufferedReader(new InputStreamReader(process.getInputStream()));
+
+            // read messages from process
+            for (String line; (processOutput.ready() && ((line = processOutput.readLine()) != null));)
+            {
+                logProcessLine(line);
+            }
+        }
+
+        public synchronized String execute(final String scriptLine) throws IOException
+        {
+            assertNotNull(process);
+
+            // read messages from process
+            for (String line; (processOutput.ready() && ((line = processOutput.readLine()) != null));)
+            {
+                logProcessLine(line);
+            }
+
+            // write script line to process
+            processInput.write(scriptLine);
+            processInput.newLine();
+            processInput.flush();
+
+            // read result or messages from process
+            String resultLine = null;
+            for (String line; ((line = processOutput.readLine()) != null);)
+            {
+                if (! line.startsWith(PortletApplicationManagerServer.SCRIPT_RESULT_LINE_PREFIX))
+                {
+                    logProcessLine(line);
+                }
+                else
+                {
+                    resultLine = line;
+                    break;
+                }
+            }
+            if ( resultLine == null)
+            {
+                throw new IOException("Unexpected EOF from process output");
+            }
+            return resultLine;
+        }
+        
+        public synchronized void shutdown() throws IOException, InterruptedException
+        {
+            assertNotNull( process);
+
+            // start thread to destroy process on timeout
+            final Thread destroyThread = new Thread(new Runnable()
+            {
+                public void run()
+                {
+                    try
+                    {
+                        Thread.sleep(10000);
+                        if ( process != null)
+                        {
+                            log.warn( "Forcibly stopping "+name);
+                            process.destroy();
+                        }
+                    }
+                    catch ( final Exception e)
+                    {
+                    }
+                }
+            }, "DestroyThread");
+            destroyThread.setDaemon( true);
+            destroyThread.start();
+
+            // close process input to shutdown server and read messages
+            processInput.close();
+            for (String line; ((line = processOutput.readLine()) != null);)
+            {
+                logProcessLine(line);
+            }
+
+            // join on process completion
+            process.waitFor();
+            processOutput.close();
+            process = null;
+
+            // join on destroy thread
+            destroyThread.interrupt();
+            destroyThread.join();
+        }
+        
+        private void logProcessLine(final String line)
+        {
+            if (!line.contains("INFO") && (line.contains("ERROR") || line.contains("Exception") || line.matches("^\\s+at\\s")))
+            {
+                log.error("{"+name+"} "+line);
+            }
+            else
+            {
+                log.info("{"+name+"} "+line);                        
+            }
+        }
+    }
+    
+    /**
+     * TestExecuteThread
+     *
+     * Execute script against specified server asynchronously.
+     */
+    private class TestExecuteThread extends Thread
+    {
+        private TestProgram server;
+        private String scriptLine;
+        private String result;
+        private Exception exception;
+        
+        private TestExecuteThread(TestProgram server, String scriptLine)
+        {
+            this.server = server;
+            this.scriptLine = scriptLine;
+        }
+        
+        public void run()
+        {
+            try
+            {
+                result = server.execute(scriptLine);
+            }
+            catch (Exception e)
+            {
+                exception = e;
+            }
+        }
+        
+        public String getResult() throws Exception
+        {
+            try
+            {
+                join();
+            }
+            catch (InterruptedException ie)
+            {
+            }
+            if (exception != null)
+            {
+                throw exception;
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Set test configuration properties.
+     * 
+     * @param baseDir project base directory path
+     * @param properties properties set to configure
+     */
+    public static Properties setTestProperties(String baseDir, Properties properties)
+    {
+        properties.setProperty("autodeployment.catalina.base", baseDir+"/target");
+        properties.setProperty("autodeployment.catalina.engine", "Catalina");
+        properties.setProperty("autodeployment.delay", "10000");
+        properties.setProperty("autodeployment.password", "test");
+        properties.setProperty("autodeployment.port", "8080");
+        properties.setProperty("autodeployment.server", "localhost");
+        properties.setProperty("autodeployment.staging.dir", baseDir+"/target");
+        properties.setProperty("autodeployment.target.dir", baseDir+"/target");
+        properties.setProperty("autodeployment.user", "test");
+        return properties;
+    }
+
+    /**
+     * Start the tests.
+     *
+     * @param args the arguments. Not used
+     */
+    public static void main(String args[])
+    {
+        TestRunner.main(new String[] {TestPortletApplicationManager.class.getName()});
+    }
+}

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/resources/log4j-stdout.properties
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/resources/log4j-stdout.properties?rev=768433&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/resources/log4j-stdout.properties (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/resources/log4j-stdout.properties Fri Apr 24 22:44:37 2009
@@ -0,0 +1,31 @@
+# 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.
+
+# ------------------------------------------------------------------------
+#
+# Stdout Logging Configuration
+#
+# $Id: log4j.properties 722139 2008-12-01 17:22:03Z rwatler $
+#
+# ------------------------------------------------------------------------
+
+log4j.rootLogger = ERROR, stdout
+
+log4j.category.org.apache.jetspeed = INFO, stdout
+log4j.additivity.org.apache.jetspeed = false
+
+log4j.appender.stdout = org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.conversionPattern = %d [%t] %-5p %c - %m%n

Added: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml?rev=768433&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml Fri Apr 24 22:44:37 2009
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<portlet-app id="test-pa" version="1.0"
+    xmlns="http://portals.apache.org/jetspeed"
+    xmlns:js="http://portals.apache.org/jetspeed"
+    xmlns:dc="http://www.purl.org/dc"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://portals.apache.org/jetspeed http://portals.apache.org/jetspeed-2/2.1/schemas/jetspeed-portlet.xsd">
+
+   <js:security-constraint-ref>admin</js:security-constraint-ref>
+    <js:metadata name="pa-version">2.1.3</js:metadata>
+ 
+    <dc:title>Jetspeed-2 Administration Portlets</dc:title>
+    <dc:title xml:lang="en">Jetspeed-2 Administration Portlets</dc:title>
+    <dc:creator>J2 Team</dc:creator>
+ 
+    <portlet>
+        <portlet-name>LoginPortlet</portlet-name>
+        <js:security-constraint-ref>public-view</js:security-constraint-ref>       
+        <dc:title>Login Portlet</dc:title>
+        <dc:creator>J2 Team</dc:creator>
+    </portlet>
+    
+    <portlet>
+        <portlet-name>LoginPortletForXHTMLBasic</portlet-name>
+        <js:security-constraint-ref>public-view</js:security-constraint-ref>       
+        <dc:title>Login XHTML Portlet</dc:title>
+        <dc:creator>J2 Team</dc:creator>
+        <js:metadata name="selector.conditional.role">admin</js:metadata>                                 
+    </portlet>
+
+
+   <portlet>
+        <portlet-name>PortalLoginPortlet</portlet-name>
+        <js:security-constraint-ref>public-view</js:security-constraint-ref>       
+        <dc:title>Portal Login Portlet</dc:title>
+        <dc:creator>J2 Team</dc:creator>
+       <js:metadata name="selector.conditional.role">admin</js:metadata>                         
+    </portlet>
+
+    <portlet>
+        <portlet-name>LocaleSelector</portlet-name>
+        <js:security-constraint-ref>public-view</js:security-constraint-ref>       
+        <dc:title>Locale Selector Portlet</dc:title>
+        <dc:creator>J2 Team</dc:creator>
+    </portlet>
+
+    <portlet>
+         <portlet-name>DateTimePortlet</portlet-name>
+         <js:security-constraint-ref>public-view</js:security-constraint-ref>
+    </portlet>
+
+    <portlet>
+         <portlet-name>ForgottenPasswordPortlet</portlet-name>
+         <js:security-constraint-ref>public-view</js:security-constraint-ref>
+         <js:metadata name="merge.portal.parameters.with.portlet.parameters">true</js:metadata>
+         <js:metadata name="merge.portal.parameters.before.portlet.parameters">true</js:metadata>
+    </portlet>
+
+    <portlet>
+         <portlet-name>UserRegistrationPortlet</portlet-name>
+         <js:security-constraint-ref>public-view</js:security-constraint-ref>
+         <js:metadata name="merge.portal.parameters.with.portlet.parameters">true</js:metadata>
+         <js:metadata name="merge.portal.parameters.before.portlet.parameters">true</js:metadata>
+    </portlet>
+
+    <portlet>
+         <portlet-name>CategoryPortletSelector</portlet-name>
+         <js:security-constraint-ref>AEUV</js:security-constraint-ref>
+         <js:metadata name="merge.portal.parameters.with.portlet.parameters">true</js:metadata>
+         <js:metadata name="merge.portal.parameters.before.portlet.parameters">true</js:metadata>
+         <js:metadata name="selector.conditional.role">admin</js:metadata>                  
+    </portlet>   
+
+    <portlet>
+        <portlet-name>WelcomeToJetspeed</portlet-name>
+        <js:security-constraint-ref>public-view</js:security-constraint-ref>       
+         <js:metadata name="selector.conditional.role">*</js:metadata>                         
+    </portlet>
+
+    <portlet>
+        <portlet-name>AboutJetspeed</portlet-name>
+        <js:security-constraint-ref>public-view</js:security-constraint-ref>       
+         <js:metadata name="selector.conditional.role">*</js:metadata>                                 
+    </portlet>
+
+    <portlet>
+        <portlet-name>JetspeedDeveloper</portlet-name>
+        <js:security-constraint-ref>public-view</js:security-constraint-ref>       
+         <js:metadata name="selector.conditional.role">*</js:metadata>                                 
+    </portlet>
+	
+	<portlet>
+		<portlet-name>ChangePasswordPortlet</portlet-name>
+        <js:security-constraint-ref>public-view</js:security-constraint-ref>       
+	</portlet>
+
+	<portlet>
+		<portlet-name>DevelopersBrowser</portlet-name>
+        <js:security-constraint-ref>devmgr</js:security-constraint-ref>    
+         <js:metadata name="selector.conditional.role">*</js:metadata>                                    
+	</portlet>
+
+	<portlet>
+		<portlet-name>DeveloperDetails</portlet-name>
+        <js:security-constraint-ref>devmgr</js:security-constraint-ref>       
+         <js:metadata name="selector.conditional.role">*</js:metadata>                                 
+	</portlet>
+			
+	<js:services>        
+        <js:service name='ApplicationServerManager'/>
+        <js:service name='DeploymentManager'/>
+		<js:service name='EntityAccessor'/>
+        <js:service name='GroupManager'/>    
+        <js:service name='PageManager'/>    
+        <js:service name='PermissionManager'/>        
+        <js:service name='PortletFactory'/>        
+        <js:service name='PortalAdministration'/>
+        <js:service name='PortletRegistryComponent'/>
+        <js:service name='PortalStatistics'/>        
+        <js:service name="Profiler" />         
+        <js:service name='RoleManager'/>
+	    <js:service name='SearchComponent'/>                
+        <js:service name="SSO" />                 
+        <js:service name='UserManager'/>     
+        <js:service name='DecorationFactory'/> 
+        <js:service name='SecurityAccessController'/>  
+        <js:service name='PortletTrackingManager'/>     
+        <js:service name='PortalConfiguration'/>
+        <js:service name='ImporterManager'/>
+        <js:service name='AuditActivity'/>
+        <js:service name='JetspeedSerializerFactory'/>
+	</js:services>
+
+</portlet-app>



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org