diff options
author | Joakim Erdfelt | 2013-08-02 21:25:53 +0000 |
---|---|---|
committer | Joakim Erdfelt | 2013-08-02 21:25:53 +0000 |
commit | 2057c4c17bfb56375210be3417c55e07dd8a3e71 (patch) | |
tree | fdcca8034aec80665245f081984ff174c8e591bb | |
parent | e87eee1b4605249acda549c583ade23f7ca2654b (diff) | |
download | org.eclipse.jetty.project-2057c4c17bfb56375210be3417c55e07dd8a3e71.tar.gz org.eclipse.jetty.project-2057c4c17bfb56375210be3417c55e07dd8a3e71.tar.xz org.eclipse.jetty.project-2057c4c17bfb56375210be3417c55e07dd8a3e71.zip |
Upgrading Junit + Hamcrest
7 files changed, 898 insertions, 41 deletions
diff --git a/jetty-spdy/spdy-core/pom.xml b/jetty-spdy/spdy-core/pom.xml index 31e4cad60d..06a7894255 100644 --- a/jetty-spdy/spdy-core/pom.xml +++ b/jetty-spdy/spdy-core/pom.xml @@ -6,9 +6,9 @@ <version>7.6.13-SNAPSHOT</version> </parent> - <modelVersion>4.0.0</modelVersion> - <artifactId>spdy-core</artifactId> - <name>Jetty :: SPDY :: Core</name> + <modelVersion>4.0.0</modelVersion> + <artifactId>spdy-core</artifactId> + <name>Jetty :: SPDY :: Core</name> <url>http://www.eclipse.org/jetty</url> <dependencies> <dependency> @@ -16,21 +16,21 @@ <artifactId>jetty-util</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest-all</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-core</artifactId> - <scope>test</scope> - </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-library</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> diff --git a/jetty-spdy/spdy-jetty/pom.xml b/jetty-spdy/spdy-jetty/pom.xml index cbcf5e42c4..ca7123af4c 100644 --- a/jetty-spdy/spdy-jetty/pom.xml +++ b/jetty-spdy/spdy-jetty/pom.xml @@ -64,13 +64,13 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <scope>test</scope> + <scope>test</scope> </dependency> <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest-all</artifactId> - <scope>test</scope> - </dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-library</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> @@ -508,7 +508,7 @@ <dependency> <groupId>org.eclipse.jetty.toolchain</groupId> <artifactId>jetty-test-helper</artifactId> - <version>2.0</version> + <version>2.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> @@ -528,17 +528,22 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <version>4.8.1</version> + <version>4.11</version> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-core</artifactId> + <version>1.3</version> </dependency> <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest-all</artifactId> - <version>1.1</version> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-library</artifactId> + <version>1.3</version> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>1.8.5</version> + <version>1.9.5</version> </dependency> </dependencies> </dependencyManagement> diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/JmxServiceTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/JmxServiceTest.java index 251ba623ea..6f771c0bed 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/JmxServiceTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/JmxServiceTest.java @@ -18,21 +18,18 @@ package org.eclipse.jetty.test.monitor; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import javax.management.MBeanServerConnection; - import org.eclipse.jetty.client.ContentExchange; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.monitor.JMXMonitor; -import org.eclipse.jetty.toolchain.jmx.JmxServiceConnection; -import org.eclipse.jetty.toolchain.test.JettyDistro; +import org.eclipse.jetty.test.support.JettyDistro; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/ProgramConfigTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/ProgramConfigTest.java index 840f3b05e3..9d4e496b38 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/ProgramConfigTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/ProgramConfigTest.java @@ -18,15 +18,13 @@ package org.eclipse.jetty.test.monitor; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import javax.management.MBeanServerConnection; - import org.eclipse.jetty.client.ContentExchange; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.http.HttpMethods; @@ -40,8 +38,7 @@ import org.eclipse.jetty.monitor.jmx.MonitorAction; import org.eclipse.jetty.monitor.triggers.GreaterThanAttrEventTrigger; import org.eclipse.jetty.monitor.triggers.LessThanOrEqualToAttrEventTrigger; import org.eclipse.jetty.monitor.triggers.OrEventTrigger; -import org.eclipse.jetty.toolchain.jmx.JmxServiceConnection; -import org.eclipse.jetty.toolchain.test.JettyDistro; +import org.eclipse.jetty.test.support.JettyDistro; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ExecutorThreadPool; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/XmlConfigTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/XmlConfigTest.java index 916028aa26..17152b54bc 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/XmlConfigTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/monitor/XmlConfigTest.java @@ -18,7 +18,7 @@ package org.eclipse.jetty.test.monitor; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.io.IOException; import java.util.Random; @@ -30,7 +30,7 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.monitor.JMXMonitor; -import org.eclipse.jetty.toolchain.test.JettyDistro; +import org.eclipse.jetty.test.support.JettyDistro; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java new file mode 100644 index 0000000000..811aa4a10c --- /dev/null +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/JettyDistro.java @@ -0,0 +1,858 @@ +package org.eclipse.jetty.test.support; + +// +//======================================================================== +//Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd. +//------------------------------------------------------------------------ +//All rights reserved. This program and the accompanying materials +//are made available under the terms of the Eclipse Public License v1.0 +//and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +//You may elect to redistribute this code under either of these licenses. +//======================================================================== +// + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.IO; +import org.eclipse.jetty.toolchain.test.JAR; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.toolchain.test.OS; +import org.eclipse.jetty.toolchain.test.PathAssert; +import org.eclipse.jetty.toolchain.test.TestingDir; +import org.junit.Assert; + +/** + * Basic process based executor for using the Jetty Distribution along with custom configurations to perform basic + * <p> + * Allows for a test specific directory, that is a copied jetty-distribution, and then modified for the test specific testing required. + * <p> + * Requires that you setup the maven-dependency-plugin appropriately for the base distribution you want to use, along with any other dependencies (wars, libs, + * etc..) that you may need from other maven projects. + * <p> + * Maven Dependency Plugin Setup: + * + * <pre> + * <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + * xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + * + * <!-- Common Destination Directories --> + * + * <properties> + * <test-wars-dir>${project.build.directory}/test-wars</test-wars-dir> + * <test-libs-dir>${project.build.directory}/test-libs</test-libs-dir> + * <test-distro-dir>${project.build.directory}/test-dist</test-distro-dir> + * </properties> + * + * <build> + * <plugins> + * <plugin> + * <groupId>org.apache.maven.plugins</groupId> + * <artifactId>maven-dependency-plugin</artifactId> + * <version>2.1</version> + * <executions> + * + * <!-- Copy LIB and WAR dependencies into place that JettyDistro can use them --> + * + * <execution> + * <id>test-lib-war-copy</id> + * <phase>process-test-resources</phase> + * <goals> + * <goal>copy</goal> + * </goals> + * <configuration> + * <artifactItems> + * <artifactItem> + * <groupId>org.mortbay.jetty.testwars</groupId> + * <artifactId>test-war-java_util_logging</artifactId> + * <version>7.3.0</version> + * <type>war</type> + * <outputDirectory>${test-wars-dir}</outputDirectory> + * </artifactItem> + * <artifactItem> + * <groupId>org.mortbay.jetty</groupId> + * <artifactId>jetty-aspect-servlet-api-2.5</artifactId> + * <version>7.3.0</version> + * <type>jar</type> + * <outputDirectory>${test-libs-dir}</outputDirectory> + * </artifactItem> + * </artifactItems> + * <overWriteIfNewer>true</overWriteIfNewer> + * <overWrite>true</overWrite> + * <stripVersion>true</stripVersion> + * </configuration> + * </execution> + * + * <!-- Extract Jetty DISTRIBUTION into place that JettyDistro can use it --> + * + * <execution> + * <id>unpack-test-dist</id> + * <phase>process-test-resources</phase> + * <goals> + * <goal>unpack</goal> + * </goals> + * <configuration> + * <artifactItems> + * <artifactItem> + * <groupId>org.eclipse.jetty</groupId> + * <artifactId>jetty-distribution</artifactId> + * <version>7.3.0</version> + * <type>zip</type> + * <overWrite>true</overWrite> + * </artifactItem> + * </artifactItems> + * <outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename> + * <outputDirectory>${test-distro-dir}</outputDirectory> + * <overWriteSnapshots>true</overWriteSnapshots> + * <overWriteIfNewer>true</overWriteIfNewer> + * </configuration> + * </execution> + * </executions> + * </plugin> + * </plugins> + * </build> + * + * </project> + * </pre> + * <p> + * If you have a specific configuration you want to setup, you'll want to prepare this configuration in an overlay directory underneath the + * <code>src/test/resources/</code> directory. <br> + * Notes: + * <ol> + * <li>The {@link JettyDistro} sets up a unique test directory (based on the constructor {@link #JettyDistro(Class)} or {@link #JettyDistro(TestingDir)}), by + * ensuring the directory is empty, then copying the <code>target/test-dist</code> directory into this new testing directory prior to the test specific changes + * to the configuration.<br> + * Note: this testing directory is a complete jetty distribution, suitable for executing via the command line for additional testing needs.</li> + * <li>The directory name you choose in <code>src/test/resources</code> will be the name you use in the {@link #overlayConfig(String)} method to provide + * replacement configurations for the Jetty Distribution.</li> + * <li>You'll want to {@link #delete(String)} any files and/or directories from the standard distribution prior to using the {@link #overlayConfig(String)} + * method.</li> + * <li>Use the {@link #copyLib(String, String)} method to copy JAR files from the <code>target/test-libs</code> directory (created and managed above using the + * <code>maven-dependency-plugin</code>) to copy the lib into the test specific.</li> + * <li>Use the {@link #copyTestWar(String)} method to copy WAR files from the <code>target/test-wars</code> directory (created and managed above using the + * <code>maven-dependency-plugin</code>) to copy the WAR into the test specific directory.</li> + * </ol> + * <p> + * Next you'll want to use Junit 4.8+ and the <code>@BeforeClass</code> and <code>@AfterClass</code> annotations to setup the <code>JettyDistro</code> + * class for setting up your testing configuration. + * <p> + * Example Test Case using {@link JettyDistro} class + * + * <pre> + * public class MySampleTest + * { + * private static JettyDistro jetty; + * + * @BeforeClass + * public static void initJetty() throws Exception + * { + * jetty = new JettyDistro(MySampleTest.class); + * + * jetty.copyTestWar("test-war-java_util_logging.war"); + * jetty.copyTestWar("test-war-policy.war"); + * + * jetty.delete("webapps/test.war"); + * jetty.delete("contexts/test.d"); + * jetty.delete("contexts/javadoc.xml"); + * jetty.delete("contexts/test.xml"); + * + * jetty.overlayConfig("no_security"); + * + * jetty.setDebug(true); + * + * jetty.start(); + * } + * + * @AfterClass + * public static void shutdownJetty() throws Exception + * { + * if (jetty != null) + * { + * jetty.stop(); + * } + * } + * + * @Test + * public void testRequest() throws Exception + * { + * SimpleRequest request = new SimpleRequest(jetty.getBaseUri()); + * String path = "/test-war-policy/security/PRACTICAL/testFilsystem"); + * String response = request.getString(path); + * Assert.assertEquals("Success", response); + * } + * } + * </pre> + */ +public class JettyDistro +{ + private String artifactName = "jetty-distribution"; + private long startTime = 60; + private TimeUnit timeUnit = TimeUnit.SECONDS; + + private File jettyHomeDir; + private Process pid; + private URI baseUri; + + private String jmxUrl; + + private boolean _debug = false; + + /** + * Setup the JettyHome as belonging in a testing directory associated with a testing clazz. + * + * @param clazz + * the testing class using this JettyDistro + * @throws IOException + * if unable to copy unpacked distribution into place for the provided testing directory + */ + public JettyDistro(Class<?> clazz) throws IOException + { + this(clazz,null); + } + + /** + * Setup the JettyHome as belonging in a testing directory associated with a testing clazz. + * + * @param clazz + * the testing class using this JettyDistro + * @param artifact + * name of jetty distribution artifact + * @throws IOException + * if unable to copy unpacked distribution into place for the provided testing directory + */ + public JettyDistro(Class<?> clazz, String artifact) throws IOException + { + this.jettyHomeDir = MavenTestingUtils.getTargetTestingDir(clazz,"jettyHome"); + if (artifact != null) + { + this.artifactName = artifact; + } + + copyBaseDistro(); + } + + /** + * Setup the JettyHome as belonging to a specific testing method directory + * + * @param testdir + * the testing directory to use as the JettyHome for this JettyDistro + * @throws IOException + * if unable to copy unpacked distribution into place for the provided testing directory + */ + public JettyDistro(TestingDir testdir) throws IOException + { + this.jettyHomeDir = testdir.getDir(); + copyBaseDistro(); + } + + /** + * Setup the JettyHome as belonging to a specific testing method directory + * + * @param testdir + * the testing directory to use as the JettyHome for this JettyDistro + * @param artifact + * name of jetty distribution artifact + * @throws IOException + * if unable to copy unpacked distribution into place for the provided testing directory + */ + public JettyDistro(TestingDir testdir, String artifact) throws IOException + { + this.jettyHomeDir = testdir.getDir(); + if (artifact != null) + { + this.artifactName = artifact; + } + + copyBaseDistro(); + } + + /** + * + * @throws IOException + * if unable to copy unpacked distribution into place for the provided testing directory + */ + private void copyBaseDistro() throws IOException + { + // The outputDirectory for the maven side dependency:unpack goal. + File distroUnpackDir = MavenTestingUtils.getTargetFile("test-dist"); + PathAssert.assertDirExists(artifactName + " dependency:unpack",distroUnpackDir); + + // The actual jetty-distribution-${version} directory is under this directory. + // Lets find it. + File subdirs[] = distroUnpackDir.listFiles(new FileFilter() + { + public boolean accept(File path) + { + if (!path.isDirectory()) + { + return false; + } + + return path.getName().startsWith(artifactName + "-"); + } + }); + + if (subdirs.length == 0) + { + // No jetty-distribution found. + StringBuilder err = new StringBuilder(); + err.append("No target/test-dist/"); + err.append(artifactName); + err.append("-${version} directory found."); + err.append("\n To fix this, run 'mvn process-test-resources' to create the directory."); + throw new IOException(err.toString()); + } + + if (subdirs.length != 1) + { + // Too many jetty-distributions found. + StringBuilder err = new StringBuilder(); + err.append("Too many target/test-dist/"); + err.append(artifactName); + err.append("-${version} directories found."); + for (File dir : subdirs) + { + err.append("\n ").append(dir.getAbsolutePath()); + } + err.append("\n To fix this, run 'mvn clean process-test-resources' to recreate the target/test-dist directory."); + throw new IOException(err.toString()); + } + + File distroSrcDir = subdirs[0]; + FS.ensureEmpty(jettyHomeDir); + System.out.printf("Copying Jetty Distribution: %s%n",distroSrcDir.getAbsolutePath()); + System.out.printf(" To Testing Dir: %s%n",jettyHomeDir.getAbsolutePath()); + IO.copyDir(distroSrcDir,jettyHomeDir); + } + + /** + * Return the $(jetty.home) directory being used for this JettyDistro + * + * @return the jetty.home directory being used + */ + public File getJettyHomeDir() + { + return this.jettyHomeDir; + } + + /** + * Copy a war file from ${project.basedir}/target/test-wars/${testWarFilename} into the ${jetty.home}/webapps/ directory + * + * @param testWarFilename + * the war file to copy (must exist) + * @throws IOException + * if unable to copy the war file. + */ + public void copyTestWar(String testWarFilename) throws IOException + { + File srcWar = MavenTestingUtils.getTargetFile("test-wars/" + testWarFilename); + File destWar = new File(jettyHomeDir,OS.separators("webapps/" + testWarFilename)); + FS.ensureDirExists(destWar.getParentFile()); + IO.copyFile(srcWar,destWar); + } + + /** + * Copy an arbitrary file from <code>src/test/resources/${resourcePath}</code> to the testing directory. + * + * @param resourcePath + * the relative path for file content within the <code>src/test/resources</code> directory. + * @param outputPath + * the testing directory relative output path for the file output (will result in a file with the outputPath name being created) + * @throws IOException + * if unable to copy resource file + */ + public void copyResource(String resourcePath, String outputPath) throws IOException + { + File srcFile = MavenTestingUtils.getTestResourceFile(resourcePath); + File destFile = new File(jettyHomeDir,OS.separators(outputPath)); + FS.ensureDirExists(destFile.getParentFile()); + IO.copyFile(srcFile,destFile); + } + + /** + * Copy an arbitrary file from <code>target/test-libs/${libFilename}</code> to the testing directory. + * + * @param libFilename + * the <code>target/test-libs/${libFilename}</code> to copy + * @param outputPath + * the destination testing directory relative output path for the lib. (will result in a file with the outputPath name being created) + * @throws IOException + * if unable to copy lib + */ + public void copyLib(String libFilename, String outputPath) throws IOException + { + File srcLib = MavenTestingUtils.getTargetFile("test-libs/" + libFilename); + File destLib = new File(jettyHomeDir,OS.separators(outputPath)); + FS.ensureDirExists(destLib.getParentFile()); + IO.copyFile(srcLib,destLib); + } + + /** + * Copy the <code>${project.basedir}/src/main/config/</code> tree into the testing directory. + * + * @throws IOException + * if unable to copy the directory tree + */ + public void copyProjectMainConfig() throws IOException + { + File srcDir = MavenTestingUtils.getProjectDir("src/main/config"); + IO.copyDir(srcDir,jettyHomeDir); + } + + /** + * Create a <code>${jetty.home}/lib/self/${jarFilename}</code> jar file from the content in the <code>${project.basedir}/target/classes/</code> directory. + * + * @throws IOException + * if unable to copy the directory tree + */ + public void createProjectLib(String jarFilename) throws IOException + { + File srcDir = MavenTestingUtils.getTargetFile("classes"); + File libSelfDir = new File(jettyHomeDir,OS.separators("lib/self")); + FS.ensureDirExists(libSelfDir); + File jarFile = new File(libSelfDir,jarFilename); + JAR.create(srcDir,jarFile); + } + + /** + * Unpack an arbitrary config from <code>target/test-configs/${configFilename}</code> to the testing directory. + * + * @param configFilename + * the <code>target/test-configs/${configFilename}</code> to copy + * @throws IOException + * if unable to unpack config file + */ + public void unpackConfig(String configFilename) throws IOException + { + File srcConfig = MavenTestingUtils.getTargetFile("test-configs/" + configFilename); + JAR.unpack(srcConfig,jettyHomeDir); + } + + /** + * Delete a File or Directory found in the ${jetty.home} directory. + * + * @param path + * the path to delete. (can be a file or directory) + */ + public void delete(String path) + { + File jettyPath = new File(jettyHomeDir,OS.separators(path)); + FS.delete(jettyPath); + } + + /** + * Return the baseUri being used for this Jetty Process Instance. + * + * @return the base URI for this Jetty Process Instance. + */ + public URI getBaseUri() + { + return this.baseUri; + } + + /** + * Return the JMX URL being used for this Jetty Process Instance. + * + * @return the JMX URL for this Jetty Process Instance. + */ + public String getJmxUrl() + { + return this.jmxUrl; + } + + /** + * Take the directory contents from ${project.basedir}/src/test/resources/${testConfigName}/ and copy it over whatever happens to be at ${jetty.home} + * + * @param testConfigName + * the src/test/resources/ directory name to use as the source diretory for the configuration we are interested in. + * @throws IOException + * if unable to copy directory. + */ + public void overlayConfig(String testConfigName) throws IOException + { + File srcDir = MavenTestingUtils.getTestResourceDir(testConfigName); + IO.copyDir(srcDir,jettyHomeDir); + } + + /** + * Start the jetty server + * + * @throws IOException + * if unable to start the server. + */ + public void start() throws IOException + { + List<String> commands = new ArrayList<String>(); + commands.add(getJavaBin()); + + commands.add("-Djetty.home=" + jettyHomeDir.getAbsolutePath()); + + // Do a dry run first to get the exact command line for Jetty process + commands.add("-jar"); + commands.add("start.jar"); + commands.add("jetty.port=0"); + if (_debug) + { + commands.add("-D.DEBUG=true"); + } + commands.add("--dry-run"); + + ProcessBuilder pbCmd = new ProcessBuilder(commands); + pbCmd.directory(jettyHomeDir); + + String cmdLine = null; + Process pidCmd = pbCmd.start(); + try + { + cmdLine = readOutputLine(pidCmd); + } + finally + { + pidCmd.destroy(); + } + + if (cmdLine == null || !cmdLine.contains("XmlConfiguration")) + { + Assert.fail("Unable to get Jetty command line"); + } + + // Need to breakdown commandline into parts, as spaces in command line will cause failures. + List<String> execCommands = splitAndUnescapeCommandLine(cmdLine); + + System.out.printf("Executing: %s%n",cmdLine); + System.out.printf("Working Dir: %s%n",jettyHomeDir.getAbsolutePath()); + + pbCmd = new ProcessBuilder(execCommands); + pid = pbCmd.start(); + + ConsoleParser parser = new ConsoleParser(); + List<String[]> jmxList = parser.newPattern("JMX Remote URL: (.*)",0); + List<String[]> connList = parser.newPattern("Started [A-Za-z]*Connector@([0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*):([0-9]*)",1); + // DISABLED: This is what exists in Jetty 9+ + // List<String[]> connList = parser.newPattern("Started [A-Za-z]*Connector@.*[\\({]([0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*):([0-9]*)[\\)}].*",1); + + startPump("STDOUT",parser,this.pid.getInputStream()); + startPump("STDERR",parser,this.pid.getErrorStream()); + + try + { + parser.waitForDone(this.startTime,this.timeUnit); + + if (!jmxList.isEmpty()) + { + this.jmxUrl = jmxList.get(0)[0]; + System.out.printf("## Found JMX connector at %s%n",this.jmxUrl); + } + + if (!connList.isEmpty()) + { + String[] params = connList.get(0); + if (params.length == 2) + { + this.baseUri = URI.create("http://localhost:" + params[1] + "/"); + } + System.out.printf("## Found Jetty connector at host: %s port: %s%n",(Object[])params); + } + + } + catch (InterruptedException e) + { + pid.destroy(); + Assert.fail("Unable to get required information within time limit"); + } + } + + public static List<String> splitAndUnescapeCommandLine(CharSequence rawCmdLine) + { + List<String> cmds = new ArrayList<String>(); + + int len = rawCmdLine.length(); + StringBuilder arg = new StringBuilder(); + boolean escaped = false; + boolean inQuote = false; + char c; + for (int i = 0; i < len; i++) + { + c = rawCmdLine.charAt(i); + if (escaped) + { + switch (c) + { + case 'r': + arg.append('\r'); + break; + case 'f': + arg.append('\f'); + break; + case 't': + arg.append('\t'); + break; + case 'n': + arg.append('\n'); + break; + case 'b': + arg.append('\b'); + break; + default: + arg.append(c); + break; + } + escaped = false; + continue; + } + + if (c == '\\') + { + escaped = true; + } + else + { + if ((c == ' ') && (!inQuote)) + { + // the delim! + cmds.add(String.valueOf(arg.toString())); + arg.setLength(0); + } + else if (c == '"') + { + inQuote = !inQuote; + } + else + { + arg.append(c); + } + } + } + cmds.add(String.valueOf(arg.toString())); + + return cmds; + } + + private String readOutputLine(Process pidCmd) throws IOException + { + InputStream in = null; + InputStreamReader reader = null; + BufferedReader buf = null; + try + { + in = pidCmd.getInputStream(); + reader = new InputStreamReader(in); + buf = new BufferedReader(reader); + return buf.readLine(); + } + finally + { + IO.close(buf); + IO.close(reader); + IO.close(in); + } + } + + private static class ConsoleParser + { + private List<ConsolePattern> patterns = new ArrayList<ConsolePattern>(); + private CountDownLatch latch; + private int count; + + public List<String[]> newPattern(String exp, int cnt) + { + ConsolePattern pat = new ConsolePattern(exp,cnt); + patterns.add(pat); + count += cnt; + + return pat.getMatches(); + } + + public void parse(String line) + { + for (ConsolePattern pat : patterns) + { + Matcher mat = pat.getMatcher(line); + if (mat.find()) + { + int num = 0, count = mat.groupCount(); + String[] match = new String[count]; + while (num++ < count) + { + match[num - 1] = mat.group(num); + } + pat.getMatches().add(match); + + if (pat.getCount() > 0) + { + getLatch().countDown(); + } + } + } + } + + public void waitForDone(long timeout, TimeUnit unit) throws InterruptedException + { + getLatch().await(timeout,unit); + } + + private CountDownLatch getLatch() + { + synchronized (this) + { + if (latch == null) + { + latch = new CountDownLatch(count); + } + } + + return latch; + } + } + + private static class ConsolePattern + { + private Pattern pattern; + private List<String[]> matches; + private int count; + + ConsolePattern(String exp, int cnt) + { + pattern = Pattern.compile(exp); + matches = new ArrayList<String[]>(); + count = cnt; + } + + public Matcher getMatcher(String line) + { + return pattern.matcher(line); + } + + public List<String[]> getMatches() + { + return matches; + } + + public int getCount() + { + return count; + } + } + + private void startPump(String mode, ConsoleParser parser, InputStream inputStream) + { + ConsoleStreamer pump = new ConsoleStreamer(mode,inputStream); + pump.setParser(parser); + Thread thread = new Thread(pump,"ConsoleStreamer/" + mode); + thread.start(); + } + + /** + * enable debug on the jetty process + * + * @param debug + */ + public void setDebug(boolean debug) + { + _debug = debug; + } + + private String getJavaBin() + { + String javaexes[] = new String[] + { "java", "java.exe" }; + + File javaHomeDir = new File(System.getProperty("java.home")); + for (String javaexe : javaexes) + { + File javabin = new File(javaHomeDir,OS.separators("bin/" + javaexe)); + if (javabin.exists() && javabin.isFile()) + { + return javabin.getAbsolutePath(); + } + } + + Assert.fail("Unable to find java bin"); + return "java"; + } + + /** + * Stop the jetty server + */ + public void stop() + { + System.out.println("Stopping JettyDistro ..."); + if (pid != null) + { + // TODO: maybe issue a STOP instead? + pid.destroy(); + } + } + + /** + * Simple streamer for the console output from a Process + */ + private static class ConsoleStreamer implements Runnable + { + private String mode; + private BufferedReader reader; + private ConsoleParser parser; + + public ConsoleStreamer(String mode, InputStream is) + { + this.mode = mode; + this.reader = new BufferedReader(new InputStreamReader(is)); + } + + public void setParser(ConsoleParser connector) + { + this.parser = connector; + } + + public void run() + { + String line; + // System.out.printf("ConsoleStreamer/%s initiated%n",mode); + try + { + while ((line = reader.readLine()) != (null)) + { + if (parser != null) + { + parser.parse(line); + } + System.out.println("[" + mode + "] " + line); + } + } + catch (IOException ignore) + { + /* ignore */ + } + finally + { + IO.close(reader); + } + // System.out.printf("ConsoleStreamer/%s finished%n",mode); + } + } + + public void setStartTime(long startTime, TimeUnit timeUnit) + { + this.startTime = startTime; + this.timeUnit = timeUnit; + } +}
\ No newline at end of file |