From a5bfd42d8f59f270d40fe52b9bb64d3c624989e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 16:55:24 +0100 Subject: [PATCH 01/21] Code import --- .editorconfig | 12 ++ .gitignore | 3 + .travis.yml | 9 + pom.xml | 112 ++++++++++++ .../java/pl/wavesoftware/gasper/Gasper.java | 117 +++++++++++++ .../pl/wavesoftware/gasper/GasperBuilder.java | 116 ++++++++++++ .../gasper/GasperConfigurations.java | 53 ++++++ .../gasper/internal/Executor.java | 165 ++++++++++++++++++ .../gasper/internal/HttpEndpoint.java | 16 ++ .../gasper/internal/Settings.java | 49 ++++++ .../gasper/internal/maven/MavenResolver.java | 67 +++++++ .../internal/maven/MavenResolverIT.java | 39 +++++ 12 files changed, 758 insertions(+) create mode 100644 .editorconfig create mode 100644 .travis.yml create mode 100644 pom.xml create mode 100644 src/main/java/pl/wavesoftware/gasper/Gasper.java create mode 100644 src/main/java/pl/wavesoftware/gasper/GasperBuilder.java create mode 100644 src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java create mode 100644 src/main/java/pl/wavesoftware/gasper/internal/Executor.java create mode 100644 src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java create mode 100644 src/main/java/pl/wavesoftware/gasper/internal/Settings.java create mode 100644 src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java create mode 100644 src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..962eb50 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = space +indent_size = 4 diff --git a/.gitignore b/.gitignore index 1cdc9f7..db834a6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ release.properties dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties + +.idea +*.iml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..54ae82f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +--- +language: java +install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -B -V +script: mvn verify +jdk: + - oraclejdk8 +cache: + directories: + - $HOME/.m2 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..69b97c5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,112 @@ + + + 4.0.0 + pl.wavesoftware + gasper + 1.0.0-SNAPSHOT + jar + Gasper + Very simple integration testing JUnit harness for 'java -jar' servers like WildFly Swarm and Spring Boot + + + 3.0.4 + 1.8 + 1.8 + UTF-8 + UTF-8 + + + + ${maven.required.version} + + + + + org.projectlombok + lombok + 1.16.6 + provided + + + + + junit + junit + 4.12 + + + com.mashape.unirest + unirest-java + 1.4.7 + + + pl.wavesoftware + eid-exceptions + 1.1.0 + + + org.slf4j + slf4j-api + 1.7.18 + + + com.google.guava + guava + 19.0 + + + + org.apache.maven + maven-model + ${maven.required.version} + + + org.apache.maven + maven-core + ${maven.required.version} + + + + org.mockito + mockito-core + 2.0.43-beta + test + + + org.assertj + assertj-core + 3.3.0 + test + + + org.slf4j + slf4j-simple + 1.6.6 + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.19.1 + + + + integration-test + verify + + + + + + + diff --git a/src/main/java/pl/wavesoftware/gasper/Gasper.java b/src/main/java/pl/wavesoftware/gasper/Gasper.java new file mode 100644 index 0000000..695c3e4 --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/Gasper.java @@ -0,0 +1,117 @@ +package pl.wavesoftware.gasper; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import pl.wavesoftware.eid.exceptions.EidIllegalStateException; +import pl.wavesoftware.gasper.internal.Executor; +import pl.wavesoftware.gasper.internal.Settings; +import pl.wavesoftware.gasper.internal.maven.MavenResolver; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static java.lang.String.format; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-04 + */ +@Slf4j +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +public final class Gasper implements TestRule { + + public static final int DEFAULT_PORT_AVAILABLE_MAX_SECONDS = 60; + public static final int DEFAULT_DEPLOYMENT_MAX_SECONDS = 30; + public static final String DEFAULT_CONTEXT = "/"; + + private final Settings settings; + private Path artifact; + private Executor executor; + + public static GasperBuilder builder() { + return new GasperBuilder(); + } + + public static GasperConfigurations configurations() { + return new GasperConfigurations(); + } + + public Integer getPort() { + return settings.getPort(); + } + + protected abstract static class RunnerCreator { + public Gasper create(Settings settings) { + return new Gasper(settings); + } + } + + @Override + public Statement apply(Statement base, Description description) { + try { + setup(); + before(); + return new Statement() { + + @Override + public void evaluate() throws Throwable { + try { + base.evaluate(); + } finally { + after(); + } + } + }; + } catch (IOException e) { + throw new EidIllegalStateException("20160305:004035", e); + } + } + + private void setup() { + log.info(format( + "%s simple integration test pl.wavesoftware.gasper starting!", this.getClass().getSimpleName() + )); + MavenResolver resolver = new MavenResolver(); + artifact = resolver.getBuildArtifact(settings.getPackaging(), settings.getClassifier()); + File workingDirectory = resolver.getBuildDirectory(); + List command = buildCommand(); + log.info(format( + "Command to be executed: \"%s\"", command.stream().collect(Collectors.joining(" ")) + )); + executor = new Executor(command, workingDirectory, settings); + } + + private void before() throws IOException { + executor.start(); + log.info("All looks ready, running tests..."); + } + + private List buildCommand() { + List command = new ArrayList<>(); + command.add("java"); + buildJavaOptions(command); + command.add("-jar"); + command.add(artifact.toAbsolutePath().toString()); + return command; + } + + private void buildJavaOptions(List command) { + command.addAll(settings.getJavaOptions().entrySet().stream() + .map(entry -> format("-D%s=%s", entry.getKey(), entry.getValue())) + .collect(Collectors.toList()) + ); + } + + private void after() { + log.info("Testing on server completed."); + executor.stop(); + } +} diff --git a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java new file mode 100644 index 0000000..343145b --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java @@ -0,0 +1,116 @@ +package pl.wavesoftware.gasper; + +import com.google.common.collect.ImmutableMap; +import pl.wavesoftware.eid.exceptions.EidIllegalStateException; +import pl.wavesoftware.gasper.internal.Executor; +import pl.wavesoftware.gasper.internal.HttpEndpoint; +import pl.wavesoftware.gasper.internal.Settings; +import pl.wavesoftware.gasper.internal.maven.MavenResolver; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.Function; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +public final class GasperBuilder extends Gasper.RunnerCreator { + + private String packaging = MavenResolver.DEFAULT_PACKAGING; + private String classifier = ""; + private Map javaOptions = new LinkedHashMap<>(); + private Map environment = new LinkedHashMap<>(); + private String portJavaOption; + private Integer port; + private boolean inheritIO = false; + private String context = Gasper.DEFAULT_CONTEXT; + private int portAvailableMaxTime = Gasper.DEFAULT_PORT_AVAILABLE_MAX_SECONDS; + private int deploymentMaxTime = Gasper.DEFAULT_DEPLOYMENT_MAX_SECONDS; + private Function contextChecker = Executor.DEFAULT_CONTEXT_CHECKER; + + public GasperBuilder withPackaging(String packaging) { + this.packaging = packaging; + return this; + } + + public GasperBuilder withClassifier(String classifier) { + this.classifier = classifier; + return this; + } + + public GasperBuilder withEnvironmentVariable(String key, String value) { + environment.put(key, value); + return this; + } + + public GasperBuilder withJavaOption(String key, String value) { + javaOptions.put(key, value); + return this; + } + + public GasperBuilder withPort(int port) { + this.port = port; + return this; + } + + public GasperBuilder usePortJavaOptionFor(String portJavaOption) { + this.portJavaOption = portJavaOption; + return this; + } + + public GasperBuilder inheritIO() { + return inheritIO(true); + } + + public GasperBuilder inheritIO(boolean inheritIO) { + this.inheritIO = inheritIO; + return this; + } + + public Gasper build() { + if (port == null) { + port = findNotBindedPort(); + } + if (portJavaOption != null) { + withJavaOption(portJavaOption, port.toString()); + } + Settings settings = new Settings( + packaging, classifier, port, + ImmutableMap.copyOf(javaOptions), ImmutableMap.copyOf(environment), + inheritIO, context, contextChecker, + portAvailableMaxTime, deploymentMaxTime + ); + return create(settings); + } + + public GasperBuilder maxStartupTime(int seconds) { + this.portAvailableMaxTime = seconds; + return this; + } + + public GasperBuilder maxDeploymentTime(int seconds) { + this.deploymentMaxTime = seconds; + return this; + } + + public GasperBuilder waitForContext(String context) { + this.context = context; + return this; + } + + public GasperBuilder useContextChecker(Function contextChecker) { + this.contextChecker = contextChecker; + return this; + } + + private static int findNotBindedPort() { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } catch (IOException ex) { + throw new EidIllegalStateException("20160305:000138", ex); + } + } +} diff --git a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java new file mode 100644 index 0000000..e193a62 --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java @@ -0,0 +1,53 @@ +package pl.wavesoftware.gasper; + +/** + * This class holds supported and tested configurations for servers. + *

+ * Configuration in this class are fairly tested and can serve as a base for configuration. + * You shouldn't try to use this class directly. Use instead {@link Gasper#builderPreconfigured()} for entry point. + *

+ * Example: + *

+ * @ClassRule
+ * public Gasper runner = Gasper.configurations()
+ *     .wildflySwarm()
+ *     .build();
+ * 
+ * + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +public final class GasperConfigurations { + public static final String WILDFLY_SWARM = "swarm.http.port"; + public static final String SPRING_BOOT = "server.port"; + protected GasperConfigurations() {} + + /** + * This method returns pre-configured Gasper builder to use with WildFly Swarm. + *

+ * You can use it directly or use {@link GasperBuilder} interface to re-configure it to you needs. + *

+ * To use it in JUnit execute method {@link GasperBuilder#create()} + * @return pre-configured {@link GasperBuilder} to use with WildFly Swarm. + */ + public GasperBuilder wildflySwarm() { + return Gasper.builder() + .withPackaging("jar") + .withClassifier("swarm") + .usePortJavaOptionFor(GasperConfigurations.WILDFLY_SWARM); + } + + /** + * This method returns pre-configured Gasper builder to use with Spring Boot. + *

+ * You can use it directly or use {@link GasperBuilder} interface to re-configure it to you needs. + *

+ * To use it in JUnit execute method {@link GasperBuilder#create()} + * @return pre-configured {@link GasperBuilder} to use with Spring Boot. + */ + public GasperBuilder springBoot() { + return Gasper.builder() + .withPackaging("jar") + .usePortJavaOptionFor(GasperConfigurations.SPRING_BOOT); + } +} diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java new file mode 100644 index 0000000..24b0a43 --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java @@ -0,0 +1,165 @@ +package pl.wavesoftware.gasper.internal; + +import com.mashape.unirest.http.HttpResponse; +import com.mashape.unirest.http.Unirest; +import com.mashape.unirest.http.exceptions.UnirestException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import pl.wavesoftware.eid.exceptions.Eid; +import pl.wavesoftware.eid.exceptions.EidIllegalStateException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.ServerSocket; +import java.nio.file.Path; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +import static java.lang.String.format; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +@Slf4j +@RequiredArgsConstructor +public class Executor { + public static final int WAIT_STEP = 125; + public static final int WAIT_STEPS_IN_SECOND = 8; + public static final Function DEFAULT_CONTEXT_CHECKER = Executor::check; + public static final String DEFAULT_SCHEME = "http"; + public static final String DEFAULT_DOMAIN = "localhost"; + public static final String DEFAULT_QUERY = null; + private static final int HTTP_OK = 200; + private static final int HTTP_BAD_REQUEST = 400; + private final List command; + private final File workingDirectory; + private final Settings settings; + private Process process; + + public void start() throws IOException { + ProcessBuilder pb = new ProcessBuilder(command); + pb.directory(workingDirectory); + if (settings.isInheritIO()) { + pb.inheritIO(); + } else { + logToFile(pb); + } + if (!settings.getEnvironment().isEmpty()) { + pb.environment().putAll(settings.getEnvironment()); + } + process = pb.start(); + + startAndWaitForPort(); + waitForHttpContext(); + } + + public void stop() { + log.info("Stopping server."); + process.destroy(); + } + + private void waitForHttpContext() { + Integer port = settings.getPort(); + String context = settings.getContext(); + int maxWait = settings.getDeploymentMaxTime(); + log.info(format("Waiting for deployment for context: \"%s\" to happen...", context)); + boolean ok = waitForContextToBecomeAvailable(port, context, maxWait); + if (!ok) { + throw new EidIllegalStateException(new Eid("20160305:123206"), + "Context %s in not available after waiting %s seconds, aborting!", + context, maxWait + ); + } + } + + private boolean waitForContextToBecomeAvailable(int port, String context, int maxSeconds) { + for (int i = 1; i <= maxSeconds * WAIT_STEPS_IN_SECOND; i++) { + try { + process.waitFor(WAIT_STEP, TimeUnit.MILLISECONDS); + if (isContextAvailable(port, context)) { + int waited = WAIT_STEP * i; + log.info(format("Context \"%s\" became available after ~%dms!", context, waited)); + return true; + } + } catch (InterruptedException e) { + log.error("Tried to wait " + WAIT_STEP + "ms, failed: " + e.getLocalizedMessage(), e); + } + } + return false; + } + + private static Boolean check(HttpEndpoint endpoint) { + String address = format("%s://%s:%d%s", + endpoint.getScheme(), + endpoint.getDomain(), + endpoint.getPort(), + endpoint.getContext() + ); + if (endpoint.getQuery() != null) { + address += "?" + endpoint.getQuery(); + } + try { + HttpResponse response = Unirest.head(address).asBinary(); + int status = response.getStatus(); + return status >= HTTP_OK && status < HTTP_BAD_REQUEST; + } catch (UnirestException e) { + EidIllegalStateException ex = new EidIllegalStateException(new Eid("20160305:125410"), e); + log.error(ex.getEid().makeLogMessage("Can't make http request - %s", e.getLocalizedMessage()), ex); + return false; + } + } + + private boolean isContextAvailable(int port, String context) { + HttpEndpoint endpoint = new HttpEndpoint( + DEFAULT_SCHEME, DEFAULT_DOMAIN, port, context, DEFAULT_QUERY + ); + return settings.getContextChecker().apply(endpoint); + } + + private void startAndWaitForPort() { + Integer port = settings.getPort(); + log.info(format("Starting server, waiting for port: %d to became active...", port)); + boolean ok = waitForPortToBecomeAvailable(process, port, settings.getPortAvailableMaxTime()); + if (!ok) { + throw new EidIllegalStateException(new Eid("20160305:003452"), + "Process %s probably didn't started well after maximum wait time is reached: %s", + command.toString(), settings.getPortAvailableMaxTime() + ); + } + } + + private static boolean waitForPortToBecomeAvailable(Process process, int port, int maxSeconds) { + for (int i = 1; i <= maxSeconds * WAIT_STEPS_IN_SECOND; i++) { + try { + process.waitFor(WAIT_STEP, TimeUnit.MILLISECONDS); + if (isPortTaken(port)) { + int waited = WAIT_STEP * i; + log.info(format("Port %d became available after ~%dms!", port, waited)); + return true; + } + } catch (InterruptedException e) { + log.error("Tried to wait " + WAIT_STEP + "ms, failed: " + e.getLocalizedMessage(), e); + } + } + return false; + } + + private void logToFile(ProcessBuilder pb) { + File tempDir = new File(System.getProperty("java.io.tmpdir")); + Path logFile = tempDir.toPath().resolve("gasper-server.log"); + pb.redirectErrorStream(true); + pb.redirectOutput(logFile.toFile()); + log.info(format("Logging server messages to: %s", logFile)); + } + + private static boolean isPortTaken(int port) { + try (ServerSocket ignored = new ServerSocket(port)) { + return false; + } catch (IOException ex) { + return true; + } + } +} diff --git a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java new file mode 100644 index 0000000..8e62d35 --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java @@ -0,0 +1,16 @@ +package pl.wavesoftware.gasper.internal; + +import lombok.Data; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +@Data +public class HttpEndpoint { + private final String scheme; + private final String domain; + private final int port; + private final String context; + private final String query; +} diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java new file mode 100644 index 0000000..448ebff --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java @@ -0,0 +1,49 @@ +package pl.wavesoftware.gasper.internal; + +import com.google.common.collect.ImmutableMap; +import lombok.Data; +import pl.wavesoftware.gasper.Gasper; + +import java.util.Map; +import java.util.function.Function; + +/** + * This class represents a set of settings for Gasper. It is used as a POJO with settings. + *

+ * CAUTION! It is internal class of Gasper, and shouldn't be used directly. Use gasper builder interface {@link Gasper#builder()} or {@link Gasper#builderPreconfigured()} to set those settings. + * + * @author Krzysztof Suszyński + * @since 2016-03-05 + * @see Gasper#builder() + * @see Gasper#builderPreconfigured() + */ +@Data +public class Settings { + private final String packaging; + private final String classifier; + private final int port; + private final Map javaOptions; + private final Map environment; + private final boolean inheritIO; + private final String context; + private final Function contextChecker; + private final int portAvailableMaxTime; + private final int deploymentMaxTime; + + /** + * Gets Java options as map + * @return a map for Java options + */ + public Map getJavaOptions() { + return ImmutableMap.copyOf(javaOptions); + } + + /** + * Gets environment variables as a map + * @return a map for environment variables + */ + public Map getEnvironment() { + return ImmutableMap.copyOf(environment); + } + +} diff --git a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java new file mode 100644 index 0000000..5ec2a5e --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java @@ -0,0 +1,67 @@ +package pl.wavesoftware.gasper.internal.maven; + +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import pl.wavesoftware.eid.exceptions.EidRuntimeException; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkState; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-04 + */ +public class MavenResolver { + + public static final String DEFAULT_POM = "pom.xml"; + public static final String DEFAULT_BUILD_DIR = "target"; + public static final String DEFAULT_PACKAGING = "jar"; + private final Model model; + + public MavenResolver() { + this(DEFAULT_POM); + } + + public MavenResolver(String pomfile) { + FileReader reader; + MavenXpp3Reader mavenReader = new MavenXpp3Reader(); + try { + reader = new FileReader(pomfile); + model = mavenReader.read(reader); + } catch (IOException | XmlPullParserException e) { + throw new EidRuntimeException("20160304:230502", e); + } + model.setPomFile(new File(pomfile)); + } + + public Path getBuildArtifact(String packaging, String classifier) { + String artifact; + Path dir = getBuildDirectory().toPath(); + String pack = Objects.equals(packaging, "") ? getModelPackaging() : packaging; + if (Objects.equals(classifier, "")) { + artifact = String.format("%s-%s.%s", + model.getArtifactId(), model.getVersion(), pack); + } else { + artifact = String.format("%s-%s-%s.%s", + model.getArtifactId(), model.getVersion(), classifier, pack); + } + return dir.resolve(artifact); + } + + public File getBuildDirectory() { + String set = model.getBuild().getOutputDirectory(); + File directory = new File(set == null ? DEFAULT_BUILD_DIR : set); + checkState(directory.isDirectory(), "20160304:230811"); + return directory; + } + + public String getModelPackaging() { + return model.getPackaging() == null ? DEFAULT_PACKAGING : model.getPackaging(); + } +} diff --git a/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java b/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java new file mode 100644 index 0000000..c7ee927 --- /dev/null +++ b/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java @@ -0,0 +1,39 @@ +package pl.wavesoftware.gasper.internal.maven; + +import org.junit.Test; + +import java.io.File; +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-04 + */ +public class MavenResolverIT { + + @Test + public void testGetBuildArtifact() throws Exception { + // given + MavenResolver resolver = new MavenResolver(); + + // when + Path artifact = resolver.getBuildArtifact("jar", ""); + + // then + assertThat(artifact).exists().isRegularFile(); + } + + @Test + public void testGetBuildDirectory() throws Exception { + // given + MavenResolver resolver = new MavenResolver(); + + // when + File directory = resolver.getBuildDirectory(); + + // then + assertThat(directory.getPath()).isEqualTo("target"); + } +} From bfa5aeab583d61658a8758aa683fb522494f09ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 20:48:25 +0100 Subject: [PATCH 02/21] Tests and major fixes. Code is done. --- .gitignore | 3 + .travis.yml | 2 +- pom.xml | 71 ++++++++++++++++- src/it/spring-boot-tester/pom.xml | 32 ++++++++ .../springboottester/SampleController.java | 21 +++++ src/it/wildfly-swarm-tester/pom.xml | 55 +++++++++++++ .../wildflyswarmtester/HelloServlet.java | 21 +++++ .../src/main/webapp/WEB-INF/beans.xml | 6 ++ .../src/main/webapp/WEB-INF/web.xml | 3 + .../java/pl/wavesoftware/gasper/Gasper.java | 77 +++++++++++++------ .../pl/wavesoftware/gasper/GasperBuilder.java | 41 +++++++--- .../gasper/internal/Executor.java | 50 ++++++------ .../gasper/internal/HttpEndpoint.java | 19 +++++ .../wavesoftware/gasper/internal/Logger.java | 20 +++++ .../gasper/internal/Settings.java | 35 ++++++++- .../gasper/internal/maven/MavenResolver.java | 50 ++++++++---- src/main/resources/gasper.txt | 7 ++ .../gasper/GasperForSpringBootIT.java | 60 +++++++++++++++ .../gasper/GasperForWildflySwarmIT.java | 45 +++++++++++ .../internal/maven/MavenResolverIT.java | 14 +++- 20 files changed, 550 insertions(+), 82 deletions(-) create mode 100644 src/it/spring-boot-tester/pom.xml create mode 100644 src/it/spring-boot-tester/src/main/java/pl/wavesoftware/examples/springboottester/SampleController.java create mode 100644 src/it/wildfly-swarm-tester/pom.xml create mode 100644 src/it/wildfly-swarm-tester/src/main/java/pl/wavesoftware/examples/wildflyswarmtester/HelloServlet.java create mode 100644 src/it/wildfly-swarm-tester/src/main/webapp/WEB-INF/beans.xml create mode 100644 src/it/wildfly-swarm-tester/src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/java/pl/wavesoftware/gasper/internal/Logger.java create mode 100644 src/main/resources/gasper.txt create mode 100644 src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java create mode 100644 src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java diff --git a/.gitignore b/.gitignore index db834a6..61eefef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +# Common Maven + target/ pom.xml.tag pom.xml.releaseBackup @@ -8,5 +10,6 @@ dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties +# IDE's .idea *.iml diff --git a/.travis.yml b/.travis.yml index 54ae82f..22fb5f9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ --- language: java install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -script: mvn verify +script: mvn verify -Pci jdk: - oraclejdk8 cache: diff --git a/pom.xml b/pom.xml index 69b97c5..9358a6f 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,8 @@ 1.0.0-SNAPSHOT jar Gasper - Very simple integration testing JUnit harness for 'java -jar' servers like WildFly Swarm and Spring Boot + Very simple integration testing JUnit harness for 'java -jar' servers like WildFly Swarm and Spring Boot + 3.0.4 @@ -89,6 +90,18 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + + -Werror + -Xlint:-deprecation + -Xlint:all + + + org.apache.maven.plugins maven-surefire-plugin @@ -107,6 +120,62 @@ + + org.apache.maven.plugins + maven-invoker-plugin + 2.0.0 + + + prepare-packages + + install + run + + package + + + + ${project.build.directory}/it + + + + + + ci + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + jacoco-initialize + + prepare-agent + prepare-agent-integration + + + + jacoco-site + post-integration-test + + report + report-integration + + + + + + pl/wavesoftware/** + + + + + + + diff --git a/src/it/spring-boot-tester/pom.xml b/src/it/spring-boot-tester/pom.xml new file mode 100644 index 0000000..802c3f5 --- /dev/null +++ b/src/it/spring-boot-tester/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + pl.wavesoftware.examples + spring-boot-tester + 1.0.0 + jar + Spring Boot Tester app + + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/src/it/spring-boot-tester/src/main/java/pl/wavesoftware/examples/springboottester/SampleController.java b/src/it/spring-boot-tester/src/main/java/pl/wavesoftware/examples/springboottester/SampleController.java new file mode 100644 index 0000000..5cd0482 --- /dev/null +++ b/src/it/spring-boot-tester/src/main/java/pl/wavesoftware/examples/springboottester/SampleController.java @@ -0,0 +1,21 @@ +package pl.wavesoftware.examples.springboottester; + +import org.springframework.boot.*; +import org.springframework.boot.autoconfigure.*; +import org.springframework.stereotype.*; +import org.springframework.web.bind.annotation.*; + +@Controller +@EnableAutoConfiguration +public class SampleController { + + @RequestMapping("/") + @ResponseBody + String home() { + return "Hello from Spring Boot!"; + } + + public static void main(String[] args) throws Exception { + SpringApplication.run(SampleController.class, args); + } +} diff --git a/src/it/wildfly-swarm-tester/pom.xml b/src/it/wildfly-swarm-tester/pom.xml new file mode 100644 index 0000000..cb05fe4 --- /dev/null +++ b/src/it/wildfly-swarm-tester/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + pl.wavesoftware.examples + wildfly-swarm-tester + 1.0.0 + war + WildFly Swarm Tester app + + + 3.2.5 + + + + 1.8 + 1.8 + UTF-8 + UTF-8 + 1.0.0.Beta2 + + + + + org.wildfly.swarm + weld + ${wildfly.swarm.version} + provided + + + org.wildfly.swarm + jsf + ${wildfly.swarm.version} + provided + + + + + + + org.wildfly.swarm + wildfly-swarm-plugin + ${wildfly.swarm.version} + + + package + + package + + + + + + + diff --git a/src/it/wildfly-swarm-tester/src/main/java/pl/wavesoftware/examples/wildflyswarmtester/HelloServlet.java b/src/it/wildfly-swarm-tester/src/main/java/pl/wavesoftware/examples/wildflyswarmtester/HelloServlet.java new file mode 100644 index 0000000..5d8e226 --- /dev/null +++ b/src/it/wildfly-swarm-tester/src/main/java/pl/wavesoftware/examples/wildflyswarmtester/HelloServlet.java @@ -0,0 +1,21 @@ +package pl.wavesoftware.examples.wildflyswarmtester; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Krzysztof Suszynski + * @since 04.03.16 + */ +@WebServlet("/") +public class HelloServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + response.getWriter().append("Hello from WildFly Swarm!"); + } +} diff --git a/src/it/wildfly-swarm-tester/src/main/webapp/WEB-INF/beans.xml b/src/it/wildfly-swarm-tester/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000..1f19832 --- /dev/null +++ b/src/it/wildfly-swarm-tester/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,6 @@ + + + diff --git a/src/it/wildfly-swarm-tester/src/main/webapp/WEB-INF/web.xml b/src/it/wildfly-swarm-tester/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..82f55e5 --- /dev/null +++ b/src/it/wildfly-swarm-tester/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,3 @@ + + + diff --git a/src/main/java/pl/wavesoftware/gasper/Gasper.java b/src/main/java/pl/wavesoftware/gasper/Gasper.java index 695c3e4..bf428af 100644 --- a/src/main/java/pl/wavesoftware/gasper/Gasper.java +++ b/src/main/java/pl/wavesoftware/gasper/Gasper.java @@ -1,24 +1,30 @@ package pl.wavesoftware.gasper; +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; -import pl.wavesoftware.eid.exceptions.EidIllegalStateException; +import pl.wavesoftware.eid.utils.EidPreconditions; import pl.wavesoftware.gasper.internal.Executor; +import pl.wavesoftware.gasper.internal.Logger; import pl.wavesoftware.gasper.internal.Settings; import pl.wavesoftware.gasper.internal.maven.MavenResolver; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import static java.lang.String.format; +import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; /** * @author Krzysztof Suszyński @@ -31,10 +37,18 @@ public final class Gasper implements TestRule { public static final int DEFAULT_PORT_AVAILABLE_MAX_SECONDS = 60; public static final int DEFAULT_DEPLOYMENT_MAX_SECONDS = 30; public static final String DEFAULT_CONTEXT = "/"; + private static final String figlet; private final Settings settings; private Path artifact; private Executor executor; + private Logger logger; + + static { + InputStream is = Gasper.class.getClassLoader().getResourceAsStream("gasper.txt"); + figlet = tryToExecute((EidPreconditions.UnsafeSupplier) () -> + CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8)), "20160305:201329"); + } public static GasperBuilder builder() { return new GasperBuilder(); @@ -48,6 +62,10 @@ public Integer getPort() { return settings.getPort(); } + public String getAddress() { + return settings.getEndpoint().fullAddress(); + } + protected abstract static class RunnerCreator { public Gasper create(Settings settings) { return new Gasper(settings); @@ -56,42 +74,42 @@ public Gasper create(Settings settings) { @Override public Statement apply(Statement base, Description description) { - try { + GasperStatement afterStmt = new GasperStatement(base, this); + return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { setup(); before(); - return new Statement() { - - @Override - public void evaluate() throws Throwable { - try { - base.evaluate(); - } finally { - after(); - } - } - }; - } catch (IOException e) { - throw new EidIllegalStateException("20160305:004035", e); + return afterStmt; + }, "20160305:004035"); + } + + @RequiredArgsConstructor + private static class GasperStatement extends Statement { + private final Statement base; + private final Gasper gasper; + + @Override + public void evaluate() throws Throwable { + try { + base.evaluate(); + } finally { + gasper.after(); + } } } private void setup() { - log.info(format( - "%s simple integration test pl.wavesoftware.gasper starting!", this.getClass().getSimpleName() - )); - MavenResolver resolver = new MavenResolver(); + log(figlet); + MavenResolver resolver = new MavenResolver(settings.getPomfile()); artifact = resolver.getBuildArtifact(settings.getPackaging(), settings.getClassifier()); File workingDirectory = resolver.getBuildDirectory(); List command = buildCommand(); - log.info(format( - "Command to be executed: \"%s\"", command.stream().collect(Collectors.joining(" ")) - )); + log("Command to be executed: \"%s\"", command.stream().collect(Collectors.joining(" "))); executor = new Executor(command, workingDirectory, settings); } private void before() throws IOException { executor.start(); - log.info("All looks ready, running tests..."); + log("All looks ready, running tests..."); } private List buildCommand() { @@ -111,7 +129,18 @@ private void buildJavaOptions(List command) { } private void after() { - log.info("Testing on server completed."); + log("Testing on server completed."); executor.stop(); } + + private void log(String frmt, Object... args) { + ensureLogger(); + logger.info(format(frmt, args)); + } + + private void ensureLogger() { + if (logger == null) { + logger = new Logger(log, settings); + } + } } diff --git a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java index 343145b..ca7a4a8 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java @@ -1,18 +1,22 @@ package pl.wavesoftware.gasper; import com.google.common.collect.ImmutableMap; -import pl.wavesoftware.eid.exceptions.EidIllegalStateException; +import org.slf4j.event.Level; +import pl.wavesoftware.eid.utils.EidPreconditions; import pl.wavesoftware.gasper.internal.Executor; import pl.wavesoftware.gasper.internal.HttpEndpoint; import pl.wavesoftware.gasper.internal.Settings; import pl.wavesoftware.gasper.internal.maven.MavenResolver; -import java.io.IOException; import java.net.ServerSocket; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Function; +import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; + /** * @author Krzysztof Suszyński * @since 2016-03-05 @@ -30,6 +34,8 @@ public final class GasperBuilder extends Gasper.RunnerCreator { private int portAvailableMaxTime = Gasper.DEFAULT_PORT_AVAILABLE_MAX_SECONDS; private int deploymentMaxTime = Gasper.DEFAULT_DEPLOYMENT_MAX_SECONDS; private Function contextChecker = Executor.DEFAULT_CONTEXT_CHECKER; + private Path pomfile = Paths.get(MavenResolver.DEFAULT_POM); + private Level level = Level.INFO; public GasperBuilder withPackaging(String packaging) { this.packaging = packaging; @@ -61,6 +67,11 @@ public GasperBuilder usePortJavaOptionFor(String portJavaOption) { return this; } + public GasperBuilder usePomFile(Path pomfile) { + this.pomfile = pomfile; + return this; + } + public GasperBuilder inheritIO() { return inheritIO(true); } @@ -81,7 +92,8 @@ public Gasper build() { packaging, classifier, port, ImmutableMap.copyOf(javaOptions), ImmutableMap.copyOf(environment), inheritIO, context, contextChecker, - portAvailableMaxTime, deploymentMaxTime + portAvailableMaxTime, deploymentMaxTime, + pomfile, level ); return create(settings); } @@ -106,11 +118,22 @@ public GasperBuilder useContextChecker(Function contextCh return this; } - private static int findNotBindedPort() { - try (ServerSocket socket = new ServerSocket(0)) { - return socket.getLocalPort(); - } catch (IOException ex) { - throw new EidIllegalStateException("20160305:000138", ex); - } + public GasperBuilder silent() { + useLogLevel(Level.WARN); + return this; + } + + public GasperBuilder useLogLevel(Level level) { + this.level = level; + return this; + } + + private static Integer findNotBindedPort() { + return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } + }, "20160305:202934"); + } } diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java index 24b0a43..89e8886 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java @@ -29,15 +29,13 @@ public class Executor { public static final int WAIT_STEP = 125; public static final int WAIT_STEPS_IN_SECOND = 8; public static final Function DEFAULT_CONTEXT_CHECKER = Executor::check; - public static final String DEFAULT_SCHEME = "http"; - public static final String DEFAULT_DOMAIN = "localhost"; - public static final String DEFAULT_QUERY = null; private static final int HTTP_OK = 200; private static final int HTTP_BAD_REQUEST = 400; private final List command; private final File workingDirectory; private final Settings settings; private Process process; + private Logger logger; public void start() throws IOException { ProcessBuilder pb = new ProcessBuilder(command); @@ -50,6 +48,7 @@ public void start() throws IOException { if (!settings.getEnvironment().isEmpty()) { pb.environment().putAll(settings.getEnvironment()); } + log("Starting server process"); process = pb.start(); startAndWaitForPort(); @@ -57,7 +56,7 @@ public void start() throws IOException { } public void stop() { - log.info("Stopping server."); + log("Stopping server process"); process.destroy(); } @@ -65,7 +64,7 @@ private void waitForHttpContext() { Integer port = settings.getPort(); String context = settings.getContext(); int maxWait = settings.getDeploymentMaxTime(); - log.info(format("Waiting for deployment for context: \"%s\" to happen...", context)); + log("Waiting for deployment for context: \"%s\" to happen...", context); boolean ok = waitForContextToBecomeAvailable(port, context, maxWait); if (!ok) { throw new EidIllegalStateException(new Eid("20160305:123206"), @@ -79,9 +78,9 @@ private boolean waitForContextToBecomeAvailable(int port, String context, int ma for (int i = 1; i <= maxSeconds * WAIT_STEPS_IN_SECOND; i++) { try { process.waitFor(WAIT_STEP, TimeUnit.MILLISECONDS); - if (isContextAvailable(port, context)) { + if (isContextAvailable()) { int waited = WAIT_STEP * i; - log.info(format("Context \"%s\" became available after ~%dms!", context, waited)); + log("Context \"%s\" became available after ~%dms!", context, waited); return true; } } catch (InterruptedException e) { @@ -92,15 +91,7 @@ private boolean waitForContextToBecomeAvailable(int port, String context, int ma } private static Boolean check(HttpEndpoint endpoint) { - String address = format("%s://%s:%d%s", - endpoint.getScheme(), - endpoint.getDomain(), - endpoint.getPort(), - endpoint.getContext() - ); - if (endpoint.getQuery() != null) { - address += "?" + endpoint.getQuery(); - } + String address = endpoint.fullAddress(); try { HttpResponse response = Unirest.head(address).asBinary(); int status = response.getStatus(); @@ -112,16 +103,14 @@ private static Boolean check(HttpEndpoint endpoint) { } } - private boolean isContextAvailable(int port, String context) { - HttpEndpoint endpoint = new HttpEndpoint( - DEFAULT_SCHEME, DEFAULT_DOMAIN, port, context, DEFAULT_QUERY - ); + private boolean isContextAvailable() { + HttpEndpoint endpoint = settings.getEndpoint(); return settings.getContextChecker().apply(endpoint); } private void startAndWaitForPort() { Integer port = settings.getPort(); - log.info(format("Starting server, waiting for port: %d to became active...", port)); + log("Waiting for port: %d to became active...", port); boolean ok = waitForPortToBecomeAvailable(process, port, settings.getPortAvailableMaxTime()); if (!ok) { throw new EidIllegalStateException(new Eid("20160305:003452"), @@ -131,13 +120,13 @@ private void startAndWaitForPort() { } } - private static boolean waitForPortToBecomeAvailable(Process process, int port, int maxSeconds) { + private boolean waitForPortToBecomeAvailable(Process process, int port, int maxSeconds) { for (int i = 1; i <= maxSeconds * WAIT_STEPS_IN_SECOND; i++) { try { process.waitFor(WAIT_STEP, TimeUnit.MILLISECONDS); if (isPortTaken(port)) { int waited = WAIT_STEP * i; - log.info(format("Port %d became available after ~%dms!", port, waited)); + log("Port %d became available after ~%dms!", port, waited); return true; } } catch (InterruptedException e) { @@ -149,10 +138,10 @@ private static boolean waitForPortToBecomeAvailable(Process process, int port, i private void logToFile(ProcessBuilder pb) { File tempDir = new File(System.getProperty("java.io.tmpdir")); - Path logFile = tempDir.toPath().resolve("gasper-server.log"); + Path logFile = tempDir.toPath().resolve("gasper.log"); pb.redirectErrorStream(true); pb.redirectOutput(logFile.toFile()); - log.info(format("Logging server messages to: %s", logFile)); + log("Logging server messages to: %s", logFile); } private static boolean isPortTaken(int port) { @@ -162,4 +151,15 @@ private static boolean isPortTaken(int port) { return true; } } + + private void log(String frmt, Object... args) { + ensureLogger(); + logger.info(format(frmt, args)); + } + + private void ensureLogger() { + if (logger == null) { + logger = new Logger(log, settings); + } + } } diff --git a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java index 8e62d35..5342252 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java @@ -2,15 +2,34 @@ import lombok.Data; +import static java.lang.String.format; + /** * @author Krzysztof Suszyński * @since 2016-03-05 */ @Data public class HttpEndpoint { + public static final String DEFAULT_SCHEME = "http"; + public static final String DEFAULT_DOMAIN = "localhost"; + public static final String DEFAULT_QUERY = null; + private final String scheme; private final String domain; private final int port; private final String context; private final String query; + + public String fullAddress() { + String address = format("%s://%s:%d%s", + getScheme(), + getDomain(), + getPort(), + getContext() + ); + if (getQuery() != null) { + address += "?" + getQuery(); + } + return address; + } } diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Logger.java b/src/main/java/pl/wavesoftware/gasper/internal/Logger.java new file mode 100644 index 0000000..9b23635 --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/internal/Logger.java @@ -0,0 +1,20 @@ +package pl.wavesoftware.gasper.internal; + +import lombok.RequiredArgsConstructor; +import org.slf4j.event.Level; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +@RequiredArgsConstructor +public class Logger { + private final org.slf4j.Logger logger; + private final Settings settings; + + public void info(String message) { + if (settings.getLevel().toInt() <= Level.INFO.toInt()) { + logger.info(message); + } + } +} diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java index 448ebff..3796403 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java @@ -1,23 +1,30 @@ package pl.wavesoftware.gasper.internal; import com.google.common.collect.ImmutableMap; -import lombok.Data; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.slf4j.event.Level; import pl.wavesoftware.gasper.Gasper; +import java.nio.file.Path; import java.util.Map; import java.util.function.Function; /** * This class represents a set of settings for Gasper. It is used as a POJO with settings. *

- * CAUTION! It is internal class of Gasper, and shouldn't be used directly. Use gasper builder interface {@link Gasper#builder()} or {@link Gasper#builderPreconfigured()} to set those settings. + * CAUTION! It is internal class of Gasper, and shouldn't be used directly. Use gasper builder interface {@link Gasper#builder()} or {@link Gasper#configurations()} to set those settings. * * @author Krzysztof Suszyński * @since 2016-03-05 * @see Gasper#builder() - * @see Gasper#builderPreconfigured() + * @see Gasper#configurations() */ -@Data +@Getter +@Setter +@RequiredArgsConstructor public class Settings { private final String packaging; private final String classifier; @@ -29,6 +36,10 @@ public class Settings { private final Function contextChecker; private final int portAvailableMaxTime; private final int deploymentMaxTime; + private final Path pomfile; + private final Level level; + @Setter(AccessLevel.NONE) + private HttpEndpoint endpoint; /** * Gets Java options as map @@ -46,4 +57,20 @@ public Map getEnvironment() { return ImmutableMap.copyOf(environment); } + public HttpEndpoint getEndpoint() { + ensureHttpEndpoint(); + return endpoint; + } + + private void ensureHttpEndpoint() { + if (endpoint == null) { + endpoint = new HttpEndpoint( + HttpEndpoint.DEFAULT_SCHEME, + HttpEndpoint.DEFAULT_DOMAIN, + port, + context, + HttpEndpoint.DEFAULT_QUERY + ); + } + } } diff --git a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java index 5ec2a5e..4a802e3 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java @@ -2,16 +2,15 @@ import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -import pl.wavesoftware.eid.exceptions.EidRuntimeException; import java.io.File; import java.io.FileReader; -import java.io.IOException; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Objects; -import static com.google.common.base.Preconditions.checkState; +import static pl.wavesoftware.eid.utils.EidPreconditions.*; + /** * @author Krzysztof Suszyński @@ -19,25 +18,39 @@ */ public class MavenResolver { - public static final String DEFAULT_POM = "pom.xml"; + public static final String DEFAULT_POM = "./pom.xml"; public static final String DEFAULT_BUILD_DIR = "target"; public static final String DEFAULT_PACKAGING = "jar"; + private static final Path CURRENT_DIR = Paths.get("./"); private final Model model; + private final Path pomDirectory; public MavenResolver() { this(DEFAULT_POM); } public MavenResolver(String pomfile) { - FileReader reader; + this(Paths.get(pomfile)); + } + + public MavenResolver(Path pomfile) { + checkArgument(pomfile.toFile().isFile(), "20160305:181005"); MavenXpp3Reader mavenReader = new MavenXpp3Reader(); - try { - reader = new FileReader(pomfile); - model = mavenReader.read(reader); - } catch (IOException | XmlPullParserException e) { - throw new EidRuntimeException("20160304:230502", e); - } - model.setPomFile(new File(pomfile)); + model = tryToExecute((UnsafeSupplier) () -> { + FileReader reader = new FileReader(pomfile.toString()); + return mavenReader.read(reader); + }, "20160305:203232"); + checkNotNull(model, "20160305:203551").setPomFile(pomfile.toFile()); + pomDirectory = pomfile.getParent() == null ? CURRENT_DIR : pomfile.getParent(); + checkArgument(pomDirectory.toFile().isDirectory(), "20160305:181211"); + } + + public Path getBuildArtifact() { + return getBuildArtifact("", ""); + } + + public Path getBuildArtifact(String classifier) { + return getBuildArtifact("", classifier); } public Path getBuildArtifact(String packaging, String classifier) { @@ -51,14 +64,17 @@ public Path getBuildArtifact(String packaging, String classifier) { artifact = String.format("%s-%s-%s.%s", model.getArtifactId(), model.getVersion(), classifier, pack); } - return dir.resolve(artifact); + Path artifactPath = dir.resolve(Paths.get(artifact)); + checkState(artifactPath.toFile().isFile(), "20160305:181432", "Is not a file: %s", artifactPath); + checkState(artifactPath.toFile().canRead(), "20160305:181456", "Can't read file: %s", artifactPath); + return artifactPath; } public File getBuildDirectory() { String set = model.getBuild().getOutputDirectory(); - File directory = new File(set == null ? DEFAULT_BUILD_DIR : set); - checkState(directory.isDirectory(), "20160304:230811"); - return directory; + Path directory = pomDirectory.resolve(Paths.get(set == null ? DEFAULT_BUILD_DIR : set)); + checkState(directory.toFile().isDirectory(), "20160304:230811"); + return directory.normalize().toFile(); } public String getModelPackaging() { diff --git a/src/main/resources/gasper.txt b/src/main/resources/gasper.txt new file mode 100644 index 0000000..c95725c --- /dev/null +++ b/src/main/resources/gasper.txt @@ -0,0 +1,7 @@ + + ____ _ + / ___| __ _ ___ _ __ ___ _ __| | +| | _ / _` / __| '_ \ / _ \ '__| | +| |_| | (_| \__ \ |_) | __/ | |_| simple integration + \____|\__,_|___/ .__/ \___|_| (_) JUnit test harness! + |_| diff --git a/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java b/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java new file mode 100644 index 0000000..1590a91 --- /dev/null +++ b/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java @@ -0,0 +1,60 @@ +package pl.wavesoftware.gasper; + +import com.mashape.unirest.http.HttpResponse; +import com.mashape.unirest.http.Unirest; +import com.mashape.unirest.http.exceptions.UnirestException; +import lombok.extern.slf4j.Slf4j; +import org.junit.ClassRule; +import org.junit.Test; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +@Slf4j +public class GasperForSpringBootIT { + + private static final Path SPRING_BOOT_POMFILE = Paths.get( + "target", "it", "spring-boot-tester", "pom.xml" + ); + + @ClassRule + public static Gasper gasper = Gasper.configurations() + .springBoot() + .usePomFile(SPRING_BOOT_POMFILE) + .build(); + + @Test + public void testGetRoot() throws UnirestException { + // given + String address = gasper.getAddress(); + String expectedMessage = "Hello from Spring Boot!"; + + // when + HttpResponse response = Unirest.get(address).asString(); + + // then + assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getBody()).isEqualTo(expectedMessage); + log.info("Server returned: " + response.getBody()); + } + + @Test + public void testGetNonExistent() throws UnirestException { + // given + String nonExistingPath = "non-existing"; + String address = gasper.getAddress() + nonExistingPath; + + // when + HttpResponse response = Unirest.get(address).asString(); + + // then + assertThat(response.getStatus()).isEqualTo(404); + } + +} diff --git a/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java b/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java new file mode 100644 index 0000000..d945bf8 --- /dev/null +++ b/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java @@ -0,0 +1,45 @@ +package pl.wavesoftware.gasper; + +import com.mashape.unirest.http.HttpResponse; +import com.mashape.unirest.http.Unirest; +import com.mashape.unirest.http.exceptions.UnirestException; +import org.junit.ClassRule; +import org.junit.Test; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +public class GasperForWildflySwarmIT { + + private static final Path WILDFLY_SWARM_POMFILE = Paths.get( + "target", "it", "wildfly-swarm-tester", "pom.xml" + ); + + @ClassRule + public static Gasper gasper = Gasper.configurations() + .wildflySwarm() + .usePomFile(WILDFLY_SWARM_POMFILE) + .silent() + .build(); + + @Test + public void testGetRoot() throws UnirestException { + // given + String address = gasper.getAddress(); + String expectedMessage = "Hello from WildFly Swarm!"; + + // when + HttpResponse response = Unirest.get(address).asString(); + + // then + assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getBody()).isEqualTo(expectedMessage); + } + +} diff --git a/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java b/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java index c7ee927..5673041 100644 --- a/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java +++ b/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java @@ -25,6 +25,18 @@ public void testGetBuildArtifact() throws Exception { assertThat(artifact).exists().isRegularFile(); } + @Test + public void testGetBuildArtifactForOtherPom() throws Exception { + // given + MavenResolver resolver = new MavenResolver("pom.xml"); + + // when + Path artifact = resolver.getBuildArtifact(); + + // then + assertThat(artifact).exists().isRegularFile(); + } + @Test public void testGetBuildDirectory() throws Exception { // given @@ -34,6 +46,6 @@ public void testGetBuildDirectory() throws Exception { File directory = resolver.getBuildDirectory(); // then - assertThat(directory.getPath()).isEqualTo("target"); + assertThat(directory.toString()).isEqualTo("target"); } } From 1bcf7c51ef5e5747470521059291f74ff4450c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 21:26:49 +0100 Subject: [PATCH 03/21] Create README.md --- README.md | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..1cce1cb --- /dev/null +++ b/README.md @@ -0,0 +1,90 @@ +# Gasper! + +Gasper is a very simple integration testing JUnit harness for `java -jar` servers like [WildFly Swarm](http://wildfly-swarm.io/) and [Spring Boot](http://projects.spring.io/spring-boot/). + +![WildFly Swarm](https://avatars3.githubusercontent.com/u/11523816?v=3&s=100) ![Spring Boot](https://avatars2.githubusercontent.com/u/317776?v=3&s=100) + +Gasper provides a simple to use JUnit `TestRule` that can be used to build integration tests with simple apps, like microservices. You can configure Gasper with easy to use builder interface. + +## Usage + +Best to use with libraries like [Unirest](http://unirest.io/java.html) and [JSON Assert](https://github.com/marcingrzejszczak/jsonassert) + +### WildFly Swarm configuration + +```java +@ClassRule +public static Gasper gasper = Gasper.configurations() + .wildflySwarm() + .build(); +``` + +### Spring Boot configuration + +```java +@ClassRule +public static Gasper gasper = Gasper.configurations() + .springBoot() + .build(); +``` + +### Example test method (Unirest + JSONAssert) + +```java +@Test +public void testGetRoot() throws UnirestException { + // given + String address = gasper.getAddress(); + String expectedMessage = "WildFly Swarm!"; + + // when + HttpResponse response = Unirest.get(address).asString(); + + // then + assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getBody()).field("hello").isEqualTo(expectedMessage); +} +``` + +### Addtional configuration + +To configure Gasper use `GasperBuilder` interface, for ex.: + +```java +@ClassRule +public static Gasper gasper = Gasper.configurations() + .wildflySwarm() + .usePomFile(Paths.get("target", "it", "wildfly-swarm-tester", "pom.xml")) + .inheritIO() + .maxStartupTime(120) + .maxDeploymentTime(20) + .useContextChecker(MyTestClass::contextChecker) + .withEnvironmentVariable("jdbc.password", DEV_PASSWORD) + .withJavaOption("my.minus-d.option", "true") + .silent() + .build(); +``` + +## Installation + +### Maven + +```xml + + pl.wavesoftware + gasper + 1.0.0 + test + +``` + +### Gradle + +```groovy +testCompile 'pl.wavesoftware:gasper:1.0.0' +``` + +## Requirements + +Gasper requires Java 8. Tested on Travis CI. + From fa7e2251b26b3e8c0c57c0f908a2174dc951ffbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 21:33:01 +0100 Subject: [PATCH 04/21] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cce1cb..86009fa 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,11 @@ Gasper is a very simple integration testing JUnit harness for `java -jar` servers like [WildFly Swarm](http://wildfly-swarm.io/) and [Spring Boot](http://projects.spring.io/spring-boot/). -![WildFly Swarm](https://avatars3.githubusercontent.com/u/11523816?v=3&s=100) ![Spring Boot](https://avatars2.githubusercontent.com/u/317776?v=3&s=100) +[![WildFly Swarm](https://avatars3.githubusercontent.com/u/11523816?v=3&s=100) +WildFly Swarm](http://wildfly-swarm.io/) + +[![Spring Boot](https://avatars2.githubusercontent.com/u/317776?v=3&s=100) +Spring Boot](http://projects.spring.io/spring-boot/) Gasper provides a simple to use JUnit `TestRule` that can be used to build integration tests with simple apps, like microservices. You can configure Gasper with easy to use builder interface. From 4de6e99a2125b53a135a10e292a18e077a3db032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 21:33:34 +0100 Subject: [PATCH 05/21] Update README.md --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 86009fa..2ea9bb2 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,7 @@ Gasper is a very simple integration testing JUnit harness for `java -jar` servers like [WildFly Swarm](http://wildfly-swarm.io/) and [Spring Boot](http://projects.spring.io/spring-boot/). -[![WildFly Swarm](https://avatars3.githubusercontent.com/u/11523816?v=3&s=100) -WildFly Swarm](http://wildfly-swarm.io/) - -[![Spring Boot](https://avatars2.githubusercontent.com/u/317776?v=3&s=100) -Spring Boot](http://projects.spring.io/spring-boot/) +[![WildFly Swarm](https://avatars3.githubusercontent.com/u/11523816?v=3&s=100)](http://wildfly-swarm.io/) [![Spring Boot](https://avatars2.githubusercontent.com/u/317776?v=3&s=100)](http://projects.spring.io/spring-boot/) Gasper provides a simple to use JUnit `TestRule` that can be used to build integration tests with simple apps, like microservices. You can configure Gasper with easy to use builder interface. From e8b5bc8bb50b7cc48ff93f5cb2410da199706e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 22:08:45 +0100 Subject: [PATCH 06/21] More tests --- .../pl/wavesoftware/gasper/GasperBuilder.java | 2 + .../gasper/internal/HttpEndpoint.java | 8 +++- .../gasper/GasperBuilderTest.java | 43 +++++++++++++++++++ .../gasper/GasperForWildflySwarmIT.java | 1 + .../gasper/internal/HttpEndpointTest.java | 19 ++++++++ 5 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java create mode 100644 src/test/java/pl/wavesoftware/gasper/internal/HttpEndpointTest.java diff --git a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java index ca7a4a8..2009198 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java @@ -37,6 +37,8 @@ public final class GasperBuilder extends Gasper.RunnerCreator { private Path pomfile = Paths.get(MavenResolver.DEFAULT_POM); private Level level = Level.INFO; + protected GasperBuilder() {} + public GasperBuilder withPackaging(String packaging) { this.packaging = packaging; return this; diff --git a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java index 5342252..5678dbd 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java @@ -1,6 +1,8 @@ package pl.wavesoftware.gasper.internal; -import lombok.Data; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; import static java.lang.String.format; @@ -8,7 +10,9 @@ * @author Krzysztof Suszyński * @since 2016-03-05 */ -@Data +@Getter +@Setter +@RequiredArgsConstructor public class HttpEndpoint { public static final String DEFAULT_SCHEME = "http"; public static final String DEFAULT_DOMAIN = "localhost"; diff --git a/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java b/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java new file mode 100644 index 0000000..583d0c7 --- /dev/null +++ b/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java @@ -0,0 +1,43 @@ +package pl.wavesoftware.gasper; + +import com.mashape.unirest.http.Unirest; +import org.junit.Test; +import pl.wavesoftware.eid.utils.EidPreconditions; +import pl.wavesoftware.gasper.internal.HttpEndpoint; + +import java.nio.file.Paths; + +import static org.assertj.core.api.Assertions.assertThat; +import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +public class GasperBuilderTest { + + @Test + public void testBuild() throws Exception { + GasperBuilder builder = new GasperBuilder(); + Gasper gasper = builder.withJavaOption("swarm.context.path", "/sub") + .maxStartupTime(100) + .maxDeploymentTime(20) + .withEnvironmentVariable("jdbc.password", "S3CreT!1") + .inheritIO() + .silent() + .usePomFile(Paths.get("pom.xml")) + .withPackaging("jar") + .waitForContext("/sub") + .withClassifier("swarm") + .useContextChecker(GasperBuilderTest::checkContext) + .withPort(11909) + .build(); + + assertThat(gasper).isNotNull(); + } + + private static Boolean checkContext(HttpEndpoint endpoint) { + return tryToExecute((EidPreconditions.UnsafeSupplier) () -> + Unirest.get(endpoint.fullAddress()).asBinary().getStatus() == 200, "20160305:215916"); + } +} diff --git a/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java b/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java index d945bf8..f382d5c 100644 --- a/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java +++ b/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java @@ -40,6 +40,7 @@ public void testGetRoot() throws UnirestException { // then assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getBody()).isEqualTo(expectedMessage); + assertThat(gasper.getPort()).isGreaterThanOrEqualTo(1000); } } diff --git a/src/test/java/pl/wavesoftware/gasper/internal/HttpEndpointTest.java b/src/test/java/pl/wavesoftware/gasper/internal/HttpEndpointTest.java new file mode 100644 index 0000000..7e2edbf --- /dev/null +++ b/src/test/java/pl/wavesoftware/gasper/internal/HttpEndpointTest.java @@ -0,0 +1,19 @@ +package pl.wavesoftware.gasper.internal; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +public class HttpEndpointTest { + + @Test + public void testFullAddress() throws Exception { + HttpEndpoint endpoint = new HttpEndpoint("http", "example.org", 8080, "/", "a=7"); + String address = endpoint.fullAddress(); + assertThat(address).isEqualTo("http://example.org:8080/?a=7"); + } +} From 89f9ab6c45f637d7a94e0f4ab3e97bcae96bdf15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 22:10:23 +0100 Subject: [PATCH 07/21] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2ea9bb2..fdfb148 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Gasper! +[![Build Status](https://travis-ci.org/wavesoftware/java-gasper.svg?branch=master)](https://travis-ci.org/wavesoftware/java-gasper) + Gasper is a very simple integration testing JUnit harness for `java -jar` servers like [WildFly Swarm](http://wildfly-swarm.io/) and [Spring Boot](http://projects.spring.io/spring-boot/). [![WildFly Swarm](https://avatars3.githubusercontent.com/u/11523816?v=3&s=100)](http://wildfly-swarm.io/) [![Spring Boot](https://avatars2.githubusercontent.com/u/317776?v=3&s=100)](http://projects.spring.io/spring-boot/) From 6948fc3a3fcc8c9ed3ed8cfe933c8a28bada9d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 22:14:10 +0100 Subject: [PATCH 08/21] Remove -Werror causing error while compiling --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9358a6f..f26974c 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,6 @@ 3.3 - -Werror -Xlint:-deprecation -Xlint:all From 7590faf93e3f0b05f9fd3c7e87f0a5898b453eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 22:22:35 +0100 Subject: [PATCH 09/21] Add Coveralls report --- README.md | 2 +- pom.xml | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fdfb148..f31c822 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Gasper! -[![Build Status](https://travis-ci.org/wavesoftware/java-gasper.svg?branch=master)](https://travis-ci.org/wavesoftware/java-gasper) +[![Build Status](https://travis-ci.org/wavesoftware/java-gasper.svg?branch=master)](https://travis-ci.org/wavesoftware/java-gasper) [![Coverage Status](https://coveralls.io/repos/github/wavesoftware/java-gasper/badge.svg?branch=develop)](https://coveralls.io/github/wavesoftware/java-gasper?branch=develop) Gasper is a very simple integration testing JUnit harness for `java -jar` servers like [WildFly Swarm](http://wildfly-swarm.io/) and [Spring Boot](http://projects.spring.io/spring-boot/). diff --git a/pom.xml b/pom.xml index f26974c..32ce993 100644 --- a/pom.xml +++ b/pom.xml @@ -176,5 +176,32 @@ + + travis + + + env.TRAVIS + true + + + + + + org.eluder.coveralls + coveralls-maven-plugin + 3.1.0 + + + coveralls-default + verify + + report + + + + + + + From d9d78a976a24344646468dbcfb85cbb7ed4dde99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 22:27:25 +0100 Subject: [PATCH 10/21] Coveralls fix --- .travis.yml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 22fb5f9..aa3f4b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ --- language: java -install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -B -V +install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -Dcoveralls.skip=true -B -V script: mvn verify -Pci jdk: - oraclejdk8 diff --git a/pom.xml b/pom.xml index 32ce993..72ba269 100644 --- a/pom.xml +++ b/pom.xml @@ -189,7 +189,7 @@ org.eluder.coveralls coveralls-maven-plugin - 3.1.0 + 4.1.0 coveralls-default From 370eb134a5ffcab9c343bcdcdc114d45d655aaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sat, 5 Mar 2016 22:38:32 +0100 Subject: [PATCH 11/21] Update Travis CI badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f31c822..bf8d655 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Gasper! -[![Build Status](https://travis-ci.org/wavesoftware/java-gasper.svg?branch=master)](https://travis-ci.org/wavesoftware/java-gasper) [![Coverage Status](https://coveralls.io/repos/github/wavesoftware/java-gasper/badge.svg?branch=develop)](https://coveralls.io/github/wavesoftware/java-gasper?branch=develop) +[![Build Status](https://travis-ci.org/wavesoftware/java-gasper.svg?branch=develop)](https://travis-ci.org/wavesoftware/java-gasper) [![Coverage Status](https://coveralls.io/repos/github/wavesoftware/java-gasper/badge.svg?branch=develop)](https://coveralls.io/github/wavesoftware/java-gasper?branch=develop) Gasper is a very simple integration testing JUnit harness for `java -jar` servers like [WildFly Swarm](http://wildfly-swarm.io/) and [Spring Boot](http://projects.spring.io/spring-boot/). From bc74233dd496ee20112770a1ef5dc5342a829374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 00:58:50 +0100 Subject: [PATCH 12/21] Spark example app --- pom.xml | 2 +- src/it/spark-tester/pom.xml | 61 +++++++++++++++++++ .../examples/sparktester/HelloApp.java | 9 +++ src/it/wildfly-swarm-tester/pom.xml | 8 +++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/it/spark-tester/pom.xml create mode 100644 src/it/spark-tester/src/main/java/pl/wavesoftware/examples/sparktester/HelloApp.java diff --git a/pom.xml b/pom.xml index 72ba269..0295d49 100644 --- a/pom.xml +++ b/pom.xml @@ -127,7 +127,6 @@ prepare-packages - install run package @@ -135,6 +134,7 @@ ${project.build.directory}/it + 3 diff --git a/src/it/spark-tester/pom.xml b/src/it/spark-tester/pom.xml new file mode 100644 index 0000000..eeeae73 --- /dev/null +++ b/src/it/spark-tester/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + pl.wavesoftware.examples + spark-tester + 1.0.0 + jar + Spark Tester app + + + 1.8 + 1.8 + UTF-8 + UTF-8 + + + + + com.sparkjava + spark-core + 2.3 + + + org.slf4j + slf4j-simple + 1.6.2 + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + + package + + shade + + + + + pl.wavesoftware.examples.sparktester.HelloApp + + + false + + + + + + + diff --git a/src/it/spark-tester/src/main/java/pl/wavesoftware/examples/sparktester/HelloApp.java b/src/it/spark-tester/src/main/java/pl/wavesoftware/examples/sparktester/HelloApp.java new file mode 100644 index 0000000..1a09eed --- /dev/null +++ b/src/it/spark-tester/src/main/java/pl/wavesoftware/examples/sparktester/HelloApp.java @@ -0,0 +1,9 @@ +package pl.wavesoftware.examples.sparktester; + +import static spark.Spark.*; + +public class HelloApp { + public static void main(String[] args) { + get("/", (req, res) -> "Hello from Spark!"); + } +} diff --git a/src/it/wildfly-swarm-tester/pom.xml b/src/it/wildfly-swarm-tester/pom.xml index cb05fe4..35167e8 100644 --- a/src/it/wildfly-swarm-tester/pom.xml +++ b/src/it/wildfly-swarm-tester/pom.xml @@ -37,6 +37,14 @@ + + org.apache.maven.plugins + maven-war-plugin + 2.5 + + true + + org.wildfly.swarm wildfly-swarm-plugin From c6b1bf0467fb4de0b85763d6b55aac59e3a513b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 00:59:45 +0100 Subject: [PATCH 13/21] License and project adresses --- pom.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pom.xml b/pom.xml index 0295d49..b4f6a01 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,7 @@ + apache20 3.0.4 1.8 1.8 @@ -18,6 +19,25 @@ UTF-8 + + + Apache License 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + repo + + + + + scm:git:https://github.com/wavesoftware/java-gasper.git + scm:git:git@github.com:wavesoftware/java-gasper.git + https://github.com/wavesoftware/java-gasper + + + + travis-ci + https://travis-ci.org/wavesoftware/java-gasper + + ${maven.required.version} From da48dc1a2f91d1076c593cdc63895408bc97eff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 01:04:50 +0100 Subject: [PATCH 14/21] Name changes to builder interface --- README.md | 33 +++++--- .../java/pl/wavesoftware/gasper/Gasper.java | 3 +- .../pl/wavesoftware/gasper/GasperBuilder.java | 82 ++++++++++--------- .../gasper/GasperConfigurations.java | 14 ++-- .../gasper/internal/Executor.java | 1 + .../gasper/internal/HttpEndpoint.java | 2 +- .../gasper/internal/Settings.java | 25 ++++-- .../gasper/GasperBuilderTest.java | 28 ++++--- .../gasper/GasperForSpringBootIT.java | 2 +- .../gasper/GasperForWildflySwarmIT.java | 4 +- 10 files changed, 113 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index bf8d655..4d3b3f9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Gasper is a very simple integration testing JUnit harness for `java -jar` server [![WildFly Swarm](https://avatars3.githubusercontent.com/u/11523816?v=3&s=100)](http://wildfly-swarm.io/) [![Spring Boot](https://avatars2.githubusercontent.com/u/317776?v=3&s=100)](http://projects.spring.io/spring-boot/) -Gasper provides a simple to use JUnit `TestRule` that can be used to build integration tests with simple apps, like microservices. You can configure Gasper with easy to use builder interface. +Gasper provides a simple to use JUnit `TestRule` that can be used to build integration tests with simple apps, like micro-services. You can configure Gasper with easy to use builder interface. ## Usage @@ -48,22 +48,31 @@ public void testGetRoot() throws UnirestException { } ``` -### Addtional configuration +### Additional configuration To configure Gasper use `GasperBuilder` interface, for ex.: ```java +private final int port = 11909; +private final String webContext = "/test"; +private final String systemPropertyForPort = "swarm.http.port"; @ClassRule -public static Gasper gasper = Gasper.configurations() - .wildflySwarm() - .usePomFile(Paths.get("target", "it", "wildfly-swarm-tester", "pom.xml")) - .inheritIO() - .maxStartupTime(120) - .maxDeploymentTime(20) - .useContextChecker(MyTestClass::contextChecker) - .withEnvironmentVariable("jdbc.password", DEV_PASSWORD) - .withJavaOption("my.minus-d.option", "true") - .silent() +public static Gasper gasper = Gasper.builder() + .silentGasperMessages() + .usingSystemPropertyForPort(systemPropertyForPort) + .withSystemProperty("swarm.context.path", webContext) + .withSystemProperty(systemPropertyForPort, String.valueOf(port)) + .withJVMOptions("-server", "-Xms1G", "-Xmx1G", "-XX:+UseConcMarkSweepGC") + .withMaxStartupTime(100) + .withMaxDeploymentTime(20) + .withEnvironmentVariable("jdbc.password", "S3CreT!1") + .withServerLoggingOnConsole() + .usingPomFile(Paths.get("pom.xml")) + .withArtifactPackaging("jar") + .waitForWebContext(webContext) + .withArtifactClassifier("swarm") + .usingWebContextChecker(GasperBuilderTest::checkContext) + .withPort(port) .build(); ``` diff --git a/src/main/java/pl/wavesoftware/gasper/Gasper.java b/src/main/java/pl/wavesoftware/gasper/Gasper.java index bf428af..5ccd219 100644 --- a/src/main/java/pl/wavesoftware/gasper/Gasper.java +++ b/src/main/java/pl/wavesoftware/gasper/Gasper.java @@ -122,7 +122,8 @@ private List buildCommand() { } private void buildJavaOptions(List command) { - command.addAll(settings.getJavaOptions().entrySet().stream() + command.addAll(settings.getJvmOptions()); + command.addAll(settings.getSystemProperties().entrySet().stream() .map(entry -> format("-D%s=%s", entry.getKey(), entry.getValue())) .collect(Collectors.toList()) ); diff --git a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java index 2009198..36528d7 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java @@ -1,6 +1,5 @@ package pl.wavesoftware.gasper; -import com.google.common.collect.ImmutableMap; import org.slf4j.event.Level; import pl.wavesoftware.eid.utils.EidPreconditions; import pl.wavesoftware.gasper.internal.Executor; @@ -11,7 +10,10 @@ import java.net.ServerSocket; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.function.Function; @@ -25,9 +27,10 @@ public final class GasperBuilder extends Gasper.RunnerCreator { private String packaging = MavenResolver.DEFAULT_PACKAGING; private String classifier = ""; - private Map javaOptions = new LinkedHashMap<>(); + private Map systemProperties = new LinkedHashMap<>(); + private List jvmOptions = new ArrayList<>(); private Map environment = new LinkedHashMap<>(); - private String portJavaOption; + private String systemPropertyForPort; private Integer port; private boolean inheritIO = false; private String context = Gasper.DEFAULT_CONTEXT; @@ -39,12 +42,12 @@ public final class GasperBuilder extends Gasper.RunnerCreator { protected GasperBuilder() {} - public GasperBuilder withPackaging(String packaging) { + public GasperBuilder withArtifactPackaging(String packaging) { this.packaging = packaging; return this; } - public GasperBuilder withClassifier(String classifier) { + public GasperBuilder withArtifactClassifier(String classifier) { this.classifier = classifier; return this; } @@ -54,8 +57,13 @@ public GasperBuilder withEnvironmentVariable(String key, String value) { return this; } - public GasperBuilder withJavaOption(String key, String value) { - javaOptions.put(key, value); + public GasperBuilder withSystemProperty(String key, String value) { + systemProperties.put(key, value); + return this; + } + + public GasperBuilder withJVMOptions(String... options) { + Collections.addAll(jvmOptions, options); return this; } @@ -64,72 +72,72 @@ public GasperBuilder withPort(int port) { return this; } - public GasperBuilder usePortJavaOptionFor(String portJavaOption) { - this.portJavaOption = portJavaOption; + public GasperBuilder usingSystemPropertyForPort(String systemPropertyForPort) { + this.systemPropertyForPort = systemPropertyForPort; return this; } - public GasperBuilder usePomFile(Path pomfile) { + public GasperBuilder usingPomFile(Path pomfile) { this.pomfile = pomfile; return this; } - public GasperBuilder inheritIO() { - return inheritIO(true); + public GasperBuilder withServerLoggingOnConsole() { + return withServerLoggingOnConsole(true); } - public GasperBuilder inheritIO(boolean inheritIO) { + public GasperBuilder withServerLoggingOnConsole(boolean inheritIO) { this.inheritIO = inheritIO; return this; } - public Gasper build() { - if (port == null) { - port = findNotBindedPort(); - } - if (portJavaOption != null) { - withJavaOption(portJavaOption, port.toString()); - } - Settings settings = new Settings( - packaging, classifier, port, - ImmutableMap.copyOf(javaOptions), ImmutableMap.copyOf(environment), - inheritIO, context, contextChecker, - portAvailableMaxTime, deploymentMaxTime, - pomfile, level - ); - return create(settings); - } - - public GasperBuilder maxStartupTime(int seconds) { + public GasperBuilder withMaxStartupTime(int seconds) { this.portAvailableMaxTime = seconds; return this; } - public GasperBuilder maxDeploymentTime(int seconds) { + public GasperBuilder withMaxDeploymentTime(int seconds) { this.deploymentMaxTime = seconds; return this; } - public GasperBuilder waitForContext(String context) { + public GasperBuilder waitForWebContext(String context) { this.context = context; return this; } - public GasperBuilder useContextChecker(Function contextChecker) { + public GasperBuilder usingWebContextChecker(Function contextChecker) { this.contextChecker = contextChecker; return this; } - public GasperBuilder silent() { - useLogLevel(Level.WARN); + public GasperBuilder silentGasperMessages() { + usingLogLevel(Level.WARN); return this; } - public GasperBuilder useLogLevel(Level level) { + public GasperBuilder usingLogLevel(Level level) { this.level = level; return this; } + public Gasper build() { + if (port == null) { + port = findNotBindedPort(); + } + if (systemPropertyForPort != null) { + withSystemProperty(systemPropertyForPort, port.toString()); + } + Settings settings = new Settings( + packaging, classifier, port, + systemProperties, jvmOptions, environment, + inheritIO, context, contextChecker, + portAvailableMaxTime, deploymentMaxTime, + pomfile, level + ); + return create(settings); + } + private static Integer findNotBindedPort() { return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { try (ServerSocket socket = new ServerSocket(0)) { diff --git a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java index e193a62..3d7a5e1 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java @@ -27,14 +27,14 @@ protected GasperConfigurations() {} *

* You can use it directly or use {@link GasperBuilder} interface to re-configure it to you needs. *

- * To use it in JUnit execute method {@link GasperBuilder#create()} + * To use it in JUnit execute method {@link GasperBuilder#build()} * @return pre-configured {@link GasperBuilder} to use with WildFly Swarm. */ public GasperBuilder wildflySwarm() { return Gasper.builder() - .withPackaging("jar") - .withClassifier("swarm") - .usePortJavaOptionFor(GasperConfigurations.WILDFLY_SWARM); + .withArtifactPackaging("jar") + .withArtifactClassifier("swarm") + .usingSystemPropertyForPort(GasperConfigurations.WILDFLY_SWARM); } /** @@ -42,12 +42,12 @@ public GasperBuilder wildflySwarm() { *

* You can use it directly or use {@link GasperBuilder} interface to re-configure it to you needs. *

- * To use it in JUnit execute method {@link GasperBuilder#create()} + * To use it in JUnit execute method {@link GasperBuilder#build()} * @return pre-configured {@link GasperBuilder} to use with Spring Boot. */ public GasperBuilder springBoot() { return Gasper.builder() - .withPackaging("jar") - .usePortJavaOptionFor(GasperConfigurations.SPRING_BOOT); + .withArtifactPackaging("jar") + .usingSystemPropertyForPort(GasperConfigurations.SPRING_BOOT); } } diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java index 89e8886..27fe993 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java @@ -148,6 +148,7 @@ private static boolean isPortTaken(int port) { try (ServerSocket ignored = new ServerSocket(port)) { return false; } catch (IOException ex) { + log.trace(format("Port %d taken", port), ex); return true; } } diff --git a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java index 5678dbd..cae3004 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java @@ -25,7 +25,7 @@ public class HttpEndpoint { private final String query; public String fullAddress() { - String address = format("%s://%s:%d%s", + String address = format("%s://%s:%s%s", getScheme(), getDomain(), getPort(), diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java index 3796403..92c14f4 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java @@ -1,14 +1,14 @@ package pl.wavesoftware.gasper.internal; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; import org.slf4j.event.Level; import pl.wavesoftware.gasper.Gasper; import java.nio.file.Path; +import java.util.List; import java.util.Map; import java.util.function.Function; @@ -23,13 +23,13 @@ * @see Gasper#configurations() */ @Getter -@Setter @RequiredArgsConstructor public class Settings { private final String packaging; private final String classifier; private final int port; - private final Map javaOptions; + private final Map systemProperties; + private final List jvmOptions; private final Map environment; private final boolean inheritIO; private final String context; @@ -38,19 +38,26 @@ public class Settings { private final int deploymentMaxTime; private final Path pomfile; private final Level level; - @Setter(AccessLevel.NONE) private HttpEndpoint endpoint; /** - * Gets Java options as map + * Retrieves Java -D style options as map * @return a map for Java options */ - public Map getJavaOptions() { - return ImmutableMap.copyOf(javaOptions); + public Map getSystemProperties() { + return ImmutableMap.copyOf(systemProperties); } /** - * Gets environment variables as a map + * Retrieves Java VM options as list + * @return a map for Java options + */ + public List getJvmOptions() { + return ImmutableList.copyOf(jvmOptions); + } + + /** + * Retrieves environment variables as a map * @return a map for environment variables */ public Map getEnvironment() { diff --git a/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java b/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java index 583d0c7..b0945b0 100644 --- a/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java +++ b/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java @@ -19,18 +19,24 @@ public class GasperBuilderTest { @Test public void testBuild() throws Exception { GasperBuilder builder = new GasperBuilder(); - Gasper gasper = builder.withJavaOption("swarm.context.path", "/sub") - .maxStartupTime(100) - .maxDeploymentTime(20) + int port = 11909; + String webContext = "/test"; + String systemPropertyForPort = "swarm.http.port"; + Gasper gasper = builder.silentGasperMessages() + .usingSystemPropertyForPort(systemPropertyForPort) + .withSystemProperty("swarm.context.path", webContext) + .withSystemProperty(systemPropertyForPort, String.valueOf(port)) + .withJVMOptions("-server", "-Xms1G", "-Xmx1G", "-XX:+UseConcMarkSweepGC") + .withMaxStartupTime(100) + .withMaxDeploymentTime(20) .withEnvironmentVariable("jdbc.password", "S3CreT!1") - .inheritIO() - .silent() - .usePomFile(Paths.get("pom.xml")) - .withPackaging("jar") - .waitForContext("/sub") - .withClassifier("swarm") - .useContextChecker(GasperBuilderTest::checkContext) - .withPort(11909) + .withServerLoggingOnConsole() + .usingPomFile(Paths.get("pom.xml")) + .withArtifactPackaging("jar") + .waitForWebContext(webContext) + .withArtifactClassifier("swarm") + .usingWebContextChecker(GasperBuilderTest::checkContext) + .withPort(port) .build(); assertThat(gasper).isNotNull(); diff --git a/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java b/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java index 1590a91..cdeeda9 100644 --- a/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java +++ b/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java @@ -26,7 +26,7 @@ public class GasperForSpringBootIT { @ClassRule public static Gasper gasper = Gasper.configurations() .springBoot() - .usePomFile(SPRING_BOOT_POMFILE) + .usingPomFile(SPRING_BOOT_POMFILE) .build(); @Test diff --git a/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java b/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java index f382d5c..b26cf94 100644 --- a/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java +++ b/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java @@ -24,8 +24,8 @@ public class GasperForWildflySwarmIT { @ClassRule public static Gasper gasper = Gasper.configurations() .wildflySwarm() - .usePomFile(WILDFLY_SWARM_POMFILE) - .silent() + .usingPomFile(WILDFLY_SWARM_POMFILE) + .silentGasperMessages() .build(); @Test From 0283aeea79a9376dae61d05b2c275c7a2cb69a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 01:05:04 +0100 Subject: [PATCH 15/21] SonarQube configuration --- pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b4f6a01..f01b56d 100644 --- a/pom.xml +++ b/pom.xml @@ -13,10 +13,15 @@ apache20 3.0.4 - 1.8 - 1.8 UTF-8 UTF-8 + ${project.build.directory}/sonar + https://sonar.wavesoftware.pl + jacoco + 8 + ${sonar.java.source} + 1.${java.source.version} + ${maven.compiler.source} From 17852761f16238cdb4dadb080e6a75c3439c1605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 01:56:47 +0100 Subject: [PATCH 16/21] Codacy + SonarQube --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d3b3f9..0747cde 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Gasper! -[![Build Status](https://travis-ci.org/wavesoftware/java-gasper.svg?branch=develop)](https://travis-ci.org/wavesoftware/java-gasper) [![Coverage Status](https://coveralls.io/repos/github/wavesoftware/java-gasper/badge.svg?branch=develop)](https://coveralls.io/github/wavesoftware/java-gasper?branch=develop) +[![Build Status](https://travis-ci.org/wavesoftware/java-gasper.svg?branch=develop)](https://travis-ci.org/wavesoftware/java-gasper) [![Coverage Status](https://coveralls.io/repos/github/wavesoftware/java-gasper/badge.svg?branch=develop)](https://coveralls.io/github/wavesoftware/java-gasper?branch=develop) [![Codacy Badge](https://api.codacy.com/project/badge/grade/5c4d1180812e438ebe872f9121ec4368)](https://www.codacy.com/app/krzysztof-suszynski/java-gasper) [![SonarQube Tech Debt](https://img.shields.io/sonar/http/sonar-ro.wavesoftware.pl/pl.wavesoftware:gasper/tech_debt.svg)](https://sonar.wavesoftware.pl/dashboard/index/2858) Gasper is a very simple integration testing JUnit harness for `java -jar` servers like [WildFly Swarm](http://wildfly-swarm.io/) and [Spring Boot](http://projects.spring.io/spring-boot/). From 19e9703f3d40e82287428a306d353b8cce394cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 11:30:13 +0100 Subject: [PATCH 17/21] Sonar fixes --- README.md | 8 +- .../java/pl/wavesoftware/gasper/Gasper.java | 71 +++++--- .../pl/wavesoftware/gasper/GasperBuilder.java | 172 ++++-------------- .../gasper/GasperConfigurations.java | 10 +- .../internal/AbstractGasperBuilder.java | 148 +++++++++++++++ .../gasper/internal/Executor.java | 50 ++--- .../wavesoftware/gasper/internal/Logger.java | 4 +- .../gasper/internal/Settings.java | 4 +- .../gasper/internal/maven/MavenResolver.java | 7 +- .../AbstractGasperBuilderTest.java} | 11 +- 10 files changed, 273 insertions(+), 212 deletions(-) create mode 100644 src/main/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilder.java rename src/test/java/pl/wavesoftware/gasper/{GasperBuilderTest.java => internal/AbstractGasperBuilderTest.java} (84%) diff --git a/README.md b/README.md index 0747cde..e1af7dc 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ private final int port = 11909; private final String webContext = "/test"; private final String systemPropertyForPort = "swarm.http.port"; @ClassRule -public static Gasper gasper = Gasper.builder() +public static Gasper gasper = Gasper.configure() .silentGasperMessages() .usingSystemPropertyForPort(systemPropertyForPort) .withSystemProperty("swarm.context.path", webContext) @@ -89,12 +89,6 @@ public static Gasper gasper = Gasper.builder() ``` -### Gradle - -```groovy -testCompile 'pl.wavesoftware:gasper:1.0.0' -``` - ## Requirements Gasper requires Java 8. Tested on Travis CI. diff --git a/src/main/java/pl/wavesoftware/gasper/Gasper.java b/src/main/java/pl/wavesoftware/gasper/Gasper.java index 5ccd219..24b9573 100644 --- a/src/main/java/pl/wavesoftware/gasper/Gasper.java +++ b/src/main/java/pl/wavesoftware/gasper/Gasper.java @@ -9,6 +9,7 @@ import org.junit.runner.Description; import org.junit.runners.model.Statement; import pl.wavesoftware.eid.utils.EidPreconditions; +import pl.wavesoftware.gasper.internal.AbstractGasperBuilder; import pl.wavesoftware.gasper.internal.Executor; import pl.wavesoftware.gasper.internal.Logger; import pl.wavesoftware.gasper.internal.Settings; @@ -37,7 +38,7 @@ public final class Gasper implements TestRule { public static final int DEFAULT_PORT_AVAILABLE_MAX_SECONDS = 60; public static final int DEFAULT_DEPLOYMENT_MAX_SECONDS = 30; public static final String DEFAULT_CONTEXT = "/"; - private static final String figlet; + private static final String FIGLET; private final Settings settings; private Path artifact; @@ -46,12 +47,18 @@ public final class Gasper implements TestRule { static { InputStream is = Gasper.class.getClassLoader().getResourceAsStream("gasper.txt"); - figlet = tryToExecute((EidPreconditions.UnsafeSupplier) () -> + FIGLET = tryToExecute((EidPreconditions.UnsafeSupplier) () -> CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8)), "20160305:201329"); } - public static GasperBuilder builder() { - return new GasperBuilder(); + /** + * Creates a builder interface {@link GasperBuilder} that can be used to configure Gasper. + *

+ * You can also use already created configurations by using method {@link #configurations()} for convenience. + * @return a configure interface for configuration purposes + */ + public static GasperBuilder configure() { + return new GasperBuilderImpl(); } public static GasperConfigurations configurations() { @@ -66,50 +73,59 @@ public String getAddress() { return settings.getEndpoint().fullAddress(); } - protected abstract static class RunnerCreator { - public Gasper create(Settings settings) { + protected interface RunnerCreator { + default Gasper create(Settings settings) { return new Gasper(settings); } } @Override public Statement apply(Statement base, Description description) { - GasperStatement afterStmt = new GasperStatement(base, this); return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { setup(); before(); - return afterStmt; + return new GasperStatement(base, this::after); }, "20160305:004035"); } + private void setup() { + log(FIGLET); + MavenResolver resolver = new MavenResolver(settings.getPomfile()); + artifact = resolver.getBuildArtifact(settings.getPackaging(), settings.getClassifier()); + File workingDirectory = resolver.getBuildDirectory(); + List command = buildCommand(); + log("Command to be executed: \"%s\"", command.stream().collect(Collectors.joining(" "))); + executor = new Executor(command, workingDirectory, settings); + } + + private void before() throws IOException { + executor.start(); + log("All looks ready, running tests..."); + } + + private void after() { + log("Testing on server completed."); + executor.stop(); + } + @RequiredArgsConstructor private static class GasperStatement extends Statement { private final Statement base; - private final Gasper gasper; + private final Procedure procedure; @Override public void evaluate() throws Throwable { try { base.evaluate(); } finally { - gasper.after(); + procedure.execute(); } } } - private void setup() { - log(figlet); - MavenResolver resolver = new MavenResolver(settings.getPomfile()); - artifact = resolver.getBuildArtifact(settings.getPackaging(), settings.getClassifier()); - File workingDirectory = resolver.getBuildDirectory(); - List command = buildCommand(); - log("Command to be executed: \"%s\"", command.stream().collect(Collectors.joining(" "))); - executor = new Executor(command, workingDirectory, settings); - } - - private void before() throws IOException { - executor.start(); - log("All looks ready, running tests..."); + @FunctionalInterface + private interface Procedure { + void execute(); } private List buildCommand() { @@ -129,11 +145,6 @@ private void buildJavaOptions(List command) { ); } - private void after() { - log("Testing on server completed."); - executor.stop(); - } - private void log(String frmt, Object... args) { ensureLogger(); logger.info(format(frmt, args)); @@ -144,4 +155,8 @@ private void ensureLogger() { logger = new Logger(log, settings); } } + + private static class GasperBuilderImpl extends AbstractGasperBuilder { + + } } diff --git a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java index 36528d7..1798ccb 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java @@ -1,149 +1,47 @@ package pl.wavesoftware.gasper; import org.slf4j.event.Level; -import pl.wavesoftware.eid.utils.EidPreconditions; -import pl.wavesoftware.gasper.internal.Executor; import pl.wavesoftware.gasper.internal.HttpEndpoint; -import pl.wavesoftware.gasper.internal.Settings; -import pl.wavesoftware.gasper.internal.maven.MavenResolver; -import java.net.ServerSocket; import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; import java.util.function.Function; -import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; - /** * @author Krzysztof Suszyński - * @since 2016-03-05 + * @since 2016-03-06 */ -public final class GasperBuilder extends Gasper.RunnerCreator { - - private String packaging = MavenResolver.DEFAULT_PACKAGING; - private String classifier = ""; - private Map systemProperties = new LinkedHashMap<>(); - private List jvmOptions = new ArrayList<>(); - private Map environment = new LinkedHashMap<>(); - private String systemPropertyForPort; - private Integer port; - private boolean inheritIO = false; - private String context = Gasper.DEFAULT_CONTEXT; - private int portAvailableMaxTime = Gasper.DEFAULT_PORT_AVAILABLE_MAX_SECONDS; - private int deploymentMaxTime = Gasper.DEFAULT_DEPLOYMENT_MAX_SECONDS; - private Function contextChecker = Executor.DEFAULT_CONTEXT_CHECKER; - private Path pomfile = Paths.get(MavenResolver.DEFAULT_POM); - private Level level = Level.INFO; - - protected GasperBuilder() {} - - public GasperBuilder withArtifactPackaging(String packaging) { - this.packaging = packaging; - return this; - } - - public GasperBuilder withArtifactClassifier(String classifier) { - this.classifier = classifier; - return this; - } - - public GasperBuilder withEnvironmentVariable(String key, String value) { - environment.put(key, value); - return this; - } - - public GasperBuilder withSystemProperty(String key, String value) { - systemProperties.put(key, value); - return this; - } - - public GasperBuilder withJVMOptions(String... options) { - Collections.addAll(jvmOptions, options); - return this; - } - - public GasperBuilder withPort(int port) { - this.port = port; - return this; - } - - public GasperBuilder usingSystemPropertyForPort(String systemPropertyForPort) { - this.systemPropertyForPort = systemPropertyForPort; - return this; - } - - public GasperBuilder usingPomFile(Path pomfile) { - this.pomfile = pomfile; - return this; - } - - public GasperBuilder withServerLoggingOnConsole() { - return withServerLoggingOnConsole(true); - } - - public GasperBuilder withServerLoggingOnConsole(boolean inheritIO) { - this.inheritIO = inheritIO; - return this; - } - - public GasperBuilder withMaxStartupTime(int seconds) { - this.portAvailableMaxTime = seconds; - return this; - } - - public GasperBuilder withMaxDeploymentTime(int seconds) { - this.deploymentMaxTime = seconds; - return this; - } - - public GasperBuilder waitForWebContext(String context) { - this.context = context; - return this; - } - - public GasperBuilder usingWebContextChecker(Function contextChecker) { - this.contextChecker = contextChecker; - return this; - } - - public GasperBuilder silentGasperMessages() { - usingLogLevel(Level.WARN); - return this; - } - - public GasperBuilder usingLogLevel(Level level) { - this.level = level; - return this; - } - - public Gasper build() { - if (port == null) { - port = findNotBindedPort(); - } - if (systemPropertyForPort != null) { - withSystemProperty(systemPropertyForPort, port.toString()); - } - Settings settings = new Settings( - packaging, classifier, port, - systemProperties, jvmOptions, environment, - inheritIO, context, contextChecker, - portAvailableMaxTime, deploymentMaxTime, - pomfile, level - ); - return create(settings); - } - - private static Integer findNotBindedPort() { - return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { - try (ServerSocket socket = new ServerSocket(0)) { - return socket.getLocalPort(); - } - }, "20160305:202934"); - - } +public interface GasperBuilder extends Gasper.RunnerCreator { + GasperBuilder withArtifactPackaging(String packaging); + + GasperBuilder withArtifactClassifier(String classifier); + + GasperBuilder withEnvironmentVariable(String key, String value); + + GasperBuilder withSystemProperty(String key, String value); + + GasperBuilder withJVMOptions(String... options); + + GasperBuilder withPort(int port); + + GasperBuilder usingSystemPropertyForPort(String systemPropertyForPort); + + GasperBuilder usingPomFile(Path pomfile); + + GasperBuilder withServerLoggingOnConsole(); + + GasperBuilder withServerLoggingOnConsole(boolean inheritIO); + + GasperBuilder withMaxStartupTime(int seconds); + + GasperBuilder withMaxDeploymentTime(int seconds); + + GasperBuilder waitForWebContext(String context); + + GasperBuilder usingWebContextChecker(Function contextChecker); + + GasperBuilder silentGasperMessages(); + + GasperBuilder usingLogLevel(Level level); + + Gasper build(); } diff --git a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java index 3d7a5e1..4a66817 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java @@ -4,7 +4,7 @@ * This class holds supported and tested configurations for servers. *

* Configuration in this class are fairly tested and can serve as a base for configuration. - * You shouldn't try to use this class directly. Use instead {@link Gasper#builderPreconfigured()} for entry point. + * You shouldn't try to use this class directly. Use instead {@link Gasper#configurations()} for entry point. *

* Example: *

@@ -23,7 +23,7 @@ public final class GasperConfigurations {
     protected GasperConfigurations() {}
 
     /**
-     * This method returns pre-configured Gasper builder to use with WildFly Swarm.
+     * This method returns pre-configured Gasper configuration to use with WildFly Swarm.
      * 

* You can use it directly or use {@link GasperBuilder} interface to re-configure it to you needs. *

@@ -31,14 +31,14 @@ protected GasperConfigurations() {} * @return pre-configured {@link GasperBuilder} to use with WildFly Swarm. */ public GasperBuilder wildflySwarm() { - return Gasper.builder() + return Gasper.configure() .withArtifactPackaging("jar") .withArtifactClassifier("swarm") .usingSystemPropertyForPort(GasperConfigurations.WILDFLY_SWARM); } /** - * This method returns pre-configured Gasper builder to use with Spring Boot. + * This method returns pre-configured Gasper configure to use with Spring Boot. *

* You can use it directly or use {@link GasperBuilder} interface to re-configure it to you needs. *

@@ -46,7 +46,7 @@ public GasperBuilder wildflySwarm() { * @return pre-configured {@link GasperBuilder} to use with Spring Boot. */ public GasperBuilder springBoot() { - return Gasper.builder() + return Gasper.configure() .withArtifactPackaging("jar") .usingSystemPropertyForPort(GasperConfigurations.SPRING_BOOT); } diff --git a/src/main/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilder.java new file mode 100644 index 0000000..a5dc967 --- /dev/null +++ b/src/main/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilder.java @@ -0,0 +1,148 @@ +package pl.wavesoftware.gasper.internal; + +import org.slf4j.event.Level; +import pl.wavesoftware.eid.utils.EidPreconditions; +import pl.wavesoftware.gasper.Gasper; +import pl.wavesoftware.gasper.GasperBuilder; +import pl.wavesoftware.gasper.internal.maven.MavenResolver; + +import java.net.ServerSocket; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; + +/** + * @author Krzysztof Suszyński + * @since 2016-03-05 + */ +public abstract class AbstractGasperBuilder implements GasperBuilder { + + private String packaging = MavenResolver.DEFAULT_PACKAGING; + private String classifier = ""; + private Map systemProperties = new LinkedHashMap<>(); + private List jvmOptions = new ArrayList<>(); + private Map environment = new LinkedHashMap<>(); + private String systemPropertyForPort; + private Integer port; + private boolean inheritIO = false; + private String context = Gasper.DEFAULT_CONTEXT; + private int portAvailableMaxTime = Gasper.DEFAULT_PORT_AVAILABLE_MAX_SECONDS; + private int deploymentMaxTime = Gasper.DEFAULT_DEPLOYMENT_MAX_SECONDS; + private Function contextChecker = Executor.DEFAULT_CONTEXT_CHECKER; + private Path pomfile = Paths.get(MavenResolver.DEFAULT_POM); + private Level level = Level.INFO; + + protected AbstractGasperBuilder() {} + + @Override public GasperBuilder withArtifactPackaging(String packaging) { + this.packaging = packaging; + return this; + } + + @Override public GasperBuilder withArtifactClassifier(String classifier) { + this.classifier = classifier; + return this; + } + + @Override public GasperBuilder withEnvironmentVariable(String key, String value) { + environment.put(key, value); + return this; + } + + @Override public GasperBuilder withSystemProperty(String key, String value) { + systemProperties.put(key, value); + return this; + } + + @Override public GasperBuilder withJVMOptions(String... options) { + Collections.addAll(jvmOptions, options); + return this; + } + + @Override public GasperBuilder withPort(int port) { + this.port = port; + return this; + } + + @Override public GasperBuilder usingSystemPropertyForPort(String systemPropertyForPort) { + this.systemPropertyForPort = systemPropertyForPort; + return this; + } + + @Override public GasperBuilder usingPomFile(Path pomfile) { + this.pomfile = pomfile; + return this; + } + + @Override public GasperBuilder withServerLoggingOnConsole() { + return withServerLoggingOnConsole(true); + } + + @Override public GasperBuilder withServerLoggingOnConsole(boolean inheritIO) { + this.inheritIO = inheritIO; + return this; + } + + @Override public GasperBuilder withMaxStartupTime(int seconds) { + this.portAvailableMaxTime = seconds; + return this; + } + + @Override public GasperBuilder withMaxDeploymentTime(int seconds) { + this.deploymentMaxTime = seconds; + return this; + } + + @Override public GasperBuilder waitForWebContext(String context) { + this.context = context; + return this; + } + + @Override public GasperBuilder usingWebContextChecker(Function contextChecker) { + this.contextChecker = contextChecker; + return this; + } + + @Override public GasperBuilder silentGasperMessages() { + usingLogLevel(Level.WARN); + return this; + } + + @Override public GasperBuilder usingLogLevel(Level level) { + this.level = level; + return this; + } + + @Override public Gasper build() { + if (port == null) { + port = findNotBindedPort(); + } + if (systemPropertyForPort != null) { + withSystemProperty(systemPropertyForPort, port.toString()); + } + Settings settings = new Settings( + packaging, classifier, port, + systemProperties, jvmOptions, environment, + inheritIO, context, contextChecker, + portAvailableMaxTime, deploymentMaxTime, + pomfile, level + ); + return create(settings); + } + + private static Integer findNotBindedPort() { + return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } + }, "20160305:202934"); + + } +} diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java index 27fe993..5a845da 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java @@ -61,11 +61,10 @@ public void stop() { } private void waitForHttpContext() { - Integer port = settings.getPort(); String context = settings.getContext(); int maxWait = settings.getDeploymentMaxTime(); log("Waiting for deployment for context: \"%s\" to happen...", context); - boolean ok = waitForContextToBecomeAvailable(port, context, maxWait); + boolean ok = waitForContextToBecomeAvailable(context, maxWait); if (!ok) { throw new EidIllegalStateException(new Eid("20160305:123206"), "Context %s in not available after waiting %s seconds, aborting!", @@ -74,17 +73,38 @@ private void waitForHttpContext() { } } - private boolean waitForContextToBecomeAvailable(int port, String context, int maxSeconds) { + private boolean waitForContextToBecomeAvailable(String context, int maxSeconds) { + return waitOnProcess(maxSeconds, (step) -> { + if (isContextAvailable()) { + int waited = WAIT_STEP * step; + log("Context \"%s\" became available after ~%dms!", context, waited); + return true; + } + return false; + }); + } + + private boolean waitForPortToBecomeAvailable(int port, int maxSeconds) { + return waitOnProcess(maxSeconds, (step) -> { + if (isPortTaken(port)) { + int waited = WAIT_STEP * step; + log("Port %d became available after ~%dms!", port, waited); + return true; + } + return false; + }); + } + + private boolean waitOnProcess(int maxSeconds, Function supplier) { for (int i = 1; i <= maxSeconds * WAIT_STEPS_IN_SECOND; i++) { try { process.waitFor(WAIT_STEP, TimeUnit.MILLISECONDS); - if (isContextAvailable()) { - int waited = WAIT_STEP * i; - log("Context \"%s\" became available after ~%dms!", context, waited); + if (supplier.apply(i)) { return true; } } catch (InterruptedException e) { log.error("Tried to wait " + WAIT_STEP + "ms, failed: " + e.getLocalizedMessage(), e); + Thread.currentThread().interrupt(); } } return false; @@ -111,7 +131,7 @@ private boolean isContextAvailable() { private void startAndWaitForPort() { Integer port = settings.getPort(); log("Waiting for port: %d to became active...", port); - boolean ok = waitForPortToBecomeAvailable(process, port, settings.getPortAvailableMaxTime()); + boolean ok = waitForPortToBecomeAvailable(port, settings.getPortAvailableMaxTime()); if (!ok) { throw new EidIllegalStateException(new Eid("20160305:003452"), "Process %s probably didn't started well after maximum wait time is reached: %s", @@ -120,22 +140,6 @@ private void startAndWaitForPort() { } } - private boolean waitForPortToBecomeAvailable(Process process, int port, int maxSeconds) { - for (int i = 1; i <= maxSeconds * WAIT_STEPS_IN_SECOND; i++) { - try { - process.waitFor(WAIT_STEP, TimeUnit.MILLISECONDS); - if (isPortTaken(port)) { - int waited = WAIT_STEP * i; - log("Port %d became available after ~%dms!", port, waited); - return true; - } - } catch (InterruptedException e) { - log.error("Tried to wait " + WAIT_STEP + "ms, failed: " + e.getLocalizedMessage(), e); - } - } - return false; - } - private void logToFile(ProcessBuilder pb) { File tempDir = new File(System.getProperty("java.io.tmpdir")); Path logFile = tempDir.toPath().resolve("gasper.log"); diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Logger.java b/src/main/java/pl/wavesoftware/gasper/internal/Logger.java index 9b23635..74870f0 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Logger.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Logger.java @@ -9,12 +9,12 @@ */ @RequiredArgsConstructor public class Logger { - private final org.slf4j.Logger logger; + private final org.slf4j.Logger slf; private final Settings settings; public void info(String message) { if (settings.getLevel().toInt() <= Level.INFO.toInt()) { - logger.info(message); + slf.info(message); } } } diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java index 92c14f4..a860f98 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java @@ -15,11 +15,11 @@ /** * This class represents a set of settings for Gasper. It is used as a POJO with settings. *

- * CAUTION! It is internal class of Gasper, and shouldn't be used directly. Use gasper builder interface {@link Gasper#builder()} or {@link Gasper#configurations()} to set those settings. + * CAUTION! It is internal class of Gasper, and shouldn't be used directly. Use gasper configure interface {@link Gasper#configure()} or {@link Gasper#configurations()} to set those settings. * * @author Krzysztof Suszyński * @since 2016-03-05 - * @see Gasper#builder() + * @see Gasper#configure() * @see Gasper#configurations() */ @Getter diff --git a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java index 4a802e3..e09dcba 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java @@ -4,7 +4,8 @@ import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import java.io.File; -import java.io.FileReader; +import java.io.FileInputStream; +import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Objects; @@ -37,8 +38,8 @@ public MavenResolver(Path pomfile) { checkArgument(pomfile.toFile().isFile(), "20160305:181005"); MavenXpp3Reader mavenReader = new MavenXpp3Reader(); model = tryToExecute((UnsafeSupplier) () -> { - FileReader reader = new FileReader(pomfile.toString()); - return mavenReader.read(reader); + InputStream is = new FileInputStream(pomfile.toFile()); + return mavenReader.read(is); }, "20160305:203232"); checkNotNull(model, "20160305:203551").setPomFile(pomfile.toFile()); pomDirectory = pomfile.getParent() == null ? CURRENT_DIR : pomfile.getParent(); diff --git a/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java b/src/test/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilderTest.java similarity index 84% rename from src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java rename to src/test/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilderTest.java index b0945b0..525460b 100644 --- a/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java +++ b/src/test/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilderTest.java @@ -1,9 +1,10 @@ -package pl.wavesoftware.gasper; +package pl.wavesoftware.gasper.internal; import com.mashape.unirest.http.Unirest; import org.junit.Test; import pl.wavesoftware.eid.utils.EidPreconditions; -import pl.wavesoftware.gasper.internal.HttpEndpoint; +import pl.wavesoftware.gasper.Gasper; +import pl.wavesoftware.gasper.GasperBuilder; import java.nio.file.Paths; @@ -14,11 +15,11 @@ * @author Krzysztof Suszyński * @since 2016-03-05 */ -public class GasperBuilderTest { +public class AbstractGasperBuilderTest { @Test public void testBuild() throws Exception { - GasperBuilder builder = new GasperBuilder(); + GasperBuilder builder = new AbstractGasperBuilder() {}; int port = 11909; String webContext = "/test"; String systemPropertyForPort = "swarm.http.port"; @@ -35,7 +36,7 @@ public void testBuild() throws Exception { .withArtifactPackaging("jar") .waitForWebContext(webContext) .withArtifactClassifier("swarm") - .usingWebContextChecker(GasperBuilderTest::checkContext) + .usingWebContextChecker(AbstractGasperBuilderTest::checkContext) .withPort(port) .build(); From 87c481694eff4164c3885cf853f6aa9da40e256c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 16:53:47 +0100 Subject: [PATCH 18/21] Jvadocs and cycle fix --- README.md | 66 +++- .../java/pl/wavesoftware/gasper/Gasper.java | 149 ++++++++- .../pl/wavesoftware/gasper/GasperBuilder.java | 288 ++++++++++++++++-- .../gasper/GasperConfigurations.java | 2 + .../internal/AbstractGasperBuilder.java | 148 --------- .../gasper/internal/maven/MavenResolver.java | 2 + ...uilderTest.java => GasperBuilderTest.java} | 13 +- 7 files changed, 475 insertions(+), 193 deletions(-) delete mode 100644 src/main/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilder.java rename src/test/java/pl/wavesoftware/gasper/{internal/AbstractGasperBuilderTest.java => GasperBuilderTest.java} (81%) diff --git a/README.md b/README.md index e1af7dc..6208178 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,41 @@ Gasper is a very simple integration testing JUnit harness for `java -jar` server [![WildFly Swarm](https://avatars3.githubusercontent.com/u/11523816?v=3&s=100)](http://wildfly-swarm.io/) [![Spring Boot](https://avatars2.githubusercontent.com/u/317776?v=3&s=100)](http://projects.spring.io/spring-boot/) -Gasper provides a simple to use JUnit `TestRule` that can be used to build integration tests with simple apps, like micro-services. You can configure Gasper with easy to use builder interface. +Gasper provides a simple to use JUnit `TestRule` that can be used to build integration tests with simple apps, like REST micro-services. You can configure Gasper easily with a builder interface. Gasper will start the application before test class and stop it after tests completes. + +Gasper supports currently only [Maven](https://maven.apache.org/). The `pom.xml` file is used to read project configuration achieving zero configuration operation. ## Usage -Best to use with libraries like [Unirest](http://unirest.io/java.html) and [JSON Assert](https://github.com/marcingrzejszczak/jsonassert) + +Gasper utilize your packaged application. It It means it should be used in integration tests that run after application is being packaged by build tool (Maven). Add this code to your `pom.xml` file (if you didn't done that before): + +```xml + +[..] + +[..] + + org.apache.maven.plugins + maven-failsafe-plugin + 2.19.1 + + + + integration-test + verify + + + + +[..] + +[..] + +``` + + +Place your integration tests in classes that ends with `*IT` or `*ITest`. ### WildFly Swarm configuration @@ -30,13 +60,17 @@ public static Gasper gasper = Gasper.configurations() .build(); ``` +Before running `GasperBuilder.build()` method, you can reconfigure those default configurations to your needs. + ### Example test method (Unirest + JSONAssert) +Gasper is best to use with libraries like [Unirest](http://unirest.io/java.html) for fetching data and asserting HTTP/S statuses and [JSON Assert](https://github.com/marcingrzejszczak/jsonassert) to validate correctness of JSON output for REST services. + ```java @Test public void testGetRoot() throws UnirestException { // given - String address = gasper.getAddress(); + String address = gasper.getAddress(); // Address to deployed app, running live on random port String expectedMessage = "WildFly Swarm!"; // when @@ -44,7 +78,7 @@ public void testGetRoot() throws UnirestException { // then assertThat(response.getStatus()).isEqualTo(200); - assertThat(response.getBody()).field("hello").isEqualTo(expectedMessage); + assertThat(response.getBody()).field("hello").isEqualTo(expectedMessage); // JSON Assert } ``` @@ -56,6 +90,7 @@ To configure Gasper use `GasperBuilder` interface, for ex.: private final int port = 11909; private final String webContext = "/test"; private final String systemPropertyForPort = "swarm.http.port"; + @ClassRule public static Gasper gasper = Gasper.configure() .silentGasperMessages() @@ -66,7 +101,7 @@ public static Gasper gasper = Gasper.configure() .withMaxStartupTime(100) .withMaxDeploymentTime(20) .withEnvironmentVariable("jdbc.password", "S3CreT!1") - .withServerLoggingOnConsole() + .withTestApplicationLoggingOnConsole() .usingPomFile(Paths.get("pom.xml")) .withArtifactPackaging("jar") .waitForWebContext(webContext) @@ -89,7 +124,26 @@ public static Gasper gasper = Gasper.configure() ``` +## Contributing + +Contributions are welcome! + +To contribute, follow the standard [git flow](http://danielkummer.github.io/git-flow-cheatsheet/) of: + +1. Fork it +1. Create your feature branch (`git checkout -b feature/my-new-feature`) +1. Commit your changes (`git commit -am 'Add some feature'`) +1. Push to the branch (`git push origin feature/my-new-feature`) +1. Create new Pull Request + +Even if you can't contribute code, if you have an idea for an improvement please open an [issue](https://github.com/wavesoftware/java-gasper/issues). + ## Requirements -Gasper requires Java 8. Tested on Travis CI. +* Java 8 +* Maven 3 + +## Releases +* `1.0.0` - codename: *SkyMango* + * First publicly available release diff --git a/src/main/java/pl/wavesoftware/gasper/Gasper.java b/src/main/java/pl/wavesoftware/gasper/Gasper.java index 24b9573..294d655 100644 --- a/src/main/java/pl/wavesoftware/gasper/Gasper.java +++ b/src/main/java/pl/wavesoftware/gasper/Gasper.java @@ -9,7 +9,6 @@ import org.junit.runner.Description; import org.junit.runners.model.Statement; import pl.wavesoftware.eid.utils.EidPreconditions; -import pl.wavesoftware.gasper.internal.AbstractGasperBuilder; import pl.wavesoftware.gasper.internal.Executor; import pl.wavesoftware.gasper.internal.Logger; import pl.wavesoftware.gasper.internal.Settings; @@ -28,6 +27,119 @@ import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; /** + *

About

+ * Gasper is a very simple integration testing JUnit harness for java -jar servers like WildFly Swarm and Spring Boot. + *

+ * Gasper provides a simple to use JUnit {@link TestRule} that can be used to build integration tests with simple apps, like REST micro-services. You can configure Gasper easily with a builder interface. Gasper will start the application before test class and stop it after tests completes. + *

+ * Gasper supports currently only Maven. The pom.xml file is used to read project configuration achieving zero configuration operation. + * + *

Usage

+ * + * Gasper utilize your packaged application. It It means it should be used in integration tests that run after application is being packaged by build tool (Maven). Add this code to your pom.xml file (if you didn't done that before): + * + *
+ * <build>
+ * [..]
+ * <plugins>
+ * [..]
+ * <plugin>
+ *   <groupId>org.apache.maven.plugins</groupId>
+ *   <artifactId>maven-failsafe-plugin</artifactId>
+ *   <version>2.19.1</version>
+ *   <executions>
+ *     <execution>
+ *       <goals>
+ *         <goal>integration-test</goal>
+ *         <goal>verify</goal>
+ *       </goals>
+ *     </execution>
+ *   </executions>
+ * </plugin>
+ * [..]
+ * </plugins>
+ * [..]
+ * </build>
+ * 
+ * + * Place your integration tests in classes that ends with *IT or *ITest. + * + *

WildFly Swarm default configuration

+ * + *
+ * @ClassRule
+ * public static Gasper gasper = Gasper.configurations()
+ *   .wildflySwarm()
+ *   .build();
+ * 
+ * + *

Spring Boot default configuration

+ * + *
+ * @ClassRule
+ * public static Gasper gasper = Gasper.configurations()
+ *   .springBoot()
+ *   .build();
+ * 
+ *

+ * Before running {@link GasperBuilder#build()} method, you can reconfigure those default configurations to your needs. + * + *

Example test method (Unirest + JSONAssert)

+ * + * Gasper is best to use with libraries like Unirest for fetching + * data and asserting HTTP/S statuses and JSON + * Assert to validate correctness of JSON output for REST services. + * + *
+ * @Test
+ * public void testGetRoot() throws UnirestException {
+ *   // given
+ *   String address = gasper.getAddress(); // Address to deployed app, running live on random port
+ *   String expectedMessage = "WildFly Swarm!";
+ *   // when
+ *   HttpResponse response = Unirest.get(address).asString();
+ *   // then
+ *   assertThat(response.getStatus()).isEqualTo(200);
+ *   assertThat(response.getBody()).field("hello").isEqualTo(expectedMessage); // JSON Assert
+ * }
+ * 
+ * + *

Additional configuration

+ * + * To configure Gasper use {@link GasperBuilder} interface, for ex.: + * + *
+ * private final int port = 11909;
+ * private final String webContext = "/test";
+ * private final String systemPropertyForPort = "swarm.http.port";
+ *
+ * @ClassRule
+ * public static Gasper gasper = Gasper.configure()
+ *   .silentGasperMessages()
+ *   .usingSystemPropertyForPort(systemPropertyForPort)
+ *   .withSystemProperty("swarm.context.path", webContext)
+ *   .withSystemProperty(systemPropertyForPort, String.valueOf(port))
+ *   .withJVMOptions("-server", "-Xms1G", "-Xmx1G", "-XX:+UseConcMarkSweepGC")
+ *   .withMaxStartupTime(100)
+ *   .withMaxDeploymentTime(20)
+ *   .withEnvironmentVariable("jdbc.password", "S3CreT!1")
+ *   .withTestApplicationLoggingOnConsole()
+ *   .usingPomFile(Paths.get("pom.xml"))
+ *   .withArtifactPackaging("jar")
+ *   .waitForWebContext(webContext)
+ *   .withArtifactClassifier("swarm")
+ *   .usingWebContextChecker(GasperBuilderTest::checkContext)
+ *   .withPort(port)
+ *   .build();
+ * 
+ * + *

Requirements

+ * + *
    + *
  • Java 8
  • + *
  • Maven 3
  • + *
+ * * @author Krzysztof Suszyński * @since 2016-03-04 */ @@ -54,31 +166,40 @@ public final class Gasper implements TestRule { /** * Creates a builder interface {@link GasperBuilder} that can be used to configure Gasper. *

- * You can also use already created configurations by using method {@link #configurations()} for convenience. + * You can also use, already created, configurations by using method {@link #configurations()} for + * convenience. * @return a configure interface for configuration purposes */ public static GasperBuilder configure() { - return new GasperBuilderImpl(); + return new GasperBuilder(); } + /** + * Retrieves {@link GasperConfigurations} which hold some pre configured {@link GasperBuilder} instances + * and can be used for convenience. + * @return a pre configured configurations + */ public static GasperConfigurations configurations() { return new GasperConfigurations(); } + /** + * Use this method to get port on which Gasper runs your test application. + * @return a usually random port on which Gasper runs your application + */ public Integer getPort() { return settings.getPort(); } + /** + * Use this method to get full address to your test application that Gasper runs. It usually + * contains a random port. + * @return a full address to running application + */ public String getAddress() { return settings.getEndpoint().fullAddress(); } - protected interface RunnerCreator { - default Gasper create(Settings settings) { - return new Gasper(settings); - } - } - @Override public Statement apply(Statement base, Description description) { return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { @@ -88,6 +209,12 @@ public Statement apply(Statement base, Description description) { }, "20160305:004035"); } + protected interface RunnerCreator { + default Gasper create(Settings settings) { + return new Gasper(settings); + } + } + private void setup() { log(FIGLET); MavenResolver resolver = new MavenResolver(settings.getPomfile()); @@ -155,8 +282,4 @@ private void ensureLogger() { logger = new Logger(log, settings); } } - - private static class GasperBuilderImpl extends AbstractGasperBuilder { - - } } diff --git a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java index 1798ccb..449e8bf 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java @@ -1,47 +1,297 @@ package pl.wavesoftware.gasper; import org.slf4j.event.Level; +import pl.wavesoftware.eid.utils.EidPreconditions; +import pl.wavesoftware.gasper.internal.Executor; import pl.wavesoftware.gasper.internal.HttpEndpoint; +import pl.wavesoftware.gasper.internal.Settings; +import pl.wavesoftware.gasper.internal.maven.MavenResolver; +import java.net.ServerSocket; import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.function.Function; +import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; + /** + * This is builder interface for {@link Gasper}. You can use it to configure it to your needs. + *

+ * Methods implements fluent interface for ease of use. + * + *

Example

+ *
+ * private final int port = 11909;
+ * private final String webContext = "/test";
+ * private final String systemPropertyForPort = "swarm.http.port";
+ *
+ * @ClassRule
+ * public static Gasper gasper = Gasper.configure()
+ *   .silentGasperMessages()
+ *   .usingSystemPropertyForPort(systemPropertyForPort)
+ *   .withSystemProperty("swarm.context.path", webContext)
+ *   .withSystemProperty(systemPropertyForPort, String.valueOf(port))
+ *   .withJVMOptions("-server", "-Xms1G", "-Xmx1G", "-XX:+UseConcMarkSweepGC")
+ *   .withMaxStartupTime(100)
+ *   .withMaxDeploymentTime(20)
+ *   .withEnvironmentVariable("jdbc.password", "S3CreT!1")
+ *   .withTestApplicationLoggingOnConsole()
+ *   .usingPomFile(Paths.get("pom.xml"))
+ *   .withArtifactPackaging("jar")
+ *   .waitForWebContext(webContext)
+ *   .withArtifactClassifier("swarm")
+ *   .usingWebContextChecker(GasperBuilderTest::checkContext)
+ *   .withPort(port)
+ *   .build();
+ * 
+ * * @author Krzysztof Suszyński - * @since 2016-03-06 + * @since 2016-03-05 */ -public interface GasperBuilder extends Gasper.RunnerCreator { - GasperBuilder withArtifactPackaging(String packaging); +public final class GasperBuilder implements Gasper.RunnerCreator { + + private String packaging = MavenResolver.DEFAULT_PACKAGING; + private String classifier = MavenResolver.DEFAULT_CLASSIFIER; + private Map systemProperties = new LinkedHashMap<>(); + private List jvmOptions = new ArrayList<>(); + private Map environment = new LinkedHashMap<>(); + private String systemPropertyForPort; + private Integer port; + private boolean inheritIO = false; + private String context = Gasper.DEFAULT_CONTEXT; + private int portAvailableMaxTime = Gasper.DEFAULT_PORT_AVAILABLE_MAX_SECONDS; + private int deploymentMaxTime = Gasper.DEFAULT_DEPLOYMENT_MAX_SECONDS; + private Function contextChecker = Executor.DEFAULT_CONTEXT_CHECKER; + private Path pomfile = Paths.get(MavenResolver.DEFAULT_POM); + private Level level = Level.INFO; + + protected GasperBuilder() {} + + /** + * Change the artifact packaging. By default it is read from your pom.xml file. Use it to point + * to other artifact. + * + * @param packaging a Java packaging, can be something like jar or war. + * @return fluent interface returning self for chaining + */ + public GasperBuilder withArtifactPackaging(String packaging) { + this.packaging = packaging; + return this; + } + + /** + * Change the artifact classifier. By default it is read from your pom.xml file. Use it to point + * to other artifact. + * + * @param classifier a Maven classifier, can be something like shade or swarm. + * @return fluent interface returning self for chaining + */ + public GasperBuilder withArtifactClassifier(String classifier) { + this.classifier = classifier; + return this; + } + + /** + * Sets a environment variable to be set for your test application + * + * @param key an environment key + * @param value an environment value + * @return fluent interface returning self for chaining + */ + public GasperBuilder withEnvironmentVariable(String key, String value) { + environment.put(key, value); + return this; + } - GasperBuilder withArtifactClassifier(String classifier); + /** + * Sets a Java system property (for ex.: -Dserver.ssl=true) variable to be set for + * your test application. + * + * @param key a system property key without -D sign + * @param value a system property value + * @return fluent interface returning self for chaining + */ + public GasperBuilder withSystemProperty(String key, String value) { + systemProperties.put(key, value); + return this; + } - GasperBuilder withEnvironmentVariable(String key, String value); + /** + * Sets a JVM options (for ex.: -Xmx2G) to be set for your test application. + * + * @param options a list of JVM options in the same form as they will be given to process + * @return fluent interface returning self for chaining + */ + public GasperBuilder withJVMOptions(String... options) { + Collections.addAll(jvmOptions, options); + return this; + } - GasperBuilder withSystemProperty(String key, String value); + /** + * Sets the port to be used for starting your test application. The port must be available and user + * must have permission to use it. By default port is automatically calculated to be random, free + * one. Use this only if you don't like automatic port lookup. + * + * @param port a port to be used + * @return fluent interface returning self for chaining + */ + public GasperBuilder withPort(int port) { + this.port = port; + return this; + } - GasperBuilder withJVMOptions(String... options); + /** + * Configures what system property use to set port in your test application. For WildFly Swarm + * and Sprint Boot this is already configured in {@link GasperConfigurations} methods + * {@link GasperConfigurations#wildflySwarm()} and {@link GasperConfigurations#springBoot()}. + * Use it if you must pass other system property. + * + * @param systemPropertyForPort a system property to be used to change te port on which your + * test application will run. + * @return fluent interface returning self for chaining + */ + public GasperBuilder usingSystemPropertyForPort(String systemPropertyForPort) { + this.systemPropertyForPort = systemPropertyForPort; + return this; + } - GasperBuilder withPort(int port); + /** + * Change the pom.xml to be used. Gasper will read your project settings from it, + * like artifactId, packaging, classifier, version + * and build directory to locate artifact to be run as test application. + * + * @param pomfile a custom pom.xml to be used to read configuration properties + * @return fluent interface returning self for chaining + */ + public GasperBuilder usingPomFile(Path pomfile) { + this.pomfile = pomfile; + return this; + } - GasperBuilder usingSystemPropertyForPort(String systemPropertyForPort); + /** + * Configures your test application to logs it's messages on console instead of log file. + * + * @return fluent interface returning self for chaining + */ + public GasperBuilder withTestApplicationLoggingOnConsole() { + return withTestApplicationLoggingOnConsole(true); + } - GasperBuilder usingPomFile(Path pomfile); + /** + * Configures your test application whether to logs it's messages on console instead + * of log file or not. + * + * @param inheritIO if true, the test application will logs it's messages on console, + * if not messages will be forwarder to [system-temp]/gasper.log + * @return fluent interface returning self for chaining + */ + public GasperBuilder withTestApplicationLoggingOnConsole(boolean inheritIO) { + this.inheritIO = inheritIO; + return this; + } - GasperBuilder withServerLoggingOnConsole(); + /** + * Sets maximum wait time for your test application to open HTTP port. Tests + * will fail if your test application will not open requested port in that time. + * + * @param seconds maximum wait time for open port in seconds + * @return fluent interface returning self for chaining + */ + public GasperBuilder withMaxStartupTime(int seconds) { + this.portAvailableMaxTime = seconds; + return this; + } - GasperBuilder withServerLoggingOnConsole(boolean inheritIO); + /** + * Sets maximum wait time for your test application to deploy expected web context. + * Tests will fail if your test application will not deploy web context in time. + * + * @param seconds maximum wait time for deployment in seconds + * @return fluent interface returning self for chaining + */ + public GasperBuilder withMaxDeploymentTime(int seconds) { + this.deploymentMaxTime = seconds; + return this; + } - GasperBuilder withMaxStartupTime(int seconds); + /** + * Sets te web context to wait for. Gasper by default will try to execute + * HEAD request to that address until it became available. By + * default te web context id just "/". + * + * @param context the web context to wait for, by default "/" + * @return fluent interface returning self for chaining + */ + public GasperBuilder waitForWebContext(String context) { + this.context = context; + return this; + } - GasperBuilder withMaxDeploymentTime(int seconds); + /** + * Change web context checker that will be used to check if web context is + * deployed. Gasper by default will try to execute HEAD request + * to that address until it became available. + * + * @param contextChecker a function to use to test if web context id up + * @return fluent interface returning self for chaining + */ + public GasperBuilder usingWebContextChecker(Function contextChecker) { + this.contextChecker = contextChecker; + return this; + } - GasperBuilder waitForWebContext(String context); + /** + * Silent Gasper log messages. + * + * @return fluent interface returning self for chaining + */ + public GasperBuilder silentGasperMessages() { + usingLogLevel(Level.WARN); + return this; + } - GasperBuilder usingWebContextChecker(Function contextChecker); + /** + * Sets log level for Gasper to limit logging. + * @param level a SLF log level + * @return fluent interface returning self for chaining + */ + public GasperBuilder usingLogLevel(Level level) { + this.level = level; + return this; + } - GasperBuilder silentGasperMessages(); + /** + * Builds final Gasper instance with all given variables + * @return a Gasper {@link org.junit.rules.TestRule} + */ + public Gasper build() { + if (port == null) { + port = findNotBindedPort(); + } + if (systemPropertyForPort != null) { + withSystemProperty(systemPropertyForPort, port.toString()); + } + Settings settings = new Settings( + packaging, classifier, port, + systemProperties, jvmOptions, environment, + inheritIO, context, contextChecker, + portAvailableMaxTime, deploymentMaxTime, + pomfile, level + ); + return create(settings); + } - GasperBuilder usingLogLevel(Level level); + private static Integer findNotBindedPort() { + return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } + }, "20160305:202934"); - Gasper build(); + } } diff --git a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java index 4a66817..5cdc062 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java @@ -14,6 +14,8 @@ * .build(); *
* + * More info in {@link Gasper} javadoc + * * @author Krzysztof Suszyński * @since 2016-03-05 */ diff --git a/src/main/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilder.java deleted file mode 100644 index a5dc967..0000000 --- a/src/main/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilder.java +++ /dev/null @@ -1,148 +0,0 @@ -package pl.wavesoftware.gasper.internal; - -import org.slf4j.event.Level; -import pl.wavesoftware.eid.utils.EidPreconditions; -import pl.wavesoftware.gasper.Gasper; -import pl.wavesoftware.gasper.GasperBuilder; -import pl.wavesoftware.gasper.internal.maven.MavenResolver; - -import java.net.ServerSocket; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; - -/** - * @author Krzysztof Suszyński - * @since 2016-03-05 - */ -public abstract class AbstractGasperBuilder implements GasperBuilder { - - private String packaging = MavenResolver.DEFAULT_PACKAGING; - private String classifier = ""; - private Map systemProperties = new LinkedHashMap<>(); - private List jvmOptions = new ArrayList<>(); - private Map environment = new LinkedHashMap<>(); - private String systemPropertyForPort; - private Integer port; - private boolean inheritIO = false; - private String context = Gasper.DEFAULT_CONTEXT; - private int portAvailableMaxTime = Gasper.DEFAULT_PORT_AVAILABLE_MAX_SECONDS; - private int deploymentMaxTime = Gasper.DEFAULT_DEPLOYMENT_MAX_SECONDS; - private Function contextChecker = Executor.DEFAULT_CONTEXT_CHECKER; - private Path pomfile = Paths.get(MavenResolver.DEFAULT_POM); - private Level level = Level.INFO; - - protected AbstractGasperBuilder() {} - - @Override public GasperBuilder withArtifactPackaging(String packaging) { - this.packaging = packaging; - return this; - } - - @Override public GasperBuilder withArtifactClassifier(String classifier) { - this.classifier = classifier; - return this; - } - - @Override public GasperBuilder withEnvironmentVariable(String key, String value) { - environment.put(key, value); - return this; - } - - @Override public GasperBuilder withSystemProperty(String key, String value) { - systemProperties.put(key, value); - return this; - } - - @Override public GasperBuilder withJVMOptions(String... options) { - Collections.addAll(jvmOptions, options); - return this; - } - - @Override public GasperBuilder withPort(int port) { - this.port = port; - return this; - } - - @Override public GasperBuilder usingSystemPropertyForPort(String systemPropertyForPort) { - this.systemPropertyForPort = systemPropertyForPort; - return this; - } - - @Override public GasperBuilder usingPomFile(Path pomfile) { - this.pomfile = pomfile; - return this; - } - - @Override public GasperBuilder withServerLoggingOnConsole() { - return withServerLoggingOnConsole(true); - } - - @Override public GasperBuilder withServerLoggingOnConsole(boolean inheritIO) { - this.inheritIO = inheritIO; - return this; - } - - @Override public GasperBuilder withMaxStartupTime(int seconds) { - this.portAvailableMaxTime = seconds; - return this; - } - - @Override public GasperBuilder withMaxDeploymentTime(int seconds) { - this.deploymentMaxTime = seconds; - return this; - } - - @Override public GasperBuilder waitForWebContext(String context) { - this.context = context; - return this; - } - - @Override public GasperBuilder usingWebContextChecker(Function contextChecker) { - this.contextChecker = contextChecker; - return this; - } - - @Override public GasperBuilder silentGasperMessages() { - usingLogLevel(Level.WARN); - return this; - } - - @Override public GasperBuilder usingLogLevel(Level level) { - this.level = level; - return this; - } - - @Override public Gasper build() { - if (port == null) { - port = findNotBindedPort(); - } - if (systemPropertyForPort != null) { - withSystemProperty(systemPropertyForPort, port.toString()); - } - Settings settings = new Settings( - packaging, classifier, port, - systemProperties, jvmOptions, environment, - inheritIO, context, contextChecker, - portAvailableMaxTime, deploymentMaxTime, - pomfile, level - ); - return create(settings); - } - - private static Integer findNotBindedPort() { - return tryToExecute((EidPreconditions.UnsafeSupplier) () -> { - try (ServerSocket socket = new ServerSocket(0)) { - return socket.getLocalPort(); - } - }, "20160305:202934"); - - } -} diff --git a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java index e09dcba..6fb5e8e 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java @@ -22,6 +22,8 @@ public class MavenResolver { public static final String DEFAULT_POM = "./pom.xml"; public static final String DEFAULT_BUILD_DIR = "target"; public static final String DEFAULT_PACKAGING = "jar"; + public static final String DEFAULT_CLASSIFIER = ""; + private static final Path CURRENT_DIR = Paths.get("./"); private final Model model; private final Path pomDirectory; diff --git a/src/test/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilderTest.java b/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java similarity index 81% rename from src/test/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilderTest.java rename to src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java index 525460b..bbfe8de 100644 --- a/src/test/java/pl/wavesoftware/gasper/internal/AbstractGasperBuilderTest.java +++ b/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java @@ -1,10 +1,9 @@ -package pl.wavesoftware.gasper.internal; +package pl.wavesoftware.gasper; import com.mashape.unirest.http.Unirest; import org.junit.Test; import pl.wavesoftware.eid.utils.EidPreconditions; -import pl.wavesoftware.gasper.Gasper; -import pl.wavesoftware.gasper.GasperBuilder; +import pl.wavesoftware.gasper.internal.HttpEndpoint; import java.nio.file.Paths; @@ -15,11 +14,11 @@ * @author Krzysztof Suszyński * @since 2016-03-05 */ -public class AbstractGasperBuilderTest { +public class GasperBuilderTest { @Test public void testBuild() throws Exception { - GasperBuilder builder = new AbstractGasperBuilder() {}; + GasperBuilder builder = new GasperBuilder(); int port = 11909; String webContext = "/test"; String systemPropertyForPort = "swarm.http.port"; @@ -31,12 +30,12 @@ public void testBuild() throws Exception { .withMaxStartupTime(100) .withMaxDeploymentTime(20) .withEnvironmentVariable("jdbc.password", "S3CreT!1") - .withServerLoggingOnConsole() + .withTestApplicationLoggingOnConsole() .usingPomFile(Paths.get("pom.xml")) .withArtifactPackaging("jar") .waitForWebContext(webContext) .withArtifactClassifier("swarm") - .usingWebContextChecker(AbstractGasperBuilderTest::checkContext) + .usingWebContextChecker(GasperBuilderTest::checkContext) .withPort(port) .build(); From b1e962dc845cd68ac90ea14278b2022086f593c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 18:17:04 +0100 Subject: [PATCH 19/21] Configure OSSRH --- LICENSE | 2 +- pom.xml | 92 +++++++++++++++++++ .../java/pl/wavesoftware/gasper/Gasper.java | 20 +++- .../pl/wavesoftware/gasper/GasperBuilder.java | 20 +++- .../gasper/GasperConfigurations.java | 18 +++- .../gasper/internal/Executor.java | 18 +++- .../gasper/internal/HttpEndpoint.java | 18 +++- .../wavesoftware/gasper/internal/Logger.java | 18 +++- .../gasper/internal/Settings.java | 18 +++- .../gasper/internal/maven/MavenResolver.java | 18 +++- .../gasper/GasperBuilderTest.java | 18 +++- .../gasper/GasperForSpringBootIT.java | 18 +++- .../gasper/GasperForWildflySwarmIT.java | 18 +++- .../gasper/internal/HttpEndpointTest.java | 18 +++- .../internal/maven/MavenResolverIT.java | 18 +++- 15 files changed, 316 insertions(+), 16 deletions(-) diff --git a/LICENSE b/LICENSE index 8dada3e..dc56359 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright 2016 Wave Software Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pom.xml b/pom.xml index f01b56d..884cb0c 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,23 @@ ${maven.compiler.source} + http://wavesoftware.github.io/java-gasper/ + + + + cardil + Krzysztof Suszyński + krzysztof.suszynski@wavesoftware.pl + Wave Software + http://wavesoftware.pl/ + + + + + Wave Software + http://wavesoftware.pl/ + + Apache License 2.0 @@ -47,6 +64,17 @@ ${maven.required.version} + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + org.projectlombok @@ -162,10 +190,74 @@ 3 + + external.atlassian.jgitflow + jgitflow-maven-plugin + 1.0-m5.1 + + true + + v + + + + + release-profile + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + ci diff --git a/src/main/java/pl/wavesoftware/gasper/Gasper.java b/src/main/java/pl/wavesoftware/gasper/Gasper.java index 294d655..e34c719 100644 --- a/src/main/java/pl/wavesoftware/gasper/Gasper.java +++ b/src/main/java/pl/wavesoftware/gasper/Gasper.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper; import com.google.common.base.Charsets; @@ -97,7 +113,7 @@ * String address = gasper.getAddress(); // Address to deployed app, running live on random port * String expectedMessage = "WildFly Swarm!"; * // when - * HttpResponse response = Unirest.get(address).asString(); + * HttpResponse<String> response = Unirest.get(address).asString(); * // then * assertThat(response.getStatus()).isEqualTo(200); * assertThat(response.getBody()).field("hello").isEqualTo(expectedMessage); // JSON Assert @@ -140,7 +156,7 @@ *
  • Maven 3
  • * * - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński <krzysztof suszynski@wavesoftware.pl> * @since 2016-03-04 */ @Slf4j diff --git a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java index 449e8bf..76534fa 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperBuilder.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper; import org.slf4j.event.Level; @@ -24,7 +40,7 @@ *

    * Methods implements fluent interface for ease of use. * - *

    Example

    + *

    Example

    *
      * private final int port = 11909;
      * private final String webContext = "/test";
    @@ -50,7 +66,7 @@
      *   .build();
      * 
    * - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ public final class GasperBuilder implements Gasper.RunnerCreator { diff --git a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java index 5cdc062..b27c59e 100644 --- a/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java +++ b/src/main/java/pl/wavesoftware/gasper/GasperConfigurations.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper; /** @@ -16,7 +32,7 @@ * * More info in {@link Gasper} javadoc * - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ public final class GasperConfigurations { diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java index 5a845da..92c7ae4 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Executor.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Executor.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper.internal; import com.mashape.unirest.http.HttpResponse; @@ -20,7 +36,7 @@ import static java.lang.String.format; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ @Slf4j diff --git a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java index cae3004..261871c 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/HttpEndpoint.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper.internal; import lombok.Getter; @@ -7,7 +23,7 @@ import static java.lang.String.format; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ @Getter diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Logger.java b/src/main/java/pl/wavesoftware/gasper/internal/Logger.java index 74870f0..fe37b23 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Logger.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Logger.java @@ -1,10 +1,26 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper.internal; import lombok.RequiredArgsConstructor; import org.slf4j.event.Level; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ @RequiredArgsConstructor diff --git a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java index a860f98..52a4e6c 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/Settings.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/Settings.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper.internal; import com.google.common.collect.ImmutableList; @@ -17,7 +33,7 @@ *

    * CAUTION! It is internal class of Gasper, and shouldn't be used directly. Use gasper configure interface {@link Gasper#configure()} or {@link Gasper#configurations()} to set those settings. * - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 * @see Gasper#configure() * @see Gasper#configurations() diff --git a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java index 6fb5e8e..a339809 100644 --- a/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java +++ b/src/main/java/pl/wavesoftware/gasper/internal/maven/MavenResolver.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper.internal.maven; import org.apache.maven.model.Model; @@ -14,7 +30,7 @@ /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-04 */ public class MavenResolver { diff --git a/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java b/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java index bbfe8de..3d24208 100644 --- a/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java +++ b/src/test/java/pl/wavesoftware/gasper/GasperBuilderTest.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper; import com.mashape.unirest.http.Unirest; @@ -11,7 +27,7 @@ import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ public class GasperBuilderTest { diff --git a/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java b/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java index cdeeda9..aa483ab 100644 --- a/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java +++ b/src/test/java/pl/wavesoftware/gasper/GasperForSpringBootIT.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper; import com.mashape.unirest.http.HttpResponse; @@ -13,7 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ @Slf4j diff --git a/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java b/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java index b26cf94..a0f8385 100644 --- a/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java +++ b/src/test/java/pl/wavesoftware/gasper/GasperForWildflySwarmIT.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper; import com.mashape.unirest.http.HttpResponse; @@ -12,7 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ public class GasperForWildflySwarmIT { diff --git a/src/test/java/pl/wavesoftware/gasper/internal/HttpEndpointTest.java b/src/test/java/pl/wavesoftware/gasper/internal/HttpEndpointTest.java index 7e2edbf..819edf8 100644 --- a/src/test/java/pl/wavesoftware/gasper/internal/HttpEndpointTest.java +++ b/src/test/java/pl/wavesoftware/gasper/internal/HttpEndpointTest.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper.internal; import org.junit.Test; @@ -5,7 +21,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-05 */ public class HttpEndpointTest { diff --git a/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java b/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java index 5673041..18a20db 100644 --- a/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java +++ b/src/test/java/pl/wavesoftware/gasper/internal/maven/MavenResolverIT.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.gasper.internal.maven; import org.junit.Test; @@ -8,7 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszyński * @since 2016-03-04 */ public class MavenResolverIT { From ece67e5d0a87abed3fc68fd4c55f318ecd5017b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 20:44:56 +0100 Subject: [PATCH 20/21] updating poms for 1.0.0 branch with snapshot versions --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 884cb0c..3d26aa9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 pl.wavesoftware gasper From ed1cb52666b8a2b3677243480e5c40de1ed527aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Suszy=C5=84ski?= Date: Sun, 6 Mar 2016 20:45:14 +0100 Subject: [PATCH 21/21] updating poms for branch'release/1.0.0' with non-snapshot versions --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3d26aa9..ae0c4f0 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 pl.wavesoftware gasper - 1.0.0-SNAPSHOT + 1.0.0 jar Gasper Very simple integration testing JUnit harness for 'java -jar' servers like WildFly Swarm and Spring Boot