diff --git a/documentation/jetty-asciidoctor-extensions/pom.xml b/documentation/jetty-asciidoctor-extensions/pom.xml
index 102bb0241c2..f2f65498407 100644
--- a/documentation/jetty-asciidoctor-extensions/pom.xml
+++ b/documentation/jetty-asciidoctor-extensions/pom.xml
@@ -37,7 +37,7 @@
org.eclipse.jetty.tests
- jetty-home-tester
+ jetty-testers
compile
diff --git a/documentation/jetty-asciidoctor-extensions/src/main/java/org/eclipse/jetty/docs/JettyIncludeExtension.java b/documentation/jetty-asciidoctor-extensions/src/main/java/org/eclipse/jetty/docs/JettyIncludeExtension.java
index 35d7abb9d16..5e7527cc2e1 100644
--- a/documentation/jetty-asciidoctor-extensions/src/main/java/org/eclipse/jetty/docs/JettyIncludeExtension.java
+++ b/documentation/jetty-asciidoctor-extensions/src/main/java/org/eclipse/jetty/docs/JettyIncludeExtension.java
@@ -29,7 +29,7 @@ import org.asciidoctor.ast.Document;
import org.asciidoctor.extension.IncludeProcessor;
import org.asciidoctor.extension.PreprocessorReader;
import org.asciidoctor.jruby.extension.spi.ExtensionRegistry;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
/**
*
Asciidoctor include extension that includes into
diff --git a/pom.xml b/pom.xml
index 2f87b9c24cb..06ebc357a5c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -873,12 +873,12 @@
org.eclipse.jetty.tests
- jetty-home-tester
+ jetty-test-session-common
${project.version}
org.eclipse.jetty.tests
- jetty-test-session-common
+ jetty-testers
${project.version}
diff --git a/tests/jetty-home-tester/pom.xml b/tests/jetty-home-tester/pom.xml
deleted file mode 100644
index 572e27e9291..00000000000
--- a/tests/jetty-home-tester/pom.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
- 4.0.0
-
- org.eclipse.jetty.tests
- tests
- 12.0.6-SNAPSHOT
-
- jetty-home-tester
- jar
- Tests :: Home Tester
-
-
- ${project.groupId}.hometester
-
-
-
-
- jakarta.inject
- jakarta.inject-api
- 1.0.5
-
-
- org.apache.maven
- maven-artifact
-
-
-
- org.apache.maven
- maven-resolver-provider
-
-
- org.apache.maven.resolver
- maven-resolver-api
- ${maven.resolver.version}
-
-
- org.apache.maven.resolver
- maven-resolver-connector-basic
- ${maven.resolver.version}
-
-
- org.apache.maven.resolver
- maven-resolver-impl
- ${maven.resolver.version}
-
-
-
- javax.annotation
- javax.annotation-api
-
-
-
-
- org.apache.maven.resolver
- maven-resolver-spi
- ${maven.resolver.version}
-
-
- org.apache.maven.resolver
- maven-resolver-supplier
- ${maven.resolver.version}
-
-
- org.apache.maven.resolver
- maven-resolver-transport-file
- ${maven.resolver.version}
-
-
- org.apache.maven.resolver
- maven-resolver-transport-http
- ${maven.resolver.version}
-
-
- org.apache.maven.resolver
- maven-resolver-util
- ${maven.resolver.version}
-
-
- org.awaitility
- awaitility
-
-
- org.eclipse.jetty.toolchain
- jetty-test-helper
- compile
-
-
- org.junit.jupiter
- junit-jupiter
- compile
-
-
- org.slf4j
- slf4j-api
-
-
-
-
diff --git a/tests/jetty-home-tester/src/main/java/org/eclipse/jetty/tests/hometester/JettyHomeTester.java b/tests/jetty-home-tester/src/main/java/org/eclipse/jetty/tests/hometester/JettyHomeTester.java
deleted file mode 100644
index eb7e49faa19..00000000000
--- a/tests/jetty-home-tester/src/main/java/org/eclipse/jetty/tests/hometester/JettyHomeTester.java
+++ /dev/null
@@ -1,838 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.tests.hometester;
-
-import java.io.BufferedReader;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.RandomAccessFile;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.URI;
-import java.nio.file.CopyOption;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-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.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Stream;
-
-import org.apache.maven.model.building.ModelBuilder;
-import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
-import org.awaitility.core.ConditionTimeoutException;
-import org.codehaus.plexus.util.StringUtils;
-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.impl.RemoteRepositoryManager;
-import org.eclipse.aether.impl.UpdatePolicyAnalyzer;
-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.checksum.ChecksumPolicyProvider;
-import org.eclipse.aether.supplier.RepositorySystemSupplier;
-import org.eclipse.aether.transfer.AbstractTransferListener;
-import org.eclipse.jetty.toolchain.test.FS;
-import org.eclipse.jetty.toolchain.test.IO;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.awaitility.Awaitility.await;
-
-/**
- * Helper class to test the Jetty Distribution
.
- * API can change without any further notice.
- * Usage:
- * {@code
- * // 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-start-ini", "--add-modules=http2c,jsp,deploy"))
- * {
- * assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
- * assertEquals(0, run1.getExitValue());
- *
- * // Install a web application.
- * File war = distribution.resolveArtifact("org.eclipse.jetty.demos:demo-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 an HTTP request to the web application.
- * HttpClient client = new HttpClient();
- * client.start();
- * ContentResponse response = client.GET("http://localhost:" + port + "/test/index.html");
- * assertEquals(HttpStatus.OK_200, response.getStatus());
- * }
- * }
- * }
- */
-public class JettyHomeTester
-{
- private static final Logger LOGGER = LoggerFactory.getLogger(JettyHomeTester.class);
-
- private static final CopyOption[] EMPTY_OPTIONS = new CopyOption[]{};
-
- private final Config config;
-
- private JettyHomeTestsRepositorySystemSupplier jettyHomeTestsRepositorySystemSupplier = new JettyHomeTestsRepositorySystemSupplier();
-
- private JettyHomeTester(Config config)
- {
- this.config = config;
- }
-
- /**
- * Starts the distribution with the given arguments
- *
- * @param args arguments to use to start the distribution
- */
- public JettyHomeTester.Run start(String... args) throws Exception
- {
- return start(Arrays.asList(args));
- }
-
- public Path getJettyBase()
- {
- return config.getJettyBase();
- }
-
- public Path getJettyHome()
- {
- return config.getJettyHome();
- }
-
- /**
- * Start the distribution with the arguments
- *
- * @param args arguments to use to start the distribution
- */
- public JettyHomeTester.Run start(List args) throws Exception
- {
- File jettyBaseDir = getJettyBase().toFile();
- Path workDir = Files.createDirectories(jettyBaseDir.toPath().resolve("work"));
-
- List commands = new ArrayList<>();
- commands.add(getJavaExecutable());
- commands.addAll(config.getJVMArgs());
- commands.add("-Djava.io.tmpdir=" + workDir.toAbsolutePath());
- int debugPort = Integer.getInteger("distribution.debug.port", 0);
- if (debugPort > 0)
- {
- commands.add("-Xdebug");
- commands.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=" + debugPort);
- }
- commands.add("-jar");
- commands.add(config.jettyHome.toAbsolutePath() + "/start.jar");
-
- args = new ArrayList<>(args);
-
- String mavenLocalRepository = config.getMavenLocalRepository();
- if (StringUtils.isNotBlank(mavenLocalRepository))
- mavenLocalRepository = System.getProperty("mavenRepoPath");
- if (StringUtils.isNotBlank(mavenLocalRepository))
- args.add("maven.local.repo=" + mavenLocalRepository);
-
- // if this JVM has `maven.repo.uri` defined, make sure to propagate it to child
- String remoteRepoUri = System.getProperty("maven.repo.uri");
- if (remoteRepoUri != null)
- {
- args.add("maven.repo.uri=" + remoteRepoUri);
- }
-
- commands.addAll(args);
-
- LOGGER.info("Executing: {}", commands);
- LOGGER.info("Working Dir: {}", jettyBaseDir.getAbsolutePath());
-
- ProcessBuilder pbCmd = new ProcessBuilder(commands);
- pbCmd.directory(jettyBaseDir);
- pbCmd.environment().putAll(config.env);
- Process process = pbCmd.start();
-
- return new Run(config, process);
- }
-
- /**
- * @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())
- {
- server.setReuseAddress(true);
- server.bind(new InetSocketAddress("localhost", 0));
- return server.getLocalPort();
- }
- }
-
- /**
- * Installs in {@code ${jetty.base}/webapps} the given war file under the given context path.
- *
- * @param testResourcePath the location of the source file in {@code src/test/resources}
- * @param baseResourcePath the location of the destination file in {@code ${jetty.base}}
- * @param options optional CopyOption
- * @throws IOException if the installation fails
- */
- public void installBaseResource(String testResourcePath, String baseResourcePath, CopyOption... options) throws IOException
- {
- Path srcFile = MavenTestingUtils.getTestResourcePath(testResourcePath);
- Path destFile = config.jettyBase.resolve(baseResourcePath);
- Files.deleteIfExists(destFile);
- if (!Files.exists(destFile.getParent()))
- Files.createDirectories(destFile.getParent());
-
- Files.copy(srcFile, destFile, options);
- }
-
- /**
- * 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
- * @return the path to the installed webapp exploded directory
- * @throws IOException if the installation fails
- */
- public Path installWarFile(File warFile, String context) throws IOException
- {
- //webapps
- Path webapps = config.jettyBase.resolve("webapps").resolve(context);
- if (!Files.exists(webapps))
- Files.createDirectories(webapps);
- unzip(warFile.toPath(), webapps);
- return webapps;
- }
-
- /**
- * Resolves an artifact given its Maven coordinates.
- *
- * @param coordinates <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>
- * @return the artifact
- * @see #installWarFile(File, String)
- */
- public File resolveArtifact(String coordinates) throws ArtifactResolutionException
- {
- RepositorySystem repositorySystem = this.jettyHomeTestsRepositorySystemSupplier.get();
-
- Artifact artifact = new DefaultArtifact(coordinates);
-
- RepositorySystemSession session = newRepositorySystemSession(repositorySystem);
-
- ArtifactRequest artifactRequest = new ArtifactRequest();
- artifactRequest.setArtifact(artifact);
- artifactRequest.setRepositories(newRepositories());
- ArtifactResult artifactResult = repositorySystem.resolveArtifact(session, artifactRequest);
-
- artifact = artifactResult.getArtifact();
- return artifact.getFile();
- }
-
- private void init() throws Exception
- {
- if (config.jettyHome == null)
- config.jettyHome = resolveHomeArtifact(config.getJettyVersion());
-
- if (config.jettyBase == null)
- {
- Path bases = MavenTestingUtils.getTargetTestingPath("bases");
- FS.ensureDirExists(bases);
- config.jettyBase = Files.createTempDirectory(bases, "jetty_base_");
- }
- else
- {
- if (!config.jettyBase.isAbsolute())
- {
- throw new IllegalStateException("Jetty Base is not an absolute path: " + config.jettyBase);
- }
- }
- }
-
- private String getJavaExecutable()
- {
- String[] javaExecutables = new String[]{"java", "java.exe"};
- Path javaBinDir = Paths.get(System.getProperty("java.home")).resolve("bin");
- for (String javaExecutable : javaExecutables)
- {
- Path javaFile = javaBinDir.resolve(javaExecutable);
- if (Files.exists(javaFile) && Files.isRegularFile(javaFile))
- return javaFile.toAbsolutePath().toString();
- }
- return "java";
- }
-
- public static synchronized void unzip(Path archive, Path outputDir) throws IOException
- {
- if (!Files.exists(outputDir))
- throw new FileNotFoundException("Directory does not exist: " + outputDir);
-
- if (!Files.isDirectory(outputDir))
- throw new FileNotFoundException("Not a directory: " + outputDir);
-
- Map env = new HashMap<>();
- env.put("releaseVersion", null); // no MultiRelease Jar file behaviors
-
- URI outputDirURI = outputDir.toUri();
- URI archiveURI = URI.create("jar:" + archive.toUri().toASCIIString());
-
- try (FileSystem fs = FileSystems.newFileSystem(archiveURI, env))
- {
- Path root = fs.getPath("/");
- int archiveURISubIndex = root.toUri().toASCIIString().indexOf("!/") + 2;
- try (Stream entriesStream = Files.walk(root))
- {
- // ensure proper unpack order (eg: directories before files)
- List sorted = entriesStream
- .sorted()
- .toList();
-
- for (Path path : sorted)
- {
- URI entryURI = path.toUri();
- String subURI = entryURI.toASCIIString().substring(archiveURISubIndex);
- URI outputPathURI = outputDirURI.resolve(subURI);
- Path outputPath = Path.of(outputPathURI);
- if (Files.isDirectory(path))
- {
- if (!Files.exists(outputPath))
- Files.createDirectory(outputPath);
- }
- else
- {
- Files.copy(path, outputPath);
- }
- }
- }
- }
- catch (FileAlreadyExistsException e)
- {
- LOGGER.warn("ignore FileAlreadyExistsException: archiveURI {}, outputDir {}", archiveURI, outputDir);
- }
- }
-
- private Path resolveHomeArtifact(String version) throws Exception
- {
- Path artifactFile = resolveArtifact("org.eclipse.jetty:jetty-home:zip:" + version).toPath();
-
- // create tmp directory to unzip distribution
- Path homes = MavenTestingUtils.getTargetTestingPath("homes");
- FS.ensureDirExists(homes);
- Path tmp = Files.createDirectories(homes.resolve(Long.toString(artifactFile.toFile().lastModified())));
- Path home = tmp.resolve("jetty-home-" + version);
- if (!Files.exists(home))
- {
- unzip(artifactFile, tmp);
- }
-
- return home;
- }
-
- private List newRepositories()
- {
- List remoteRepositories = new ArrayList<>(config.mavenRemoteRepositories.size() + 1);
- config.mavenRemoteRepositories.forEach((key, value) -> remoteRepositories.add(new RemoteRepository.Builder(key, "default", value).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)
- {
- DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
-
- LocalRepository localRepo = new LocalRepository(config.mavenLocalRepository);
- session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
-
- session.setTransferListener(new LogTransferListener());
- session.setRepositoryListener(new LogRepositoryListener());
-
- return session;
- }
-
- public static class Config
- {
- private final Map mavenRemoteRepositories = new HashMap<>();
- private Path jettyBase;
- private Path jettyHome;
- private String jettyVersion;
- private String mavenLocalRepository = System.getProperty("mavenRepoPath", System.getProperty("user.home") + "/.m2/repository");
- private List jvmArgs = new ArrayList<>();
- private Map env = new HashMap<>();
-
- public Path getJettyBase()
- {
- return jettyBase;
- }
-
- public Path getJettyHome()
- {
- return jettyHome;
- }
-
- public String getJettyVersion()
- {
- return jettyVersion;
- }
-
- public String getMavenLocalRepository()
- {
- return mavenLocalRepository;
- }
-
- public List getJVMArgs()
- {
- return Collections.unmodifiableList(jvmArgs);
- }
-
- public Map getEnv()
- {
- return Collections.unmodifiableMap(env);
- }
-
- @Override
- public String toString()
- {
- return String.format("%s@%x{jettyBase=%s, jettyHome=%s, jettyVersion=%s, mavenLocalRepository=%s, mavenRemoteRepositories=%s}",
- getClass().getSimpleName(),
- hashCode(),
- jettyBase,
- jettyHome,
- jettyVersion,
- mavenLocalRepository,
- mavenRemoteRepositories);
- }
- }
-
- 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());
- }
- }
-
- /**
- * A distribution run wraps the process that started the Jetty distribution.
- */
- public static class Run implements Closeable
- {
- private final Config config;
- private final Process process;
- private final List consoleStreamers = new ArrayList<>();
- private final Queue logs = new ConcurrentLinkedQueue<>();
-
- private Run(Config config, Process process)
- {
- this.config = config;
- this.process = process;
- consoleStreamers.add(startPump("STDOUT", process.getInputStream()));
- consoleStreamers.add(startPump("STDERR", process.getErrorStream()));
- }
-
- public Config getConfig()
- {
- return config;
- }
-
- 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 process 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
- {
- boolean result = process.waitFor(time, unit);
- if (result)
- stopConsoleStreamers();
- return result;
- }
-
- /**
- * @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 process.
- *
- * @see #awaitFor(long, TimeUnit)
- */
- public void stop()
- {
- process.destroy();
- stopConsoleStreamers();
- }
-
- /**
- * Forcibly destroys the distribution process.
- */
- public void destroy()
- {
- process.destroyForcibly();
- stopConsoleStreamers();
- }
-
- private void stopConsoleStreamers()
- {
- consoleStreamers.forEach(ConsoleStreamer::stop);
- }
-
- @Override
- public void close()
- {
- stop();
- // delete the content of temporary base and home?
- //IO.delete(this.config.getJettyBase());
- //IO.delete(this.config.getJettyHome().getParent());
- }
-
- /**
- * 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
- {
- try
- {
- await().atMost(time, unit).until(() -> logs.stream().anyMatch(s -> s.contains(txt)));
- return true;
- }
- catch (ConditionTimeoutException e)
- {
- return false;
- }
- }
-
- /**
- * Awaits the logs file to contain the given text, for the given amount of time.
- *
- * @param logFile the log file to test
- * @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 awaitLogsFileFor(Path logFile, String txt, long time, TimeUnit unit) throws InterruptedException
- {
- LogFileStreamer logFileStreamer = new LogFileStreamer(logFile);
- Thread thread = new Thread(logFileStreamer, "LogFileStreamer/" + logFile);
- thread.start();
- try
- {
- await().atMost(time, unit).until(() -> logs.stream().anyMatch(s -> s.contains(txt)));
- return true;
- }
- catch (ConditionTimeoutException e)
- {
- return false;
- }
- finally
- {
- logFileStreamer.stop();
- }
- }
-
- /**
- * 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);
- }
- }
-
- private class LogFileStreamer implements Runnable
- {
- private RandomAccessFile inputFile;
- private volatile boolean stop;
- private final Path logFile;
-
- public LogFileStreamer(Path logFile)
- {
- this.logFile = logFile;
- }
-
- @Override
- public void run()
- {
- String currentLine;
- long pos = 0;
- while (!stop)
- {
- try
- {
- inputFile = new RandomAccessFile(logFile.toFile(), "r");
- inputFile.seek(pos);
- if ((currentLine = inputFile.readLine()) != null)
- {
- logs.add(currentLine);
- }
- pos = inputFile.getFilePointer();
- }
- catch (IOException e)
- {
- //ignore
- }
- finally
- {
- IO.close(inputFile);
- }
- }
- }
-
- public void stop()
- {
- stop = true;
- IO.close(inputFile);
- }
- }
-
- public Queue getLogs()
- {
- return logs;
- }
- }
-
- public static class Builder
- {
- private final Config config = new Config();
-
- private Builder()
- {
- }
-
- /**
- * @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 this Builder
- */
- public Builder jettyVersion(String jettyVersion)
- {
- config.jettyVersion = jettyVersion;
- return this;
- }
-
- /**
- * @param jettyHome Path to the local exploded jetty distribution
- * if configured the jettyVersion parameter will not be used
- * @return this Builder
- */
- public Builder jettyHome(Path 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 this Builder
- */
- public Builder jettyBase(Path jettyBase)
- {
- config.jettyBase = jettyBase;
- return this;
- }
-
- /**
- * @param mavenLocalRepository Path to the local maven repository
- * @return this Builder
- */
- public Builder mavenLocalRepository(String mavenLocalRepository)
- {
- if (StringUtils.isBlank(mavenLocalRepository))
- return this;
-
- config.mavenLocalRepository = mavenLocalRepository;
- return this;
- }
-
- /**
- * If needed to resolve the Jetty distribution from another Maven remote repositories
- *
- * @param id the id
- * @param url the Maven remote repository url
- * @return this Builder
- */
- public Builder addRemoteRepository(String id, String url)
- {
- config.mavenRemoteRepositories.put(id, url);
- return this;
- }
-
- /**
- * @param jvmArgs the jvm args to add
- * @return this Builder
- */
- public Builder jvmArgs(List jvmArgs)
- {
- config.jvmArgs = jvmArgs;
- return this;
- }
-
- /**
- * @param env the env to add
- * @return this Builder
- */
- public Builder env(Map env)
- {
- config.env = env;
- return this;
- }
-
- /**
- * @return an empty instance of Builder
- */
- public static Builder newInstance()
- {
- return new Builder();
- }
-
- /**
- * @return a new configured instance of {@link JettyHomeTester}
- */
- public JettyHomeTester build() throws Exception
- {
- JettyHomeTester tester = new JettyHomeTester(config);
- tester.init();
- return tester;
- }
- }
-
- private static class JettyHomeTestsRepositorySystemSupplier extends RepositorySystemSupplier
- {
-
- ModelBuilder modelBuilder;
-
- RemoteRepositoryManager remoteRepositoryManager;
-
- @Override
- protected ModelBuilder getModelBuilder()
- {
- modelBuilder = super.getModelBuilder();
- return modelBuilder;
- }
-
- @Override
- protected RemoteRepositoryManager getRemoteRepositoryManager(
- UpdatePolicyAnalyzer updatePolicyAnalyzer, ChecksumPolicyProvider checksumPolicyProvider)
- {
- remoteRepositoryManager = super.getRemoteRepositoryManager(updatePolicyAnalyzer, checksumPolicyProvider);
- return remoteRepositoryManager;
- }
- }
-}
diff --git a/tests/jetty-testers/pom.xml b/tests/jetty-testers/pom.xml
new file mode 100644
index 00000000000..528d81fd7c0
--- /dev/null
+++ b/tests/jetty-testers/pom.xml
@@ -0,0 +1,42 @@
+
+
+
+ 4.0.0
+
+ org.eclipse.jetty.tests
+ tests
+ 12.0.6-SNAPSHOT
+
+ jetty-testers
+ jar
+ Tests :: Testers
+
+
+ ${project.groupId}.testers
+
+
+
+
+ org.apache.maven.resolver
+ maven-resolver-supplier
+ ${maven.resolver.version}
+
+
+ org.codehaus.plexus
+ plexus-xml
+
+
+ org.eclipse.jetty.toolchain
+ jetty-test-helper
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
diff --git a/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/JPMSTester.java b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/JPMSTester.java
new file mode 100644
index 00000000000..25b80700a64
--- /dev/null
+++ b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/JPMSTester.java
@@ -0,0 +1,351 @@
+//
+// ========================================================================
+// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.testers;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.jetty.toolchain.test.FS;
+import org.eclipse.jetty.toolchain.test.IO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class to test JPMS applications, that will be run in
+ * a forked JVM with the parameters specified to {@link Builder}.
+ * APIs can change without any further notice.
+ * Usage:
+ * {@code
+ * String jettyVersion = "12.0.0";
+ * try (JPMSTester app = new JPMSTester.Builder(workDirPath)
+ * .jvmArgs("-Xmx1G")
+ * // Your application module-info source, will be compiled on-the-fly.
+ * .moduleInfo("""
+ * module app
+ * {
+ * requires ...;
+ * exports ...;
+ * }
+ * """)
+ * // Add the JPMS module dependencies required by your application.
+ * .addToModulePath("org.eclipse.jetty:jetty-jetty-client:" + jettyVersion)
+ * .mainClass(Main.class)
+ * .args(networkPort)
+ * .build())
+ * {
+ * // Your main class will run and produce some output in console.
+ * assertTrue(app.awaitConsoleLogsFor("DONE", Duration.ofSeconds(10)));
+ * }
+ * }
+ */
+public class JPMSTester extends ProcessWrapper
+{
+ private static final Logger LOG = LoggerFactory.getLogger(JPMSTester.class);
+
+ private final Config config;
+
+ private JPMSTester(Config config, Process process)
+ {
+ super(process);
+ this.config = config;
+ }
+
+ /**
+ * @return the configuration of this instance
+ */
+ public Config getConfig()
+ {
+ return config;
+ }
+
+ /**
+ * The configuration of a {@link JPMSTester}.
+ */
+ public static class Config
+ {
+ private Path workDir;
+ private List jvmArgs;
+ private String moduleInfo;
+ private final List modulePaths = new ArrayList<>();
+ private final List classPaths = new ArrayList<>();
+ private Class> mainClass;
+ private List args;
+
+ public List getJVMArgs()
+ {
+ return jvmArgs == null ? List.of() : jvmArgs;
+ }
+
+ public Path getWorkingDirectory()
+ {
+ return workDir;
+ }
+
+ public String getModuleInfo()
+ {
+ return moduleInfo;
+ }
+
+ public List getModulePaths()
+ {
+ return modulePaths;
+ }
+
+ public List getClassPaths()
+ {
+ return classPaths;
+ }
+
+ public Class> getMainClass()
+ {
+ return mainClass;
+ }
+
+ public List getArgs()
+ {
+ return args == null ? List.of() : args;
+ }
+ }
+
+ /**
+ * A builder for {@link JPMSTester}.
+ */
+ public static class Builder
+ {
+ private final MavenHelper mavenHelper = new MavenHelper();
+ private final Config config = new Config();
+ private Path classesDir;
+
+ /**
+ * Creates a new instance with the specified root directory.
+ * The root directory will be the root of possibly many application modules,
+ * and will be used to create an application-specific subdirectory for each
+ * JPMS applications, so that for example a client and a server JPMS applications
+ * are grouped under the same root directory.
+ *
+ * @param rootDir the root directory
+ * @throws IOException if the application-specific subdirectory cannot be created
+ * @see #build()
+ */
+ public Builder(Path rootDir) throws IOException
+ {
+ FS.ensureDirExists(rootDir);
+ config.workDir = Files.createTempDirectory(rootDir, "jpms");
+ }
+
+ /**
+ * @param jvmArgs the JVM arguments
+ * @return this instance
+ */
+ public Builder jvmArgs(String... jvmArgs)
+ {
+ config.jvmArgs = List.of(jvmArgs);
+ return this;
+ }
+
+ /**
+ * @param classesDir the root directory of the compiles classes of this application
+ * @return this instance
+ */
+ public Builder classesDirectory(Path classesDir)
+ {
+ this.classesDir = classesDir;
+ return this;
+ }
+
+ /**
+ * @param moduleInfo the source of this application {@code module-info.java}
+ * @return this instance
+ */
+ public Builder moduleInfo(String moduleInfo)
+ {
+ config.moduleInfo = moduleInfo;
+ return this;
+ }
+
+ /**
+ * Adds to the module-path the given Maven artifact.
+ *
+ * @param mavenCoordinate the Maven coordinates of the artifact
+ * @return this instance
+ * @throws ArtifactResolutionException if the Maven artifact cannot be resolved
+ */
+ public Builder addToModulePath(String mavenCoordinate) throws ArtifactResolutionException
+ {
+ return addToModulePath(mavenHelper.resolveArtifact(mavenCoordinate));
+ }
+
+ /**
+ * Adds to the module-path the given path, either a directory or a jar file.
+ *
+ * @param path the path or jar to add to the module-path
+ * @return this instance
+ */
+ public Builder addToModulePath(Path path)
+ {
+ config.modulePaths.add(path);
+ return this;
+ }
+
+ /**
+ * Adds to the class-path the given Maven artifact.
+ *
+ * @param mavenCoordinate the Maven coordinates of the artifact
+ * @return this instance
+ * @throws ArtifactResolutionException if the Maven artifact cannot be resolved
+ */
+ public Builder addToClassPath(String mavenCoordinate) throws ArtifactResolutionException
+ {
+ return addToClassPath(mavenHelper.resolveArtifact(mavenCoordinate));
+ }
+
+ /**
+ * Adds to the class-path the given path, either a directory or a jar file.
+ *
+ * @param path the path or jar to add to the class-path
+ * @return this instance
+ */
+ public Builder addToClassPath(Path path)
+ {
+ config.classPaths.add(path);
+ return this;
+ }
+
+ /**
+ * Specifies the main class of the JPMS application.
+ * The main class must be in the module specified by
+ * {@link #moduleInfo(String)} and publicly exported.
+ *
+ * @param mainClass the JPMS application main class
+ * @return this instance
+ */
+ public Builder mainClass(Class> mainClass)
+ {
+ config.mainClass = mainClass;
+ return this;
+ }
+
+ /**
+ * @param args the application arguments
+ * @return this instance
+ */
+ public Builder args(String... args)
+ {
+ config.args = List.of(args);
+ return this;
+ }
+
+ /**
+ * Builds a {@link JPMSTester} instance, forking a JVM with the parameters specified in this instance.
+ * The {@code module-info.java} source specified via {@link #moduleInfo(String)} will be compiled and
+ * saved in the application-specific subdirectory (see {@link #Builder(Path)}).
+ * The forked JVM working directory will be the application-specific subdirectory.
+ *
+ * @return a {@link JPMSTester} instance
+ * @throws Exception in case of failures to either compile {@code module-info.java} or fork of the JVM
+ */
+ public JPMSTester build() throws Exception
+ {
+ if (config.getModuleInfo() == null)
+ throw new IllegalArgumentException("missing module-info");
+
+ if (classesDir == null)
+ throw new IllegalArgumentException("missing classes directory");
+
+ if (config.getMainClass() == null)
+ throw new IllegalArgumentException("missing main class");
+
+ Path workDir = config.getWorkingDirectory();
+ IO.copyDir(classesDir, workDir);
+
+ String modulePath = config.getModulePaths().stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator));
+ if (!modulePath.isEmpty())
+ modulePath += File.pathSeparator;
+ modulePath += workDir.toString();
+
+ String classPath = config.getClassPaths().stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator));
+
+ ModuleReference module = compileModuleInfo(modulePath, classPath);
+
+ List commands = new ArrayList<>();
+ commands.add(Tester.getJavaExecutable("java"));
+ commands.addAll(config.getJVMArgs());
+ commands.add("--module-path");
+ commands.add(modulePath);
+ if (!classPath.isEmpty())
+ {
+ commands.add("--class-path");
+ commands.add(classPath);
+ }
+ commands.add("--module");
+ commands.add("%s/%s".formatted(module.descriptor().name(), config.getMainClass().getName()));
+ commands.addAll(config.getArgs());
+
+ LOG.info("executing: " + String.join(" ", commands));
+
+ ProcessBuilder processBuilder = new ProcessBuilder(commands);
+ processBuilder.directory(workDir.toFile());
+ return new JPMSTester(config, processBuilder.start());
+ }
+
+ private ModuleReference compileModuleInfo(String modulePath, String classPath) throws Exception
+ {
+ List commands = new ArrayList<>();
+ commands.add(Tester.getJavaExecutable("javac"));
+ commands.add("--module-path");
+ commands.add(modulePath);
+ if (!classPath.isEmpty())
+ {
+ commands.add("--class-path");
+ commands.add(classPath);
+ }
+
+ Path workDir = config.getWorkingDirectory();
+ Path moduleInfoPath = workDir.resolve("module-info.java");
+ Files.writeString(moduleInfoPath, config.getModuleInfo(), StandardCharsets.US_ASCII, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+ commands.add(moduleInfoPath.toString());
+
+ // This additional class is necessary to be able to compile module-info.java.
+ // There should be one additional class for every exported package, but just
+ // use the one derived from the main class for now.
+ String packageName = config.getMainClass().getPackageName();
+ Path bogusClassPath = workDir.resolve(packageName.replace('.', '/')).resolve("Bogus.java");
+ Files.writeString(bogusClassPath, "package %s; class Bogus {}".formatted(packageName), StandardCharsets.US_ASCII, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+ commands.add(bogusClassPath.toString());
+
+ LOG.info("executing: " + String.join(" ", commands));
+
+ ProcessBuilder processBuilder = new ProcessBuilder(commands);
+ try (ProcessWrapper javac = new ProcessWrapper(processBuilder.start()))
+ {
+ javac.whenExit().orTimeout(10, TimeUnit.SECONDS).get();
+ }
+ if (!Files.exists(workDir.resolve("module-info.class")))
+ throw new IllegalStateException("could not compile module-info");
+
+ return ModuleFinder.of(workDir).findAll().stream().findAny().orElseThrow();
+ }
+ }
+}
diff --git a/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/JettyHomeTester.java b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/JettyHomeTester.java
new file mode 100644
index 00000000000..978a3568bda
--- /dev/null
+++ b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/JettyHomeTester.java
@@ -0,0 +1,450 @@
+//
+// ========================================================================
+// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.testers;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.CopyOption;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+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.stream.Stream;
+
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.jetty.toolchain.test.FS;
+import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class to test the Jetty Distribution
.
+ * API can change without any further notice.
+ * Usage:
+ * {@code
+ * // Create the distribution.
+ * String jettyVersion = "12.0.0";
+ * JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
+ * .jettyVersion(jettyVersion)
+ * .jettyBase(Paths.get("demo-base"))
+ * .build();
+ *
+ * // The first run initializes the Jetty Base.
+ * try (JettyHomeTester.Run run1 = distribution.start("--create-start-ini", "--add-modules=http2c,jsp,deploy"))
+ * {
+ * assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
+ * assertEquals(0, run1.getExitValue());
+ *
+ * // Install a web application.
+ * Path war = distribution.resolveArtifact("org.eclipse.jetty.demos:demo-simple-webapp:war:" + jettyVersion);
+ * distribution.installWar(war, "test");
+ *
+ * // The second run starts the distribution.
+ * int port = 9090;
+ * try (JettyHomeTester.Run run = distribution.start("jetty.http.port=" + port))
+ * {
+ * // Wait for Jetty to be fully started.
+ * assertTrue(run1.awaitConsoleLogsFor("Started @", 20, TimeUnit.SECONDS));
+ *
+ * // Make an HTTP request to the web application.
+ * HttpClient client = new HttpClient();
+ * client.start();
+ * ContentResponse response = client.GET("http://localhost:" + port + "/test/index.html");
+ * assertEquals(HttpStatus.OK_200, response.getStatus());
+ * }
+ * }
+ * }
+ */
+public class JettyHomeTester
+{
+ private static final Logger LOG = LoggerFactory.getLogger(JettyHomeTester.class);
+
+ private final MavenHelper mavenHelper = new MavenHelper();
+ private final Config config;
+
+ private JettyHomeTester(Config config)
+ {
+ this.config = config;
+ }
+
+ /**
+ * Starts the distribution with the given arguments
+ *
+ * @param args arguments to use to start the distribution
+ */
+ public JettyHomeTester.Run start(String... args) throws Exception
+ {
+ return start(Arrays.asList(args));
+ }
+
+ public Path getJettyBase()
+ {
+ return config.getJettyBase();
+ }
+
+ public Path getJettyHome()
+ {
+ return config.getJettyHome();
+ }
+
+ /**
+ * Start the distribution with the arguments
+ *
+ * @param args arguments to use to start the distribution
+ */
+ public JettyHomeTester.Run start(List args) throws Exception
+ {
+ File jettyBaseDir = getJettyBase().toFile();
+ Path workDir = Files.createDirectories(jettyBaseDir.toPath().resolve("work"));
+
+ List commands = new ArrayList<>();
+ commands.add(Tester.getJavaExecutable("java"));
+ commands.addAll(config.getJVMArgs());
+ commands.add("-Djava.io.tmpdir=" + workDir.toAbsolutePath());
+ int debugPort = Integer.getInteger("distribution.debug.port", 0);
+ if (debugPort > 0)
+ {
+ commands.add("-Xdebug");
+ commands.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=" + debugPort);
+ }
+ commands.add("-jar");
+ commands.add(config.jettyHome.toAbsolutePath() + "/start.jar");
+
+ args = new ArrayList<>(args);
+
+ String mavenLocalRepository = config.getMavenLocalRepository();
+ if (StringUtils.isNotBlank(mavenLocalRepository))
+ mavenLocalRepository = System.getProperty("mavenRepoPath");
+ if (StringUtils.isNotBlank(mavenLocalRepository))
+ args.add("maven.local.repo=" + mavenLocalRepository);
+
+ // if this JVM has `maven.repo.uri` defined, make sure to propagate it to child
+ String remoteRepoUri = System.getProperty("maven.repo.uri");
+ if (remoteRepoUri != null)
+ {
+ args.add("maven.repo.uri=" + remoteRepoUri);
+ }
+
+ commands.addAll(args);
+
+ LOG.info("Executing: {}", commands);
+ LOG.info("Working Dir: {}", jettyBaseDir.getAbsolutePath());
+
+ ProcessBuilder pbCmd = new ProcessBuilder(commands);
+ pbCmd.directory(jettyBaseDir);
+ pbCmd.environment().putAll(config.env);
+ Process process = pbCmd.start();
+
+ return new Run(process, config);
+ }
+
+ /**
+ * Installs in {@code ${jetty.base}/webapps} the given war file under the given context path.
+ *
+ * @param testResourcePath the location of the source file in {@code src/test/resources}
+ * @param baseResourcePath the location of the destination file in {@code ${jetty.base}}
+ * @param options optional CopyOption
+ * @throws IOException if the installation fails
+ */
+ public void installBaseResource(String testResourcePath, String baseResourcePath, CopyOption... options) throws IOException
+ {
+ Path srcFile = MavenTestingUtils.getTestResourcePath(testResourcePath);
+ Path destFile = config.jettyBase.resolve(baseResourcePath);
+ Files.deleteIfExists(destFile);
+ if (!Files.exists(destFile.getParent()))
+ Files.createDirectories(destFile.getParent());
+
+ Files.copy(srcFile, destFile, options);
+ }
+
+ /**
+ * Installs in {@code ${jetty.base}/webapps} the given war file under the given context path.
+ *
+ * @param warPath the war file to install
+ * @param context the context path
+ * @return the path to the installed webapp exploded directory
+ * @throws IOException if the installation fails
+ */
+ public Path installWar(Path warPath, String context) throws IOException
+ {
+ //webapps
+ Path webapps = config.jettyBase.resolve("webapps").resolve(context);
+ if (!Files.exists(webapps))
+ Files.createDirectories(webapps);
+ unzip(warPath, webapps);
+ return webapps;
+ }
+
+ public Path resolveArtifact(String mavenCoordinate) throws ArtifactResolutionException
+ {
+ return mavenHelper.resolveArtifact(mavenCoordinate);
+ }
+
+ private void init() throws Exception
+ {
+ if (config.jettyHome == null)
+ config.jettyHome = resolveHomeArtifact(config.getJettyVersion());
+
+ if (config.jettyBase == null)
+ {
+ Path bases = MavenTestingUtils.getTargetTestingPath("bases");
+ FS.ensureDirExists(bases);
+ config.jettyBase = Files.createTempDirectory(bases, "jetty_base_");
+ }
+ else
+ {
+ if (!config.jettyBase.isAbsolute())
+ {
+ throw new IllegalStateException("Jetty Base is not an absolute path: " + config.jettyBase);
+ }
+ }
+ }
+
+ public static void unzip(Path archive, Path outputDir) throws IOException
+ {
+ if (!Files.exists(outputDir))
+ throw new FileNotFoundException("Directory does not exist: " + outputDir);
+
+ if (!Files.isDirectory(outputDir))
+ throw new FileNotFoundException("Not a directory: " + outputDir);
+
+ Map env = new HashMap<>();
+ env.put("releaseVersion", null); // no MultiRelease Jar file behaviors
+
+ URI outputDirURI = outputDir.toUri();
+ URI archiveURI = URI.create("jar:" + archive.toUri().toASCIIString());
+
+ try (FileSystem fs = FileSystems.newFileSystem(archiveURI, env))
+ {
+ Path root = fs.getPath("/");
+ int archiveURISubIndex = root.toUri().toASCIIString().indexOf("!/") + 2;
+ try (Stream entriesStream = Files.walk(root))
+ {
+ // ensure proper unpack order (eg: directories before files)
+ List sorted = entriesStream
+ .sorted()
+ .toList();
+
+ for (Path path : sorted)
+ {
+ URI entryURI = path.toUri();
+ String subURI = entryURI.toASCIIString().substring(archiveURISubIndex);
+ URI outputPathURI = outputDirURI.resolve(subURI);
+ Path outputPath = Path.of(outputPathURI);
+ if (Files.isDirectory(path))
+ {
+ if (!Files.exists(outputPath))
+ Files.createDirectory(outputPath);
+ }
+ else
+ {
+ Files.copy(path, outputPath);
+ }
+ }
+ }
+ }
+ catch (FileAlreadyExistsException e)
+ {
+ LOG.warn("ignore FileAlreadyExistsException: archiveURI {}, outputDir {}", archiveURI, outputDir);
+ }
+ }
+
+ private Path resolveHomeArtifact(String version) throws Exception
+ {
+ Path artifactFile = mavenHelper.resolveArtifact("org.eclipse.jetty:jetty-home:zip:" + version);
+ Path homes = MavenTestingUtils.getTargetTestingPath("homes");
+ FS.ensureDirExists(homes);
+ Path tmp = Files.createDirectories(homes.resolve(Long.toString(artifactFile.toFile().lastModified())));
+ Path home = tmp.resolve("jetty-home-" + version);
+ if (!Files.exists(home))
+ unzip(artifactFile, tmp);
+ return home;
+ }
+
+ public static class Config
+ {
+ private Path jettyBase;
+ private Path jettyHome;
+ private String jettyVersion;
+ private String mavenLocalRepository = System.getProperty("mavenRepoPath", System.getProperty("user.home") + "/.m2/repository");
+ private List jvmArgs = new ArrayList<>();
+ private Map env = new HashMap<>();
+
+ public Path getJettyBase()
+ {
+ return jettyBase;
+ }
+
+ public Path getJettyHome()
+ {
+ return jettyHome;
+ }
+
+ public String getJettyVersion()
+ {
+ return jettyVersion;
+ }
+
+ public String getMavenLocalRepository()
+ {
+ return mavenLocalRepository;
+ }
+
+ public List getJVMArgs()
+ {
+ return Collections.unmodifiableList(jvmArgs);
+ }
+
+ public Map getEnv()
+ {
+ return Collections.unmodifiableMap(env);
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x{jettyBase=%s, jettyHome=%s, jettyVersion=%s, mavenLocalRepository=%s}",
+ getClass().getSimpleName(),
+ hashCode(),
+ jettyBase,
+ jettyHome,
+ jettyVersion,
+ mavenLocalRepository);
+ }
+ }
+
+ /**
+ * A distribution run wraps the process that started the Jetty distribution.
+ */
+ public static class Run extends ProcessWrapper
+ {
+ private final Config config;
+
+ private Run(Process process, Config config)
+ {
+ super(process);
+ this.config = config;
+ }
+
+ public Config getConfig()
+ {
+ return config;
+ }
+ }
+
+ public static class Builder
+ {
+ private final Config config = new Config();
+
+ private Builder()
+ {
+ }
+
+ /**
+ * @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 this Builder
+ */
+ public Builder jettyVersion(String jettyVersion)
+ {
+ config.jettyVersion = jettyVersion;
+ return this;
+ }
+
+ /**
+ * @param jettyHome Path to the local exploded jetty distribution
+ * if configured the jettyVersion parameter will not be used
+ * @return this Builder
+ */
+ public Builder jettyHome(Path 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 this Builder
+ */
+ public Builder jettyBase(Path jettyBase)
+ {
+ config.jettyBase = jettyBase;
+ return this;
+ }
+
+ /**
+ * @param mavenLocalRepository Path to the local maven repository
+ * @return this Builder
+ */
+ public Builder mavenLocalRepository(String mavenLocalRepository)
+ {
+ if (StringUtils.isBlank(mavenLocalRepository))
+ return this;
+
+ config.mavenLocalRepository = mavenLocalRepository;
+ return this;
+ }
+
+ /**
+ * @param jvmArgs the jvm args to add
+ * @return this Builder
+ */
+ public Builder jvmArgs(List jvmArgs)
+ {
+ config.jvmArgs = jvmArgs;
+ return this;
+ }
+
+ /**
+ * @param env the env to add
+ * @return this Builder
+ */
+ public Builder env(Map env)
+ {
+ config.env = env;
+ return this;
+ }
+
+ /**
+ * @return an empty instance of Builder
+ */
+ public static Builder newInstance()
+ {
+ return new Builder();
+ }
+
+ /**
+ * @return a new configured instance of {@link JettyHomeTester}
+ */
+ public JettyHomeTester build() throws Exception
+ {
+ JettyHomeTester tester = new JettyHomeTester(config);
+ tester.init();
+ return tester;
+ }
+ }
+}
diff --git a/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/MavenHelper.java b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/MavenHelper.java
new file mode 100644
index 00000000000..be66b808382
--- /dev/null
+++ b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/MavenHelper.java
@@ -0,0 +1,97 @@
+//
+// ========================================================================
+// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.testers;
+
+import java.nio.file.Path;
+import java.util.List;
+
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+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.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.supplier.RepositorySystemSupplier;
+import org.eclipse.aether.transfer.AbstractTransferListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class MavenHelper
+{
+ private static final Logger LOG = LoggerFactory.getLogger(MavenHelper.class);
+
+ private final RepositorySystemSupplier repositorySystem = new RepositorySystemSupplier();
+
+ public Path resolveArtifact(String coordinates) throws ArtifactResolutionException
+ {
+ RepositorySystem repositorySystem = this.repositorySystem.get();
+
+ Artifact artifact = new DefaultArtifact(coordinates);
+
+ RepositorySystemSession session = newRepositorySystemSession(repositorySystem);
+
+ ArtifactRequest artifactRequest = new ArtifactRequest();
+ artifactRequest.setArtifact(artifact);
+ artifactRequest.setRepositories(List.of(newCentralRepository()));
+ ArtifactResult artifactResult = repositorySystem.resolveArtifact(session, artifactRequest);
+
+ artifact = artifactResult.getArtifact();
+ return artifact.getFile().toPath();
+ }
+
+ private DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system)
+ {
+ DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
+
+ String mavenLocalRepository = System.getProperty("mavenRepoPath", System.getProperty("user.home") + "/.m2/repository");
+ LocalRepository localRepository = new LocalRepository(mavenLocalRepository);
+ session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepository));
+
+ session.setTransferListener(new LogTransferListener());
+ session.setRepositoryListener(new LogRepositoryListener());
+
+ return session;
+ }
+
+ private static RemoteRepository newCentralRepository()
+ {
+ return new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build();
+ }
+
+ private static class LogTransferListener extends AbstractTransferListener
+ {
+ }
+
+ private static class LogRepositoryListener extends AbstractRepositoryListener
+ {
+ @Override
+ public void artifactDownloaded(RepositoryEvent event)
+ {
+ LOG.debug("downloaded {}", event.getFile());
+ }
+
+ @Override
+ public void artifactResolved(RepositoryEvent event)
+ {
+ LOG.debug("artifact resolved {}", event.getFile());
+ }
+ }
+}
diff --git a/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/ProcessWrapper.java b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/ProcessWrapper.java
new file mode 100644
index 00000000000..f95f7d999d1
--- /dev/null
+++ b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/ProcessWrapper.java
@@ -0,0 +1,218 @@
+//
+// ========================================================================
+// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.testers;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.time.Duration;
+import java.util.Collection;
+import java.util.Queue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.toolchain.test.IO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A useful wrapper of {@link Process} instances.
+ * The process output and error streams are captured each by a thread
+ * associated with this instance, and and exposed via {@link #getLogs()}
+ * and {@link #awaitConsoleLogsFor(String, Duration)}.
+ * Process termination can be handled asynchronously via {@link #whenExit()}.
+ */
+public class ProcessWrapper implements AutoCloseable
+{
+ private static final Logger LOG = LoggerFactory.getLogger(ProcessWrapper.class);
+
+ private final Queue logs = new ConcurrentLinkedQueue<>();
+ private final Process process;
+ private final ConsoleStreamer stdOut;
+ private final ConsoleStreamer stdErr;
+
+ public ProcessWrapper(Process process)
+ {
+ this.process = process;
+ this.stdOut = startConsoleStreamer("out", process.getInputStream());
+ this.stdErr = startConsoleStreamer("err", process.getErrorStream());
+ }
+
+ public Process getProcess()
+ {
+ return process;
+ }
+
+ /**
+ * @return a collection of the logs emitted on the process output and error streams
+ */
+ public Collection getLogs()
+ {
+ return logs;
+ }
+
+ /**
+ * Returns a {@link CompletableFuture} that completes when the process exits
+ * and when the threads capturing the process output and error stream exit.
+ * The returned {@link CompletableFuture} can be used to wait for a timeout
+ * via {@code processWrapper.whenExit().orTimeout(5, TimeUnit.SECONDS)}.
+ *
+ * @return a CompletableFuture that completes when the process exits
+ */
+ public CompletableFuture whenExit()
+ {
+ return getProcess().onExit().thenCombine(joinConsoleStreamers(), (p, v) -> p);
+ }
+
+ /**
+ * Same as {@link Process#waitFor(long, TimeUnit)}.
+ * Use this method for simple assertions in test
+ * code, when it is known that the process will exit.
+ *
+ * @param time the time to wait
+ * @param unit the unit of time
+ * @return {@code true} if the process has exited and {@code false} if the time elapsed before the process has exited
+ * @throws InterruptedException if the current thread is interrupted while waiting
+ */
+ public boolean awaitFor(long time, TimeUnit unit) throws InterruptedException
+ {
+ return getProcess().waitFor(time, unit);
+ }
+
+ public boolean awaitFor(Duration duration) throws InterruptedException
+ {
+ return awaitFor(duration.toMillis(), TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Polls the console log lines derived from the
+ * process output and error streams for the given text.
+ *
+ * @param txt the text to search in the log lines
+ * @param time the time to wait
+ * @param unit the unit of time
+ * @return {@code true} if the text was found in a log line,
+ * {@code false} if the text was not found within the given time
+ * @throws InterruptedException if the current thread is interrupted while waiting
+ */
+ public boolean awaitConsoleLogsFor(String txt, long time, TimeUnit unit) throws InterruptedException
+ {
+ long poll = 50;
+ long millis = unit.toMillis(time);
+ while (millis > 0)
+ {
+ millis -= poll;
+ Thread.sleep(poll);
+ if (getLogs().stream().anyMatch(s -> s.contains(txt)))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean awaitConsoleLogsFor(String txt, Duration duration) throws InterruptedException
+ {
+ return awaitConsoleLogsFor(txt, duration.toMillis(), TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Same as {@link Process#exitValue()}.
+ *
+ * @return the process exit value
+ * @throws IllegalThreadStateException if the process has not exited
+ */
+ public int getExitValue() throws IllegalThreadStateException
+ {
+ return getProcess().exitValue();
+ }
+
+ /**
+ * Stops the process by calling {@link Process#destroy()}, and returns {@link #whenExit()}.
+ *
+ * @return a CompletableFuture that completes when the process exits
+ */
+ public CompletableFuture stop()
+ {
+ getProcess().destroy();
+ return whenExit();
+ }
+
+ /**
+ * Calls {@link #stop()} and blocks via
+ * {@link CompletableFuture#join()} until the process has exited.
+ */
+ @Override
+ public void close()
+ {
+ stop().join();
+ }
+
+ private ConsoleStreamer startConsoleStreamer(String mode, InputStream stream)
+ {
+ ConsoleStreamer streamer = new ConsoleStreamer(mode, stream);
+ streamer.start();
+ return streamer;
+ }
+
+ private CompletableFuture joinConsoleStreamers()
+ {
+ return CompletableFuture.allOf(stdOut.join(), stdErr.join());
+ }
+
+ private class ConsoleStreamer implements Runnable
+ {
+ private final CompletableFuture completable = new CompletableFuture<>();
+ private final Thread thread;
+ private final BufferedReader reader;
+
+ private ConsoleStreamer(String mode, InputStream stream)
+ {
+ this.thread = new Thread(this, "process/" + mode);
+ this.reader = new BufferedReader(new InputStreamReader(stream));
+ }
+
+ private void start()
+ {
+ thread.start();
+ }
+
+ private CompletableFuture join()
+ {
+ return completable;
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ String line;
+ while ((line = reader.readLine()) != null)
+ {
+ LOG.info(line);
+ logs.add(line);
+ }
+ }
+ catch (Throwable x)
+ {
+ LOG.trace("", x);
+ }
+ finally
+ {
+ IO.close(reader);
+ completable.complete(null);
+ }
+ }
+ }
+}
diff --git a/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/Tester.java b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/Tester.java
new file mode 100644
index 00000000000..a7bd7ad452e
--- /dev/null
+++ b/tests/jetty-testers/src/main/java/org/eclipse/jetty/tests/testers/Tester.java
@@ -0,0 +1,57 @@
+//
+// ========================================================================
+// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.testers;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public interface Tester
+{
+ /**
+ * @return a free port chosen by the OS that can be used to listen to
+ * @throws IOException if a free port is not available
+ */
+ static int freePort() throws IOException
+ {
+ try (ServerSocket server = new ServerSocket())
+ {
+ server.setReuseAddress(true);
+ server.bind(new InetSocketAddress("localhost", 0));
+ return server.getLocalPort();
+ }
+ }
+
+ /**
+ * Returns a Java executable under the {@code $JAVA_HOME/bin} directory.
+ *
+ * @param command the Java command to search for (for example, "java", "javac", "jstack", etc.)
+ * @return the Java command
+ */
+ static String getJavaExecutable(String command)
+ {
+ String[] javaExecutables = new String[]{command, command + ".exe"};
+ Path javaBinDir = Paths.get(System.getProperty("java.home")).resolve("bin");
+ for (String javaExecutable : javaExecutables)
+ {
+ Path javaFile = javaBinDir.resolve(javaExecutable);
+ if (Files.exists(javaFile) && Files.isRegularFile(javaFile))
+ return javaFile.toAbsolutePath().toString();
+ }
+ return command;
+ }
+}
diff --git a/tests/pom.xml b/tests/pom.xml
index bf2790c6c9e..42b9e5021bc 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -11,13 +11,12 @@
pom
Tests
- jetty-home-tester
+ jetty-testers
jetty-jmh
jetty-test-session-common
test-distribution
test-integration
-
-
+
true
diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml
index db2bd7c1fc0..3d6a43c6343 100644
--- a/tests/test-distribution/pom.xml
+++ b/tests/test-distribution/pom.xml
@@ -79,11 +79,13 @@
org.eclipse.jetty
jetty-slf4j-impl
+ ${project.version}
test
org.eclipse.jetty.tests
- jetty-home-tester
+ jetty-testers
+ ${project.version}
test
diff --git a/tests/test-distribution/test-distribution-common/pom.xml b/tests/test-distribution/test-distribution-common/pom.xml
index 26c5e2308db..ee4ea0e3b4c 100644
--- a/tests/test-distribution/test-distribution-common/pom.xml
+++ b/tests/test-distribution/test-distribution-common/pom.xml
@@ -94,9 +94,8 @@
org.eclipse.jetty.tests
- jetty-home-tester
+ jetty-testers
${project.version}
- compile
org.eclipse.jetty.toolchain
@@ -114,6 +113,11 @@
org.slf4j
slf4j-api
+
+ org.awaitility
+ awaitility
+ test
+
org.eclipse.jetty
jetty-client
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java
index 8b0fc5cb002..391d9297300 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java
@@ -13,13 +13,14 @@
package org.eclipse.jetty.tests.distribution;
-import java.io.File;
import java.net.URI;
+import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
@@ -57,15 +58,15 @@ public class BadAppTests extends AbstractJettyHomeTest
{
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertThat(run1.getExitValue(), is(0));
-
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-badinit-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "badapp");
+
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-badinit-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "badapp");
// Setup webapps directory
distribution.installBaseResource("badapp-" + env + "/badapp_throwonunavailable_true.xml",
"webapps/badapp.xml");
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitFor(START_TIMEOUT, TimeUnit.SECONDS), "Should have exited");
@@ -96,14 +97,14 @@ public class BadAppTests extends AbstractJettyHomeTest
{
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertThat(run1.getExitValue(), is(0));
-
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-badinit-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "badapp");
+
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-badinit-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "badapp");
distribution.installBaseResource("badapp-" + env + "/badapp_throwonunavailable_false.xml",
"webapps/badapp.xml");
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -138,11 +139,11 @@ public class BadAppTests extends AbstractJettyHomeTest
{
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertThat(run1.getExitValue(), is(0));
-
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-badinit-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "badapp");
- int port = distribution.freePort();
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-badinit-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "badapp");
+
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port, "jetty.server.dumpAfterStart=true"))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -182,10 +183,10 @@ public class BadAppTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File badWebApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":" + "jetty-" + env + "-test-bad-websocket-webapp:war:" + jettyVersion);
- distribution.installWarFile(badWebApp, "test");
+ Path badWebApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":" + "jetty-" + env + "-test-bad-websocket-webapp:war:" + jettyVersion);
+ distribution.installWar(badWebApp, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
String[] args2 = {"jetty.http.port=" + port};
try (JettyHomeTester.Run run2 = distribution.start(args2))
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java
index db62ee40a69..55185e39c1e 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.tests.distribution;
-import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -26,7 +25,8 @@ import java.util.stream.Stream;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.eclipse.jetty.util.StringUtil;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -104,14 +104,14 @@ public class CDITests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-" + integration + "-cdi-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "demo");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-" + integration + "-cdi-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "demo");
distribution.installBaseResource("jetty-logging.properties", "resources/jetty-logging.properties", StandardCopyOption.REPLACE_EXISTING);
if (configure != null)
configure.accept(distribution);
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
index 600eb1e40c6..8120451450e 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
@@ -23,7 +23,8 @@ import java.util.stream.Stream;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.client.FormRequestContent;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.eclipse.jetty.util.Fields;
import org.junit.jupiter.api.Tag;
@@ -61,8 +62,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("demos", env)
@@ -148,8 +149,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("demo-jsp", env)
@@ -194,8 +195,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("demo-jaas", env)
@@ -241,8 +242,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("demo-jsp", env)
@@ -290,8 +291,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("demo-async-rest", env)
@@ -346,8 +347,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("demos", env)
@@ -402,8 +403,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("demos", env)
@@ -459,8 +460,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
assertTrue(runConfig.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, runConfig.getExitValue());
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsStart = {
"jetty.http.port=" + httpPort,
"jetty.ssl.port=" + sslPort
@@ -526,8 +527,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
assertTrue(runConfig.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, runConfig.getExitValue());
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsStart = {
"jetty.http.port=" + httpPort,
@@ -561,8 +562,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http,demo-handler"
@@ -604,8 +605,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig =
{
@@ -666,8 +667,8 @@ public class DemoModulesTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
- int sslPort = distribution.freePort();
+ int httpPort = Tester.freePort();
+ int sslPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("demos", env)
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
index c624c181129..ff6b97c0776 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
@@ -28,12 +28,13 @@ import java.nio.file.StandardOpenOption;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
-import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.client.HttpClient;
@@ -51,7 +52,8 @@ import org.eclipse.jetty.http3.client.transport.HttpClientTransportOverHTTP3;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.content.ByteBufferContentSource;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.PathMatchers;
import org.eclipse.jetty.util.BlockingArrayQueue;
@@ -96,7 +98,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -128,7 +130,7 @@ public class DistributionTests extends AbstractJettyHomeTest
Path pidfile = run1.getConfig().getJettyBase().resolve("jetty.pid");
Path statefile = run1.getConfig().getJettyBase().resolve("jetty.state");
- int port = distribution.freePort();
+ int port = Tester.freePort();
List args = new ArrayList<>();
args.add("jetty.http.port=" + port);
@@ -191,7 +193,7 @@ public class DistributionTests extends AbstractJettyHomeTest
String jettyVersion = System.getProperty("jettyVersion");
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
.jettyVersion(jettyVersion)
- .jettyBase(jettyBase)
+ .jettyBase(jettyBase)
.build();
String mods = String.join(",",
@@ -207,8 +209,8 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "test");
try (JettyHomeTester.Run run2 = distribution.start("jetty.quickstart.mode=GENERATE"))
{
@@ -221,7 +223,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(Files.exists(quickstartWebXml));
assertNotEquals(0, Files.size(quickstartWebXml));
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run3 = distribution.start("jetty.http.port=" + port, "jetty.quickstart.mode=QUICKSTART"))
{
@@ -245,7 +247,7 @@ public class DistributionTests extends AbstractJettyHomeTest
String jettyVersion = System.getProperty("jettyVersion");
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
.jettyVersion(jettyVersion)
- .jettyBase(jettyBase)
+ .jettyBase(jettyBase)
.build();
String mods = String.join(",",
@@ -263,10 +265,10 @@ public class DistributionTests extends AbstractJettyHomeTest
// Verify that --create-start-ini works
assertTrue(Files.exists(distribution.getJettyBase().resolve("start.ini")));
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -306,10 +308,10 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("--jpms", "jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -362,10 +364,10 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
String portProp = ssl ? "jetty.ssl.port" : "jetty.http.port";
try (JettyHomeTester.Run run2 = distribution.start(portProp + "=" + port))
{
@@ -407,10 +409,10 @@ public class DistributionTests extends AbstractJettyHomeTest
assertEquals(0, run1.getExitValue());
assertTrue(Files.exists(distribution.getJettyBase().resolve("resources/log4j2.xml")));
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-jsp-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -451,10 +453,10 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-websocket-client-provided-webapp:war:" + jettyVersion);
- distribution.installWarFile(webApp, "test");
+ Path webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-websocket-client-provided-webapp:war:" + jettyVersion);
+ distribution.installWar(webApp, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
List args = new ArrayList<>();
args.add(ssl ? "jetty.ssl.port=" + port : "jetty.http.port=" + port);
if (Boolean.parseBoolean(jpms))
@@ -500,10 +502,10 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-websocket-client-webapp:war:" + jettyVersion);
- distribution.installWarFile(webApp, "test");
+ Path webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-websocket-client-webapp:war:" + jettyVersion);
+ distribution.installWar(webApp, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
List args = new ArrayList<>();
args.add(ssl ? "jetty.ssl.port=" + port : "jetty.http.port=" + port);
if (Boolean.parseBoolean(jpms))
@@ -566,15 +568,15 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-proxy-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "proxy");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-proxy-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "proxy");
Path loggingProps = distribution.getJettyBase().resolve("resources/jetty-logging.properties");
String loggingConfig = """
# Default for everything is INFO
org.eclipse.jetty.LEVEL=INFO
- # to see full logger names
+ # to see full logger names
# org.eclipse.jetty.logging.appender.NAME_CONDENSE=false
# to see CR LF as-is (not escaped) in output (useful for DEBUG of request/response headers)
org.eclipse.jetty.logging.appender.MESSAGE_ESCAPE=false
@@ -584,7 +586,7 @@ public class DistributionTests extends AbstractJettyHomeTest
Files.writeString(loggingProps, loggingConfig, StandardCharsets.UTF_8, StandardOpenOption.TRUNCATE_EXISTING);
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("--jpms", "jetty.http.port=" + port, "jetty.server.dumpAfterStart=true"))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -630,11 +632,11 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(10, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-websocket-webapp:war:" + jettyVersion);
- distribution.installWarFile(webApp, "test1");
- distribution.installWarFile(webApp, "test2");
+ Path webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-websocket-webapp:war:" + jettyVersion);
+ distribution.installWar(webApp, "test1");
+ distribution.installWar(webApp, "test2");
- int port = distribution.freePort();
+ int port = Tester.freePort();
List args2 = new ArrayList<>();
args2.add("jetty.http.port=" + port);
if (Boolean.parseBoolean(jpms))
@@ -710,12 +712,18 @@ public class DistributionTests extends AbstractJettyHomeTest
distribution.getJettyBase().resolve("resources").resolve("log4j2.xml"),
StandardCopyOption.REPLACE_EXISTING);
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
- assertTrue(run2.awaitLogsFileFor(
- distribution.getJettyBase().resolve("logs").resolve("jetty.log"),
- "Started oejs.Server@", 10, TimeUnit.SECONDS));
+ Path logFile = distribution.getJettyBase().resolve("logs").resolve("jetty.log");
+ await().atMost(10, TimeUnit.SECONDS).until(() -> Files.exists(logFile));
+ await().atMost(10, TimeUnit.SECONDS).until(() ->
+ {
+ try (Stream lines = Files.lines(logFile))
+ {
+ return lines.anyMatch(line -> line.contains("Started oejs.Server@"));
+ }
+ });
startHttpClient();
ContentResponse response = client.GET("http://localhost:" + port);
@@ -746,7 +754,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(Files.exists(julConfig));
Files.write(julConfig, Arrays.asList(System.lineSeparator(), "org.eclipse.jetty.level=FINE"), StandardOpenOption.APPEND);
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -788,17 +796,17 @@ public class DistributionTests extends AbstractJettyHomeTest
String loggerName = getClass().getName();
String message = "test-log-line";
String xml = "" +
- "" +
- "" +
- "" +
- " " +
- " " + loggerName + "" +
- " " +
- " " +
- " " + message + "" +
- " " +
- " " +
- "";
+ "" +
+ "" +
+ "" +
+ " " +
+ " " + loggerName + "" +
+ " " +
+ " " +
+ " " + message + "" +
+ " " +
+ " " +
+ "";
Files.write(julXML, List.of(xml), StandardOpenOption.CREATE);
Path julIni = jettyBase.resolve("start.d/logging-jul-capture.ini");
@@ -808,7 +816,7 @@ public class DistributionTests extends AbstractJettyHomeTest
Path jettyLogConfig = jettyBase.resolve("resources/jetty-logging.properties");
Files.write(jettyLogConfig, List.of(loggerName + ".LEVEL=DEBUG"), StandardOpenOption.TRUNCATE_EXISTING);
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -892,12 +900,12 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run2.awaitFor(START_TIMEOUT, TimeUnit.SECONDS), String.join("", run2.getLogs()));
assertEquals(0, run2.getExitValue());
- int port = distribution.freePort();
- int sslPort = distribution.freePort();
+ int port = Tester.freePort();
+ int sslPort = Tester.freePort();
try (JettyHomeTester.Run run3 = distribution.start("jetty.http.port=" + port, "jetty.ssl.port=" + sslPort))
{
assertTrue(run3.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS),
- String.join("", run3.getLogs()));
+ String.join("", run3.getLogs()));
// Check for the protocol order: fcgi must be after ssl and before http.
assertTrue(run3.getLogs().stream()
@@ -1000,8 +1008,8 @@ public class DistributionTests extends AbstractJettyHomeTest
Files.createDirectories(jettyBaseModules);
Path execModule = jettyBaseModules.resolve("exec.mod");
String module = "" +
- "[exec]\n" +
- "--show-version";
+ "[exec]\n" +
+ "--show-version";
Files.write(execModule, List.of(module), StandardOpenOption.CREATE);
try (JettyHomeTester.Run run1 = distribution.start(List.of("--add-modules=http,exec")))
@@ -1009,7 +1017,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -1035,11 +1043,11 @@ public class DistributionTests extends AbstractJettyHomeTest
// Create module with an [ini] section with an invalid password,
// which should be overridden on the command line at startup.
String module = "" +
- "[depends]\n" +
- "ssl\n" +
- "\n" +
- "[ini]\n" +
- "" + pathProperty + "=modbased\n";
+ "[depends]\n" +
+ "ssl\n" +
+ "\n" +
+ "[ini]\n" +
+ "" + pathProperty + "=modbased\n";
Files.writeString(jettyBaseModules.resolve("ssl-ini.mod"), module, StandardOpenOption.CREATE);
try (JettyHomeTester.Run run1 = distribution.start("--add-module=https,test-keystore,ssl-ini"))
@@ -1048,7 +1056,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertEquals(0, run1.getExitValue());
// Override the property on the command line with the correct password.
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start(pathProperty + "=cmdline", "jetty.ssl.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -1087,7 +1095,7 @@ public class DistributionTests extends AbstractJettyHomeTest
fileWriter.write(testFileContent);
}
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -1141,7 +1149,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.getLogs().stream().anyMatch(log -> log.contains("WARN") && log.contains(reason)));
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -1167,8 +1175,8 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- int h2Port = distribution.freePort();
- int h3Port = distribution.freePort();
+ int h2Port = Tester.freePort();
+ int h3Port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start(List.of("jetty.ssl.selectors=1", "jetty.ssl.port=" + h2Port, "jetty.quic.port=" + h3Port)))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -1205,9 +1213,9 @@ public class DistributionTests extends AbstractJettyHomeTest
try (JettyHomeTester.Run run2 = distribution.start("--dry-run"))
{
run2.awaitFor(START_TIMEOUT, TimeUnit.SECONDS);
- Queue logs = run2.getLogs();
+ Collection logs = run2.getLogs();
assertThat(logs.size(), equalTo(1));
- assertThat(logs.poll(), not(containsString("${jetty.home.uri}")));
+ assertThat(logs.iterator().next(), not(containsString("${jetty.home.uri}")));
}
}
}
@@ -1237,7 +1245,7 @@ public class DistributionTests extends AbstractJettyHomeTest
);
Files.write(requestLogIni, lines, StandardCharsets.UTF_8, StandardOpenOption.TRUNCATE_EXISTING);
- int port = distribution.freePort();
+ int port = Tester.freePort();
String[] args2 = {
"jetty.http.port=" + port,
};
@@ -1280,7 +1288,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertEquals(0, run1.getExitValue());
// Add a FastCGI connector to simulate, for example, php-fpm.
- int fcgiPort = distribution.freePort();
+ int fcgiPort = Tester.freePort();
//Path jettyBase = distribution.getJettyBase();
Path jettyBaseEtc = jettyBase.resolve("etc");
Files.createDirectories(jettyBaseEtc);
@@ -1352,7 +1360,7 @@ public class DistributionTests extends AbstractJettyHomeTest
""".replace("$P", String.valueOf(fcgiPort)), StandardOpenOption.CREATE);
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + httpPort, "etc/fcgi-connector.xml"))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -1395,7 +1403,7 @@ public class DistributionTests extends AbstractJettyHomeTest
Files.writeString(jettyLogging, loggingConfig, StandardOpenOption.TRUNCATE_EXISTING);
// Add a FastCGI connector to simulate, for example, php-fpm.
- int fcgiPort = distribution.freePort();
+ int fcgiPort = Tester.freePort();
Path jettyBaseEtc = jettyBase.resolve("etc");
Files.createDirectories(jettyBaseEtc);
Path fcgiConnectorXML = jettyBaseEtc.resolve("fcgi-connector.xml");
@@ -1476,7 +1484,7 @@ public class DistributionTests extends AbstractJettyHomeTest
environment=$ENV
""".replace("$ENV", env), StandardOpenOption.CREATE);
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + httpPort, "etc/fcgi-connector.xml"))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -1507,7 +1515,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(10, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start(List.of("jetty.http.selectors=1", "jetty.http.port=" + httpPort)))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", 10, TimeUnit.SECONDS));
@@ -1537,7 +1545,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start(List.of("jetty.http.selectors=1", "jetty.http.port=" + httpPort)))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
@@ -1580,7 +1588,7 @@ public class DistributionTests extends AbstractJettyHomeTest
""";
Files.writeString(jettyLogging, loggingConfig, StandardOpenOption.TRUNCATE_EXISTING);
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
String contextPath = "/" + toEnvironment("demo-simple", env);
try (JettyHomeTester.Run run2 = distribution.start(List.of("jetty.http.selectors=1", "jetty.http.port=" + httpPort)))
{
@@ -1618,7 +1626,7 @@ public class DistributionTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http," + toEnvironment("deploy", env) + "," + toEnvironment("webapp", env)
@@ -1635,11 +1643,11 @@ public class DistributionTests extends AbstractJettyHomeTest
};
// Put war into ${jetty.base}/wars/ directory
- File srcWar = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-simple-webapp:war:" + jettyVersion);
+ Path srcWar = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-simple-webapp:war:" + jettyVersion);
Path warsDir = jettyBase.resolve("wars");
FS.ensureDirExists(warsDir);
Path destWar = warsDir.resolve("demo.war");
- Files.copy(srcWar.toPath(), destWar);
+ Files.copy(srcWar, destWar);
// Create XML for deployable
String xml = """
@@ -1702,7 +1710,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(10, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
List args = List.of(
"jetty.inetaccess.exclude=|/excludedPath/*",
"jetty.http.port=" + httpPort);
@@ -1739,7 +1747,7 @@ public class DistributionTests extends AbstractJettyHomeTest
run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS);
assertThat(run1.getExitValue(), is(0));
- int httpPort1 = distribution.freePort();
+ int httpPort1 = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start(List.of("jetty.http.port=" + httpPort1)))
{
assertThat(run2.awaitConsoleLogsFor("Started oejs.Server", START_TIMEOUT, TimeUnit.SECONDS), is(true));
@@ -1756,7 +1764,7 @@ public class DistributionTests extends AbstractJettyHomeTest
assertTrue(response.getHeaders().contains(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
}
- int httpPort2 = distribution.freePort();
+ int httpPort2 = Tester.freePort();
List args = List.of(
"jetty.http.port=" + httpPort2,
// Allow a different origin.
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java
index 0c0748c4e63..1d94802a596 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java
@@ -18,7 +18,8 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@@ -53,7 +54,7 @@ public class DynamicListenerTests extends AbstractJettyHomeTest
assertEquals(0, run1.getExitValue());
}
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java
index 352b63f06d9..7a100b1280b 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java
@@ -13,14 +13,14 @@
package org.eclipse.jetty.tests.distribution;
-import java.io.File;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@@ -46,7 +46,7 @@ public class GzipModuleTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=http,gzip," + toEnvironment("deploy", env) + "," + toEnvironment("webapp", env)
@@ -61,8 +61,8 @@ public class GzipModuleTests extends AbstractJettyHomeTest
"jetty.http.port=" + httpPort
};
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-simple-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "demo");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-simple-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "demo");
try (JettyHomeTester.Run runStart = distribution.start(argsStart))
{
@@ -88,7 +88,7 @@ public class GzipModuleTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=gzip,http," + toEnvironment("deploy", env) + "," + toEnvironment("webapp", env)
@@ -103,8 +103,8 @@ public class GzipModuleTests extends AbstractJettyHomeTest
"jetty.http.port=" + httpPort
};
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-simple-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "demo");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + "-demo-simple-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "demo");
try (JettyHomeTester.Run runStart = distribution.start(argsStart))
{
@@ -131,7 +131,7 @@ public class GzipModuleTests extends AbstractJettyHomeTest
.jettyBase(jettyBase)
.build();
- int httpPort = distribution.freePort();
+ int httpPort = Tester.freePort();
String[] argsConfig = {
"--add-modules=gzip,http," + toEnvironment("deploy", env) + "," + toEnvironment("webapp", env)
@@ -147,8 +147,8 @@ public class GzipModuleTests extends AbstractJettyHomeTest
"jetty.gzip.excludedMimeTypeList=image/vnd.microsoft.icon"
};
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + " .demos:jetty-" + env + "-demo-simple-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "demo");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + " .demos:jetty-" + env + "-demo-simple-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "demo");
try (JettyHomeTester.Run runStart = distribution.start(argsStart))
{
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/LoggingOptionsTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/LoggingOptionsTests.java
index e51359ffad4..34a50de7312 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/LoggingOptionsTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/LoggingOptionsTests.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.tests.distribution;
-import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
@@ -24,7 +23,8 @@ import java.util.stream.Stream;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -169,10 +169,10 @@ public class LoggingOptionsTests extends AbstractJettyHomeTest
}
}
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + ".demo-jsp-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ".demos:jetty-" + env + ".demo-jsp-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run requestRun = distribution.start("jetty.http.port=" + port))
{
assertTrue(requestRun.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/ModulesTest.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/ModulesTest.java
index ab54802b26c..beb1e30d8c2 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/ModulesTest.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/ModulesTest.java
@@ -18,7 +18,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.logging.JettyLevel;
import org.eclipse.jetty.logging.JettyLogger;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java
index 85ad0ad83af..3c84c466cd0 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java
@@ -13,12 +13,13 @@
package org.eclipse.jetty.tests.distribution;
-import java.io.File;
+import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@@ -52,10 +53,10 @@ public class OsgiAppTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-felix-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-felix-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
try (JettyHomeTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/StatsTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/StatsTests.java
index 8ead169cd4c..140a77c4bf1 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/StatsTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/StatsTests.java
@@ -25,7 +25,8 @@ import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.util.ajax.JSON;
import org.junit.jupiter.api.Disabled;
@@ -69,7 +70,7 @@ public class StatsTests extends AbstractJettyHomeTest
distribution.installBaseResource("stats-webapp-" + env + "/index.html", "webapps/demo/index.html");
distribution.installBaseResource("stats-webapp-" + env + "/WEB-INF/web.xml", "webapps/demo/WEB-INF/web.xml");
- int port = distribution.freePort();
+ int port = Tester.freePort();
String[] args2 = {
"jetty.http.port=" + port
};
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/jettysh/ImageOS.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/jettysh/ImageOS.java
index 1744ded579d..dc5670cdd7e 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/jettysh/ImageOS.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/jettysh/ImageOS.java
@@ -17,7 +17,7 @@ import java.io.File;
import java.nio.file.Path;
import java.util.function.Consumer;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
import org.testcontainers.images.builder.dockerfile.DockerfileBuilder;
public abstract class ImageOS extends ImageFromDSL
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/AbstractSessionDistributionTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/AbstractSessionDistributionTests.java
index b53ca15788f..e5c7080d2ab 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/AbstractSessionDistributionTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/AbstractSessionDistributionTests.java
@@ -14,7 +14,6 @@
package org.eclipse.jetty.tests.distribution.session;
import java.io.BufferedWriter;
-import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -29,7 +28,8 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@@ -87,11 +87,11 @@ public abstract class AbstractSessionDistributionTests extends AbstractJettyHome
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File war = jettyHomeTester.resolveArtifact("org.eclipse.jetty." + environment +
+ Path war = jettyHomeTester.resolveArtifact("org.eclipse.jetty." + environment +
":" + "jetty-" + environment + "-test-simple-session-webapp:war:" + jettyVersion);
- jettyHomeTester.installWarFile(war, "test");
+ jettyHomeTester.installWar(war, "test");
- int port = jettyHomeTester.freePort();
+ int port = Tester.freePort();
args = new ArrayList<>(Collections.singletonList("jetty.http.port=" + port));
args.addAll(getSecondStartExtraArgs());
argsStart = args.toArray(new String[0]);
diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/HazelcastSessionDistributionTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/HazelcastSessionDistributionTests.java
index 4fe9d1150f0..2a3afa57778 100644
--- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/HazelcastSessionDistributionTests.java
+++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/HazelcastSessionDistributionTests.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.tests.distribution.session;
-import java.io.File;
import java.io.OutputStream;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
@@ -29,7 +28,8 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
@@ -161,10 +161,10 @@ public class HazelcastSessionDistributionTests extends AbstractSessionDistributi
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-session-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ Path war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-session-webapp:war:" + jettyVersion);
+ distribution.installWar(war, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
List argsStart = Arrays.asList(
"jetty.http.port=" + port,
"jetty.session.hazelcast.onlyClient=false",
diff --git a/tests/test-distribution/test-ee10-distribution/pom.xml b/tests/test-distribution/test-ee10-distribution/pom.xml
index 5be75047bdd..3c664deea44 100644
--- a/tests/test-distribution/test-ee10-distribution/pom.xml
+++ b/tests/test-distribution/test-ee10-distribution/pom.xml
@@ -13,41 +13,9 @@
${project.groupId}.ee10.distribution
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.eclipse.jetty.tests
- test-distribution-common
-
-
- org.eclipse.jetty.toolchain
- jetty-test-helper
-
-
- org.junit.jupiter
- junit-jupiter
-
-
-
- org.slf4j
- slf4j-api
-
org.eclipse.jetty
jetty-client
@@ -56,14 +24,11 @@
org.eclipse.jetty
jetty-openid
- ${project.version}
test
-
org.eclipse.jetty
jetty-slf4j-impl
- ${project.version}
test
@@ -79,6 +44,11 @@
war
test
+
+ org.eclipse.jetty.tests
+ jetty-testers
+ test
+
org.eclipse.jetty.tests
test-distribution-common
diff --git a/tests/test-distribution/test-ee10-distribution/src/test/java/org/eclipse/jetty/ee10/tests/distribution/OpenIdTests.java b/tests/test-distribution/test-ee10-distribution/src/test/java/org/eclipse/jetty/ee10/tests/distribution/OpenIdTests.java
index 8746d279639..78d8f31fa51 100644
--- a/tests/test-distribution/test-ee10-distribution/src/test/java/org/eclipse/jetty/ee10/tests/distribution/OpenIdTests.java
+++ b/tests/test-distribution/test-ee10-distribution/src/test/java/org/eclipse/jetty/ee10/tests/distribution/OpenIdTests.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.ee10.tests.distribution;
-import java.io.File;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
@@ -21,7 +20,8 @@ import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.ee10.tests.distribution.openid.OpenIdProvider;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -56,10 +56,10 @@ public class OpenIdTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File webApp = distribution.resolveArtifact("org.eclipse.jetty.ee10:jetty-ee10-test-openid-webapp:war:" + jettyVersion);
- distribution.installWarFile(webApp, "test");
+ Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee10:jetty-ee10-test-openid-webapp:war:" + jettyVersion);
+ distribution.installWar(webApp, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
openIdProvider.start();
String[] args2 = {
diff --git a/tests/test-distribution/test-ee9-distribution/pom.xml b/tests/test-distribution/test-ee9-distribution/pom.xml
index d41933d8c20..2b93c735312 100644
--- a/tests/test-distribution/test-ee9-distribution/pom.xml
+++ b/tests/test-distribution/test-ee9-distribution/pom.xml
@@ -13,40 +13,9 @@
${project.groupId}.ee9.distribution
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.eclipse.jetty.tests
- test-distribution-common
-
-
- org.eclipse.jetty.toolchain
- jetty-test-helper
-
-
- org.junit.jupiter
- junit-jupiter
-
-
- org.slf4j
- slf4j-api
-
org.eclipse.jetty
jetty-client
@@ -55,7 +24,6 @@
org.eclipse.jetty
jetty-slf4j-impl
- ${project.version}
test
@@ -77,6 +45,11 @@
war
test
+
+ org.eclipse.jetty.tests
+ jetty-testers
+ test
+
org.eclipse.jetty.tests
test-distribution-common
diff --git a/tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/OpenIdTests.java b/tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/OpenIdTests.java
index ff8b0fb236c..410dd07f49c 100644
--- a/tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/OpenIdTests.java
+++ b/tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/OpenIdTests.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.ee9.tests.distribution;
-import java.io.File;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
@@ -21,7 +20,8 @@ import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.ee9.tests.distribution.openid.OpenIdProvider;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
-import org.eclipse.jetty.tests.hometester.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.JettyHomeTester;
+import org.eclipse.jetty.tests.testers.Tester;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -59,10 +59,10 @@ public class OpenIdTests extends AbstractJettyHomeTest
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
- File webApp = distribution.resolveArtifact("org.eclipse.jetty.ee9:jetty-ee9-test-openid-webapp:war:" + jettyVersion);
- distribution.installWarFile(webApp, "test");
+ Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee9:jetty-ee9-test-openid-webapp:war:" + jettyVersion);
+ distribution.installWar(webApp, "test");
- int port = distribution.freePort();
+ int port = Tester.freePort();
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
openIdProvider.start();
String[] args2 = {