Skip to content

Commit

Permalink
Merge pull request #17 from turing85/bugfix/run-on-executor
Browse files Browse the repository at this point in the history
Use dedicated executor service for test execution
  • Loading branch information
christophd authored Sep 11, 2024
2 parents 6436cfe + c08d4e7 commit d4a4229
Showing 1 changed file with 74 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Stream;
Expand Down Expand Up @@ -80,11 +84,14 @@ public class CitrusRemoteApplication extends AbstractVerticle {
private Future<List<RemoteResult>> remoteResultFuture;

/** Latest test reports */
private final RemoteTestResultReporter remoteTestResultReporter = new RemoteTestResultReporter();
private final RemoteTestResultReporter remoteTestResultReporter =
new RemoteTestResultReporter();

/** Router customizations */
private final List<Consumer<Router>> routerCustomizations;

private final ExecutorService executorService = Executors.newCachedThreadPool();

private final JsonRequestTransformer requestTransformer = new JsonRequestTransformer();
private final JsonResponseTransformer responseTransformer = new JsonResponseTransformer();

Expand Down Expand Up @@ -224,64 +231,92 @@ private void addResultsEndpoints(Router router) {
response.sendFile(suiteResultFile.toString());
} else {
response.setStatusCode(HttpResponseStatus.NOT_FOUND.code())
.end("Failed to find suite result file: %s".formatted(suiteResultFile));
.end("Failed to find suite result file: %s"
.formatted(suiteResultFile));
}
}));
}

private void addRunEndpoints(Router router) {
router.get("/run")
.handler(wrapThrowingHandler(ctx -> {
TestRunConfiguration runConfiguration = new TestRunConfiguration();
MultiMap queryParams = ctx.request().params();
if (queryParams.contains("engine")) {
String engine = queryParams.get("engine");
runConfiguration.setEngine(URLDecoder.decode(engine, ENCODING));
} else {
runConfiguration.setEngine(configuration.getEngine());
}

if (queryParams.contains("includes")) {
String value = queryParams.get("includes");
runConfiguration.setIncludes(URLDecoder.decode(value, ENCODING)
.split(","));
}

if (queryParams.contains("package")) {
String value = queryParams.get("package");
runConfiguration.setPackages(Collections.singletonList(
URLDecoder.decode(value, ENCODING)));
}

if (queryParams.contains("class")) {
String value = queryParams.get("class");
runConfiguration.setTestSources(Collections.singletonList(
TestClass.fromString(URLDecoder.decode(value, ENCODING))));
}

ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON)
.end(responseTransformer.render(runTests(runConfiguration)));
TestRunConfiguration runConfiguration = constructRunConfig(ctx);
runTestsAsync(runConfiguration, ctx.response());
}));
router.put("/run")
.handler(wrapThrowingHandler(ctx -> {
remoteResultFuture = getVertx().executeBlocking(
new RunJob(requestTransformer.read(ctx.body().asString(), TestRunConfiguration.class)) {
@Override
public List<RemoteResult> run(TestRunConfiguration runConfiguration) {
return runTests(runConfiguration);
}
});
remoteResultFuture = Future.fromCompletionStage(CompletableFuture.supplyAsync(
constructTestRun(ctx)::call,
executorService));
ctx.response().end("");
}));
router.post("/run")
.handler(wrapThrowingHandler(ctx -> {
HttpServerResponse response = ctx.response();
TestRunConfiguration runConfiguration = requestTransformer.read(
ctx.body().asString(),
TestRunConfiguration.class);
ctx.response().end(responseTransformer.render(runTests(runConfiguration)));
runTestsAsync(runConfiguration, response);
}));
}

private TestRunConfiguration constructRunConfig(RoutingContext ctx)
throws UnsupportedEncodingException {
TestRunConfiguration runConfiguration = new TestRunConfiguration();
MultiMap queryParams = ctx.request().params();
if (queryParams.contains("engine")) {
String engine = queryParams.get("engine");
runConfiguration.setEngine(URLDecoder.decode(engine, ENCODING));
} else {
runConfiguration.setEngine(configuration.getEngine());
}

if (queryParams.contains("includes")) {
String value = queryParams.get("includes");
runConfiguration.setIncludes(URLDecoder.decode(value, ENCODING)
.split(","));
}

if (queryParams.contains("package")) {
String value = queryParams.get("package");
runConfiguration.setPackages(Collections.singletonList(
URLDecoder.decode(value, ENCODING)));
}

if (queryParams.contains("class")) {
String value = queryParams.get("class");
runConfiguration.setTestSources(Collections.singletonList(
TestClass.fromString(URLDecoder.decode(value, ENCODING))));
}
return runConfiguration;
}

private void runTestsAsync(
TestRunConfiguration runConfiguration,
HttpServerResponse response) {
Future
.fromCompletionStage(CompletableFuture.supplyAsync(
() -> runTests(runConfiguration),
executorService))
.onSuccess(results ->
response.end(responseTransformer.render(results)))
.onFailure(error -> response
.setStatusCode(HttpResponseStatus.INTERNAL_SERVER_ERROR.code())
.end(error.getMessage()));
}

private RunJob constructTestRun(RoutingContext ctx) {
TestRunConfiguration config = requestTransformer.read(
ctx.body().asString(),
TestRunConfiguration.class);
return new RunJob(config) {
@Override
public List<RemoteResult> run(TestRunConfiguration runConfiguration) {
return runTests(runConfiguration);
}
};
}

private void addConfigEndpoints(Router router) {
router.get("/configuration")
.handler(wrapThrowingHandler(ctx ->
Expand Down

0 comments on commit d4a4229

Please sign in to comment.