From 972dc015bbeecd608b4177c6fda70713efd4df99 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Mon, 24 Sep 2018 19:24:29 +1000
Subject: [PATCH 01/14] sugar syntax changes
Signed-off-by: olivier lamy
---
tests/pom.xml | 1 +
.../eclipse/jetty/test/support/JettyDistro.java | 15 ++++++---------
.../jetty/test/support/TestableJettyServer.java | 4 ++--
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/tests/pom.xml b/tests/pom.xml
index 6eac047ab2f..56a34b1eb7e 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -67,5 +67,6 @@
test-quickstart
test-jmx
test-http-client-transport
+ test-modules
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
index b523e9bf398..299be625e9c 100644
--- 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
@@ -56,6 +56,7 @@ import org.eclipse.jetty.toolchain.test.JAR;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.PathAssert;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
+import org.junit.jupiter.api.Assertions;
/**
@@ -315,19 +316,15 @@ public class JettyDistro
// The actual jetty-distribution-${version} directory is under this directory.
// Lets find it.
- File subdirs[] = distroUnpackDir.listFiles(new FileFilter()
- {
- @Override
- public boolean accept(File path)
+ File subdirs[] = distroUnpackDir.listFiles( path ->
{
if (!path.isDirectory())
{
return false;
}
-
return path.getName().startsWith(artifactName + "-");
}
- });
+ );
if (subdirs.length == 0)
{
@@ -550,7 +547,7 @@ public class JettyDistro
if (cmdLine == null || !cmdLine.contains("XmlConfiguration"))
{
- fail("Unable to get Jetty command line");
+ Assertions.fail( "Unable to get Jetty command line");
}
// Need to breakdown commandline into parts, as spaces in command line will cause failures.
@@ -595,7 +592,7 @@ public class JettyDistro
catch (InterruptedException e)
{
pid.destroy();
- fail("Unable to get required information within time limit");
+ Assertions.fail( "Unable to get required information within time limit");
}
}
@@ -804,7 +801,7 @@ public class JettyDistro
}
}
- fail("Unable to find java bin");
+ Assertions.fail( "Unable to find java bin");
return "java";
}
diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java
index d47cc4380db..a612e6592e7 100644
--- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java
+++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java
@@ -49,7 +49,7 @@ import org.junit.jupiter.api.Disabled;
public class TestableJettyServer
{
private List _xmlConfigurations;
- private final Map _properties = new HashMap();
+ private final Map _properties = new HashMap<>();
private Server _server;
private int _serverPort;
private String _scheme = HttpScheme.HTTP.asString();
@@ -60,7 +60,7 @@ public class TestableJettyServer
public TestableJettyServer() throws IOException
{
- _xmlConfigurations = new ArrayList();
+ _xmlConfigurations = new ArrayList<>();
Properties properties = new Properties();
/* Establish Popular Directories */
From 6a42d3ba0833deb98a85ef841df843cec0eeac1b Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Mon, 24 Sep 2018 19:24:49 +1000
Subject: [PATCH 02/14] Issue #3343 add api/tools to test jetty distribution
Signed-off-by: olivier lamy
---
tests/pom.xml | 2 +-
tests/test-distribution/pom.xml | 91 +++
.../distribution/DistributionTester.java | 605 ++++++++++++++++++
.../tests/distribution/HttpModuleTests.java | 67 ++
.../src/test/resources/index.html | 1 +
.../src/test/resources/static_content.xml | 11 +
tests/test-webapps/pom.xml | 3 +-
tests/test-webapps/test-simple-webapp/pom.xml | 16 +
.../src/main/webapp/WEB-INF/web.xml | 10 +
.../src/main/webapp/index.jsp | 5 +
10 files changed, 809 insertions(+), 2 deletions(-)
create mode 100644 tests/test-distribution/pom.xml
create mode 100644 tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
create mode 100644 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
create mode 100644 tests/test-distribution/src/test/resources/index.html
create mode 100644 tests/test-distribution/src/test/resources/static_content.xml
create mode 100644 tests/test-webapps/test-simple-webapp/pom.xml
create mode 100644 tests/test-webapps/test-simple-webapp/src/main/webapp/WEB-INF/web.xml
create mode 100644 tests/test-webapps/test-simple-webapp/src/main/webapp/index.jsp
diff --git a/tests/pom.xml b/tests/pom.xml
index 56a34b1eb7e..4078a8dce7d 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -67,6 +67,6 @@
test-quickstart
test-jmx
test-http-client-transport
- test-modules
+ test-distribution
diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml
new file mode 100644
index 00000000000..bc9e78b6124
--- /dev/null
+++ b/tests/test-distribution/pom.xml
@@ -0,0 +1,91 @@
+
+
+ tests-parent
+ org.eclipse.jetty.tests
+ 9.4.15-SNAPSHOT
+
+ 4.0.0
+
+ test-distribution
+ jar
+
+
+ ${project.build.outputDirectory}/jetty_home
+ 1.3.1
+
+
+
+
+ org.eclipse.jetty
+ jetty-client
+ ${project.version}
+
+
+ org.eclipse.jetty
+ jetty-distribution
+ ${project.version}
+ zip
+
+
+ org.eclipse.jetty
+ jetty-start
+ ${project.version}
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j.version}
+
+
+ org.apache.maven
+ maven-resolver-provider
+ 3.6.0
+
+
+ org.apache.maven
+ maven-artifact
+ 3.6.0
+
+
+ org.apache.maven.resolver
+ maven-resolver-connector-basic
+ ${mavenResolver.version}
+
+
+ org.apache.maven.resolver
+ maven-resolver-transport-file
+ ${mavenResolver.version}
+
+
+ org.apache.maven.resolver
+ maven-resolver-transport-http
+ ${mavenResolver.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}
+
+
+ org.eclipse.jetty.tests
+ test-simple-webapp
+ ${project.version}
+ war
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ ${settings.localRepository}
+ ${project.version}
+
+
+
+
+
+
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
new file mode 100644
index 00000000000..6fa371a3230
--- /dev/null
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
@@ -0,0 +1,605 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2019 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.
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.eclipse.aether.AbstractRepositoryListener;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
+import org.eclipse.aether.impl.DefaultServiceLocator;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
+import org.eclipse.aether.spi.connector.transport.TransporterFactory;
+import org.eclipse.aether.transfer.AbstractTransferListener;
+import org.eclipse.aether.transport.file.FileTransporterFactory;
+import org.eclipse.aether.transport.http.HttpTransporterFactory;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.start.FS;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ *
+ * Please note this class is use for Jetty Distribution testing.
+ * So API can change without any further notice.
+ *
+ */
+public class DistributionTester {
+
+ private Process pid;
+
+ private URI baseUri;
+
+ private String jmxUrl;
+
+ private long waitStartTime = 60;
+
+ private long maxWaitToStop = 60000;
+
+ private TimeUnit timeUnit = TimeUnit.SECONDS;
+
+ private Path jettyBase;
+
+ private File jettyHomeDir;
+
+ private String jettyVersion;
+ private String jettyHome;
+ private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
+
+ private static final Logger LOGGER = Log.getLogger(DistributionTester.class);
+
+ private List logs = new ArrayList<>();
+
+ private HttpClient httpClient;
+
+ private DistributionTester(Path jettyBase)
+ throws Exception {
+ this.jettyBase = jettyBase;
+ }
+
+ private DistributionTester initialise() throws Exception {
+
+ if (StringUtils.isNotEmpty(jettyHome)) {
+ jettyHomeDir = Paths.get(jettyHome).toFile();
+ } else {
+ // 9.4.14.v20181114 9.4.15-SNAPSHOT
+ jettyHomeDir = resolveDistribution(this.jettyVersion);
+ }
+
+ this.httpClient = new HttpClient();
+ httpClient.start();
+
+ return this;
+
+ }
+
+ public void start() throws Exception {
+ start(Collections.emptyList());
+ }
+
+ public void start(String... args) throws Exception {
+ start(Arrays.asList(args));
+ }
+
+ public void start(List args)
+ throws Exception {
+
+ // do we want to be sure and use "--testing-mode" to not break surefire with a System.exit ???
+
+ logs.clear();
+
+ List commands = new ArrayList<>();
+ commands.add(getJavaBin());
+
+ commands.add("-Djetty.home=" + jettyHomeDir.getAbsolutePath());
+ commands.add("-Djetty.base=" + jettyBase.toAbsolutePath().toString());
+
+ commands.add("-jar");
+ commands.add(jettyHomeDir.getAbsolutePath() + "/start.jar");
+ commands.add("jetty.http.port=0");
+
+ commands.addAll(args);
+
+ ProcessBuilder pbCmd = new ProcessBuilder(commands);
+ pbCmd.directory(jettyHomeDir);
+
+ LOGGER.info("Executing: {}", commands);
+ LOGGER.info("Working Dir: {}", jettyHomeDir.getAbsolutePath());
+
+ pbCmd = new ProcessBuilder(commands);
+ pid = pbCmd.start();
+
+ ConsoleParser parser = new ConsoleParser();
+ List jmxList = parser.newPattern("JMX Remote URL: (.*)", 0);
+ // Started ServerConnector@76f2bbc1{HTTP/1.1,[http/1.1]}{0.0.0.0:50214}
+ List connList =
+ parser.newPattern("[A-Za-z]*Connector@.*\\{.*\\}\\{(.*)\\:([0-9]*)}", 1);
+
+ startPump("STDOUT", parser, this.pid.getInputStream());
+ startPump("STDERR", parser, this.pid.getErrorStream());
+
+ try {
+ long start = System.currentTimeMillis();
+ parser.waitForDone(this.waitStartTime, this.timeUnit);
+ LOGGER.info("wait start {}", System.currentTimeMillis() - start);
+
+
+ if (!jmxList.isEmpty()) {
+ this.jmxUrl = jmxList.get(0)[0];
+ LOGGER.info("## Found JMX connector at {}", this.jmxUrl);
+ }
+
+ if (!connList.isEmpty()) {
+ String[] params = connList.get(0);
+ if (params.length == 2) {
+ this.baseUri = URI.create("http://localhost:" + params[1]);
+ }
+ LOGGER.info("## Found Jetty connector at port: {}", params[1]);
+ }
+
+ } catch (InterruptedException e) {
+ pid.destroy();
+ }
+
+ }
+
+
+ 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();
+ }
+
+ /**
+ * Simple streamer for the console output from a Process
+ */
+ private 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;
+ }
+
+ @Override
+ public void run() {
+ String line;
+ try {
+ while ((line = reader.readLine()) != (null)) {
+ if (parser != null) {
+ parser.parse(line);
+ }
+ // using LOGGER generates too long lines..
+ //LOGGER.info("[{}] {}",mode, line);
+ System.out.println("[" + mode + "] " + line);
+ DistributionTester.this.logs.add(line);
+ }
+ } catch (IOException ignore) {
+ // ignore
+ } finally {
+ IO.close(reader);
+ }
+ }
+ }
+
+ private static class ConsoleParser {
+ private List patterns = new ArrayList<>();
+
+ private CountDownLatch latch;
+
+ private int count;
+
+ public List 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 matches;
+
+ private int count;
+
+ ConsolePattern(String exp, int cnt) {
+ pattern = Pattern.compile(exp);
+ matches = new ArrayList<>();
+ count = cnt;
+ }
+
+ public Matcher getMatcher(String line) {
+ return pattern.matcher(line);
+ }
+
+ public List getMatches() {
+ return matches;
+ }
+
+ public int getCount() {
+ return count;
+ }
+ }
+
+
+ public void installWarFile(File warFile, String context) throws IOException {
+ //webapps
+ Path webapps = Paths.get(jettyBase.toString(),"webapps", context);
+ if (!Files.exists(webapps)) {
+ Files.createDirectories(webapps);
+ }
+ unzip(warFile, webapps.toFile());
+ }
+
+ //---------------------------------------
+ // Assert methods
+ //---------------------------------------
+
+ public void assertLogsContains(String txt){
+ assertTrue(logs.stream().filter(s -> StringUtils.contains(s, txt)).count()>0);
+ }
+
+
+ public void assertUrlStatus(String url, int expectedStatus){
+ try {
+ ContentResponse contentResponse = httpClient.GET(getBaseUri() + url);
+ int status = contentResponse.getStatus();
+ assertEquals(expectedStatus, status, () -> "status not " + expectedStatus + " but " + status);
+ } catch (InterruptedException|ExecutionException|TimeoutException e) {
+ fail(e.getMessage(),e);
+ }
+ }
+
+ public void assertUrlContains(String url, String content){
+ try {
+ ContentResponse contentResponse = httpClient.GET(getBaseUri() + url);
+ String contentResponseStr = contentResponse.getContentAsString();
+ assertTrue(StringUtils.contains(contentResponseStr, content), () -> "content not containing '" + content + "'");
+ } catch (InterruptedException|ExecutionException|TimeoutException e) {
+ fail(e.getMessage(),e);
+ }
+ }
+
+
+ private void unzip(File zipFile, File output) throws IOException {
+ try (InputStream fileInputStream = Files.newInputStream(zipFile.toPath());
+ ZipInputStream zipInputStream = new ZipInputStream(fileInputStream))
+ {
+ ZipEntry entry = zipInputStream.getNextEntry();
+ while (entry != null) {
+ if (entry.isDirectory()) {
+ File dir = new File(output, entry.getName());
+ if (!Files.exists(dir.toPath())) {
+ Files.createDirectories(dir.toPath());
+ }
+ } else {
+ // Read zipEntry and write to a file.
+ File file = new File(output, entry.getName());
+ if(!Files.exists(file.getParentFile().toPath())){
+ Files.createDirectories(file.getParentFile().toPath());
+ }
+ try (OutputStream outputStream = Files.newOutputStream(file.toPath())) {
+ IOUtil.copy(zipInputStream,outputStream);
+ }
+ }
+ // Get next entry
+ entry = zipInputStream.getNextEntry();
+ }
+ }
+ }
+
+ //---------------------------------------
+ // Maven Utils methods
+ //---------------------------------------
+
+ /**
+ *
+ * @param coordinates :[:[:]]:
+ * @return the artifact
+ * @throws ArtifactResolutionException
+ */
+ public File resolveArtifact(String coordinates) throws ArtifactResolutionException {
+ RepositorySystem repositorySystem = newRepositorySystem();
+
+ Artifact artifact = new DefaultArtifact(coordinates);
+
+ RepositorySystemSession session = newRepositorySystemSession(repositorySystem);
+
+ ArtifactRequest artifactRequest = new ArtifactRequest();
+ artifactRequest.setArtifact(artifact);
+ artifactRequest.setRepositories(newRepositories(repositorySystem, newRepositorySystemSession(repositorySystem)));
+ ArtifactResult artifactResult = repositorySystem.resolveArtifact(session, artifactRequest);
+
+ artifact = artifactResult.getArtifact();
+ return artifact.getFile();
+ }
+
+ private File resolveDistribution(String version) throws Exception {
+ File artifactFile = resolveArtifact("org.eclipse.jetty:jetty-distribution:zip:" + version);
+
+ // create tmp directory to unzip distribution
+ Path tmp = Files.createTempDirectory("jetty_test");
+ tmp.toFile().deleteOnExit();
+
+ unzip(artifactFile, tmp.toFile());
+ return new File(tmp.toFile(), "jetty-distribution-" + version);
+ }
+
+
+
+ private RepositorySystem newRepositorySystem() {
+ DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
+ locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
+ locator.addService(TransporterFactory.class, FileTransporterFactory.class);
+ locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
+
+ locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() {
+ @Override
+ public void serviceCreationFailed(Class> type, Class> impl, Throwable exception) {
+ LOGGER.warn("Service creation failed for {} implementation {}: {}",
+ type, impl, exception.getMessage(), exception);
+ }
+ });
+
+ return locator.getService(RepositorySystem.class);
+ }
+
+ private List newRepositories(RepositorySystem system, RepositorySystemSession session) {
+ return new ArrayList<>(Collections.singletonList(newCentralRepository()));
+ }
+
+ private DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system) {
+ DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
+
+
+ LocalRepository localRepo = new LocalRepository(mavenLocalRepository);
+ session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
+
+ session.setTransferListener(new LogTransferListener());
+ session.setRepositoryListener(new LogRepositoryListener());
+
+ return session;
+ }
+
+ private static class LogTransferListener extends AbstractTransferListener {
+ // no op
+ }
+
+ private static class LogRepositoryListener extends AbstractRepositoryListener {
+
+ @Override
+ public void artifactDownloaded(RepositoryEvent event) {
+ LOGGER.debug("distribution downloaded to {}", event.getFile());
+ }
+
+ @Override
+ public void artifactResolved(RepositoryEvent event) {
+ LOGGER.debug("distribution resolved to {}", event.getFile());
+ }
+ }
+
+
+ private static RemoteRepository newCentralRepository() {
+ return new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build();
+ }
+
+
+ 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, FS.separators("bin/" + javaexe));
+ if (javabin.exists() && javabin.isFile()) {
+ return javabin.getAbsolutePath();
+ }
+ }
+ return "java";
+ }
+
+ public void stop()
+ throws Exception {
+
+ long start = System.currentTimeMillis();
+ while (this.pid.isAlive()&&(System.currentTimeMillis()-start
+
+
+ /scratch
+
+
+
+ true
+
+
+
\ No newline at end of file
diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml
index 64c4f6ee87c..e4d1e2219d3 100644
--- a/tests/test-webapps/pom.xml
+++ b/tests/test-webapps/pom.xml
@@ -39,5 +39,6 @@
test-jaas-webapp
test-jndi-webapp
test-http2-webapp
+ test-simple-webapp
-
+
\ No newline at end of file
diff --git a/tests/test-webapps/test-simple-webapp/pom.xml b/tests/test-webapps/test-simple-webapp/pom.xml
new file mode 100644
index 00000000000..846a05cf2d0
--- /dev/null
+++ b/tests/test-webapps/test-simple-webapp/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+ org.eclipse.jetty.tests
+ test-webapps-parent
+ 9.4.15-SNAPSHOT
+
+
+ test-simple-webapp
+
+ war
+
+ Test :: Jetty Test Simple Webapp
+
+
diff --git a/tests/test-webapps/test-simple-webapp/src/main/webapp/WEB-INF/web.xml b/tests/test-webapps/test-simple-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..4905321a949
--- /dev/null
+++ b/tests/test-webapps/test-simple-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,10 @@
+
+
+
+ Very Simple Web Application
+
diff --git a/tests/test-webapps/test-simple-webapp/src/main/webapp/index.jsp b/tests/test-webapps/test-simple-webapp/src/main/webapp/index.jsp
new file mode 100644
index 00000000000..c38169bb958
--- /dev/null
+++ b/tests/test-webapps/test-simple-webapp/src/main/webapp/index.jsp
@@ -0,0 +1,5 @@
+
+
+Hello World!
+
+
From d9bfece0cc58229021fb70a476c22fbd6781bc96 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Mon, 11 Feb 2019 12:59:14 +1000
Subject: [PATCH 03/14] rename class, add more javadoc
Signed-off-by: olivier lamy
---
...ionTester.java => DistributionRunner.java} | 152 +++++++++++++++---
.../tests/distribution/HttpModuleTests.java | 36 ++---
2 files changed, 145 insertions(+), 43 deletions(-)
rename tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/{DistributionTester.java => DistributionRunner.java} (81%)
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java
similarity index 81%
rename from tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
rename to tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java
index 6fa371a3230..bb22e1d67c8 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java
@@ -35,7 +35,9 @@ import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@@ -81,7 +83,7 @@ import org.eclipse.jetty.util.log.Logger;
* So API can change without any further notice.
*
*/
-public class DistributionTester {
+public class DistributionRunner {
private Process pid;
@@ -103,23 +105,29 @@ public class DistributionTester {
private String jettyHome;
private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
- private static final Logger LOGGER = Log.getLogger(DistributionTester.class);
+ private static final Logger LOGGER = Log.getLogger(DistributionRunner.class);
private List logs = new ArrayList<>();
private HttpClient httpClient;
- private DistributionTester(Path jettyBase)
+ private Map mavenRemoteRepositories = new HashMap<>();
+
+ private DistributionRunner(Path jettyBase)
throws Exception {
this.jettyBase = jettyBase;
}
- private DistributionTester initialise() throws Exception {
+ /**
+ *
+ * @return DistributionRunner setup jettyHome directory and start httpClient.
+ * @throws Exception
+ */
+ private DistributionRunner initialise() throws Exception {
if (StringUtils.isNotEmpty(jettyHome)) {
jettyHomeDir = Paths.get(jettyHome).toFile();
} else {
- // 9.4.14.v20181114 9.4.15-SNAPSHOT
jettyHomeDir = resolveDistribution(this.jettyVersion);
}
@@ -130,14 +138,28 @@ public class DistributionTester {
}
+ /**
+ * start the instance with no arguments
+ * @throws Exception
+ */
public void start() throws Exception {
start(Collections.emptyList());
}
+ /**
+ * start the instance with the arguments
+ * @param args arguments to use to start the distribution
+ * @throws Exception
+ */
public void start(String... args) throws Exception {
start(Arrays.asList(args));
}
+ /**
+ * start the instance with the arguments
+ * @param args arguments to use to start the distribution
+ * @throws Exception
+ */
public void start(List args)
throws Exception {
@@ -239,7 +261,7 @@ public class DistributionTester {
// using LOGGER generates too long lines..
//LOGGER.info("[{}] {}",mode, line);
System.out.println("[" + mode + "] " + line);
- DistributionTester.this.logs.add(line);
+ DistributionRunner.this.logs.add(line);
}
} catch (IOException ignore) {
// ignore
@@ -446,7 +468,16 @@ public class DistributionTester {
}
private List newRepositories(RepositorySystem system, RepositorySystemSession session) {
- return new ArrayList<>(Collections.singletonList(newCentralRepository()));
+ List remoteRepositories = new ArrayList<>(this.mavenRemoteRepositories.size()+1);
+ this.mavenRemoteRepositories.entrySet().stream().forEach(stringStringEntry -> {
+ remoteRepositories.add(new RemoteRepository.Builder(stringStringEntry.getKey(), "default", stringStringEntry.getValue()).build());
+ });
+ remoteRepositories.add(newCentralRepository());
+ return remoteRepositories;
+ }
+
+ private static RemoteRepository newCentralRepository() {
+ return new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build();
}
private DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system) {
@@ -480,10 +511,6 @@ public class DistributionTester {
}
- private static RemoteRepository newCentralRepository() {
- return new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build();
- }
-
private String getJavaBin() {
String javaexes[] = new String[]{"java", "java.exe"};
@@ -498,6 +525,7 @@ public class DistributionTester {
return "java";
}
+ ?
public void stop()
throws Exception {
@@ -514,12 +542,25 @@ public class DistributionTester {
LOGGER.info("still alive so force destroy process");
this.pid.destroyForcibly();
}
+ if(httpClient!=null&&httpClient.isRunning()){
+ httpClient.stop();
+ }
}
+ /**
+ * remove the content from JettyBase directory
+ * @throws IOException
+ */
public void cleanJettyBase() throws IOException {
FileUtils.cleanDirectory(this.jettyBase.toFile());
}
+ /**
+ * Method to use in finally block of a test and when using @After in a unit test.
+ * if running, it stops the distribution.
+ * Cleanup JettyBase and JettyHome directories
+ * @throws Exception
+ */
public void cleanup() throws Exception {
stop();
if (Files.exists(this.jettyBase)) {
@@ -530,17 +571,28 @@ public class DistributionTester {
// cleanup jetty distribution
IO.delete(this.jettyHomeDir);
}
-
}
+ /**
+ *
+ * @return the directory used as JettyBase
+ */
public Path getJettyBase() {
return jettyBase;
}
+ /**
+ *
+ * @return the {@link URI} to use to access the jetty instance (random port has been detected)
+ */
public URI getBaseUri() {
return baseUri;
}
+ /**
+ *
+ * @return the connection to use to access JMX (if configured)
+ */
public String getJmxUrl() {
return jmxUrl;
}
@@ -564,42 +616,104 @@ public class DistributionTester {
private long waitStartTime = 60;
+ private long maxWaitToStop = 60000;
+
+ private Map mavenRemoteRepositories = new HashMap<>();
+
+ /**
+ *
+ * @param jettyVersion the version to use (format: 9.4.14.v20181114 9.4.15-SNAPSHOT).
+ * The distribution will be downloaded from local repository or remote
+ * @return the {@link Builder}
+ */
public Builder jettyVersion(String jettyVersion) {
this.jettyVersion = jettyVersion;
return this;
}
+ /**
+ *
+ * @param jettyHome Path to the local exploded jetty distribution
+ * if configured the jettyVersion parameter will not be used
+ * @return the {@link Builder}
+ */
public Builder jettyHome(String jettyHome) {
this.jettyHome = jettyHome;
return this;
}
+ /**
+ *
+ * @param mavenLocalRepository Path to the local maven repository
+ * @return the {@link Builder}
+ */
public Builder mavenLocalRepository(String mavenLocalRepository) {
this.mavenLocalRepository = mavenLocalRepository;
return this;
}
+ /**
+ *
+ * @param waitStartTime the maximum time in seconds to wait the start of the distribution
+ * @return the {@link Builder}
+ */
public Builder waitStartTime(long waitStartTime) {
this.waitStartTime = waitStartTime;
return this;
}
+ /**
+ *
+ * @param maxWaitToStop the maximum time in seconds to wait after stop the distribution
+ * process before forcing the stop.
+ * @return the {@link Builder}
+ */
+ public Builder maxWaitToStop(long maxWaitToStop) {
+ this.maxWaitToStop = maxWaitToStop;
+ return this;
+ }
+
+ /**
+ *
+ * If needed to resolve JettyDistribtion from another Maven remote repositories
+ * @param id the id
+ * @param url the Maven remote repository url
+ * @return the {@link Builder}
+ */
+ public Builder addRemoteRepository(String id, String url) {
+ this.mavenRemoteRepositories.put(id, url);
+ return this;
+ }
+
+ /**
+ *
+ * @return an empty instance of {@link Builder}
+ */
public static Builder newInstance() {
return new Builder();
}
- public DistributionTester build()
+ /**
+ *
+ * @return a new configured instance of {@link DistributionRunner}
+ * @throws Exception
+ */
+ public DistributionRunner build()
throws Exception {
if (jettyBase == null) {
this.jettyBase = Files.createTempDirectory("jetty_base_test");
this.jettyBase.toFile().deleteOnExit();
}
- DistributionTester distributionTester = new DistributionTester(jettyBase);
- distributionTester.jettyVersion = jettyVersion;
- distributionTester.jettyHome = jettyHome;
- distributionTester.mavenLocalRepository = mavenLocalRepository;
- distributionTester.waitStartTime = waitStartTime;
- return distributionTester.initialise();
+ DistributionRunner distributionRunner = new DistributionRunner(jettyBase);
+ distributionRunner.jettyVersion = jettyVersion;
+ distributionRunner.jettyHome = jettyHome;
+ distributionRunner.mavenLocalRepository = mavenLocalRepository;
+ distributionRunner.waitStartTime = waitStartTime;
+ distributionRunner.maxWaitToStop = maxWaitToStop;
+ if(!this.mavenRemoteRepositories.isEmpty()) {
+ distributionRunner.mavenRemoteRepositories.putAll(this.mavenRemoteRepositories);
+ }
+ return distributionRunner.initialise();
}
}
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
index 2cc3a334b3b..44aebfd597a 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
@@ -18,49 +18,37 @@
package org.eclipse.jetty.tests.distribution;
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.File;
-import java.net.URI;
-import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
public class HttpModuleTests
{
@Test
public void http_module() throws Exception
{
- // System.getProperty( "jetty_home" )
- DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
+ DistributionRunner distributionRunner = DistributionRunner.Builder.newInstance() //
.jettyVersion(System.getProperty("jetty_version")) //
.mavenLocalRepository(System.getProperty("mavenRepoPath")) //
.waitStartTime(30) //
.build(); //
try
{
- distributionTester.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
- distributionTester.stop();
+ distributionRunner.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
+ distributionRunner.stop();
- Path jettyBase = distributionTester.getJettyBase();
+ Path jettyBase = distributionRunner.getJettyBase();
- File war = distributionTester.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
- distributionTester.installWarFile(war, "test");
- distributionTester.start();
- distributionTester.assertLogsContains("Started @");
- distributionTester.assertUrlStatus("/test/index.jsp", 200);
- distributionTester.assertUrlContains("/test/index.jsp", "Hello");
+ File war = distributionRunner.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
+ distributionRunner.installWarFile(war, "test");
+ distributionRunner.start();
+ distributionRunner.assertLogsContains("Started @");
+ distributionRunner.assertUrlStatus("/test/index.jsp", 200);
+ distributionRunner.assertUrlContains("/test/index.jsp", "Hello");
} finally {
- distributionTester.stop();
- distributionTester.cleanup();
+ distributionRunner.stop();
+ distributionRunner.cleanup();
}
}
From 85fd1db963d72f8322a049bb5d97edffd9ffc1a8 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Mon, 11 Feb 2019 15:55:27 +1000
Subject: [PATCH 04/14] add jpms test
Signed-off-by: olivier lamy
---
.../distribution/DistributionRunner.java | 11 ++--
.../distribution/JpmsActivatedTests.java | 59 +++++++++++++++++++
2 files changed, 66 insertions(+), 4 deletions(-)
create mode 100644 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java
index bb22e1d67c8..c0f4d66f45e 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java
@@ -525,7 +525,10 @@ public class DistributionRunner {
return "java";
}
- ?
+ /**
+ * Stop the distribution
+ * @throws Exception
+ */
public void stop()
throws Exception {
@@ -542,9 +545,6 @@ public class DistributionRunner {
LOGGER.info("still alive so force destroy process");
this.pid.destroyForcibly();
}
- if(httpClient!=null&&httpClient.isRunning()){
- httpClient.stop();
- }
}
/**
@@ -563,6 +563,9 @@ public class DistributionRunner {
*/
public void cleanup() throws Exception {
stop();
+ if(httpClient!=null&&httpClient.isRunning()){
+ httpClient.stop();
+ }
if (Files.exists(this.jettyBase)) {
// cleanup jetty base
IO.delete(this.jettyBase.toFile());
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
new file mode 100644
index 00000000000..6ef7548ca77
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
@@ -0,0 +1,59 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2019 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.
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution;
+
+import java.io.File;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnJre;
+import org.junit.jupiter.api.condition.EnabledOnJre;
+import org.junit.jupiter.api.condition.JRE;
+
+public class JpmsActivatedTests
+{
+ @Test
+ @DisabledOnJre(JRE.JAVA_8)
+ public void jpms_activated() throws Exception
+ {
+ DistributionRunner distributionRunner = DistributionRunner.Builder.newInstance() //
+ .jettyVersion(System.getProperty("jetty_version")) //
+ .mavenLocalRepository(System.getProperty("mavenRepoPath")) //
+ .waitStartTime(30) //
+ .build(); //
+ try
+ {
+ distributionRunner.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
+ distributionRunner.stop();
+
+ Path jettyBase = distributionRunner.getJettyBase();
+
+ File war = distributionRunner.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
+ distributionRunner.installWarFile(war, "test");
+ distributionRunner.start("--jpms");
+ distributionRunner.assertLogsContains("Started @");
+ distributionRunner.assertUrlStatus("/test/index.jsp", 200);
+ distributionRunner.assertUrlContains("/test/index.jsp", "Hello");
+ } finally {
+ distributionRunner.stop();
+ distributionRunner.cleanup();
+ }
+
+ }
+}
From dd4041dae1f5c979d0a49479ecdc911aebbb3da9 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Mon, 11 Feb 2019 17:14:27 +1000
Subject: [PATCH 05/14] cleanup not used variable
Signed-off-by: olivier lamy
---
.../org/eclipse/jetty/tests/distribution/HttpModuleTests.java | 2 --
.../eclipse/jetty/tests/distribution/JpmsActivatedTests.java | 2 --
2 files changed, 4 deletions(-)
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
index 44aebfd597a..0afef157e2b 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
@@ -38,8 +38,6 @@ public class HttpModuleTests
distributionRunner.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
distributionRunner.stop();
- Path jettyBase = distributionRunner.getJettyBase();
-
File war = distributionRunner.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
distributionRunner.installWarFile(war, "test");
distributionRunner.start();
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
index 6ef7548ca77..cd7964cd6cf 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
@@ -42,8 +42,6 @@ public class JpmsActivatedTests
distributionRunner.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
distributionRunner.stop();
- Path jettyBase = distributionRunner.getJettyBase();
-
File war = distributionRunner.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
distributionRunner.installWarFile(war, "test");
distributionRunner.start("--jpms");
From 214bc03270ccb96f5a43388de463b208629a8a23 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Mon, 11 Feb 2019 19:08:57 +1000
Subject: [PATCH 06/14] DistributionTester is definitely a better name
Signed-off-by: olivier lamy
---
...ionRunner.java => DistributionTester.java} | 32 +++++++++----------
.../tests/distribution/HttpModuleTests.java | 23 +++++++------
.../distribution/JpmsActivatedTests.java | 24 +++++++-------
3 files changed, 38 insertions(+), 41 deletions(-)
rename tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/{DistributionRunner.java => DistributionTester.java} (96%)
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
similarity index 96%
rename from tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java
rename to tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
index c0f4d66f45e..31f74f46e0d 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionRunner.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
@@ -83,7 +83,7 @@ import org.eclipse.jetty.util.log.Logger;
* So API can change without any further notice.
*
*/
-public class DistributionRunner {
+public class DistributionTester {
private Process pid;
@@ -105,7 +105,7 @@ public class DistributionRunner {
private String jettyHome;
private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
- private static final Logger LOGGER = Log.getLogger(DistributionRunner.class);
+ private static final Logger LOGGER = Log.getLogger(DistributionTester.class);
private List logs = new ArrayList<>();
@@ -113,17 +113,17 @@ public class DistributionRunner {
private Map mavenRemoteRepositories = new HashMap<>();
- private DistributionRunner(Path jettyBase)
+ private DistributionTester(Path jettyBase)
throws Exception {
this.jettyBase = jettyBase;
}
/**
*
- * @return DistributionRunner setup jettyHome directory and start httpClient.
+ * @return DistributionTester setup jettyHome directory and start httpClient.
* @throws Exception
*/
- private DistributionRunner initialise() throws Exception {
+ private DistributionTester initialise() throws Exception {
if (StringUtils.isNotEmpty(jettyHome)) {
jettyHomeDir = Paths.get(jettyHome).toFile();
@@ -261,7 +261,7 @@ public class DistributionRunner {
// using LOGGER generates too long lines..
//LOGGER.info("[{}] {}",mode, line);
System.out.println("[" + mode + "] " + line);
- DistributionRunner.this.logs.add(line);
+ DistributionTester.this.logs.add(line);
}
} catch (IOException ignore) {
// ignore
@@ -698,25 +698,25 @@ public class DistributionRunner {
/**
*
- * @return a new configured instance of {@link DistributionRunner}
+ * @return a new configured instance of {@link DistributionTester}
* @throws Exception
*/
- public DistributionRunner build()
+ public DistributionTester build()
throws Exception {
if (jettyBase == null) {
this.jettyBase = Files.createTempDirectory("jetty_base_test");
this.jettyBase.toFile().deleteOnExit();
}
- DistributionRunner distributionRunner = new DistributionRunner(jettyBase);
- distributionRunner.jettyVersion = jettyVersion;
- distributionRunner.jettyHome = jettyHome;
- distributionRunner.mavenLocalRepository = mavenLocalRepository;
- distributionRunner.waitStartTime = waitStartTime;
- distributionRunner.maxWaitToStop = maxWaitToStop;
+ DistributionTester distributionTester = new DistributionTester(jettyBase);
+ distributionTester.jettyVersion = jettyVersion;
+ distributionTester.jettyHome = jettyHome;
+ distributionTester.mavenLocalRepository = mavenLocalRepository;
+ distributionTester.waitStartTime = waitStartTime;
+ distributionTester.maxWaitToStop = maxWaitToStop;
if(!this.mavenRemoteRepositories.isEmpty()) {
- distributionRunner.mavenRemoteRepositories.putAll(this.mavenRemoteRepositories);
+ distributionTester.mavenRemoteRepositories.putAll(this.mavenRemoteRepositories);
}
- return distributionRunner.initialise();
+ return distributionTester.initialise();
}
}
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
index 0afef157e2b..08c3ae187a1 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
@@ -21,32 +21,31 @@ package org.eclipse.jetty.tests.distribution;
import org.junit.jupiter.api.Test;
import java.io.File;
-import java.nio.file.Path;
public class HttpModuleTests
{
@Test
public void http_module() throws Exception
{
- DistributionRunner distributionRunner = DistributionRunner.Builder.newInstance() //
+ DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
.jettyVersion(System.getProperty("jetty_version")) //
.mavenLocalRepository(System.getProperty("mavenRepoPath")) //
.waitStartTime(30) //
.build(); //
try
{
- distributionRunner.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
- distributionRunner.stop();
+ distributionTester.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
+ distributionTester.stop();
- File war = distributionRunner.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
- distributionRunner.installWarFile(war, "test");
- distributionRunner.start();
- distributionRunner.assertLogsContains("Started @");
- distributionRunner.assertUrlStatus("/test/index.jsp", 200);
- distributionRunner.assertUrlContains("/test/index.jsp", "Hello");
+ File war = distributionTester.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
+ distributionTester.installWarFile(war, "test");
+ distributionTester.start();
+ distributionTester.assertLogsContains("Started @");
+ distributionTester.assertUrlStatus("/test/index.jsp", 200);
+ distributionTester.assertUrlContains("/test/index.jsp", "Hello");
} finally {
- distributionRunner.stop();
- distributionRunner.cleanup();
+ distributionTester.stop();
+ distributionTester.cleanup();
}
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
index cd7964cd6cf..2462626db7f 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
@@ -19,11 +19,9 @@
package org.eclipse.jetty.tests.distribution;
import java.io.File;
-import java.nio.file.Path;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
-import org.junit.jupiter.api.condition.EnabledOnJre;
import org.junit.jupiter.api.condition.JRE;
public class JpmsActivatedTests
@@ -32,25 +30,25 @@ public class JpmsActivatedTests
@DisabledOnJre(JRE.JAVA_8)
public void jpms_activated() throws Exception
{
- DistributionRunner distributionRunner = DistributionRunner.Builder.newInstance() //
+ DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
.jettyVersion(System.getProperty("jetty_version")) //
.mavenLocalRepository(System.getProperty("mavenRepoPath")) //
.waitStartTime(30) //
.build(); //
try
{
- distributionRunner.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
- distributionRunner.stop();
+ distributionTester.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
+ distributionTester.stop();
- File war = distributionRunner.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
- distributionRunner.installWarFile(war, "test");
- distributionRunner.start("--jpms");
- distributionRunner.assertLogsContains("Started @");
- distributionRunner.assertUrlStatus("/test/index.jsp", 200);
- distributionRunner.assertUrlContains("/test/index.jsp", "Hello");
+ File war = distributionTester.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
+ distributionTester.installWarFile(war, "test");
+ distributionTester.start("--jpms");
+ distributionTester.assertLogsContains("Started @");
+ distributionTester.assertUrlStatus("/test/index.jsp", 200);
+ distributionTester.assertUrlContains("/test/index.jsp", "Hello");
} finally {
- distributionRunner.stop();
- distributionRunner.cleanup();
+ distributionTester.stop();
+ distributionTester.cleanup();
}
}
From cbc9a9cff3ffca45d07d3d8b1e6098328614c07c Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Mon, 11 Feb 2019 21:34:52 +1000
Subject: [PATCH 07/14] apply some comments from review
Signed-off-by: olivier lamy
---
tests/test-distribution/pom.xml | 2 +-
.../distribution/DistributionTester.java | 565 ++++++++++--------
.../tests/distribution/HttpModuleTests.java | 23 +-
.../distribution/JpmsActivatedTests.java | 23 +-
4 files changed, 338 insertions(+), 275 deletions(-)
diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml
index bc9e78b6124..1eb78e8b518 100644
--- a/tests/test-distribution/pom.xml
+++ b/tests/test-distribution/pom.xml
@@ -11,7 +11,7 @@
jar
- ${project.build.outputDirectory}/jetty_home
+ ${project.groupId}.test_distribution
1.3.1
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
index 31f74f46e0d..3bd2883fff5 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.BufferedReader;
+import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -83,85 +84,71 @@ import org.eclipse.jetty.util.log.Logger;
* So API can change without any further notice.
*
*/
-public class DistributionTester {
-
- private Process pid;
-
- private URI baseUri;
-
- private String jmxUrl;
-
- private long waitStartTime = 60;
-
- private long maxWaitToStop = 60000;
-
- private TimeUnit timeUnit = TimeUnit.SECONDS;
-
- private Path jettyBase;
-
- private File jettyHomeDir;
-
- private String jettyVersion;
- private String jettyHome;
- private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
+public class DistributionTester implements Closeable
+{
private static final Logger LOGGER = Log.getLogger(DistributionTester.class);
+ private Process pid;
+ private URI baseUri;
+ private String jmxUrl;
+ private Config config;
+ private List consoleStreamers = new ArrayList<>();
private List logs = new ArrayList<>();
-
private HttpClient httpClient;
- private Map mavenRemoteRepositories = new HashMap<>();
+ private static class Config
+ {
+ private long waitStartTime = 60;
- private DistributionTester(Path jettyBase)
- throws Exception {
- this.jettyBase = jettyBase;
+ private long maxWaitToStop = 60000;
+
+ private TimeUnit timeUnit = TimeUnit.SECONDS;
+
+ private Path jettyBase;
+
+ private File jettyHomeDir;
+
+ private String jettyVersion;
+ private String jettyHome;
+ private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
+ private Map mavenRemoteRepositories = new HashMap<>();
}
- /**
- *
- * @return DistributionTester setup jettyHome directory and start httpClient.
- * @throws Exception
- */
- private DistributionTester initialise() throws Exception {
-
- if (StringUtils.isNotEmpty(jettyHome)) {
- jettyHomeDir = Paths.get(jettyHome).toFile();
- } else {
- jettyHomeDir = resolveDistribution(this.jettyVersion);
- }
-
- this.httpClient = new HttpClient();
- httpClient.start();
-
- return this;
+ private DistributionTester(Config config) {
+ this.config = config;
}
+
/**
* start the instance with no arguments
- * @throws Exception
*/
- public void start() throws Exception {
+ public DistributionTester start() throws Exception
+ {
start(Collections.emptyList());
+ return this;
}
/**
* start the instance with the arguments
+ *
* @param args arguments to use to start the distribution
- * @throws Exception
*/
- public void start(String... args) throws Exception {
+ public DistributionTester start(String... args) throws Exception
+ {
start(Arrays.asList(args));
+ return this;
}
/**
* start the instance with the arguments
+ *
* @param args arguments to use to start the distribution
- * @throws Exception
*/
- public void start(List args)
- throws Exception {
+ public DistributionTester start(List args)
+ throws Exception
+ {
// do we want to be sure and use "--testing-mode" to not break surefire with a System.exit ???
@@ -170,20 +157,20 @@ public class DistributionTester {
List commands = new ArrayList<>();
commands.add(getJavaBin());
- commands.add("-Djetty.home=" + jettyHomeDir.getAbsolutePath());
- commands.add("-Djetty.base=" + jettyBase.toAbsolutePath().toString());
+ commands.add("-Djetty.home=" + config.jettyHomeDir.getAbsolutePath());
+ commands.add("-Djetty.base=" + config.jettyBase.toAbsolutePath().toString());
commands.add("-jar");
- commands.add(jettyHomeDir.getAbsolutePath() + "/start.jar");
+ commands.add(config.jettyHomeDir.getAbsolutePath() + "/start.jar");
commands.add("jetty.http.port=0");
commands.addAll(args);
ProcessBuilder pbCmd = new ProcessBuilder(commands);
- pbCmd.directory(jettyHomeDir);
+ pbCmd.directory(config.jettyHomeDir);
LOGGER.info("Executing: {}", commands);
- LOGGER.info("Working Dir: {}", jettyHomeDir.getAbsolutePath());
+ LOGGER.info("Working Dir: {}", config.jettyHomeDir.getAbsolutePath());
pbCmd = new ProcessBuilder(commands);
pid = pbCmd.start();
@@ -194,12 +181,12 @@ public class DistributionTester {
List connList =
parser.newPattern("[A-Za-z]*Connector@.*\\{.*\\}\\{(.*)\\:([0-9]*)}", 1);
- startPump("STDOUT", parser, this.pid.getInputStream());
- startPump("STDERR", parser, this.pid.getErrorStream());
+ consoleStreamers.add(startPump("STDOUT", parser, this.pid.getInputStream()));
+ consoleStreamers.add(startPump("STDERR", parser, this.pid.getErrorStream()));
try {
long start = System.currentTimeMillis();
- parser.waitForDone(this.waitStartTime, this.timeUnit);
+ parser.waitForDone(config.waitStartTime, config.timeUnit);
LOGGER.info("wait start {}", System.currentTimeMillis() - start);
@@ -219,42 +206,169 @@ public class DistributionTester {
} catch (InterruptedException e) {
pid.destroy();
}
+ return this;
+ }
+ public void installWarFile(File warFile, String context) throws IOException
+ {
+ //webapps
+ Path webapps = Paths.get(config.jettyBase.toString(), "webapps", context);
+ if (!Files.exists(webapps))
+ {
+ Files.createDirectories(webapps);
+ }
+ unzip(warFile, webapps.toFile());
+ }
+
+ //---------------------------------------
+ // Assert methods
+ //---------------------------------------
+
+ public DistributionTester assertLogsContains(String txt)
+ {
+ assertTrue(logs.stream().filter(s -> StringUtils.contains(s, txt)).count() > 0);
+ return this;
}
- private void startPump(String mode, ConsoleParser parser, InputStream inputStream) {
+ public DistributionTester assertUrlStatus(String url, int expectedStatus)
+ {
+ try
+ {
+ ContentResponse contentResponse = httpClient.GET(getBaseUri() + url);
+ int status = contentResponse.getStatus();
+ assertEquals(expectedStatus, status, () -> "status not " + expectedStatus + " but " + status);
+ } catch (InterruptedException | ExecutionException | TimeoutException e)
+ {
+ fail(e.getMessage(), e);
+ }
+ return this;
+ }
+
+ public DistributionTester assertUrlContains(String url, String content)
+ {
+ try
+ {
+ ContentResponse contentResponse = httpClient.GET(getBaseUri() + url);
+ String contentResponseStr = contentResponse.getContentAsString();
+ assertTrue(StringUtils.contains(contentResponseStr, content), () -> "content not containing '" + content + "'");
+ } catch (InterruptedException | ExecutionException | TimeoutException e)
+ {
+ fail(e.getMessage(), e);
+ }
+ return this;
+ }
+
+ /**
+ * @param coordinates :[:[:]]:
+ * @return the artifact
+ */
+ public File resolveArtifact(String coordinates) throws ArtifactResolutionException
+ {
+ RepositorySystem repositorySystem = newRepositorySystem();
+
+ Artifact artifact = new DefaultArtifact(coordinates);
+
+ RepositorySystemSession session = newRepositorySystemSession(repositorySystem);
+
+ ArtifactRequest artifactRequest = new ArtifactRequest();
+ artifactRequest.setArtifact(artifact);
+ artifactRequest.setRepositories(newRepositories(repositorySystem, newRepositorySystemSession(repositorySystem)));
+ ArtifactResult artifactResult = repositorySystem.resolveArtifact(session, artifactRequest);
+
+ artifact = artifactResult.getArtifact();
+ return artifact.getFile();
+ }
+
+ /**
+ * @return the directory used as JettyBase
+ */
+ public Path getJettyBase()
+ {
+ return config.jettyBase;
+ }
+
+ /**
+ * @return the {@link URI} to use to access the jetty instance (random port has been detected)
+ */
+ public URI getBaseUri()
+ {
+ return baseUri;
+ }
+
+ /**
+ * @return the connection to use to access JMX (if configured)
+ */
+ public String getJmxUrl()
+ {
+ return jmxUrl;
+ }
+
+ /**
+ * @return DistributionTester setup jettyHome directory and start httpClient.
+ */
+ private DistributionTester initialise() throws Exception
+ {
+ if (config.jettyBase == null)
+ {
+ config.jettyBase = Files.createTempDirectory("jetty_base_test");
+ config.jettyBase.toFile().deleteOnExit();
+ }
+
+ if (StringUtils.isNotEmpty(config.jettyHome))
+ {
+ config.jettyHomeDir = Paths.get(config.jettyHome).toFile();
+ } else
+ {
+ config.jettyHomeDir = resolveDistribution(config.jettyVersion);
+ }
+
+ this.httpClient = new HttpClient();
+ httpClient.start();
+ return this;
+ }
+
+
+ private ConsoleStreamer 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();
+ return pump;
}
/**
* Simple streamer for the console output from a Process
*/
private class ConsoleStreamer
- implements Runnable {
+ implements Runnable
+ {
private String mode;
private BufferedReader reader;
private ConsoleParser parser;
- public ConsoleStreamer(String mode, InputStream is) {
+ private volatile boolean stop;
+
+ public ConsoleStreamer(String mode, InputStream is)
+ {
this.mode = mode;
this.reader = new BufferedReader(new InputStreamReader(is));
}
- public void setParser(ConsoleParser connector) {
+ public void setParser(ConsoleParser connector)
+ {
this.parser = connector;
}
@Override
- public void run() {
+ public void run()
+ {
String line;
try {
- while ((line = reader.readLine()) != (null)) {
+ while ((line = reader.readLine()) != null && !stop) {
if (parser != null) {
parser.parse(line);
}
@@ -271,32 +385,39 @@ public class DistributionTester {
}
}
- private static class ConsoleParser {
+ private static class ConsoleParser
+ {
private List patterns = new ArrayList<>();
private CountDownLatch latch;
private int count;
- public List newPattern(String exp, int cnt) {
+ public List 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) {
+ public void parse(String line)
+ {
+ for (ConsolePattern pat : patterns)
+ {
Matcher mat = pat.getMatcher(line);
- if (mat.find()) {
+ if (mat.find())
+ {
int num = 0, count = mat.groupCount();
String[] match = new String[count];
- while (num++ < count) {
+ while (num++ < count)
+ {
match[num - 1] = mat.group(num);
}
pat.getMatches().add(match);
- if (pat.getCount() > 0) {
+ if (pat.getCount() > 0)
+ {
getLatch().countDown();
}
}
@@ -304,13 +425,17 @@ public class DistributionTester {
}
public void waitForDone(long timeout, TimeUnit unit)
- throws InterruptedException {
+ throws InterruptedException
+ {
getLatch().await(timeout, unit);
}
- private CountDownLatch getLatch() {
- synchronized (this) {
- if (latch == null) {
+ private CountDownLatch getLatch()
+ {
+ synchronized (this)
+ {
+ if (latch == null)
+ {
latch = new CountDownLatch(count);
}
}
@@ -318,91 +443,63 @@ public class DistributionTester {
}
}
- private static class ConsolePattern {
+ private static class ConsolePattern
+ {
private Pattern pattern;
private List matches;
private int count;
- ConsolePattern(String exp, int cnt) {
+ ConsolePattern(String exp, int cnt)
+ {
pattern = Pattern.compile(exp);
matches = new ArrayList<>();
count = cnt;
}
- public Matcher getMatcher(String line) {
+ public Matcher getMatcher(String line)
+ {
return pattern.matcher(line);
}
- public List getMatches() {
+ public List getMatches()
+ {
return matches;
}
- public int getCount() {
+ public int getCount()
+ {
return count;
}
}
- public void installWarFile(File warFile, String context) throws IOException {
- //webapps
- Path webapps = Paths.get(jettyBase.toString(),"webapps", context);
- if (!Files.exists(webapps)) {
- Files.createDirectories(webapps);
- }
- unzip(warFile, webapps.toFile());
- }
-
- //---------------------------------------
- // Assert methods
- //---------------------------------------
-
- public void assertLogsContains(String txt){
- assertTrue(logs.stream().filter(s -> StringUtils.contains(s, txt)).count()>0);
- }
-
-
- public void assertUrlStatus(String url, int expectedStatus){
- try {
- ContentResponse contentResponse = httpClient.GET(getBaseUri() + url);
- int status = contentResponse.getStatus();
- assertEquals(expectedStatus, status, () -> "status not " + expectedStatus + " but " + status);
- } catch (InterruptedException|ExecutionException|TimeoutException e) {
- fail(e.getMessage(),e);
- }
- }
-
- public void assertUrlContains(String url, String content){
- try {
- ContentResponse contentResponse = httpClient.GET(getBaseUri() + url);
- String contentResponseStr = contentResponse.getContentAsString();
- assertTrue(StringUtils.contains(contentResponseStr, content), () -> "content not containing '" + content + "'");
- } catch (InterruptedException|ExecutionException|TimeoutException e) {
- fail(e.getMessage(),e);
- }
- }
-
-
- private void unzip(File zipFile, File output) throws IOException {
+ private void unzip(File zipFile, File output) throws IOException
+ {
try (InputStream fileInputStream = Files.newInputStream(zipFile.toPath());
- ZipInputStream zipInputStream = new ZipInputStream(fileInputStream))
+ ZipInputStream zipInputStream = new ZipInputStream(fileInputStream))
{
ZipEntry entry = zipInputStream.getNextEntry();
- while (entry != null) {
- if (entry.isDirectory()) {
+ while (entry != null)
+ {
+ if (entry.isDirectory())
+ {
File dir = new File(output, entry.getName());
if (!Files.exists(dir.toPath())) {
Files.createDirectories(dir.toPath());
}
- } else {
+ } else
+ {
// Read zipEntry and write to a file.
File file = new File(output, entry.getName());
- if(!Files.exists(file.getParentFile().toPath())){
+ if (!Files.exists(file.getParentFile().toPath()))
+ {
Files.createDirectories(file.getParentFile().toPath());
}
- try (OutputStream outputStream = Files.newOutputStream(file.toPath())) {
- IOUtil.copy(zipInputStream,outputStream);
+ try (OutputStream outputStream = Files.newOutputStream(file.toPath()))
+ {
+ IOUtil.copy(zipInputStream, outputStream);
}
}
// Get next entry
@@ -415,29 +512,8 @@ public class DistributionTester {
// Maven Utils methods
//---------------------------------------
- /**
- *
- * @param coordinates :[:[:]]:
- * @return the artifact
- * @throws ArtifactResolutionException
- */
- public File resolveArtifact(String coordinates) throws ArtifactResolutionException {
- RepositorySystem repositorySystem = newRepositorySystem();
-
- Artifact artifact = new DefaultArtifact(coordinates);
-
- RepositorySystemSession session = newRepositorySystemSession(repositorySystem);
-
- ArtifactRequest artifactRequest = new ArtifactRequest();
- artifactRequest.setArtifact(artifact);
- artifactRequest.setRepositories(newRepositories(repositorySystem, newRepositorySystemSession(repositorySystem)));
- ArtifactResult artifactResult = repositorySystem.resolveArtifact(session, artifactRequest);
-
- artifact = artifactResult.getArtifact();
- return artifact.getFile();
- }
-
- private File resolveDistribution(String version) throws Exception {
+ private File resolveDistribution(String version) throws Exception
+ {
File artifactFile = resolveArtifact("org.eclipse.jetty:jetty-distribution:zip:" + version);
// create tmp directory to unzip distribution
@@ -449,16 +525,18 @@ public class DistributionTester {
}
-
- private RepositorySystem newRepositorySystem() {
+ private RepositorySystem newRepositorySystem()
+ {
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
- locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() {
+ locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler()
+ {
@Override
- public void serviceCreationFailed(Class> type, Class> impl, Throwable exception) {
+ public void serviceCreationFailed(Class> type, Class> impl, Throwable exception)
+ {
LOGGER.warn("Service creation failed for {} implementation {}: {}",
type, impl, exception.getMessage(), exception);
}
@@ -467,24 +545,27 @@ public class DistributionTester {
return locator.getService(RepositorySystem.class);
}
- private List newRepositories(RepositorySystem system, RepositorySystemSession session) {
- List remoteRepositories = new ArrayList<>(this.mavenRemoteRepositories.size()+1);
- this.mavenRemoteRepositories.entrySet().stream().forEach(stringStringEntry -> {
- remoteRepositories.add(new RemoteRepository.Builder(stringStringEntry.getKey(), "default", stringStringEntry.getValue()).build());
- });
+ private List newRepositories(RepositorySystem system, RepositorySystemSession session)
+ {
+ List remoteRepositories = new ArrayList<>(config.mavenRemoteRepositories.size() + 1);
+ config.mavenRemoteRepositories.entrySet().stream().forEach( stringStringEntry ->
+ remoteRepositories.add(new RemoteRepository.Builder(stringStringEntry.getKey(), "default", stringStringEntry.getValue()).build())
+ );
remoteRepositories.add(newCentralRepository());
return remoteRepositories;
}
- private static RemoteRepository newCentralRepository() {
+ private static RemoteRepository newCentralRepository()
+ {
return new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build();
}
- private DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system) {
+ private DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system)
+ {
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
- LocalRepository localRepo = new LocalRepository(mavenLocalRepository);
+ LocalRepository localRepo = new LocalRepository(config.mavenLocalRepository);
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
session.setTransferListener(new LogTransferListener());
@@ -493,11 +574,13 @@ public class DistributionTester {
return session;
}
- private static class LogTransferListener extends AbstractTransferListener {
+ private static class LogTransferListener extends AbstractTransferListener
+ {
// no op
}
- private static class LogRepositoryListener extends AbstractRepositoryListener {
+ private static class LogRepositoryListener extends AbstractRepositoryListener
+ {
@Override
public void artifactDownloaded(RepositoryEvent event) {
@@ -511,12 +594,13 @@ public class DistributionTester {
}
-
- private String getJavaBin() {
+ private String getJavaBin()
+ {
String javaexes[] = new String[]{"java", "java.exe"};
File javaHomeDir = new File(System.getProperty("java.home"));
- for (String javaexe : javaexes) {
+ for (String javaexe : javaexes)
+ {
File javabin = new File(javaHomeDir, FS.separators("bin/" + javaexe));
if (javabin.exists() && javabin.isFile()) {
return javabin.getAbsolutePath();
@@ -527,85 +611,72 @@ public class DistributionTester {
/**
* Stop the distribution
- * @throws Exception
*/
public void stop()
- throws Exception {
-
+ throws IOException
+ {
long start = System.currentTimeMillis();
- while (this.pid.isAlive()&&(System.currentTimeMillis()-start consoleStreamer.stop=true);
}
/**
* Method to use in finally block of a test and when using @After in a unit test.
* if running, it stops the distribution.
* Cleanup JettyBase and JettyHome directories
- * @throws Exception
*/
- public void cleanup() throws Exception {
+ public void close() throws IOException
+ {
stop();
- if(httpClient!=null&&httpClient.isRunning()){
- httpClient.stop();
+ if (httpClient != null && httpClient.isRunning()) {
+ try
+ {
+ httpClient.stop();
+ } catch (Exception e)
+ {
+ throw new IOException(e.getMessage(),e);
+ }
}
- if (Files.exists(this.jettyBase)) {
+ if (Files.exists(config.jettyBase))
+ {
// cleanup jetty base
- IO.delete(this.jettyBase.toFile());
+ IO.delete(config.jettyBase.toFile());
}
- if (Files.exists(this.jettyHomeDir.toPath())) {
+ if (Files.exists(config.jettyHomeDir.toPath()))
+ {
// cleanup jetty distribution
- IO.delete(this.jettyHomeDir);
+ IO.delete(config.jettyHomeDir);
}
}
- /**
- *
- * @return the directory used as JettyBase
- */
- public Path getJettyBase() {
- return jettyBase;
- }
-
- /**
- *
- * @return the {@link URI} to use to access the jetty instance (random port has been detected)
- */
- public URI getBaseUri() {
- return baseUri;
- }
-
- /**
- *
- * @return the connection to use to access JMX (if configured)
- */
- public String getJmxUrl() {
- return jmxUrl;
- }
-
//---------------------------------------
// Builder class
//---------------------------------------
- public static class Builder {
- private Builder() {
+ public static class Builder
+ {
+ private Builder()
+ {
// no op
}
@@ -621,102 +692,100 @@ public class DistributionTester {
private long maxWaitToStop = 60000;
- private Map mavenRemoteRepositories = new HashMap<>();
+ private Map mavenRemoteRepositories = new HashMap<>();
/**
- *
* @param jettyVersion the version to use (format: 9.4.14.v20181114 9.4.15-SNAPSHOT).
- * The distribution will be downloaded from local repository or remote
+ * The distribution will be downloaded from local repository or remote
* @return the {@link Builder}
*/
- public Builder jettyVersion(String jettyVersion) {
+ public Builder jettyVersion(String jettyVersion)
+ {
this.jettyVersion = jettyVersion;
return this;
}
/**
- *
* @param jettyHome Path to the local exploded jetty distribution
* if configured the jettyVersion parameter will not be used
* @return the {@link Builder}
*/
- public Builder jettyHome(String jettyHome) {
+ public Builder jettyHome(String jettyHome)
+ {
this.jettyHome = jettyHome;
return this;
}
/**
- *
* @param mavenLocalRepository Path to the local maven repository
* @return the {@link Builder}
*/
- public Builder mavenLocalRepository(String mavenLocalRepository) {
+ public Builder mavenLocalRepository(String mavenLocalRepository)
+ {
this.mavenLocalRepository = mavenLocalRepository;
return this;
}
/**
- *
* @param waitStartTime the maximum time in seconds to wait the start of the distribution
* @return the {@link Builder}
*/
- public Builder waitStartTime(long waitStartTime) {
+ public Builder waitStartTime(long waitStartTime)
+ {
this.waitStartTime = waitStartTime;
return this;
}
/**
- *
* @param maxWaitToStop the maximum time in seconds to wait after stop the distribution
* process before forcing the stop.
* @return the {@link Builder}
*/
- public Builder maxWaitToStop(long maxWaitToStop) {
+ public Builder maxWaitToStop(long maxWaitToStop)
+ {
this.maxWaitToStop = maxWaitToStop;
return this;
}
/**
- *
* If needed to resolve JettyDistribtion from another Maven remote repositories
+ *
* @param id the id
* @param url the Maven remote repository url
* @return the {@link Builder}
*/
- public Builder addRemoteRepository(String id, String url) {
+ public Builder addRemoteRepository(String id, String url)
+ {
this.mavenRemoteRepositories.put(id, url);
return this;
}
/**
- *
* @return an empty instance of {@link Builder}
*/
- public static Builder newInstance() {
+ public static Builder newInstance()
+ {
return new Builder();
}
/**
- *
* @return a new configured instance of {@link DistributionTester}
- * @throws Exception
*/
public DistributionTester build()
- throws Exception {
- if (jettyBase == null) {
- this.jettyBase = Files.createTempDirectory("jetty_base_test");
- this.jettyBase.toFile().deleteOnExit();
+ throws Exception
+ {
+ Config config = new Config();
+ config.jettyBase = jettyBase;
+ config.jettyVersion = jettyVersion;
+ config.jettyHome = jettyHome;
+ config.mavenLocalRepository = mavenLocalRepository;
+ config.waitStartTime = waitStartTime;
+ config.maxWaitToStop = maxWaitToStop;
+ if (!this.mavenRemoteRepositories.isEmpty())
+ {
+ config.mavenRemoteRepositories.putAll(this.mavenRemoteRepositories);
}
- DistributionTester distributionTester = new DistributionTester(jettyBase);
- distributionTester.jettyVersion = jettyVersion;
- distributionTester.jettyHome = jettyHome;
- distributionTester.mavenLocalRepository = mavenLocalRepository;
- distributionTester.waitStartTime = waitStartTime;
- distributionTester.maxWaitToStop = maxWaitToStop;
- if(!this.mavenRemoteRepositories.isEmpty()) {
- distributionTester.mavenRemoteRepositories.putAll(this.mavenRemoteRepositories);
- }
- return distributionTester.initialise();
+ return new DistributionTester(config).initialise();
}
}
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
index 08c3ae187a1..a60766fe990 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
@@ -27,25 +27,22 @@ public class HttpModuleTests
@Test
public void http_module() throws Exception
{
- DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
- .jettyVersion(System.getProperty("jetty_version")) //
- .mavenLocalRepository(System.getProperty("mavenRepoPath")) //
- .waitStartTime(30) //
- .build(); //
- try
+
+ try(DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
+ .jettyVersion(System.getProperty("jetty_version")) //
+ .mavenLocalRepository(System.getProperty("mavenRepoPath")) //
+ .waitStartTime(30) //
+ .build())
{
distributionTester.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
distributionTester.stop();
File war = distributionTester.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
distributionTester.installWarFile(war, "test");
- distributionTester.start();
- distributionTester.assertLogsContains("Started @");
- distributionTester.assertUrlStatus("/test/index.jsp", 200);
- distributionTester.assertUrlContains("/test/index.jsp", "Hello");
- } finally {
- distributionTester.stop();
- distributionTester.cleanup();
+ distributionTester.start() //
+ .assertLogsContains("Started @") //
+ .assertUrlStatus("/test/index.jsp", 200) //
+ .assertUrlContains("/test/index.jsp", "Hello");
}
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
index 2462626db7f..fcf8300b7f9 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
@@ -30,25 +30,22 @@ public class JpmsActivatedTests
@DisabledOnJre(JRE.JAVA_8)
public void jpms_activated() throws Exception
{
- DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
- .jettyVersion(System.getProperty("jetty_version")) //
- .mavenLocalRepository(System.getProperty("mavenRepoPath")) //
- .waitStartTime(30) //
- .build(); //
- try
+
+ try(DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
+ .jettyVersion(System.getProperty("jetty_version")) //
+ .mavenLocalRepository(System.getProperty("mavenRepoPath")) //
+ .waitStartTime(30) //
+ .build())
{
distributionTester.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
distributionTester.stop();
File war = distributionTester.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
distributionTester.installWarFile(war, "test");
- distributionTester.start("--jpms");
- distributionTester.assertLogsContains("Started @");
- distributionTester.assertUrlStatus("/test/index.jsp", 200);
- distributionTester.assertUrlContains("/test/index.jsp", "Hello");
- } finally {
- distributionTester.stop();
- distributionTester.cleanup();
+ distributionTester.start("--jpms") //
+ .assertLogsContains("Started @") //
+ .assertUrlStatus("/test/index.jsp", 200)
+ .assertUrlContains("/test/index.jsp", "Hello");
}
}
From cb6b9d4a39afae2fdaf761c61ea120ef9fe503da Mon Sep 17 00:00:00 2001
From: Richard Bradley
Date: Mon, 11 Feb 2019 13:39:05 +0000
Subject: [PATCH 08/14] Include Vary:Origin on all responses
Signed-off-by: Richard Bradley
---
.../java/org/eclipse/jetty/servlets/CrossOriginFilter.java | 3 +--
.../java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
index d25f3f44d65..692be858f1c 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
@@ -400,8 +400,7 @@ public class CrossOriginFilter implements Filter
{
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
//W3C CORS spec http://www.w3.org/TR/cors/#resource-implementation
- if (!anyOriginAllowed)
- response.addHeader("Vary", ORIGIN_HEADER);
+ response.addHeader("Vary", ORIGIN_HEADER);
if (allowCredentials)
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
if (!exposedHeaders.isEmpty())
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java
index d55bfcfafee..37a5aeb6771 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java
@@ -135,7 +135,7 @@ public class CrossOriginFilterTest
Set fieldNames = response.getFieldNamesCollection();
assertThat(response.toString(), CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, isIn(fieldNames));
assertThat(response.toString(), CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, isIn(fieldNames));
- assertThat(response.toString(), "Vary", not(isIn(fieldNames)));
+ assertThat(response.toString(), "Vary", isIn(fieldNames));
assertTrue(latch.await(1, TimeUnit.SECONDS));
}
From b0207dd90d99010fa207105a3b9df55f50bea34e Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Mon, 11 Feb 2019 19:37:49 +0100
Subject: [PATCH 09/14] Issue #3343 - Add an API/tools to be able to test Jetty
Distribution.
Reworked the implementation.
Deleted unused stuff.
Written more tests.
Signed-off-by: Simone Bordet
---
tests/test-distribution/pom.xml | 55 +-
.../distribution/DistributionTester.java | 690 ++++++------------
.../AbstractDistributionTest.java | 29 +
.../tests/distribution/DistributionTests.java | 210 ++++++
.../tests/distribution/HttpModuleTests.java | 49 --
.../distribution/JpmsActivatedTests.java | 52 --
.../src/test/resources/index.html | 1 -
.../test/resources/jetty-logging.properties | 2 +
.../src/test/resources/static_content.xml | 11 -
9 files changed, 486 insertions(+), 613 deletions(-)
create mode 100644 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java
create mode 100644 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
delete mode 100644 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
delete mode 100644 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
delete mode 100644 tests/test-distribution/src/test/resources/index.html
create mode 100644 tests/test-distribution/src/test/resources/jetty-logging.properties
delete mode 100644 tests/test-distribution/src/test/resources/static_content.xml
diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml
index 1eb78e8b518..a2e8a386e72 100644
--- a/tests/test-distribution/pom.xml
+++ b/tests/test-distribution/pom.xml
@@ -11,41 +11,28 @@
jar
- ${project.groupId}.test_distribution
+ ${project.groupId}.tests.distribution
1.3.1
-
- org.eclipse.jetty
- jetty-client
- ${project.version}
-
-
- org.eclipse.jetty
- jetty-distribution
- ${project.version}
- zip
-
-
- org.eclipse.jetty
- jetty-start
- ${project.version}
-
org.slf4j
slf4j-simple
- ${slf4j.version}
- org.apache.maven
- maven-resolver-provider
- 3.6.0
+ org.eclipse.jetty
+ jetty-util
+ ${project.version}
org.apache.maven
maven-artifact
- 3.6.0
+
+
+ org.apache.maven
+ maven-resolver-provider
+ ${maven.version}
org.apache.maven.resolver
@@ -62,18 +49,33 @@
maven-resolver-transport-http
${mavenResolver.version}
+
- org.junit.jupiter
- junit-jupiter-api
- ${junit.version}
+ org.eclipse.jetty
+ jetty-client
+ ${project.version}
+ test
+
+
+ org.eclipse.jetty.http2
+ http2-http-client-transport
+ ${project.version}
+ test
org.eclipse.jetty.tests
test-simple-webapp
${project.version}
war
+ test
+
+
+ org.eclipse.jetty.toolchain
+ jetty-test-helper
+ test
+
@@ -82,10 +84,11 @@
${settings.localRepository}
- ${project.version}
+ ${project.version}
+
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
index 3bd2883fff5..3a29dff86fa 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
@@ -18,10 +18,6 @@
package org.eclipse.jetty.tests.distribution;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
-
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
@@ -29,28 +25,21 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.net.URI;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-import org.apache.commons.lang3.StringUtils;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
-import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.eclipse.aether.AbstractRepositoryListener;
import org.eclipse.aether.DefaultRepositorySystemSession;
@@ -71,142 +60,76 @@ import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transfer.AbstractTransferListener;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.start.FS;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
- *
- * Please note this class is use for Jetty Distribution testing.
- * So API can change without any further notice.
- *
+ * Helper class to test the Jetty Distribution
.
+ * API can change without any further notice.
*/
-public class DistributionTester implements Closeable
+public class DistributionTester
{
-
private static final Logger LOGGER = Log.getLogger(DistributionTester.class);
- private Process pid;
- private URI baseUri;
- private String jmxUrl;
private Config config;
private List consoleStreamers = new ArrayList<>();
private List logs = new ArrayList<>();
- private HttpClient httpClient;
- private static class Config
+ private DistributionTester(Config config)
{
- private long waitStartTime = 60;
-
- private long maxWaitToStop = 60000;
-
- private TimeUnit timeUnit = TimeUnit.SECONDS;
-
- private Path jettyBase;
-
- private File jettyHomeDir;
-
- private String jettyVersion;
- private String jettyHome;
- private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
- private Map mavenRemoteRepositories = new HashMap<>();
- }
-
-
- private DistributionTester(Config config) {
this.config = config;
}
-
/**
- * start the instance with no arguments
- */
- public DistributionTester start() throws Exception
- {
- start(Collections.emptyList());
- return this;
- }
-
- /**
- * start the instance with the arguments
+ * Starts the instance with the given arguments
*
* @param args arguments to use to start the distribution
*/
- public DistributionTester start(String... args) throws Exception
+ public DistributionTester.Run start(String... args) throws Exception
{
- start(Arrays.asList(args));
- return this;
+ return start(Arrays.asList(args));
}
/**
- * start the instance with the arguments
+ * Start the instance with the arguments
*
* @param args arguments to use to start the distribution
*/
- public DistributionTester start(List args)
- throws Exception
+ public DistributionTester.Run start(List args) throws Exception
{
-
// do we want to be sure and use "--testing-mode" to not break surefire with a System.exit ???
logs.clear();
List commands = new ArrayList<>();
- commands.add(getJavaBin());
-
- commands.add("-Djetty.home=" + config.jettyHomeDir.getAbsolutePath());
- commands.add("-Djetty.base=" + config.jettyBase.toAbsolutePath().toString());
-
+ commands.add(getJavaExecutable());
commands.add("-jar");
- commands.add(config.jettyHomeDir.getAbsolutePath() + "/start.jar");
- commands.add("jetty.http.port=0");
-
+ commands.add(config.jettyHome.toAbsolutePath() + "/start.jar");
commands.addAll(args);
- ProcessBuilder pbCmd = new ProcessBuilder(commands);
- pbCmd.directory(config.jettyHomeDir);
-
+ File workingDir = config.jettyBase.toFile();
LOGGER.info("Executing: {}", commands);
- LOGGER.info("Working Dir: {}", config.jettyHomeDir.getAbsolutePath());
+ LOGGER.info("Working Dir: {}", workingDir.getAbsolutePath());
- pbCmd = new ProcessBuilder(commands);
- pid = pbCmd.start();
+ ProcessBuilder pbCmd = new ProcessBuilder(commands);
+ pbCmd.directory(workingDir);
+ Process process = pbCmd.start();
- ConsoleParser parser = new ConsoleParser();
- List jmxList = parser.newPattern("JMX Remote URL: (.*)", 0);
- // Started ServerConnector@76f2bbc1{HTTP/1.1,[http/1.1]}{0.0.0.0:50214}
- List connList =
- parser.newPattern("[A-Za-z]*Connector@.*\\{.*\\}\\{(.*)\\:([0-9]*)}", 1);
+ consoleStreamers.add(startPump("STDOUT", process.getInputStream()));
+ consoleStreamers.add(startPump("STDERR", process.getErrorStream()));
- consoleStreamers.add(startPump("STDOUT", parser, this.pid.getInputStream()));
- consoleStreamers.add(startPump("STDERR", parser, this.pid.getErrorStream()));
+ return new Run(process);
+ }
- try {
- long start = System.currentTimeMillis();
- parser.waitForDone(config.waitStartTime, config.timeUnit);
- LOGGER.info("wait start {}", System.currentTimeMillis() - start);
-
-
- if (!jmxList.isEmpty()) {
- this.jmxUrl = jmxList.get(0)[0];
- LOGGER.info("## Found JMX connector at {}", this.jmxUrl);
- }
-
- if (!connList.isEmpty()) {
- String[] params = connList.get(0);
- if (params.length == 2) {
- this.baseUri = URI.create("http://localhost:" + params[1]);
- }
- LOGGER.info("## Found Jetty connector at port: {}", params[1]);
- }
-
- } catch (InterruptedException e) {
- pid.destroy();
+ public int randomPort() throws IOException
+ {
+ try (ServerSocket server = new ServerSocket())
+ {
+ server.setReuseAddress(true);
+ server.bind(new InetSocketAddress("localhost", 0));
+ return server.getLocalPort();
}
- return this;
}
public void installWarFile(File warFile, String context) throws IOException
@@ -214,51 +137,10 @@ public class DistributionTester implements Closeable
//webapps
Path webapps = Paths.get(config.jettyBase.toString(), "webapps", context);
if (!Files.exists(webapps))
- {
Files.createDirectories(webapps);
- }
unzip(warFile, webapps.toFile());
}
- //---------------------------------------
- // Assert methods
- //---------------------------------------
-
- public DistributionTester assertLogsContains(String txt)
- {
- assertTrue(logs.stream().filter(s -> StringUtils.contains(s, txt)).count() > 0);
- return this;
- }
-
-
- public DistributionTester assertUrlStatus(String url, int expectedStatus)
- {
- try
- {
- ContentResponse contentResponse = httpClient.GET(getBaseUri() + url);
- int status = contentResponse.getStatus();
- assertEquals(expectedStatus, status, () -> "status not " + expectedStatus + " but " + status);
- } catch (InterruptedException | ExecutionException | TimeoutException e)
- {
- fail(e.getMessage(), e);
- }
- return this;
- }
-
- public DistributionTester assertUrlContains(String url, String content)
- {
- try
- {
- ContentResponse contentResponse = httpClient.GET(getBaseUri() + url);
- String contentResponseStr = contentResponse.getContentAsString();
- assertTrue(StringUtils.contains(contentResponseStr, content), () -> "content not containing '" + content + "'");
- } catch (InterruptedException | ExecutionException | TimeoutException e)
- {
- fail(e.getMessage(), e);
- }
- return this;
- }
-
/**
* @param coordinates :[:[:]]:
* @return the artifact
@@ -273,208 +155,50 @@ public class DistributionTester implements Closeable
ArtifactRequest artifactRequest = new ArtifactRequest();
artifactRequest.setArtifact(artifact);
- artifactRequest.setRepositories(newRepositories(repositorySystem, newRepositorySystemSession(repositorySystem)));
+ artifactRequest.setRepositories(newRepositories());
ArtifactResult artifactResult = repositorySystem.resolveArtifact(session, artifactRequest);
artifact = artifactResult.getArtifact();
return artifact.getFile();
}
- /**
- * @return the directory used as JettyBase
- */
- public Path getJettyBase()
+ private void init() throws Exception
{
- return config.jettyBase;
- }
+ if (config.jettyHome == null)
+ config.jettyHome = resolveDistribution(config.jettyVersion);
- /**
- * @return the {@link URI} to use to access the jetty instance (random port has been detected)
- */
- public URI getBaseUri()
- {
- return baseUri;
- }
-
- /**
- * @return the connection to use to access JMX (if configured)
- */
- public String getJmxUrl()
- {
- return jmxUrl;
- }
-
- /**
- * @return DistributionTester setup jettyHome directory and start httpClient.
- */
- private DistributionTester initialise() throws Exception
- {
if (config.jettyBase == null)
{
- config.jettyBase = Files.createTempDirectory("jetty_base_test");
- config.jettyBase.toFile().deleteOnExit();
+ config.jettyBase = Files.createTempDirectory("jetty_base_");
}
-
- if (StringUtils.isNotEmpty(config.jettyHome))
+ else
{
- config.jettyHomeDir = Paths.get(config.jettyHome).toFile();
- } else
- {
- config.jettyHomeDir = resolveDistribution(config.jettyVersion);
+ if (!config.jettyBase.isAbsolute())
+ config.jettyBase = config.jettyHome.resolve(config.jettyBase);
}
-
- this.httpClient = new HttpClient();
- httpClient.start();
- return this;
}
-
- private ConsoleStreamer startPump(String mode, ConsoleParser parser, InputStream inputStream)
+ private String getJavaExecutable()
{
- ConsoleStreamer pump = new ConsoleStreamer(mode, inputStream);
- pump.setParser(parser);
+ String[] javaExecutables = new String[]{"java", "java.exe"};
+ File javaHomeDir = new File(System.getProperty("java.home"));
+ for (String javaExecutable : javaExecutables)
+ {
+ File javaFile = new File(javaHomeDir, "bin" + File.separator + javaExecutable);
+ if (javaFile.exists() && javaFile.isFile())
+ return javaFile.getAbsolutePath();
+ }
+ return "java";
+ }
+
+ private ConsoleStreamer startPump(String mode, InputStream stream)
+ {
+ ConsoleStreamer pump = new ConsoleStreamer(stream);
Thread thread = new Thread(pump, "ConsoleStreamer/" + mode);
thread.start();
return pump;
}
- /**
- * Simple streamer for the console output from a Process
- */
- private class ConsoleStreamer
- implements Runnable
- {
- private String mode;
-
- private BufferedReader reader;
-
- private ConsoleParser parser;
-
- private volatile boolean stop;
-
- public ConsoleStreamer(String mode, InputStream is)
- {
- this.mode = mode;
- this.reader = new BufferedReader(new InputStreamReader(is));
- }
-
- public void setParser(ConsoleParser connector)
- {
- this.parser = connector;
- }
-
- @Override
- public void run()
- {
- String line;
- try {
- while ((line = reader.readLine()) != null && !stop) {
- if (parser != null) {
- parser.parse(line);
- }
- // using LOGGER generates too long lines..
- //LOGGER.info("[{}] {}",mode, line);
- System.out.println("[" + mode + "] " + line);
- DistributionTester.this.logs.add(line);
- }
- } catch (IOException ignore) {
- // ignore
- } finally {
- IO.close(reader);
- }
- }
- }
-
- private static class ConsoleParser
- {
- private List patterns = new ArrayList<>();
-
- private CountDownLatch latch;
-
- private int count;
-
- public List 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 matches;
-
- private int count;
-
- ConsolePattern(String exp, int cnt)
- {
- pattern = Pattern.compile(exp);
- matches = new ArrayList<>();
- count = cnt;
- }
-
- public Matcher getMatcher(String line)
- {
- return pattern.matcher(line);
- }
-
- public List getMatches()
- {
- return matches;
- }
-
- public int getCount()
- {
- return count;
- }
- }
-
-
private void unzip(File zipFile, File output) throws IOException
{
try (InputStream fileInputStream = Files.newInputStream(zipFile.toPath());
@@ -486,10 +210,12 @@ public class DistributionTester implements Closeable
if (entry.isDirectory())
{
File dir = new File(output, entry.getName());
- if (!Files.exists(dir.toPath())) {
+ if (!Files.exists(dir.toPath()))
+ {
Files.createDirectories(dir.toPath());
}
- } else
+ }
+ else
{
// Read zipEntry and write to a file.
File file = new File(output, entry.getName());
@@ -508,23 +234,19 @@ public class DistributionTester implements Closeable
}
}
- //---------------------------------------
- // Maven Utils methods
- //---------------------------------------
-
- private File resolveDistribution(String version) throws Exception
+ private Path resolveDistribution(String version) throws Exception
{
File artifactFile = resolveArtifact("org.eclipse.jetty:jetty-distribution:zip:" + version);
// create tmp directory to unzip distribution
- Path tmp = Files.createTempDirectory("jetty_test");
- tmp.toFile().deleteOnExit();
+ Path tmp = Files.createTempDirectory("jetty_home_");
+ File tmpFile = tmp.toFile();
- unzip(artifactFile, tmp.toFile());
- return new File(tmp.toFile(), "jetty-distribution-" + version);
+ unzip(artifactFile, tmpFile);
+
+ return tmp.resolve("jetty-distribution-" + version);
}
-
private RepositorySystem newRepositorySystem()
{
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
@@ -545,12 +267,10 @@ public class DistributionTester implements Closeable
return locator.getService(RepositorySystem.class);
}
- private List newRepositories(RepositorySystem system, RepositorySystemSession session)
+ private List newRepositories()
{
List remoteRepositories = new ArrayList<>(config.mavenRemoteRepositories.size() + 1);
- config.mavenRemoteRepositories.entrySet().stream().forEach( stringStringEntry ->
- remoteRepositories.add(new RemoteRepository.Builder(stringStringEntry.getKey(), "default", stringStringEntry.getValue()).build())
- );
+ config.mavenRemoteRepositories.forEach((key, value) -> remoteRepositories.add(new RemoteRepository.Builder(key, "default", value).build()));
remoteRepositories.add(newCentralRepository());
return remoteRepositories;
}
@@ -564,7 +284,6 @@ public class DistributionTester implements Closeable
{
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
-
LocalRepository localRepo = new LocalRepository(config.mavenLocalRepository);
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
@@ -574,6 +293,62 @@ public class DistributionTester implements Closeable
return session;
}
+ public Path getJettyHome()
+ {
+ return config.jettyHome;
+ }
+
+ private static class Config
+ {
+ private Path jettyBase;
+ private Path jettyHome;
+ private String jettyVersion;
+ private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
+ private Map mavenRemoteRepositories = new HashMap<>();
+ }
+
+ /**
+ * Simple streamer for the console output from a Process
+ */
+ private class ConsoleStreamer implements Runnable
+ {
+ private final BufferedReader reader;
+ private volatile boolean stop;
+
+ public ConsoleStreamer(InputStream stream)
+ {
+ this.reader = new BufferedReader(new InputStreamReader(stream));
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ String line;
+ while ((line = reader.readLine()) != null && !stop)
+ {
+ LOGGER.info("{}", line);
+ DistributionTester.this.logs.add(line);
+ }
+ }
+ catch (IOException ignore)
+ {
+ // ignore
+ }
+ finally
+ {
+ IO.close(reader);
+ }
+ }
+
+ public void stop()
+ {
+ stop = true;
+ IO.close(reader);
+ }
+ }
+
private static class LogTransferListener extends AbstractTransferListener
{
// no op
@@ -581,138 +356,136 @@ public class DistributionTester implements Closeable
private static class LogRepositoryListener extends AbstractRepositoryListener
{
-
@Override
- public void artifactDownloaded(RepositoryEvent event) {
+ public void artifactDownloaded(RepositoryEvent event)
+ {
LOGGER.debug("distribution downloaded to {}", event.getFile());
}
@Override
- public void artifactResolved(RepositoryEvent event) {
+ public void artifactResolved(RepositoryEvent event)
+ {
LOGGER.debug("distribution resolved to {}", event.getFile());
}
}
-
- private String getJavaBin()
+ public class Run implements Closeable
{
- String javaexes[] = new String[]{"java", "java.exe"};
+ private final Process process;
- File javaHomeDir = new File(System.getProperty("java.home"));
- for (String javaexe : javaexes)
+ public Run(Process process)
{
- File javabin = new File(javaHomeDir, FS.separators("bin/" + javaexe));
- if (javabin.exists() && javabin.isFile()) {
- return javabin.getAbsolutePath();
- }
+ this.process = process;
}
- return "java";
- }
- /**
- * Stop the distribution
- */
- public void stop()
- throws IOException
- {
- long start = System.currentTimeMillis();
- while (this.pid.isAlive() && (System.currentTimeMillis() - start < config.maxWaitToStop))
+ /**
+ * Waits for the given time for the distribution to stop.
+ *
+ * @param time the time to wait
+ * @param unit the unit of time
+ * @return true if the distribution process is terminated, false if the timeout elapsed
+ * @throws InterruptedException if the wait is interrupted
+ */
+ public boolean awaitFor(long time, TimeUnit unit) throws InterruptedException
{
- this.pid.destroy();
- if (this.pid.isAlive())
- {
- // wait a bit to try again
- try
- {
- Thread.sleep(500);
- } catch (InterruptedException e)
- {
- throw new IOException(e.getMessage(),e);
- }
- }
+ boolean result = process.waitFor(time, unit);
+ if (result)
+ stopConsoleStreamers();
+ return result;
}
- // still alive so force stop
- if (this.pid.isAlive())
- {
- LOGGER.info("still alive so force destroy process");
- this.pid.destroyForcibly();
- }
- consoleStreamers.forEach(consoleStreamer -> consoleStreamer.stop=true);
- }
- /**
- * Method to use in finally block of a test and when using @After in a unit test.
- * if running, it stops the distribution.
- * Cleanup JettyBase and JettyHome directories
- */
- public void close() throws IOException
- {
- stop();
- if (httpClient != null && httpClient.isRunning()) {
- try
+ public int getExitValue()
+ {
+ return process.exitValue();
+ }
+
+ /**
+ * Stops the distribution.
+ *
+ * @see #awaitFor(long, TimeUnit)
+ */
+ public void stop()
+ {
+ process.destroy();
+ stopConsoleStreamers();
+ }
+
+ public void destroy()
+ {
+ process.destroyForcibly();
+ stopConsoleStreamers();
+ }
+
+ private void stopConsoleStreamers()
+ {
+ consoleStreamers.forEach(ConsoleStreamer::stop);
+ }
+
+ /**
+ * Method to use in finally block of a test and when using @After in a unit test.
+ * if running, it stops the distribution.
+ * Cleanup JettyBase and JettyHome directories
+ */
+ @Override
+ public void close()
+ {
+ destroy();
+ }
+
+ public boolean awaitConsoleLogsFor(String txt, long time, TimeUnit unit) throws InterruptedException
+ {
+ long end = System.nanoTime() + unit.toNanos(time);
+ while (System.nanoTime() < end)
{
- httpClient.stop();
- } catch (Exception e)
- {
- throw new IOException(e.getMessage(),e);
+ boolean result = logs.stream().anyMatch(s -> s.contains(txt));
+ if (result)
+ return true;
+ Thread.sleep(250);
}
- }
- if (Files.exists(config.jettyBase))
- {
- // cleanup jetty base
- IO.delete(config.jettyBase.toFile());
- }
- if (Files.exists(config.jettyHomeDir.toPath()))
- {
- // cleanup jetty distribution
- IO.delete(config.jettyHomeDir);
+ return false;
}
}
-
- //---------------------------------------
- // Builder class
- //---------------------------------------
public static class Builder
{
+ private Config config = new Config();
+
private Builder()
{
- // no op
}
- private Path jettyBase;
-
- private String jettyVersion;
-
- private String jettyHome;
-
- private String mavenLocalRepository;
-
- private long waitStartTime = 60;
-
- private long maxWaitToStop = 60000;
-
- private Map mavenRemoteRepositories = new HashMap<>();
-
/**
* @param jettyVersion the version to use (format: 9.4.14.v20181114 9.4.15-SNAPSHOT).
- * The distribution will be downloaded from local repository or remote
+ * The distribution will be downloaded from local repository or remote
* @return the {@link Builder}
*/
public Builder jettyVersion(String jettyVersion)
{
- this.jettyVersion = jettyVersion;
+ config.jettyVersion = jettyVersion;
return this;
}
/**
* @param jettyHome Path to the local exploded jetty distribution
- * if configured the jettyVersion parameter will not be used
+ * if configured the jettyVersion parameter will not be used
* @return the {@link Builder}
*/
- public Builder jettyHome(String jettyHome)
+ public Builder jettyHome(Path jettyHome)
{
- this.jettyHome = jettyHome;
+ config.jettyHome = jettyHome;
+ return this;
+ }
+
+ /**
+ * Sets the path for the Jetty Base directory.
+ * If the path is relative, it will be resolved against the Jetty Home directory.
+ *
+ * @param jettyBase Path to the local Jetty Base directory
+ * @return the {@link Builder}
+ */
+ public Builder jettyBase(Path jettyBase)
+ {
+ config.jettyBase = jettyBase;
return this;
}
@@ -722,41 +495,20 @@ public class DistributionTester implements Closeable
*/
public Builder mavenLocalRepository(String mavenLocalRepository)
{
- this.mavenLocalRepository = mavenLocalRepository;
+ config.mavenLocalRepository = mavenLocalRepository;
return this;
}
/**
- * @param waitStartTime the maximum time in seconds to wait the start of the distribution
- * @return the {@link Builder}
- */
- public Builder waitStartTime(long waitStartTime)
- {
- this.waitStartTime = waitStartTime;
- return this;
- }
-
- /**
- * @param maxWaitToStop the maximum time in seconds to wait after stop the distribution
- * process before forcing the stop.
- * @return the {@link Builder}
- */
- public Builder maxWaitToStop(long maxWaitToStop)
- {
- this.maxWaitToStop = maxWaitToStop;
- return this;
- }
-
- /**
- * If needed to resolve JettyDistribtion from another Maven remote repositories
+ * If needed to resolve the Jetty distribution from another Maven remote repositories
*
- * @param id the id
+ * @param id the id
* @param url the Maven remote repository url
* @return the {@link Builder}
*/
public Builder addRemoteRepository(String id, String url)
{
- this.mavenRemoteRepositories.put(id, url);
+ config.mavenRemoteRepositories.put(id, url);
return this;
}
@@ -771,21 +523,11 @@ public class DistributionTester implements Closeable
/**
* @return a new configured instance of {@link DistributionTester}
*/
- public DistributionTester build()
- throws Exception
+ public DistributionTester build() throws Exception
{
- Config config = new Config();
- config.jettyBase = jettyBase;
- config.jettyVersion = jettyVersion;
- config.jettyHome = jettyHome;
- config.mavenLocalRepository = mavenLocalRepository;
- config.waitStartTime = waitStartTime;
- config.maxWaitToStop = maxWaitToStop;
- if (!this.mavenRemoteRepositories.isEmpty())
- {
- config.mavenRemoteRepositories.putAll(this.mavenRemoteRepositories);
- }
- return new DistributionTester(config).initialise();
+ DistributionTester tester = new DistributionTester(config);
+ tester.init();
+ return tester;
}
}
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java
new file mode 100644
index 00000000000..f345b53e846
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java
@@ -0,0 +1,29 @@
+package org.eclipse.jetty.tests.distribution;
+
+import java.util.function.Supplier;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.junit.jupiter.api.AfterEach;
+
+public class AbstractDistributionTest
+{
+ protected HttpClient client;
+
+ protected void startHttpClient() throws Exception
+ {
+ startHttpClient(HttpClient::new);
+ }
+
+ protected void startHttpClient(Supplier supplier) throws Exception
+ {
+ client = supplier.get();
+ client.start();
+ }
+
+ @AfterEach
+ public void dispose() throws Exception
+ {
+ if (client != null)
+ client.stop();
+ }
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
new file mode 100644
index 00000000000..131336218ae
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
@@ -0,0 +1,210 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2019 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.
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http2.client.HTTP2Client;
+import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnJre;
+import org.junit.jupiter.api.condition.JRE;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class DistributionTests extends AbstractDistributionTest
+{
+ @Test
+ public void testStartStop() throws Exception
+ {
+ String jettyVersion = System.getProperty("jettyVersion");
+ DistributionTester distribution = DistributionTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ try (DistributionTester.Run run1 = distribution.start("--add-to-start=http"))
+ {
+ assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
+ assertEquals(0, run1.getExitValue());
+
+ int port = distribution.randomPort();
+ try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
+ {
+ assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
+
+ startHttpClient();
+ ContentResponse response = client.GET("http://localhost:" + port);
+ assertEquals(HttpStatus.NOT_FOUND_404, response.getStatus());
+
+ run2.stop();
+ assertTrue(run2.awaitFor(5, TimeUnit.SECONDS));
+ }
+ }
+ }
+
+ @Test
+ public void testSimpleWebAppWithJSP() throws Exception
+ {
+ String jettyVersion = System.getProperty("jettyVersion");
+ DistributionTester distribution = DistributionTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ String[] args1 = {
+ "--create-startd",
+ "--approve-all-licenses",
+ "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,servlet,servlets"
+ };
+ try (DistributionTester.Run run1 = distribution.start(args1))
+ {
+ assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
+ assertEquals(0, run1.getExitValue());
+
+ File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
+ distribution.installWarFile(war, "test");
+
+ int port = distribution.randomPort();
+ try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
+ {
+ assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
+
+ startHttpClient();
+ ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertThat(response.getContentAsString(), containsString("Hello"));
+ assertThat(response.getContentAsString(), not(containsString("<%")));
+ }
+ }
+ }
+
+ @Test
+ @DisabledOnJre(JRE.JAVA_8)
+ public void testSimpleWebAppWithJSPOnModulePath() throws Exception
+ {
+ String jettyVersion = System.getProperty("jettyVersion");
+ DistributionTester distribution = DistributionTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ String[] args1 = {
+ "--create-startd",
+ "--approve-all-licenses",
+ "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,servlet,servlets"
+ };
+ try (DistributionTester.Run run1 = distribution.start(args1))
+ {
+ assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
+ assertEquals(0, run1.getExitValue());
+
+ File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
+ distribution.installWarFile(war, "test");
+
+ int port = distribution.randomPort();
+ String[] args2 = {
+ "--jpms",
+ "jetty.http.port=" + port
+ };
+ try (DistributionTester.Run run2 = distribution.start(args2))
+ {
+ assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
+
+ startHttpClient();
+ ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertThat(response.getContentAsString(), containsString("Hello"));
+ assertThat(response.getContentAsString(), not(containsString("<%")));
+ }
+ }
+ }
+
+ @Test
+ @DisabledOnJre(JRE.JAVA_8)
+ public void testSimpleWebAppWithJSPOverH2C() throws Exception
+ {
+ String jettyVersion = System.getProperty("jettyVersion");
+ DistributionTester distribution = DistributionTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ String[] args1 = {
+ "--create-startd",
+ "--add-to-start=http2c,jsp,deploy"
+ };
+ try (DistributionTester.Run run1 = distribution.start(args1))
+ {
+ assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
+ assertEquals(0, run1.getExitValue());
+
+ File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
+ distribution.installWarFile(war, "test");
+
+ int port = distribution.randomPort();
+ try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
+ {
+ assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
+
+ HTTP2Client h2Client = new HTTP2Client();
+ startHttpClient(() -> new HttpClient(new HttpClientTransportOverHTTP2(h2Client), null));
+ ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertThat(response.getContentAsString(), containsString("Hello"));
+ assertThat(response.getContentAsString(), not(containsString("<%")));
+ }
+ }
+ }
+
+ @Test
+ public void testDemoBase() throws Exception
+ {
+ String jettyVersion = System.getProperty("jettyVersion");
+ DistributionTester distribution = DistributionTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .jettyBase(Paths.get("demo-base"))
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ int port = distribution.randomPort();
+ String[] args1 = {
+ "jetty.http.port=" + port
+ };
+ try (DistributionTester.Run run1 = distribution.start(args1))
+ {
+ assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS));
+
+ startHttpClient();
+ ContentResponse response = client.GET("http://localhost:" + port + "/test/jsp/dump.jsp");
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertThat(response.getContentAsString(), containsString("PathInfo"));
+ assertThat(response.getContentAsString(), not(containsString("<%")));
+ }
+ }
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
deleted file mode 100644
index a60766fe990..00000000000
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HttpModuleTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2019 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.
-// ========================================================================
-//
-
-package org.eclipse.jetty.tests.distribution;
-
-import org.junit.jupiter.api.Test;
-
-import java.io.File;
-
-public class HttpModuleTests
-{
- @Test
- public void http_module() throws Exception
- {
-
- try(DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
- .jettyVersion(System.getProperty("jetty_version")) //
- .mavenLocalRepository(System.getProperty("mavenRepoPath")) //
- .waitStartTime(30) //
- .build())
- {
- distributionTester.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
- distributionTester.stop();
-
- File war = distributionTester.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
- distributionTester.installWarFile(war, "test");
- distributionTester.start() //
- .assertLogsContains("Started @") //
- .assertUrlStatus("/test/index.jsp", 200) //
- .assertUrlContains("/test/index.jsp", "Hello");
- }
-
- }
-}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
deleted file mode 100644
index fcf8300b7f9..00000000000
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/JpmsActivatedTests.java
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2019 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.
-// ========================================================================
-//
-
-package org.eclipse.jetty.tests.distribution;
-
-import java.io.File;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.DisabledOnJre;
-import org.junit.jupiter.api.condition.JRE;
-
-public class JpmsActivatedTests
-{
- @Test
- @DisabledOnJre(JRE.JAVA_8)
- public void jpms_activated() throws Exception
- {
-
- try(DistributionTester distributionTester = DistributionTester.Builder.newInstance() //
- .jettyVersion(System.getProperty("jetty_version")) //
- .mavenLocalRepository(System.getProperty("mavenRepoPath")) //
- .waitStartTime(30) //
- .build())
- {
- distributionTester.start("--create-startd", "--approve-all-licenses", "--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,jmx-remote,servlet,servlets");
- distributionTester.stop();
-
- File war = distributionTester.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + System.getProperty("jetty_version"));
- distributionTester.installWarFile(war, "test");
- distributionTester.start("--jpms") //
- .assertLogsContains("Started @") //
- .assertUrlStatus("/test/index.jsp", 200)
- .assertUrlContains("/test/index.jsp", "Hello");
- }
-
- }
-}
diff --git a/tests/test-distribution/src/test/resources/index.html b/tests/test-distribution/src/test/resources/index.html
deleted file mode 100644
index 97fa4767509..00000000000
--- a/tests/test-distribution/src/test/resources/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Some content here
\ No newline at end of file
diff --git a/tests/test-distribution/src/test/resources/jetty-logging.properties b/tests/test-distribution/src/test/resources/jetty-logging.properties
new file mode 100644
index 00000000000..d96a696f82e
--- /dev/null
+++ b/tests/test-distribution/src/test/resources/jetty-logging.properties
@@ -0,0 +1,2 @@
+org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
+#org.eclipse.jetty.LEVEL=DEBUG
diff --git a/tests/test-distribution/src/test/resources/static_content.xml b/tests/test-distribution/src/test/resources/static_content.xml
deleted file mode 100644
index 87312cdbaac..00000000000
--- a/tests/test-distribution/src/test/resources/static_content.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
- /scratch
-
-
-
- true
-
-
-
\ No newline at end of file
From 3c665dfc1c0df47613982d94fd6854ad64ccbc96 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Mon, 11 Feb 2019 21:36:14 +0100
Subject: [PATCH 10/14] Issue #3343 - Add an API/tools to be able to test Jetty
Distribution.
Added missing license header.
Signed-off-by: Simone Bordet
---
.../distribution/AbstractDistributionTest.java | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java
index f345b53e846..1050918ed13 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractDistributionTest.java
@@ -1,3 +1,21 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2019 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.
+// ========================================================================
+//
+
package org.eclipse.jetty.tests.distribution;
import java.util.function.Supplier;
From 9c59db6fdd917bc7b50af9a72db06b062edc357d Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Mon, 11 Feb 2019 21:41:29 +0100
Subject: [PATCH 11/14] Issue #3343 - Add an API/tools to be able to test Jetty
Distribution.
Updated maven.version to 3.6.0.
Signed-off-by: Simone Bordet
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 618abf07342..a2f6ebbe413 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,7 @@
1.2.0
1.1.5
5.3.1
- 3.5.0
+ 3.6.0
3.1.0
2.4.5.Final
1.0.5
From a1a02d99420ede9af8af956414a04a4c399a6636 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Tue, 12 Feb 2019 12:25:57 +1000
Subject: [PATCH 12/14] fix CI test, distribution must be build first as we
want to use a fresh build of the distro
Signed-off-by: olivier lamy
---
tests/test-distribution/pom.xml | 6 ++++++
.../jetty/tests/distribution/DistributionTester.java | 8 ++++++++
2 files changed, 14 insertions(+)
diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml
index a2e8a386e72..81887312760 100644
--- a/tests/test-distribution/pom.xml
+++ b/tests/test-distribution/pom.xml
@@ -16,6 +16,12 @@
+
+ org.eclipse.jetty
+ jetty-distribution
+ ${project.version}
+ zip
+
org.slf4j
slf4j-simple
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
index 3a29dff86fa..64ea31fac53 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
@@ -305,6 +305,14 @@ public class DistributionTester
private String jettyVersion;
private String mavenLocalRepository = System.getProperty("user.home") + "/.m2/repository";
private Map mavenRemoteRepositories = new HashMap<>();
+
+ @Override
+ public String toString()
+ {
+ return "Config{" + "jettyBase=" + jettyBase + ", jettyHome=" + jettyHome + ", jettyVersion='" + jettyVersion
+ + '\'' + ", mavenLocalRepository='" + mavenLocalRepository + '\'' + ", mavenRemoteRepositories="
+ + mavenRemoteRepositories + '}';
+ }
}
/**
From 2d88b3b9597b3b5ffea80b60a421b0fdf948a128 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Tue, 12 Feb 2019 09:04:45 +0100
Subject: [PATCH 13/14] Issue #3343 - Add an API/tools to be able to test Jetty
Distribution.
Refactored streamers into class Run.
Added javadocs.
Moved "maven.resolver.version" to main POM for consistency.
Signed-off-by: Simone Bordet
---
pom.xml | 1 +
tests/test-distribution/pom.xml | 7 +-
.../distribution/DistributionTester.java | 216 +++++++++++-------
.../tests/distribution/DistributionTests.java | 15 +-
4 files changed, 148 insertions(+), 91 deletions(-)
diff --git a/pom.xml b/pom.xml
index a2f6ebbe413..8a9f39dab55 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,6 +35,7 @@
1.1.5
5.3.1
3.6.0
+ 1.3.1
3.1.0
2.4.5.Final
1.0.5
diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml
index 81887312760..3a938007a0c 100644
--- a/tests/test-distribution/pom.xml
+++ b/tests/test-distribution/pom.xml
@@ -12,7 +12,6 @@
${project.groupId}.tests.distribution
- 1.3.1
@@ -43,17 +42,17 @@
org.apache.maven.resolver
maven-resolver-connector-basic
- ${mavenResolver.version}
+ ${maven.resolver.version}
org.apache.maven.resolver
maven-resolver-transport-file
- ${mavenResolver.version}
+ ${maven.resolver.version}
org.apache.maven.resolver
maven-resolver-transport-http
- ${mavenResolver.version}
+ ${maven.resolver.version}
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
index 64ea31fac53..57571c4d0c0 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/DistributionTester.java
@@ -67,14 +67,46 @@ import org.eclipse.jetty.util.log.Logger;
/**
* Helper class to test the Jetty Distribution
.
* API can change without any further notice.
+ * Usage:
+ *
+ * // Create the distribution.
+ * String jettyVersion = "9.4.14.v20181114";
+ * DistributionTester distribution = DistributionTester.Builder.newInstance()
+ * .jettyVersion(jettyVersion)
+ * .jettyBase(Paths.get("demo-base"))
+ * .build();
+ *
+ * // The first run initializes the Jetty Base.
+ * try (DistributionTester.Run run1 = distribution.start("--create-startd", "--add-to-start=http2c,jsp,deploy"))
+ * {
+ * assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
+ * assertEquals(0, run1.getExitValue());
+ *
+ * // Install a web application.
+ * File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
+ * distribution.installWarFile(war, "test");
+ *
+ * // The second run starts the distribution.
+ * int port = 9090;
+ * try (DistributionTester.Run run = distribution.start("jetty.http.port=" + port))
+ * {
+ * // Wait for Jetty to be fully started.
+ * assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS));
+ *
+ * // Make a HTTP request to the web application.
+ * HttpClient client = new HttpClient();
+ * client.start();
+ * ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
+ * assertEquals(HttpStatus.OK_200, response.getStatus());
+ * }
+ * }
+ *
*/
public class DistributionTester
{
private static final Logger LOGGER = Log.getLogger(DistributionTester.class);
private Config config;
- private List consoleStreamers = new ArrayList<>();
- private List logs = new ArrayList<>();
private DistributionTester(Config config)
{
@@ -82,7 +114,7 @@ public class DistributionTester
}
/**
- * Starts the instance with the given arguments
+ * Starts the distribution with the given arguments
*
* @param args arguments to use to start the distribution
*/
@@ -92,16 +124,12 @@ public class DistributionTester
}
/**
- * Start the instance with the arguments
+ * Start the distribution with the arguments
*
* @param args arguments to use to start the distribution
*/
public DistributionTester.Run start(List args) throws Exception
{
- // do we want to be sure and use "--testing-mode" to not break surefire with a System.exit ???
-
- logs.clear();
-
List commands = new ArrayList<>();
commands.add(getJavaExecutable());
commands.add("-jar");
@@ -116,13 +144,14 @@ public class DistributionTester
pbCmd.directory(workingDir);
Process process = pbCmd.start();
- consoleStreamers.add(startPump("STDOUT", process.getInputStream()));
- consoleStreamers.add(startPump("STDERR", process.getErrorStream()));
-
return new Run(process);
}
- public int randomPort() throws IOException
+ /**
+ * @return a free port chosen by the OS that can be used to listen to
+ * @throws IOException if a free port is not available
+ */
+ public int freePort() throws IOException
{
try (ServerSocket server = new ServerSocket())
{
@@ -132,6 +161,13 @@ public class DistributionTester
}
}
+ /**
+ * Installs in {@code ${jetty.base}/webapps} the given war file under the given context path.
+ *
+ * @param warFile the war file to install
+ * @param context the context path
+ * @throws IOException if the installation fails
+ */
public void installWarFile(File warFile, String context) throws IOException
{
//webapps
@@ -142,8 +178,11 @@ public class DistributionTester
}
/**
+ * Resolves an artifact given its Maven coordinates.
+ *
* @param coordinates :[:[:]]:
* @return the artifact
+ * @see #installWarFile(File, String)
*/
public File resolveArtifact(String coordinates) throws ArtifactResolutionException
{
@@ -191,14 +230,6 @@ public class DistributionTester
return "java";
}
- private ConsoleStreamer startPump(String mode, InputStream stream)
- {
- ConsoleStreamer pump = new ConsoleStreamer(stream);
- Thread thread = new Thread(pump, "ConsoleStreamer/" + mode);
- thread.start();
- return pump;
- }
-
private void unzip(File zipFile, File output) throws IOException
{
try (InputStream fileInputStream = Files.newInputStream(zipFile.toPath());
@@ -293,11 +324,6 @@ public class DistributionTester
return session;
}
- public Path getJettyHome()
- {
- return config.jettyHome;
- }
-
private static class Config
{
private Path jettyBase;
@@ -309,51 +335,14 @@ public class DistributionTester
@Override
public String toString()
{
- return "Config{" + "jettyBase=" + jettyBase + ", jettyHome=" + jettyHome + ", jettyVersion='" + jettyVersion
- + '\'' + ", mavenLocalRepository='" + mavenLocalRepository + '\'' + ", mavenRemoteRepositories="
- + mavenRemoteRepositories + '}';
- }
- }
-
- /**
- * Simple streamer for the console output from a Process
- */
- private class ConsoleStreamer implements Runnable
- {
- private final BufferedReader reader;
- private volatile boolean stop;
-
- public ConsoleStreamer(InputStream stream)
- {
- this.reader = new BufferedReader(new InputStreamReader(stream));
- }
-
- @Override
- public void run()
- {
- try
- {
- String line;
- while ((line = reader.readLine()) != null && !stop)
- {
- LOGGER.info("{}", line);
- DistributionTester.this.logs.add(line);
- }
- }
- catch (IOException ignore)
- {
- // ignore
- }
- finally
- {
- IO.close(reader);
- }
- }
-
- public void stop()
- {
- stop = true;
- IO.close(reader);
+ return String.format("%s@%x{jettyBase=%s, jettyHome=%s, jettyVersion=%s, mavenLocalRepository=%s, mavenRemoteRepositories=%s}",
+ getClass().getSimpleName(),
+ hashCode(),
+ jettyBase,
+ jettyHome,
+ jettyVersion,
+ mavenLocalRepository,
+ mavenRemoteRepositories);
}
}
@@ -377,17 +366,32 @@ public class DistributionTester
}
}
- public class Run implements Closeable
+ /**
+ * A distribution run wraps the process that started the Jetty distribution.
+ */
+ public static class Run implements Closeable
{
private final Process process;
+ private final List consoleStreamers = new ArrayList<>();
+ private final List logs = new ArrayList<>();
- public Run(Process process)
+ private Run(Process process)
{
this.process = process;
+ consoleStreamers.add(startPump("STDOUT", process.getInputStream()));
+ consoleStreamers.add(startPump("STDERR", process.getErrorStream()));
+ }
+
+ private ConsoleStreamer startPump(String mode, InputStream stream)
+ {
+ ConsoleStreamer pump = new ConsoleStreamer(stream);
+ Thread thread = new Thread(pump, "ConsoleStreamer/" + mode);
+ thread.start();
+ return pump;
}
/**
- * Waits for the given time for the distribution to stop.
+ * Waits for the given time for the distribution process to stop.
*
* @param time the time to wait
* @param unit the unit of time
@@ -402,13 +406,17 @@ public class DistributionTester
return result;
}
- public int getExitValue()
+ /**
+ * @return the distribution process exit value
+ * @throws IllegalThreadStateException if the distribution process is not terminated yet
+ */
+ public int getExitValue() throws IllegalThreadStateException
{
return process.exitValue();
}
/**
- * Stops the distribution.
+ * Stops the distribution process.
*
* @see #awaitFor(long, TimeUnit)
*/
@@ -418,6 +426,9 @@ public class DistributionTester
stopConsoleStreamers();
}
+ /**
+ * Forcibly destroys the distribution process.
+ */
public void destroy()
{
process.destroyForcibly();
@@ -430,9 +441,7 @@ public class DistributionTester
}
/**
- * Method to use in finally block of a test and when using @After in a unit test.
- * if running, it stops the distribution.
- * Cleanup JettyBase and JettyHome directories
+ * @see #destroy()
*/
@Override
public void close()
@@ -440,6 +449,15 @@ public class DistributionTester
destroy();
}
+ /**
+ * Awaits the console logs to contain the given text, for the given amount of time.
+ *
+ * @param txt the text that must be present in the console logs
+ * @param time the time to wait
+ * @param unit the unit of time
+ * @return true if the text was found, false if the timeout elapsed
+ * @throws InterruptedException if the wait is interrupted
+ */
public boolean awaitConsoleLogsFor(String txt, long time, TimeUnit unit) throws InterruptedException
{
long end = System.nanoTime() + unit.toNanos(time);
@@ -452,6 +470,48 @@ public class DistributionTester
}
return false;
}
+
+ /**
+ * Simple streamer for the console output from a Process
+ */
+ private class ConsoleStreamer implements Runnable
+ {
+ private final BufferedReader reader;
+ private volatile boolean stop;
+
+ public ConsoleStreamer(InputStream stream)
+ {
+ this.reader = new BufferedReader(new InputStreamReader(stream));
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ String line;
+ while ((line = reader.readLine()) != null && !stop)
+ {
+ LOGGER.info("{}", line);
+ logs.add(line);
+ }
+ }
+ catch (IOException ignore)
+ {
+ // ignore
+ }
+ finally
+ {
+ IO.close(reader);
+ }
+ }
+
+ public void stop()
+ {
+ stop = true;
+ IO.close(reader);
+ }
+ }
}
public static class Builder
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
index 131336218ae..11718fed86f 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
@@ -53,7 +53,7 @@ public class DistributionTests extends AbstractDistributionTest
assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- int port = distribution.randomPort();
+ int port = distribution.freePort();
try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
@@ -90,7 +90,7 @@ public class DistributionTests extends AbstractDistributionTest
File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
distribution.installWarFile(war, "test");
- int port = distribution.randomPort();
+ int port = distribution.freePort();
try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
@@ -127,7 +127,7 @@ public class DistributionTests extends AbstractDistributionTest
File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
distribution.installWarFile(war, "test");
- int port = distribution.randomPort();
+ int port = distribution.freePort();
String[] args2 = {
"--jpms",
"jetty.http.port=" + port
@@ -167,7 +167,7 @@ public class DistributionTests extends AbstractDistributionTest
File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
distribution.installWarFile(war, "test");
- int port = distribution.randomPort();
+ int port = distribution.freePort();
try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
@@ -192,11 +192,8 @@ public class DistributionTests extends AbstractDistributionTest
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
- int port = distribution.randomPort();
- String[] args1 = {
- "jetty.http.port=" + port
- };
- try (DistributionTester.Run run1 = distribution.start(args1))
+ int port = distribution.freePort();
+ try (DistributionTester.Run run1 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS));
From 265cc79225faa47bd638961e98e5f7850ac686d2 Mon Sep 17 00:00:00 2001
From: olivier lamy
Date: Tue, 12 Feb 2019 18:22:39 +1000
Subject: [PATCH 14/14] jetty-distribution is test scope
Signed-off-by: olivier lamy
---
tests/test-distribution/pom.xml | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml
index 3a938007a0c..84002f6b15c 100644
--- a/tests/test-distribution/pom.xml
+++ b/tests/test-distribution/pom.xml
@@ -15,12 +15,6 @@
-
- org.eclipse.jetty
- jetty-distribution
- ${project.version}
- zip
-
org.slf4j
slf4j-simple
@@ -55,6 +49,13 @@
${maven.resolver.version}
+
+ org.eclipse.jetty
+ jetty-distribution
+ ${project.version}
+ zip
+ test
+
org.eclipse.jetty
jetty-client