From 6ca0e05e03ef681f9da34d4bd7796a78f9477c9a Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Fri, 28 Jul 2017 17:11:51 +0200 Subject: [PATCH] Fixes #17 - LoadGeneratorStarter not flexible. --- .../starter/AbstractLoadGeneratorStarter.java | 216 ------------------ .../starter/JenkinsRemoteStarter.java | 71 +----- .../starter/LoadGeneratorStarter.java | 93 ++++---- .../starter/LoadGeneratorStarterArgs.java | 77 +++++++ .../starter/LoadGeneratorStarterTest.java | 133 +++++------ ...rce.groovy => single_fail_resource.groovy} | 0 6 files changed, 209 insertions(+), 381 deletions(-) delete mode 100644 jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/AbstractLoadGeneratorStarter.java rename jetty-load-generator-starter/src/test/resources/{single_resource.groovy => single_fail_resource.groovy} (100%) diff --git a/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/AbstractLoadGeneratorStarter.java b/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/AbstractLoadGeneratorStarter.java deleted file mode 100644 index e63f3123..00000000 --- a/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/AbstractLoadGeneratorStarter.java +++ /dev/null @@ -1,216 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.mortbay.jetty.load.generator.starter; - -import java.io.InputStream; -import java.io.Reader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import groovy.lang.Binding; -import groovy.lang.GroovyShell; -import org.codehaus.groovy.control.CompilerConfiguration; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.xml.XmlConfiguration; -import org.mortbay.jetty.load.generator.HTTP1ClientTransportBuilder; -import org.mortbay.jetty.load.generator.HTTP2ClientTransportBuilder; -import org.mortbay.jetty.load.generator.HTTPClientTransportBuilder; -import org.mortbay.jetty.load.generator.LoadGenerator; -import org.mortbay.jetty.load.generator.Resource; - -public abstract class AbstractLoadGeneratorStarter { - private Logger logger = Log.getLogger(getClass()); - private LoadGeneratorStarterArgs starterArgs; - private ExecutorService executorService; - private Resource resource; - private Request.Listener[] listeners; - - public AbstractLoadGeneratorStarter(LoadGeneratorStarterArgs runnerArgs) { - this.starterArgs = runnerArgs; - } - - public void run() throws Exception { - LoadGenerator.Builder builder = new LoadGenerator.Builder(); - Resource resource = getResource(builder); - builder.threads(starterArgs.getThreads()) - .warmupIterationsPerThread(starterArgs.getWarmupIterations()) - .iterationsPerThread(starterArgs.getIterations()) - .usersPerThread(starterArgs.getUsers()) - .channelsPerUser(starterArgs.getChannelsPerUser()) - .resource(resource) - .resourceRate(starterArgs.getResourceRate()) - .httpClientTransportBuilder(httpClientTransportBuilder()) - .sslContextFactory(sslContextFactory()) - .scheme(starterArgs.getScheme()) - .host(starterArgs.getHost()) - .port(starterArgs.getPort()) - .maxRequestsQueued(starterArgs.getMaxRequestsQueued()); - - long runFor = starterArgs.getRunningTime(); - if (runFor > 0) { - builder = builder.runFor(runFor, starterArgs.getRunningTimeUnit()); - } - - ExecutorService executor = getExecutorService(); - if (executor != null) { - builder = builder.executor(executor); - } - - for (Resource.Listener listener : getResourceListeners()) { - builder = builder.resourceListener(listener); - } - - for (Request.Listener listener : getRequestListeners()) { - builder = builder.requestListener(listener); - } - - for (LoadGenerator.Listener listener : getLoadGeneratorListeners()) { - builder = builder.listener(listener); - } - - LoadGenerator loadGenerator = builder.build(); - logger.info("load generator config: {}", loadGenerator.getConfig()); - logger.info("load generation begin"); - CompletableFuture cf = loadGenerator.begin(); - cf.whenComplete((x, f) -> { - if (f == null) { - logger.info("load generation complete"); - } else { - logger.info("load generation failure", f); - } - }).join(); - } - - protected LoadGenerator.Listener[] getLoadGeneratorListeners() { - return new LoadGenerator.Listener[0]; - } - - protected Resource.Listener[] getResourceListeners() { - return new Resource.Listener[0]; - } - - protected Request.Listener[] getRequestListeners() { - return listeners == null ? new Request.Listener[0] : this.listeners; - } - - protected void setRequestListeners(Request.Listener[] listeners) { - this.listeners = listeners; - } - - public ExecutorService getExecutorService() { - return executorService; - } - - public void setExecutorService(ExecutorService executor) { - this.executorService = executor; - } - - public Resource getResource(LoadGenerator.Builder builder) throws Exception { - if (resource != null) { - return resource; - } - - String jsonPath = starterArgs.getResourceJSONPath(); - if (jsonPath != null) { - Path path = Paths.get(jsonPath); - if (Files.exists(path)) { - return resource = evaluateJSON(path); - } - } - String xmlPath = starterArgs.getResourceXMLPath(); - if (xmlPath != null) { - Path path = Paths.get(xmlPath); - try (InputStream inputStream = Files.newInputStream(path)) { - return resource = (Resource)new XmlConfiguration(inputStream).configure(); - } - } - String groovyPath = starterArgs.getResourceGroovyPath(); - if (groovyPath != null) { - Path path = Paths.get(groovyPath); - try (Reader reader = Files.newBufferedReader(path)) { - Map context = new HashMap<>(); - context.put("loadGeneratorBuilder", builder); - return resource = (Resource)evaluateGroovy(reader, context); - } - } - - throw new IllegalArgumentException("resource not defined"); - } - - protected static Resource evaluateJSON(Path profilePath) throws Exception { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - return objectMapper.readValue(profilePath.toFile(), Resource.class); - } - - protected static String writeAsJsonTmp(Resource resource) throws Exception { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); - Path tmpPath = Files.createTempFile("profile", ".tmp"); - objectMapper.writeValue(tmpPath.toFile(), resource); - return tmpPath.toString(); - } - - protected static Object evaluateGroovy(Reader script, Map context) throws Exception { - CompilerConfiguration config = new CompilerConfiguration(CompilerConfiguration.DEFAULT); - config.setDebug(true); - config.setVerbose(true); - Binding binding = new Binding(context); - GroovyShell interpreter = new GroovyShell(binding, config); - return interpreter.evaluate(script); - } - - public HTTPClientTransportBuilder httpClientTransportBuilder() { - LoadGeneratorStarterArgs.Transport transport = getStarterArgs().getTransport(); - switch (transport) { - case HTTP: - case HTTPS: { - return new HTTP1ClientTransportBuilder().selectors(getStarterArgs().getSelectors()); - } - case H2C: - case H2: { - return new HTTP2ClientTransportBuilder().selectors(getStarterArgs().getSelectors()); - } - default: { - throw new IllegalArgumentException("unsupported transport " + transport); - } - } - } - - public SslContextFactory sslContextFactory() { - // FIXME make this more configurable - SslContextFactory sslContextFactory = new SslContextFactory(true); - return sslContextFactory; - } - - public LoadGeneratorStarterArgs getStarterArgs() { - return starterArgs; - } -} diff --git a/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/JenkinsRemoteStarter.java b/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/JenkinsRemoteStarter.java index 46a7a032..29157f67 100644 --- a/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/JenkinsRemoteStarter.java +++ b/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/JenkinsRemoteStarter.java @@ -29,10 +29,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import com.beust.jcommander.JCommander; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.mortbay.jetty.load.generator.LoadGenerator; import org.mortbay.jetty.load.generator.Resource; import org.mortbay.jetty.load.generator.listeners.QpsListenerDisplay; @@ -42,8 +38,8 @@ * Class to start remote process for Jenkins */ public class JenkinsRemoteStarter { - private static final Logger LOGGER = Log.getLogger(JenkinsRemoteStarter.class); private static List nodeListeners; + private static List loadGeneratorListeners; public static List getNodeListeners() { return nodeListeners; @@ -53,8 +49,6 @@ public static void setNodeListeners(List nodeListeners) { JenkinsRemoteStarter.nodeListeners = nodeListeners; } - public static List loadGeneratorListeners; - public static List getLoadGeneratorListeners() { return loadGeneratorListeners; } @@ -121,59 +115,18 @@ public void close() throws IOException { public static void launch(List argsList) throws Exception { final String[] args = argsList.toArray(new String[argsList.size()]); - - LoadGeneratorStarterArgs runnerArgs = new LoadGeneratorStarterArgs(); - - try { - JCommander jCommander = new JCommander(runnerArgs, args); - if (runnerArgs.isHelp()) { - jCommander.usage(); - System.exit(0); - } - } catch (Exception e) { - new JCommander(runnerArgs).usage(); + LoadGeneratorStarterArgs starterArgs = LoadGeneratorStarter.parse(args); + LoadGenerator.Builder builder = LoadGeneratorStarter.prepare(starterArgs); + if (nodeListeners != null) { + nodeListeners.forEach(builder::resourceListener); } - - try { - LoadGeneratorStarter runner = new LoadGeneratorStarter(runnerArgs) { - - QpsListenerDisplay qpsListenerDisplay = - new QpsListenerDisplay(10, 30, TimeUnit.SECONDS); - - private RequestQueuedListenerDisplay requestQueuedListenerDisplay = // - // FIXME those values need to be configurable!! // - new RequestQueuedListenerDisplay(10, 30, TimeUnit.SECONDS); - - @Override - protected Resource.Listener[] getResourceListeners() { - return nodeListeners.toArray(new Resource.Listener[nodeListeners.size()]); - } - - @Override - protected LoadGenerator.Listener[] getLoadGeneratorListeners() { - loadGeneratorListeners.add(qpsListenerDisplay); - loadGeneratorListeners.add(requestQueuedListenerDisplay); - return loadGeneratorListeners.toArray(new LoadGenerator.Listener[loadGeneratorListeners.size()]); - } - - @Override - protected Request.Listener[] getRequestListeners() { - return new Request.Listener[]{qpsListenerDisplay, requestQueuedListenerDisplay}; - } - }; - - LOGGER.info("start LoadGenerator to " + runnerArgs.getHost() // - + ", runningTime: " + runnerArgs.getRunningTime() // - + ", runningTimeUnit: " + runnerArgs.getRunningTimeUnit() // - + ", runIterations: " + runnerArgs.getIterations()); - runner.run(); - - LOGGER.info("LoadGenerator stopped"); - - } catch (Exception e) { - e.printStackTrace(); - new JCommander(runnerArgs).usage(); - System.exit(1); + if (loadGeneratorListeners != null) { + loadGeneratorListeners.forEach(builder::listener); } + QpsListenerDisplay qpsListenerDisplay = new QpsListenerDisplay(10, 30, TimeUnit.SECONDS); + RequestQueuedListenerDisplay requestQueuedListenerDisplay = new RequestQueuedListenerDisplay(10, 30, TimeUnit.SECONDS); + builder.listener(qpsListenerDisplay).listener(requestQueuedListenerDisplay) + .requestListener(qpsListenerDisplay).requestListener(requestQueuedListenerDisplay); + LoadGeneratorStarter.run(builder); } } diff --git a/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarter.java b/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarter.java index adfa820c..2775bd1a 100644 --- a/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarter.java +++ b/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarter.java @@ -19,65 +19,76 @@ package org.mortbay.jetty.load.generator.starter; import java.text.SimpleDateFormat; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import com.beust.jcommander.JCommander; -import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -import org.mortbay.jetty.load.generator.Resource; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.mortbay.jetty.load.generator.LoadGenerator; import org.mortbay.jetty.load.generator.listeners.CollectorInformations; import org.mortbay.jetty.load.generator.listeners.report.GlobalSummaryListener; -public class LoadGeneratorStarter extends AbstractLoadGeneratorStarter { +public class LoadGeneratorStarter { private static final Logger LOGGER = Log.getLogger(LoadGeneratorStarter.class); - public LoadGeneratorStarter(LoadGeneratorStarterArgs runnerArgs) { - super(runnerArgs); - } - public static void main(String[] args) throws Exception { - LoadGeneratorStarterArgs runnerArgs = new LoadGeneratorStarterArgs(); - - try { - JCommander jCommander = new JCommander(runnerArgs, args); - if (runnerArgs.isHelp()) { - jCommander.usage(); - return; - } - } catch (Exception e) { - e.printStackTrace(); - new JCommander(runnerArgs).usage(); + LoadGeneratorStarterArgs starterArgs = parse(args); + if (starterArgs == null) { return; } + LoadGenerator.Builder builder = prepare(starterArgs); + GlobalSummaryListener globalSummaryListener = new GlobalSummaryListener(); + builder = builder.resourceListener(globalSummaryListener).requestListener(globalSummaryListener); + run(builder); + if (starterArgs.isDisplayStats()) { + displayGlobalSummaryListener(globalSummaryListener); + } + } - try { - GlobalSummaryListener globalSummaryListener = new GlobalSummaryListener(); - LoadGeneratorStarter runner = new LoadGeneratorStarter(runnerArgs) { - @Override - protected Resource.Listener[] getResourceListeners() { - return new Resource.Listener[]{globalSummaryListener}; - } - - @Override - protected Request.Listener[] getRequestListeners() { - return new Request.Listener[]{globalSummaryListener}; - } - }; + public static LoadGeneratorStarterArgs parse(String[] args) { + LoadGeneratorStarterArgs starterArgs = new LoadGeneratorStarterArgs(); + JCommander jCommander = new JCommander(starterArgs, args); + if (starterArgs.isHelp()) { + jCommander.usage(); + return null; + } + return starterArgs; + } - runner.run(); + public static LoadGenerator.Builder prepare(LoadGeneratorStarterArgs starterArgs) throws Exception { + LoadGenerator.Builder builder = new LoadGenerator.Builder(); + return builder.threads(starterArgs.getThreads()) + .warmupIterationsPerThread(starterArgs.getWarmupIterations()) + .iterationsPerThread(starterArgs.getIterations()) + .usersPerThread(starterArgs.getUsers()) + .channelsPerUser(starterArgs.getChannelsPerUser()) + .resource(starterArgs.getResource(builder)) + .resourceRate(starterArgs.getResourceRate()) + .httpClientTransportBuilder(starterArgs.getHttpClientTransportBuilder()) + .sslContextFactory(new SslContextFactory()) + .scheme(starterArgs.getScheme()) + .host(starterArgs.getHost()) + .port(starterArgs.getPort()) + .maxRequestsQueued(starterArgs.getMaxRequestsQueued()); + } - if (runnerArgs.isDisplayStats()) { - runner.displayGlobalSummaryListener(globalSummaryListener); + public static void run(LoadGenerator.Builder builder) { + LoadGenerator loadGenerator = builder.build(); + LOGGER.info("load generator config: {}", loadGenerator.getConfig()); + LOGGER.info("load generation begin"); + CompletableFuture cf = loadGenerator.begin(); + cf.whenComplete((x, f) -> { + if (f == null) { + LOGGER.info("load generation complete"); + } else { + LOGGER.info("load generation failure", f); } - - } catch (Exception e) { - LOGGER.info("error happened", e); - new JCommander(runnerArgs).usage(); - } + }).join(); } - public void displayGlobalSummaryListener(GlobalSummaryListener globalSummaryListener) { + private static void displayGlobalSummaryListener(GlobalSummaryListener globalSummaryListener) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss z"); CollectorInformations latencyTimeSummary = new CollectorInformations(globalSummaryListener.getLatencyTimeHistogram() // @@ -123,7 +134,7 @@ public void displayGlobalSummaryListener(GlobalSummaryListener globalSummaryList LOGGER.info(""); } - static long nanosToMillis(long nanosValue) { + private static long nanosToMillis(long nanosValue) { return TimeUnit.NANOSECONDS.toMillis(nanosValue); } } diff --git a/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarterArgs.java b/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarterArgs.java index 0953e81b..1971042f 100644 --- a/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarterArgs.java +++ b/jetty-load-generator-starter/src/main/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarterArgs.java @@ -18,9 +18,27 @@ package org.mortbay.jetty.load.generator.starter; +import java.io.InputStream; +import java.io.Reader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; import com.beust.jcommander.Parameter; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import groovy.lang.Binding; +import groovy.lang.GroovyShell; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.eclipse.jetty.xml.XmlConfiguration; +import org.mortbay.jetty.load.generator.HTTP1ClientTransportBuilder; +import org.mortbay.jetty.load.generator.HTTP2ClientTransportBuilder; +import org.mortbay.jetty.load.generator.HTTPClientTransportBuilder; +import org.mortbay.jetty.load.generator.LoadGenerator; +import org.mortbay.jetty.load.generator.Resource; public class LoadGeneratorStarterArgs { @Parameter(names = {"--threads", "-t"}, description = "LoadGenerator threads") @@ -273,6 +291,65 @@ public void setChannelsPerUser(int channelsPerUser) { this.channelsPerUser = channelsPerUser; } + public Resource getResource(LoadGenerator.Builder builder) throws Exception { + String jsonPath = getResourceJSONPath(); + if (jsonPath != null) { + Path path = Paths.get(jsonPath); + if (Files.exists(path)) { + return evaluateJSON(path); + } + } + String xmlPath = getResourceXMLPath(); + if (xmlPath != null) { + Path path = Paths.get(xmlPath); + try (InputStream inputStream = Files.newInputStream(path)) { + return (Resource)new XmlConfiguration(inputStream).configure(); + } + } + String groovyPath = getResourceGroovyPath(); + if (groovyPath != null) { + Path path = Paths.get(groovyPath); + try (Reader reader = Files.newBufferedReader(path)) { + Map context = new HashMap<>(); + context.put("loadGeneratorBuilder", builder); + return evaluateGroovy(reader, context); + } + } + throw new IllegalArgumentException("resource not defined"); + } + + public static Resource evaluateJSON(Path profilePath) throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + return objectMapper.readValue(profilePath.toFile(), Resource.class); + } + + public static Resource evaluateGroovy(Reader script, Map context) throws Exception { + CompilerConfiguration config = new CompilerConfiguration(CompilerConfiguration.DEFAULT); + config.setDebug(true); + config.setVerbose(true); + Binding binding = new Binding(context); + GroovyShell interpreter = new GroovyShell(binding, config); + return (Resource)interpreter.evaluate(script); + } + + public HTTPClientTransportBuilder getHttpClientTransportBuilder() { + Transport transport = getTransport(); + switch (transport) { + case HTTP: + case HTTPS: { + return new HTTP1ClientTransportBuilder().selectors(getSelectors()); + } + case H2C: + case H2: { + return new HTTP2ClientTransportBuilder().selectors(getSelectors()); + } + default: { + throw new IllegalArgumentException("unsupported transport " + transport); + } + } + } + public enum Transport { HTTP, HTTPS, diff --git a/jetty-load-generator-starter/src/test/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarterTest.java b/jetty-load-generator-starter/src/test/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarterTest.java index c10b801e..a26be0c1 100644 --- a/jetty-load-generator-starter/src/test/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarterTest.java +++ b/jetty-load-generator-starter/src/test/java/org/mortbay/jetty/load/generator/starter/LoadGeneratorStarterTest.java @@ -19,10 +19,9 @@ import java.io.IOException; import java.io.Reader; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.Collections; -import java.util.List; import java.util.Locale; import java.util.concurrent.atomic.AtomicInteger; @@ -31,7 +30,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import com.beust.jcommander.JCommander; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; @@ -49,6 +49,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mortbay.jetty.load.generator.LoadGenerator; import org.mortbay.jetty.load.generator.Resource; public class LoadGeneratorStarterTest { @@ -70,7 +71,7 @@ public void startJetty() throws Exception { ServletContextHandler statsContext = new ServletContextHandler(statisticsHandler, "/"); statsContext.addServlet(new ServletHolder(new StatisticsServlet()), "/stats"); testServlet = new TestServlet(); - testServlet.server = server; + testServlet.connector = connector; statsContext.addServlet(new ServletHolder(testServlet), "/"); server.start(); } @@ -84,26 +85,27 @@ public void stopJetty() throws Exception { @Test public void simpleTest() throws Exception { - List args = new ArrayList<>(); - args.add("--warmup-iterations"); - args.add("10"); - args.add("-h"); - args.add("localhost"); - args.add("--port"); - args.add(Integer.toString(connector.getLocalPort())); - args.add("--running-time"); - args.add("10"); - args.add("--running-time-unit"); - args.add("s"); - args.add("--resource-rate"); - args.add("3"); - args.add("--transport"); - args.add("http"); - args.add("--users"); - args.add("3"); - args.add("--resource-groovy-path"); - args.add("src/test/resources/tree_resources.groovy"); - LoadGeneratorStarter.main(args.toArray(new String[args.size()])); + String[] args = new String[]{ + "--warmup-iterations", + "10", + "-h", + "localhost", + "--port", + Integer.toString(connector.getLocalPort()), + "--running-time", + "10", + "--running-time-unit", + "s", + "--resource-rate", + "3", + "--transport", + "http", + "--users", + "3", + "--resource-groovy-path", + "src/test/resources/tree_resources.groovy" + }; + LoadGeneratorStarter.main(args); int getNumber = testServlet.getNumber.get(); LOGGER.debug("received get: {}", getNumber); Assert.assertTrue("getNumber return: " + getNumber, getNumber > 10); @@ -111,31 +113,32 @@ public void simpleTest() throws Exception { @Test public void failFast() throws Exception { - List args = new ArrayList<>(); - args.add("--warmup-iterations"); - args.add("10"); - args.add("-h"); - args.add("localhost"); - args.add("--port"); - args.add(Integer.toString(connector.getLocalPort())); - args.add("--running-time"); - args.add("10"); - args.add("--running-time-unit"); - args.add("s"); - args.add("--resource-rate"); - args.add("3"); - args.add("--transport"); - args.add("http"); - args.add("--users"); - args.add("1"); - args.add("--resource-groovy-path"); - args.add("src/test/resources/single_resource.groovy"); - - LoadGeneratorStarterArgs runnerArgs = new LoadGeneratorStarterArgs(); - new JCommander(runnerArgs, args.toArray(new String[args.size()])); - - AtomicInteger onFailure = new AtomicInteger(0), onCommit = new AtomicInteger(0); - Request.Listener.Adapter adapter = new Request.Listener.Adapter() { + String[] args = new String[]{ + "--warmup-iterations", + "10", + "-h", + "localhost", + "--port", + Integer.toString(connector.getLocalPort()), + "--running-time", + "10", + "--running-time-unit", + "s", + "--resource-rate", + "3", + "--transport", + "http", + "--users", + "1", + "--resource-groovy-path", + "src/test/resources/single_fail_resource.groovy" + }; + LoadGeneratorStarterArgs starterArgs = LoadGeneratorStarter.parse(args); + LoadGenerator.Builder builder = LoadGeneratorStarter.prepare(starterArgs); + + AtomicInteger onFailure = new AtomicInteger(0); + AtomicInteger onCommit = new AtomicInteger(0); + Request.Listener.Adapter requestListener = new Request.Listener.Adapter() { @Override public void onFailure(Request request, Throwable failure) { LOGGER.info("fail: {}", onFailure.incrementAndGet()); @@ -146,29 +149,29 @@ public void onCommit(Request request) { LOGGER.info("onCommit: {}", onCommit.incrementAndGet()); } }; + builder.requestListener(requestListener); - LoadGeneratorStarter runner = new LoadGeneratorStarter(runnerArgs); - runner.setRequestListeners(new Request.Listener[]{adapter}); - boolean exception = false; try { - runner.run(); - } catch (Exception e) { - exception = true; + LoadGeneratorStarter.run(builder); + Assert.fail(); + } catch (Exception x) { + // Expected. } - LOGGER.info("onFailure: {}, onCommit: {}", onFailure, onCommit); - Assert.assertTrue("not in exception", exception); + int getNumber = testServlet.getNumber.get(); - LOGGER.debug("received get: {}", getNumber); - Assert.assertTrue("getNumber return: " + getNumber, getNumber == 5); + Assert.assertEquals(5, getNumber); Assert.assertTrue(onFailure.get() < 10); } @Test - public void json_serial_deserial_from_groovy() throws Exception { + public void fromGroovyToJSON() throws Exception { try (Reader reader = Files.newBufferedReader(Paths.get("src/test/resources/tree_resources.groovy"))) { - Resource resource = (Resource)AbstractLoadGeneratorStarter.evaluateGroovy(reader, Collections.emptyMap()); - String path = AbstractLoadGeneratorStarter.writeAsJsonTmp(resource); - Resource fromJson = AbstractLoadGeneratorStarter.evaluateJSON(Paths.get(path)); + Resource resource = LoadGeneratorStarterArgs.evaluateGroovy(reader, Collections.emptyMap()); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + Path tmpPath = Files.createTempFile("profile", ".tmp"); + objectMapper.writeValue(tmpPath.toFile(), resource); + Resource fromJson = LoadGeneratorStarterArgs.evaluateJSON(tmpPath); Assert.assertEquals(resource.descendantCount(), fromJson.descendantCount()); } } @@ -176,7 +179,7 @@ public void json_serial_deserial_from_groovy() throws Exception { private static class TestServlet extends HttpServlet { private AtomicInteger getNumber = new AtomicInteger(0); private AtomicInteger postNumber = new AtomicInteger(0); - private Server server; + private ServerConnector connector; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -187,7 +190,7 @@ protected void service(HttpServletRequest request, HttpServletResponse response) if (fail != null) { if (getNumber.get() >= Integer.parseInt(fail)) { try { - server.stop(); + connector.stop(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } diff --git a/jetty-load-generator-starter/src/test/resources/single_resource.groovy b/jetty-load-generator-starter/src/test/resources/single_fail_resource.groovy similarity index 100% rename from jetty-load-generator-starter/src/test/resources/single_resource.groovy rename to jetty-load-generator-starter/src/test/resources/single_fail_resource.groovy