diff --git a/src/org/labkey/test/stress/Simulation.java b/src/org/labkey/test/stress/Simulation.java index f18672e71d..c1907d51ae 100644 --- a/src/org/labkey/test/stress/Simulation.java +++ b/src/org/labkey/test/stress/Simulation.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; @@ -35,7 +36,6 @@ import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; /** * Simulation: A series of activities that represents some user workflow (e.g. loading the dashboard, navigating to the sample finder, and performing a search). For simplicity, API simulations in the initial proof of concept will consist of a single activity. @@ -230,7 +230,10 @@ private void makeRequest(Activity.RequestParams requestParams) throws Interrupte * {@link #_connectionFactory} - used to generate an API connection for the simulation to use * *
  • - * {@link #activityDefinitions} - {@link Activity} list that defines the simulation. These are deserialized from {@link ApiTestsDocument} XML files. + * {@link #activityFiles} - {@link ApiTestsDocument} XML files that define the simulation. Used to generate {@link Activity} definitions. + *
  • + *
  • + * {@link #replacements} - String replacements to inject into activity definitions. e.g. 'CONTAINER' or 'USERID' *
  • *
  • * {@link #maxActivityThreads} - the size of thread pool to use for requests @@ -248,7 +251,8 @@ public static class Definition { private final Supplier _connectionFactory; - private List activityDefinitions = Collections.emptyList(); + private List activityFiles = new ArrayList<>(); + private Map replacements = Collections.emptyMap(); private int maxActivityThreads = 6; // This seems to be the number of parallel requests browsers handle private int delayBetweenActivities = 5_000; private boolean runOnce = false; @@ -287,15 +291,13 @@ public Definition setDelayBetweenActivities(int delayBetweenActivities) public Definition setActivityFiles(File... activityFiles) { - return setActivityFilesWithReplacements( - Arrays.stream(activityFiles).collect(Collectors.toMap(f -> f, f -> Collections.emptyMap()))); + this.activityFiles = Arrays.asList(activityFiles); + return this; } - public Definition setActivityFilesWithReplacements(Map> activityFilesWithReplacements) + public Definition setReplacements(Map replacements) { - activityDefinitions = activityFilesWithReplacements.entrySet().stream() - .map(entry -> new Activity(entry.getKey().getName(), Definition.parseTests(entry.getKey(), entry.getValue()))) - .toList(); + this.replacements = new HashMap<>(replacements); return this; } @@ -305,6 +307,17 @@ public Definition setRunOnce(boolean runOnce) return this; } + private List buildActivityDefinitions() + { + if (activityFiles.isEmpty()) + { + throw new IllegalArgumentException("No activity files specified"); + } + return activityFiles.stream() + .map(file -> new Activity(file.getName(), Definition.parseTests(file, replacements))) + .toList(); + } + /** * Start the simulation according to this definition * @param resultCollectorFactory The simulation will submit results to the supplied {@link ResultCollector} @@ -316,7 +329,7 @@ public Simulation startSimulation(Function Connection connection = _connectionFactory.get(); // Prime connection before starting simulation to ensure credentials are good new WhoAmICommand().execute(connection, null); - return new Simulation<>(connection, activityDefinitions, delayBetweenActivities, maxActivityThreads, resultCollectorFactory.apply(connection), runOnce); + return new Simulation<>(connection, buildActivityDefinitions(), delayBetweenActivities, maxActivityThreads, resultCollectorFactory.apply(connection), runOnce); } public Simulation startSimulation() throws IOException, CommandException