/* * JacORB - a free Java ORB * * Copyright (C) 1997-2006 The JacORB project. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.jacorb.test.harness; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Properties; import org.jacorb.test.harness.launch.Launcher; /** * @author Alphonse Bendt * @author Nick Cross */ public class ServerSetup { private static class ProcessShutdown extends Thread { // only hold a weak reference to the process to // allow it to be gc'ed private final WeakReference<Process> processRef; public ProcessShutdown(Process process) { processRef = new WeakReference<Process>(process); } @Override public void run() { Process process = processRef.get(); if (process != null) { try { process.destroy(); } catch (Exception e) { e.printStackTrace(); } } } } private final Properties serverOrbProperties = new Properties(); private final String servantName; private final String testServer; private Process serverProcess; private StreamListener outListener, errListener; private String serverIOR; protected String outName = "OUT"; protected String errName = "ERR"; private final List<String> serverArgs = new ArrayList<String>(); private String serverIORFailedMesg; /** * Server setup with explicit server class/servant name and optional properties. * @param testServer * @param servantName * @param optionalProperties * @throws IOException */ public ServerSetup(String testServer, String servantName, Properties optionalProperties) throws IOException { this(testServer, servantName, null , optionalProperties); } public ServerSetup(String testServer, String servantName, String[] testServantArgs, Properties optionalProperties) throws IOException { this.testServer = getTestServer(testServer); this.servantName = servantName; serverArgs.add(servantName); if (TestUtils.verbose) { serverOrbProperties.setProperty("jacorb.log.default.verbosity", "4"); } else { serverOrbProperties.setProperty("jacorb.log.default.verbosity", "0"); } if (TestUtils.isSSLEnabled) { // In this case we have been configured to run all the tests // in SSL mode. For simplicity, we will use the demo/ssl keystore // and properties (partly to ensure that they always work) Properties serverProps = CommonSetup.loadSSLProps("jsse_server_props", "jsse_server_ks"); serverOrbProperties.putAll(serverProps); } if (optionalProperties != null) { serverOrbProperties.putAll(optionalProperties); } for (int i = 0; testServantArgs != null && i < testServantArgs.length; i++) { serverArgs.add(testServantArgs[i]); } } /** * Default server setup * @param servantName * @throws IOException */ public ServerSetup(String servantName) throws IOException { this(null, servantName, null); } private String getTestServer(String optionalTestServer) { if (optionalTestServer == null) { return "org.jacorb.test.harness.TestServer"; } return optionalTestServer; } public void setUp() { Properties serverProperties = new Properties(); serverProperties.setProperty("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB"); serverProperties.setProperty("org.omg.CORBA.ORBSingletonClass", "org.jacorb.orb.ORBSingleton"); serverProperties.put ("jacorb.implname", servantName); serverProperties.putAll (serverOrbProperties); final String prefix = "jacorb.test.serverproperty."; final Iterator<String> i = System.getProperties().stringPropertyNames().iterator(); while(i.hasNext()) { String key = i.next(); if (!key.startsWith(prefix)) { continue; } String value = System.getProperty(key); String propName = key.substring(prefix.length()); serverProperties.setProperty(propName, value); } final Launcher launcher = getLauncher(System.getProperty("java.class.path"), serverProperties, getTestServerMain(), serverArgs.toArray(new String[serverArgs.size()])); serverProcess = launcher.launch(); // add a shutdown hook to ensure that the server process // is shutdown even if this JVM is going down unexpectedly Runtime.getRuntime().addShutdownHook(new ProcessShutdown(serverProcess)); outListener = new StreamListener (serverProcess.getInputStream(), servantName + '-' + outName); errListener = new StreamListener (serverProcess.getErrorStream(), servantName + '-' + errName); outListener.start(); errListener.start(); serverIOR = outListener.getIOR(TestUtils.timeout); } public void tearDown() throws Exception { if (serverProcess != null) { outListener.setDestroyed(); errListener.setDestroyed(); outListener = null; errListener = null; serverProcess.destroy(); serverProcess.waitFor(); serverProcess = null; serverIOR = null; } } public String getServerIOR() { if (serverIOR == null) { if (serverIORFailedMesg == null) { String exc = errListener.getException(1000); String details = dumpStreamListener(); serverIORFailedMesg = "could not access IOR for Server.\nServant: " + servantName + "\nTimeout: " + TestUtils.timeout + " millis.\nThis maybe caused by: " + exc + '\n' + details; } fail(serverIORFailedMesg); } return serverIOR; } public String getTestServerMain() { return testServer; } private String dumpStreamListener() { StringBuffer details = new StringBuffer(); details.append(outListener.toString()); details.append(errListener.toString()); return details.toString(); } /** * Returns a launcher for the specified JacORB version. * If coverage is true, sets up the launcher to that * coverage information will be gathered. * @param classpath * @param properties * @param mainClass * @param processArgs */ private Launcher getLauncher (String classpath, Properties properties, String mainClass, String[] processArgs) { String home = null; try { home = locateHome(properties); } catch(Exception e) { TestUtils.getLogger().debug("unable to locate JacORB home. classpath will be only be set using the System property java.class.path: " + e.getMessage()); } final Properties props = new Properties(); if (properties != null) { props.putAll(properties); } Iterator<Object> it = System.getProperties().keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); if (key.startsWith("jacorb.test")) { props.put(key, System.getProperty(key)); } } // Extract any VM arguments e.g. java agent (used by coverage) etc and pass // them to the server laucher so it uses the same parameters. RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); List<String> jvmArgs = new ArrayList<String>(); Iterator<String> s = runtimeMxBean.getInputArguments().iterator(); while (s.hasNext()) { String jvmArg = s.next(); // Don't pass Xboot or -D - they are handled separately. if ( ! jvmArg.startsWith("-Xbootclasspath") && ! jvmArg.startsWith("-D")) { jvmArgs.add(jvmArg); } } try { Launcher launcher = new Launcher(); launcher.setClasspath(classpath); launcher.setMainClass(mainClass); launcher.setArgs(processArgs); launcher.setVmArgs(jvmArgs); if (home != null) { launcher.setJacorbHome(new File(home)); } launcher.setProperties(props); launcher.init(); return launcher; } catch (Exception e) { StringWriter out = new StringWriter(); e.printStackTrace(new PrintWriter(out)); throw new IllegalArgumentException(out.toString()); } } private String locateHome(Properties props) { String jacorbHome = props.getProperty("jacorb.home"); if (jacorbHome == null) { jacorbHome = System.getProperty("jacorb.home"); } if (jacorbHome != null) { return jacorbHome; } String testHome = props.getProperty("jacorb.test.home"); if (testHome == null) { testHome = System.getProperty("jacorb.test.home"); } if (testHome == null) { testHome = TestUtils.testHome(); } if (testHome == null) { throw new RuntimeException("cannot determine jacorb.test.home"); } return new File(testHome).getParentFile().getParentFile().toString(); } }