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 = {