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:55 UTC

svn commit: r768434 [1/3] - in /portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components: page-manager/src/test/org/apache/jetspeed/page/cache/ portal/ portal/src/test/ portal/src/test/org/apache/jetspeed/tools/pamanager/ portal/test/as...

Author: rwatler
Date: Fri Apr 24 22:44:54 2009
New Revision: 768434

URL: http://svn.apache.org/viewvc?rev=768434&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/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/log4j-stdout.properties
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/assembly/pwa.xml
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/WEB-INF/
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/WEB-INF/portlet.xml
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/WEB-INF/web.xml
Modified:
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/test/org/apache/jetspeed/page/cache/TestDatabasePageManagerCache.java
    portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/pom.xml

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

Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/pom.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/pom.xml?rev=768434&r1=768433&r2=768434&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/pom.xml (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/pom.xml Fri Apr 24 22:44:54 2009
@@ -198,6 +198,16 @@
             <artifactId>mockrunner</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>commons-jexl</groupId>
+            <artifactId>commons-jexl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${pom.groupId}</groupId>
+            <artifactId>jetspeed-serializer</artifactId>
+            <scope>test</scope>
+        </dependency>
 
         <!-- Runtime Dependencies -->
         <dependency>
@@ -247,7 +257,6 @@
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-surefire-plugin</artifactId>
               <configuration>
-                  <skip>true</skip>
                 <excludes>
                   <exclude>**/*TestAggregator.java</exclude>
                 </excludes>

Added: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/log4j-stdout.properties
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/log4j-stdout.properties?rev=768434&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/log4j-stdout.properties (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/log4j-stdout.properties Fri Apr 24 22:44:54 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/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java?rev=768434&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/PortletApplicationManagerServer.java Fri Apr 24 22:44:54 2009
@@ -0,0 +1,273 @@
+/*
+ * 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 java.util.Properties;
+
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+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.jndi.JetspeedTestJNDIComponent;
+import org.apache.jetspeed.components.portletregistry.RegistryException;
+import org.apache.jetspeed.engine.JetspeedEngineConstants;
+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 ClassPathXmlApplicationContext ctx;
+    private String baseDir;
+    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 String [] bootConfigurations = new String[]{"boot/datasource.xml"};
+        final List configurationsList = new ArrayList();
+        configurationsList.add("prefs.xml");
+        configurationsList.add("transaction.xml");
+        configurationsList.add("cache.xml");
+        configurationsList.add("jetspeed-base.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("pwa.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-spi-atz.xml");
+        configurationsList.add("security-atz.xml");
+        configurationsList.add("search.xml");
+        configurationsList.add("cluster-node.xml");
+        final String [] configurations = (String[])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+"/../../src/webapp";
+        final ApplicationContext bootContext = new ClassPathXmlApplicationContext(bootConfigurations, true);
+        ctx = new ClassPathXmlApplicationContext(configurations, false, bootContext);
+        PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
+        Properties p = TestPortletApplicationManager.setTestProperties(baseDir, new Properties());
+        p.setProperty("supported.portletmode.autoswitch.config", "false");
+        p.setProperty("supported.portletmode.autoswitch.edit_defaults", "false");
+        p.setProperty("supported.portletmode.autoswitch.config.surrogate.portlet", "j2-admin::CustomConfigModePortlet");
+        p.setProperty(JetspeedEngineConstants.APPLICATION_ROOT_KEY, appRoot);
+        ppc.setProperties(p);
+        ctx.addBeanFactoryPostProcessor(ppc);
+        ctx.refresh();
+
+        // access portal application manager
+        portletApplicationManager = (PortletApplicationManagement)ctx.getBean("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
+        ctx.close();
+        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+"/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/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java?rev=768434&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/test/org/apache/jetspeed/tools/pamanager/TestPortletApplicationManager.java Fri Apr 24 22:44:54 2009
@@ -0,0 +1,508 @@
+/*
+ * 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.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+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 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 = false;
+    public static final int TEST_PORTLET_APPLICATION_RESTARTS = 1;
+
+    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 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 confList = new ArrayList(Arrays.asList(confs));
+        confList.add("deployment.xml");
+        if (TEST_USE_VERSIONED_PAM)
+        {
+            confList.add("alternate/versioned-deployment/deployment.xml");
+        }
+        confList.add("pwa.xml");
+        confList.add("security-managers.xml");
+        confList.add("security-providers.xml");
+        confList.add("security-spi-atn.xml");
+        confList.add("security-spi.xml");
+        confList.add("security-spi-atz.xml");
+        confList.add("security-atz.xml");
+        confList.add("search.xml");
+        confList.add("cluster-node.xml");
+        return (String[]) confList.toArray(new String[1]);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.jetspeed.components.util.RegistrySupportedTestCase#getPostProcessProperties()
+     */
+    protected Properties getPostProcessProperties()
+    {
+        // 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.getPostProcessProperties());
+    }
+
+    /* (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();
+        for (Iterator iter = System.getProperties().entrySet().iterator(); iter.hasNext();)
+        {
+            final Map.Entry systemProperty = (Map.Entry)iter.next();
+            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 StringBuffer classPathBuilder = new StringBuffer();
+        final ClassLoader loader = this.getClass().getClassLoader();
+        assertTrue(loader instanceof URLClassLoader);
+        final URLClassLoader urlLoader = (URLClassLoader)loader;
+        assertNotNull(urlLoader.getURLs());
+        for (int i = 0; (i < urlLoader.getURLs().length); i++)
+        {
+            final URL pathURL = urlLoader.getURLs()[i];
+
+            // convert path URL to file path
+            final String path = new File(new URI(pathURL.toString())).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)ctx.getBean("PAM");
+        assertTrue(portletApplicationManager.isStarted());
+        Class portletApplicationManagerClass = ctx.getBean("org.apache.jetspeed.tools.pamanager.PortletApplicationManager").getClass();
+        log.debug("PortletApplicationManager: "+portletApplicationManagerClass);
+        // unregister portlet application
+        try
+        {
+            portletApplicationManager.unregisterPortletApplication(CONTEXT_NAME);
+        }
+        catch (RegistryException re)
+        {
+        }
+    }   
+
+    /**
+     * 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.indexOf("Exception") == -1);
+                    result = startPortletApplication1.getResult();
+                    assertTrue(result.indexOf("Exception") == -1);
+                }
+                else
+                {
+                    // stop portlet application synchronously
+                    result = server0.execute("portletApplicationManagerServer.startPortletApplication();");
+                    assertTrue(result.indexOf("Exception") == -1);
+                    result = server1.execute("portletApplicationManagerServer.startPortletApplication();");
+                    assertTrue(result.indexOf("Exception") == -1);                    
+                }
+                // stop portlet application synchronously
+                result = server1.execute("portletApplicationManagerServer.stopPortletApplication();");
+                assertTrue(result.indexOf("Exception") == -1);
+                result = server0.execute("portletApplicationManagerServer.stopPortletApplication();");
+                assertTrue(result.indexOf("Exception") == -1);
+                // 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 List commandAndArgs = new ArrayList();
+            commandAndArgs.add(javaExecutablePath.getCanonicalPath());
+            for (Iterator iter = systemProperties.entrySet().iterator(); iter.hasNext();)
+            {
+                final Map.Entry systemProperty = (Map.Entry)iter.next();
+                final String propertyName = (String)systemProperty.getKey();
+                String propertyValue = (String)systemProperty.getValue();
+                commandAndArgs.add( "-D"+propertyName+"="+propertyValue);
+            }
+            commandAndArgs.add("-Dlog4j.configuration=log4j-stdout.properties");
+            commandAndArgs.add("-classpath");
+            commandAndArgs.add(classPath);
+            commandAndArgs.add(mainClass.getName());
+
+            // launch test programs
+            process = Runtime.getRuntime().exec((String []) commandAndArgs.toArray(new String[commandAndArgs.size()]), null, projectDirectoryPath);
+
+            // 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.indexOf("INFO") == -1) && ((line.indexOf("ERROR") != -1) || (line.indexOf("Exception") != -1) || 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/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/assembly/pwa.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/assembly/pwa.xml?rev=768434&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/assembly/pwa.xml (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/assembly/pwa.xml Fri Apr 24 22:44:54 2009
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+<!--
+    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.
+-->
+<beans>
+
+    <!-- Portlet Window Component -->
+    <bean id="PortletWindowAccessor" class="org.apache.jetspeed.container.window.impl.PortletWindowAccessorImpl"
+        name="org.apache.jetspeed.container.window.PortletWindowAccessor">
+        <constructor-arg index='0'>
+            <ref bean="org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent" />
+        </constructor-arg>
+        <constructor-arg index='1'>
+            <ref bean="portletFactory" />
+        </constructor-arg>
+        <constructor-arg index='2'>
+            <ref bean="org.apache.jetspeed.components.portletregistry.PortletRegistry" />
+        </constructor-arg>        
+         <constructor-arg index='3'>
+            <ref bean="portletWindowCache" />
+        </constructor-arg>
+        <!-- enable window validation -->
+        <constructor-arg type="boolean" index='4'>
+            <value>false</value>
+        </constructor-arg>
+    </bean>
+
+</beans>

Added: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml?rev=768434&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/test/testdata/test-pa/WEB-INF/jetspeed-portlet.xml Fri Apr 24 22:44:54 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