Merge branch 'jetty-9.4.x'
This commit is contained in:
commit
6d669892b7
|
@ -32,41 +32,9 @@
|
||||||
<onlyAnalyze>org.eclipse.jetty.start.*</onlyAnalyze>
|
<onlyAnalyze>org.eclipse.jetty.start.*</onlyAnalyze>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<minimizeJar>true</minimizeJar>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
<artifactSet>
|
|
||||||
<includes>
|
|
||||||
<include>org.eclipse.jetty:jetty-util</include>
|
|
||||||
</includes>
|
|
||||||
</artifactSet>
|
|
||||||
<relocations>
|
|
||||||
<relocation>
|
|
||||||
<pattern>org.eclipse.jetty.util</pattern>
|
|
||||||
<shadedPattern>org.eclipse.jetty.start.util</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
</relocations>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-util</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||||
<artifactId>jetty-test-helper</artifactId>
|
<artifactId>jetty-test-helper</artifactId>
|
||||||
|
|
|
@ -34,8 +34,6 @@ import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.TopologicalSort;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access for all modules declared, as well as what is enabled.
|
* Access for all modules declared, as well as what is enabled.
|
||||||
*/
|
*/
|
||||||
|
@ -205,15 +203,8 @@ public class Modules implements Iterable<Module>
|
||||||
module.getDepends().forEach(add);
|
module.getDepends().forEach(add);
|
||||||
module.getOptional().forEach(add);
|
module.getOptional().forEach(add);
|
||||||
}
|
}
|
||||||
try
|
|
||||||
{
|
sort.sort(_modules);
|
||||||
sort.sort(_modules);
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e)
|
|
||||||
{
|
|
||||||
System.err.println(sort.dump());
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Module> getEnabled()
|
public List<Module> getEnabled()
|
||||||
|
|
|
@ -41,6 +41,7 @@ public class StartLog
|
||||||
private final static PrintStream stderr = System.err;
|
private final static PrintStream stderr = System.err;
|
||||||
private static volatile PrintStream out = System.out;
|
private static volatile PrintStream out = System.out;
|
||||||
private static volatile PrintStream err = System.err;
|
private static volatile PrintStream err = System.err;
|
||||||
|
private static volatile PrintStream logStream = System.err;
|
||||||
private final static StartLog INSTANCE = new StartLog();
|
private final static StartLog INSTANCE = new StartLog();
|
||||||
|
|
||||||
public static void debug(String format, Object... args)
|
public static void debug(String format, Object... args)
|
||||||
|
@ -74,12 +75,12 @@ public class StartLog
|
||||||
|
|
||||||
public static void log(String type, String msg)
|
public static void log(String type, String msg)
|
||||||
{
|
{
|
||||||
err.println(type + ": " + msg);
|
logStream.println(type + ": " + msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void log(String type, String format, Object... args)
|
public static void log(String type, String format, Object... args)
|
||||||
{
|
{
|
||||||
err.printf(type + ": " + format + "%n",args);
|
logStream.printf(type + ": " + format + "%n",args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(String format, Object... args)
|
public static void info(String format, Object... args)
|
||||||
|
@ -94,7 +95,7 @@ public class StartLog
|
||||||
|
|
||||||
public static void warn(Throwable t)
|
public static void warn(Throwable t)
|
||||||
{
|
{
|
||||||
t.printStackTrace(err);
|
t.printStackTrace(logStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isDebugEnabled()
|
public static boolean isDebugEnabled()
|
||||||
|
@ -163,9 +164,10 @@ public class StartLog
|
||||||
|
|
||||||
err.println("StartLog to " + logfile);
|
err.println("StartLog to " + logfile);
|
||||||
OutputStream fileout = Files.newOutputStream(startLog,StandardOpenOption.CREATE,StandardOpenOption.APPEND);
|
OutputStream fileout = Files.newOutputStream(startLog,StandardOpenOption.CREATE,StandardOpenOption.APPEND);
|
||||||
PrintStream logger = new PrintStream(fileout);
|
PrintStream logger = new PrintStream(fileout,true);
|
||||||
out=logger;
|
out=logger;
|
||||||
err=logger;
|
err=logger;
|
||||||
|
setStream(logger);
|
||||||
System.setErr(logger);
|
System.setErr(logger);
|
||||||
System.setOut(logger);
|
System.setOut(logger);
|
||||||
err.println("StartLog Establishing " + logfile + " on " + new Date());
|
err.println("StartLog Establishing " + logfile + " on " + new Date());
|
||||||
|
@ -189,7 +191,20 @@ public class StartLog
|
||||||
err.println("StartLog ended");
|
err.println("StartLog ended");
|
||||||
stderr.println("StartLog ended");
|
stderr.println("StartLog ended");
|
||||||
}
|
}
|
||||||
|
setStream(stderr);
|
||||||
System.setErr(stderr);
|
System.setErr(stderr);
|
||||||
System.setOut(stdout);
|
System.setOut(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PrintStream getStream()
|
||||||
|
{
|
||||||
|
return logStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PrintStream setStream(PrintStream stream)
|
||||||
|
{
|
||||||
|
PrintStream ret = logStream;
|
||||||
|
logStream = stream;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.eclipse.jetty.start;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Topological sort a list or array.
|
||||||
|
* <p>A Topological sort is used when you have a partial ordering expressed as
|
||||||
|
* dependencies between elements (also often represented as edges in a directed
|
||||||
|
* acyclic graph). A Topological sort should not be used when you have a total
|
||||||
|
* ordering expressed as a {@link Comparator} over the items. The algorithm has
|
||||||
|
* the additional characteristic that dependency sets are sorted by the original
|
||||||
|
* list order so that order is preserved when possible.</p>
|
||||||
|
* <p>
|
||||||
|
* The sort algorithm works by recursively visiting every item, once and
|
||||||
|
* only once. On each visit, the items dependencies are first visited and then the
|
||||||
|
* item is added to the sorted list. Thus the algorithm ensures that dependency
|
||||||
|
* items are always added before dependent items.</p>
|
||||||
|
*
|
||||||
|
* @param <T> The type to be sorted. It must be able to be added to a {@link HashSet}
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public class TopologicalSort<T>
|
||||||
|
{
|
||||||
|
private final Map<T,Set<T>> _dependencies = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a dependency to be considered in the sort.
|
||||||
|
* @param dependent The dependent item will be sorted after all its dependencies
|
||||||
|
* @param dependency The dependency item, will be sorted before its dependent item
|
||||||
|
*/
|
||||||
|
public void addDependency(T dependent, T dependency)
|
||||||
|
{
|
||||||
|
Set<T> set = _dependencies.get(dependent);
|
||||||
|
if (set==null)
|
||||||
|
{
|
||||||
|
set=new HashSet<>();
|
||||||
|
_dependencies.put(dependent,set);
|
||||||
|
}
|
||||||
|
set.add(dependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sort the passed array according to dependencies previously set with
|
||||||
|
* {@link #addDependency(Object, Object)}. Where possible, ordering will be
|
||||||
|
* preserved if no dependency
|
||||||
|
* @param array The array to be sorted.
|
||||||
|
*/
|
||||||
|
public void sort(T[] array)
|
||||||
|
{
|
||||||
|
List<T> sorted = new ArrayList<>();
|
||||||
|
Set<T> visited = new HashSet<>();
|
||||||
|
Comparator<T> comparator = new InitialOrderComparator<>(array);
|
||||||
|
|
||||||
|
// Visit all items in the array
|
||||||
|
for (T t : array)
|
||||||
|
visit(t,visited,sorted,comparator);
|
||||||
|
|
||||||
|
sorted.toArray(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sort the passed list according to dependencies previously set with
|
||||||
|
* {@link #addDependency(Object, Object)}. Where possible, ordering will be
|
||||||
|
* preserved if no dependency
|
||||||
|
* @param list The list to be sorted.
|
||||||
|
*/
|
||||||
|
public void sort(Collection<T> list)
|
||||||
|
{
|
||||||
|
List<T> sorted = new ArrayList<>();
|
||||||
|
Set<T> visited = new HashSet<>();
|
||||||
|
Comparator<T> comparator = new InitialOrderComparator<>(list);
|
||||||
|
|
||||||
|
// Visit all items in the list
|
||||||
|
for (T t : list)
|
||||||
|
visit(t,visited,sorted,comparator);
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
list.addAll(sorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Visit an item to be sorted.
|
||||||
|
* @param item The item to be visited
|
||||||
|
* @param visited The Set of items already visited
|
||||||
|
* @param sorted The list to sort items into
|
||||||
|
* @param comparator A comparator used to sort dependencies.
|
||||||
|
*/
|
||||||
|
private void visit(T item, Set<T> visited, List<T> sorted,Comparator<T> comparator)
|
||||||
|
{
|
||||||
|
// If the item has not been visited
|
||||||
|
if(!visited.contains(item))
|
||||||
|
{
|
||||||
|
// We are visiting it now, so add it to the visited set
|
||||||
|
visited.add(item);
|
||||||
|
|
||||||
|
// Lookup the items dependencies
|
||||||
|
Set<T> dependencies = _dependencies.get(item);
|
||||||
|
if (dependencies!=null)
|
||||||
|
{
|
||||||
|
// Sort the dependencies
|
||||||
|
SortedSet<T> ordered_deps = new TreeSet<>(comparator);
|
||||||
|
ordered_deps.addAll(dependencies);
|
||||||
|
|
||||||
|
// recursively visit each dependency
|
||||||
|
for (T d:ordered_deps)
|
||||||
|
visit(d,visited,sorted,comparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that we have visited all our dependencies, they and their
|
||||||
|
// dependencies will have been added to the sorted list. So we can
|
||||||
|
// now add the current item and it will be after its dependencies
|
||||||
|
sorted.add(item);
|
||||||
|
}
|
||||||
|
else if (!sorted.contains(item))
|
||||||
|
// If we have already visited an item, but it has not yet been put in the
|
||||||
|
// sorted list, then we must be in a cycle!
|
||||||
|
throw new IllegalStateException("cyclic at "+item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** A comparator that is used to sort dependencies in the order they
|
||||||
|
* were in the original list. This ensures that dependencies are visited
|
||||||
|
* in the original order and no needless reordering takes place.
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
private static class InitialOrderComparator<T> implements Comparator<T>
|
||||||
|
{
|
||||||
|
private final Map<T,Integer> _indexes = new HashMap<>();
|
||||||
|
InitialOrderComparator(T[] initial)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
for (T t : initial)
|
||||||
|
_indexes.put(t,i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
InitialOrderComparator(Collection<T> initial)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
for (T t : initial)
|
||||||
|
_indexes.put(t,i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(T o1, T o2)
|
||||||
|
{
|
||||||
|
Integer i1=_indexes.get(o1);
|
||||||
|
Integer i2=_indexes.get(o2);
|
||||||
|
if (i1==null || i2==null || i1.equals(o2))
|
||||||
|
return 0;
|
||||||
|
if (i1<i2)
|
||||||
|
return -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "TopologicalSort "+_dependencies;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,24 +20,25 @@ package org.eclipse.jetty.start;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.eclipse.jetty.start.Props.Prop;
|
import org.eclipse.jetty.start.Props.Prop;
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
|
import org.eclipse.jetty.toolchain.test.PathAssert;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
@ -45,38 +46,51 @@ public class ConfigurationAssert
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file.
|
* Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file.
|
||||||
*
|
*
|
||||||
* @param baseHome
|
* @param baseHome the BaseHome used. Access it via {@link Main#getBaseHome()}
|
||||||
* the BaseHome used. Access it via {@link Main#getBaseHome()}
|
* @param args the StartArgs that has been processed via {@link Main#processCommandLine(String[])}
|
||||||
* @param args
|
* @param filename the filename of the assertion values
|
||||||
* the StartArgs that has been processed via {@link Main#processCommandLine(String[])}
|
|
||||||
* @param filename
|
|
||||||
* the filename of the assertion values
|
|
||||||
* @throws FileNotFoundException if unable to find the configuration
|
* @throws FileNotFoundException if unable to find the configuration
|
||||||
* @throws IOException if unable to process the configuration
|
* @throws IOException if unable to process the configuration
|
||||||
*/
|
*/
|
||||||
public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException
|
public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException
|
||||||
{
|
{
|
||||||
assertConfiguration(baseHome,args,MavenTestingUtils.getTestResourceFile(filename));
|
assertConfiguration(baseHome, args, null, MavenTestingUtils.getTestResourceFile(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file.
|
* Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file.
|
||||||
*
|
*
|
||||||
* @param baseHome
|
* @param baseHome the BaseHome used. Access it via {@link Main#getBaseHome()}
|
||||||
* the BaseHome used. Access it via {@link Main#getBaseHome()}
|
* @param args the StartArgs that has been processed via {@link Main#processCommandLine(String[])}
|
||||||
* @param args
|
* @param output the captured output that you want to assert against
|
||||||
* the StartArgs that has been processed via {@link Main#processCommandLine(String[])}
|
* @param filename the filename of the assertion values
|
||||||
* @param file
|
|
||||||
* the file of the assertion values
|
|
||||||
* @throws FileNotFoundException if unable to find the configuration
|
* @throws FileNotFoundException if unable to find the configuration
|
||||||
* @throws IOException if unable to process the configuration
|
* @throws IOException if unable to process the configuration
|
||||||
*/
|
*/
|
||||||
public static void assertConfiguration(BaseHome baseHome, StartArgs args, File file) throws FileNotFoundException, IOException
|
public static void assertConfiguration(BaseHome baseHome, StartArgs args, String output, String filename) throws FileNotFoundException, IOException
|
||||||
{
|
{
|
||||||
|
assertConfiguration(baseHome, args, output, MavenTestingUtils.getTestResourceFile(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file.
|
||||||
|
*
|
||||||
|
* @param baseHome the BaseHome used. Access it via {@link Main#getBaseHome()}
|
||||||
|
* @param args the StartArgs that has been processed via {@link Main#processCommandLine(String[])}
|
||||||
|
* @param file the file of the assertion values
|
||||||
|
* @throws FileNotFoundException if unable to find the configuration
|
||||||
|
* @throws IOException if unable to process the configuration
|
||||||
|
*/
|
||||||
|
public static void assertConfiguration(BaseHome baseHome, StartArgs args, String output, File file) throws FileNotFoundException, IOException
|
||||||
|
{
|
||||||
|
if(output != null)
|
||||||
|
{
|
||||||
|
System.err.println(output);
|
||||||
|
}
|
||||||
Path testResourcesDir = MavenTestingUtils.getTestResourcesDir().toPath().toRealPath();
|
Path testResourcesDir = MavenTestingUtils.getTestResourcesDir().toPath().toRealPath();
|
||||||
TextFile textFile = new TextFile(file.toPath());
|
TextFile textFile = new TextFile(file.toPath());
|
||||||
|
|
||||||
// Validate XMLs (order is important)
|
// Validate XMLs (order is important)
|
||||||
List<String> expectedXmls = new ArrayList<>();
|
List<String> expectedXmls = new ArrayList<>();
|
||||||
for (String line : textFile)
|
for (String line : textFile)
|
||||||
|
@ -89,10 +103,10 @@ public class ConfigurationAssert
|
||||||
List<String> actualXmls = new ArrayList<>();
|
List<String> actualXmls = new ArrayList<>();
|
||||||
for (Path xml : args.getXmlFiles())
|
for (Path xml : args.getXmlFiles())
|
||||||
{
|
{
|
||||||
actualXmls.add(shorten(baseHome,xml,testResourcesDir));
|
actualXmls.add(shorten(baseHome, xml, testResourcesDir));
|
||||||
}
|
}
|
||||||
assertOrdered("XML Resolution Order",expectedXmls,actualXmls);
|
assertOrdered("XML Resolution Order", expectedXmls, actualXmls);
|
||||||
|
|
||||||
// Validate LIBs (order is not important)
|
// Validate LIBs (order is not important)
|
||||||
List<String> expectedLibs = new ArrayList<>();
|
List<String> expectedLibs = new ArrayList<>();
|
||||||
for (String line : textFile)
|
for (String line : textFile)
|
||||||
|
@ -105,10 +119,10 @@ public class ConfigurationAssert
|
||||||
List<String> actualLibs = new ArrayList<>();
|
List<String> actualLibs = new ArrayList<>();
|
||||||
for (File path : args.getClasspath())
|
for (File path : args.getClasspath())
|
||||||
{
|
{
|
||||||
actualLibs.add(shorten(baseHome,path.toPath(),testResourcesDir));
|
actualLibs.add(shorten(baseHome, path.toPath(), testResourcesDir));
|
||||||
}
|
}
|
||||||
assertContainsUnordered("Libs",expectedLibs,actualLibs);
|
assertContainsUnordered("Libs", expectedLibs, actualLibs);
|
||||||
|
|
||||||
// Validate PROPERTIES (order is not important)
|
// Validate PROPERTIES (order is not important)
|
||||||
Set<String> expectedProperties = new HashSet<>();
|
Set<String> expectedProperties = new HashSet<>();
|
||||||
for (String line : textFile)
|
for (String line : textFile)
|
||||||
|
@ -123,16 +137,16 @@ public class ConfigurationAssert
|
||||||
{
|
{
|
||||||
String name = prop.key;
|
String name = prop.key;
|
||||||
if ("jetty.home".equals(name) || "jetty.base".equals(name) ||
|
if ("jetty.home".equals(name) || "jetty.base".equals(name) ||
|
||||||
"user.dir".equals(name) || prop.origin.equals(Props.ORIGIN_SYSPROP) ||
|
"user.dir".equals(name) || prop.origin.equals(Props.ORIGIN_SYSPROP) ||
|
||||||
name.startsWith("java."))
|
name.startsWith("java."))
|
||||||
{
|
{
|
||||||
// strip these out from assertion, to make assertions easier.
|
// strip these out from assertion, to make assertions easier.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
actualProperties.add(prop.key + "=" + args.getProperties().expand(prop.value));
|
actualProperties.add(prop.key + "=" + args.getProperties().expand(prop.value));
|
||||||
}
|
}
|
||||||
assertContainsUnordered("Properties",expectedProperties,actualProperties);
|
assertContainsUnordered("Properties", expectedProperties, actualProperties);
|
||||||
|
|
||||||
// Validate Downloads
|
// Validate Downloads
|
||||||
List<String> expectedDownloads = new ArrayList<>();
|
List<String> expectedDownloads = new ArrayList<>();
|
||||||
for (String line : textFile)
|
for (String line : textFile)
|
||||||
|
@ -147,20 +161,34 @@ public class ConfigurationAssert
|
||||||
{
|
{
|
||||||
if (darg.uri != null)
|
if (darg.uri != null)
|
||||||
{
|
{
|
||||||
actualDownloads.add(String.format("%s|%s",darg.uri,darg.location));
|
actualDownloads.add(String.format("%s|%s", darg.uri, darg.location));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertContainsUnordered("Downloads",expectedDownloads,actualDownloads);
|
assertContainsUnordered("Downloads", expectedDownloads, actualDownloads);
|
||||||
|
|
||||||
textFile.stream()
|
// File / Path Existence Checks
|
||||||
.filter(s->s.startsWith("EXISTS|")).map(f->f.substring(7)).forEach(f->
|
streamOf(textFile, "EXISTS").forEach(f ->
|
||||||
{
|
{
|
||||||
Path path=baseHome.getBasePath().resolve(f);
|
Path path = baseHome.getPath(f);
|
||||||
assertTrue(baseHome.toShortForm(path)+" exists?",Files.exists(path));
|
if (f.endsWith("/"))
|
||||||
assertEquals(baseHome.toShortForm(path)+" isDir?",f.endsWith("/"),Files.isDirectory(path));
|
{
|
||||||
|
PathAssert.assertDirExists("Required Directory", path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PathAssert.assertFileExists("Required File", path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Output Validation
|
||||||
|
streamOf(textFile, "OUTPUT").forEach(regex ->
|
||||||
|
{
|
||||||
|
Pattern pat = Pattern.compile(regex);
|
||||||
|
Matcher mat = pat.matcher(output);
|
||||||
|
assertTrue("Output [\n" + output + "]\nContains Regex Match: " + pat.pattern(), mat.find());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String shorten(BaseHome baseHome, Path path, Path testResourcesDir)
|
private static String shorten(BaseHome baseHome, Path path, Path testResourcesDir)
|
||||||
{
|
{
|
||||||
String value = baseHome.toShortForm(path);
|
String value = baseHome.toShortForm(path);
|
||||||
|
@ -168,7 +196,7 @@ public class ConfigurationAssert
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.startsWith(testResourcesDir))
|
if (path.startsWith(testResourcesDir))
|
||||||
{
|
{
|
||||||
int len = testResourcesDir.toString().length();
|
int len = testResourcesDir.toString().length();
|
||||||
|
@ -181,41 +209,47 @@ public class ConfigurationAssert
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Assert.assertEquals(msg,expectedSet.size(),actualSet.size());
|
Assert.assertEquals(msg, expectedSet.size(), actualSet.size());
|
||||||
if (!expectedSet.isEmpty())
|
if (!expectedSet.isEmpty())
|
||||||
Assert.assertThat(msg,actualSet,Matchers.containsInAnyOrder(expectedSet.toArray()));
|
assertThat(msg, actualSet, Matchers.containsInAnyOrder(expectedSet.toArray()));
|
||||||
}
|
}
|
||||||
catch(AssertionError e)
|
catch (AssertionError e)
|
||||||
{
|
{
|
||||||
System.err.println("Expected: "+expectedSet);
|
System.err.println("Expected: " + expectedSet);
|
||||||
System.err.println("Actual : "+actualSet);
|
System.err.println("Actual : " + actualSet);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void assertOrdered(String msg, List<String> expectedList, List<String> actualList)
|
public static void assertOrdered(String msg, List<String> expectedList, List<String> actualList)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Assert.assertEquals(msg,expectedList.size(),actualList.size());
|
Assert.assertEquals(msg, expectedList.size(), actualList.size());
|
||||||
if (!expectedList.isEmpty())
|
if (!expectedList.isEmpty())
|
||||||
Assert.assertThat(msg,actualList,Matchers.contains(expectedList.toArray()));
|
assertThat(msg, actualList, Matchers.contains(expectedList.toArray()));
|
||||||
}
|
}
|
||||||
catch(AssertionError e)
|
catch (AssertionError e)
|
||||||
{
|
{
|
||||||
System.err.println("Expected: "+expectedList);
|
System.err.println("Expected: " + expectedList);
|
||||||
System.err.println("Actual : "+actualList);
|
System.err.println("Actual : " + actualList);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Stream<String> streamOf(TextFile textFile, String key)
|
||||||
|
{
|
||||||
|
return textFile.stream()
|
||||||
|
.filter(s -> s.startsWith(key + "|")).map(f -> getValue(f));
|
||||||
|
}
|
||||||
|
|
||||||
private static String getValue(String arg)
|
private static String getValue(String arg)
|
||||||
{
|
{
|
||||||
int idx = arg.indexOf('|');
|
int idx = arg.indexOf('|');
|
||||||
Assert.assertThat("Expecting '|' sign in [" + arg + "]",idx,greaterThanOrEqualTo(0));
|
assertThat("Expecting '|' sign in [" + arg + "]", idx, greaterThanOrEqualTo(0));
|
||||||
String value = arg.substring(idx + 1).trim();
|
String value = arg.substring(idx + 1).trim();
|
||||||
Assert.assertThat("Expecting Value after '|' in [" + arg + "]",value.length(),greaterThan(0));
|
assertThat("Expecting Value after '|' in [" + arg + "]", value.length(), greaterThan(0));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.toolchain.test.IO;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
|
|
|
@ -20,15 +20,19 @@ package org.eclipse.jetty.start;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.IO;
|
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@ -46,107 +50,114 @@ public class TestUseCases
|
||||||
{
|
{
|
||||||
@Parameters(name = "{0}")
|
@Parameters(name = "{0}")
|
||||||
public static List<Object[]> getCases() throws Exception
|
public static List<Object[]> getCases() throws Exception
|
||||||
{
|
{
|
||||||
File usecases = MavenTestingUtils.getTestResourceDir("usecases/");
|
File usecases = MavenTestingUtils.getTestResourceDir("usecases/");
|
||||||
File[] cases=usecases.listFiles(new FilenameFilter()
|
File[] cases = usecases.listFiles((dir, name) -> name.endsWith(".assert.txt"));
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean accept(File dir, String name)
|
|
||||||
{
|
|
||||||
return name.endsWith(".assert.txt");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Arrays.sort(cases);
|
Arrays.sort(cases);
|
||||||
|
|
||||||
List<Object[]> ret = new ArrayList<>();
|
List<Object[]> ret = new ArrayList<>();
|
||||||
for(File assertTxt:cases)
|
for (File assertTxt : cases)
|
||||||
{
|
{
|
||||||
String caseName=assertTxt.getName().replace(".assert.txt","");
|
String caseName = assertTxt.getName().replace(".assert.txt", "");
|
||||||
String baseName=caseName.split("\\.")[0];
|
ret.add(new Object[]{caseName});
|
||||||
ret.add(new Object[] {caseName,baseName, assertTxt, lines(new File(usecases,caseName+".prepare.txt")),lines(new File(usecases,caseName+".cmdline.txt"))});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String[] lines(File file) throws IOException
|
|
||||||
{
|
|
||||||
if (!file.exists() || !file.canRead())
|
|
||||||
return new String[0];
|
|
||||||
return IO.readToString(file).split("[\n\r]+");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Parameter(0)
|
@Parameter(0)
|
||||||
public String caseName;
|
public String caseName;
|
||||||
|
|
||||||
@Parameter(1)
|
|
||||||
public String baseName;
|
|
||||||
|
|
||||||
@Parameter(2)
|
|
||||||
public File assertFile;
|
|
||||||
|
|
||||||
@Parameter(3)
|
|
||||||
public String[] prepare;
|
|
||||||
|
|
||||||
@Parameter(4)
|
|
||||||
public String[] commandLineArgs;
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUseCase() throws Exception
|
public void testUseCase() throws Exception
|
||||||
{
|
{
|
||||||
|
String baseName = caseName.replaceFirst("\\..*$", "");
|
||||||
|
File assertFile = MavenTestingUtils.getTestResourceFile("usecases/" + caseName + ".assert.txt");
|
||||||
|
|
||||||
Path homeDir = MavenTestingUtils.getTestResourceDir("dist-home").toPath().toRealPath();
|
Path homeDir = MavenTestingUtils.getTestResourceDir("dist-home").toPath().toRealPath();
|
||||||
|
|
||||||
Path baseSrcDir = MavenTestingUtils.getTestResourceDir("usecases/" + baseName).toPath().toRealPath();
|
Path baseSrcDir = MavenTestingUtils.getTestResourceDir("usecases/" + baseName).toPath().toRealPath();
|
||||||
Path baseDir = MavenTestingUtils.getTargetTestingPath(caseName);
|
Path baseDir = MavenTestingUtils.getTargetTestingPath(caseName);
|
||||||
if (baseDir.toFile().exists())
|
org.eclipse.jetty.toolchain.test.FS.ensureEmpty(baseDir);
|
||||||
org.eclipse.jetty.toolchain.test.FS.cleanDirectory(baseDir);
|
org.eclipse.jetty.toolchain.test.IO.copyDir(baseSrcDir.toFile(), baseDir.toFile());
|
||||||
else
|
|
||||||
baseDir.toFile().mkdirs();
|
|
||||||
org.eclipse.jetty.toolchain.test.IO.copyDir(baseSrcDir.toFile(),baseDir.toFile());
|
|
||||||
|
|
||||||
|
System.setProperty("jetty.home", homeDir.toString());
|
||||||
|
System.setProperty("jetty.base", baseDir.toString());
|
||||||
|
|
||||||
System.setProperty("jetty.home",homeDir.toString());
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
System.setProperty("jetty.base",baseDir.toString());
|
PrintStream originalStream = StartLog.setStream(new PrintStream(out));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (prepare != null && prepare.length>0)
|
// If there is a "{caseName}.prepare.txt" then use those
|
||||||
|
// lines as if you are calling start.jar once to setup
|
||||||
|
// the base directory.
|
||||||
|
List<String> prepareArgs = lines(caseName + ".prepare.txt");
|
||||||
|
if (!prepareArgs.isEmpty())
|
||||||
{
|
{
|
||||||
for (String arg : prepare)
|
Main main = new Main();
|
||||||
{
|
List<String> cmdLine = new ArrayList<>();
|
||||||
Main main = new Main();
|
cmdLine.add("--testing-mode");
|
||||||
List<String> cmdLine = new ArrayList<>();
|
cmdLine.addAll(prepareArgs);
|
||||||
cmdLine.add("--testing-mode");
|
|
||||||
cmdLine.addAll(Arrays.asList(arg.split(" ")));
|
main.start(main.processCommandLine(cmdLine));
|
||||||
main.start(main.processCommandLine(cmdLine));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Main main = new Main();
|
Main main = new Main();
|
||||||
List<String> cmdLine = new ArrayList<>();
|
List<String> cmdLine = new ArrayList<>();
|
||||||
cmdLine.add("--debug");
|
// cmdLine.add("--debug");
|
||||||
if (commandLineArgs != null)
|
|
||||||
{
|
// If there is a "{caseName}.cmdline.txt" then these
|
||||||
for (String arg : commandLineArgs)
|
// entries are extra command line argument to use for
|
||||||
cmdLine.add(arg);
|
// the actual testcase
|
||||||
}
|
cmdLine.addAll(lines(caseName + ".cmdline.txt"));
|
||||||
|
|
||||||
StartArgs args = main.processCommandLine(cmdLine);
|
StartArgs args = main.processCommandLine(cmdLine);
|
||||||
args.getAllModules().checkEnabledModules();
|
args.getAllModules().checkEnabledModules();
|
||||||
BaseHome baseHome = main.getBaseHome();
|
BaseHome baseHome = main.getBaseHome();
|
||||||
ConfigurationAssert.assertConfiguration(baseHome,args,assertFile);
|
|
||||||
|
StartLog.setStream(originalStream);
|
||||||
|
String output = out.toString(StandardCharsets.UTF_8.name());
|
||||||
|
ConfigurationAssert.assertConfiguration(baseHome, args, output, assertFile);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
List<String> exceptions = Arrays.asList(lines(assertFile)).stream().filter(s->s.startsWith("EX|")).collect(toList());
|
List<String> exceptions = lines(assertFile).stream().filter(s -> s.startsWith("EX|")).collect(toList());
|
||||||
if (exceptions.isEmpty())
|
if (exceptions.isEmpty())
|
||||||
throw e;
|
throw e;
|
||||||
for (String ex:exceptions)
|
for (String ex : exceptions)
|
||||||
{
|
{
|
||||||
ex=ex.substring(3);
|
ex = ex.substring(3);
|
||||||
Assert.assertThat(e.toString(),Matchers.containsString(ex));
|
Assert.assertThat(e.toString(), Matchers.containsString(ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
StartLog.setStream(originalStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> lines(String filename) throws IOException
|
||||||
|
{
|
||||||
|
return lines(MavenTestingUtils.getTestResourcesPath().resolve("usecases" + File.separator + filename).toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> lines(File file) throws IOException
|
||||||
|
{
|
||||||
|
if (!file.exists() || !file.canRead())
|
||||||
|
return Collections.emptyList();
|
||||||
|
List<String> ret = new ArrayList<>();
|
||||||
|
try (FileReader reader = new FileReader(file);
|
||||||
|
BufferedReader buf = new BufferedReader(reader))
|
||||||
|
{
|
||||||
|
String line;
|
||||||
|
while ((line = buf.readLine()) != null)
|
||||||
|
{
|
||||||
|
line = line.trim();
|
||||||
|
if (line.length() > 0)
|
||||||
|
{
|
||||||
|
ret.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
--create-startd --add=tom
|
--create-startd
|
||||||
|
--add-to-start=tom
|
||||||
|
|
|
@ -19,5 +19,9 @@ PROP|optional.prop=value0
|
||||||
|
|
||||||
# Files / Directories to create
|
# Files / Directories to create
|
||||||
EXISTS|maindir/
|
EXISTS|maindir/
|
||||||
EXISTS|start.d/start.ini
|
EXISTS|start.d/main.ini
|
||||||
|
EXISTS|start.d/extra.ini
|
||||||
EXISTS|start.d/optional.ini
|
EXISTS|start.d/optional.ini
|
||||||
|
|
||||||
|
# Output Assertions [regex!] (order is irrelevant)
|
||||||
|
OUTPUT|MKDIR: \$\{jetty.base\}/maindir
|
Loading…
Reference in New Issue