summaryrefslogtreecommitdiffstats
path: root/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/TestRunnerHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/TestRunnerHandler.java')
-rw-r--r--vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/TestRunnerHandler.java165
1 files changed, 53 insertions, 112 deletions
diff --git a/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/TestRunnerHandler.java b/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/TestRunnerHandler.java
index 4c359071fc9..62601e4dfa0 100644
--- a/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/TestRunnerHandler.java
+++ b/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/TestRunnerHandler.java
@@ -1,34 +1,27 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.testrunner;
-import ai.vespa.hosted.api.TestDescriptor;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.inject.Inject;
+import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.container.jdisc.EmptyResponse;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.container.jdisc.LoggingRequestHandler;
+import com.yahoo.exception.ExceptionUtils;
+import com.yahoo.restapi.MessageResponse;
+import com.yahoo.restapi.SlimeJsonResponse;
import com.yahoo.slime.Cursor;
-import com.yahoo.slime.JsonFormat;
import com.yahoo.slime.Slime;
-import com.yahoo.slime.SlimeUtils;
-import com.yahoo.vespa.testrunner.legacy.LegacyTestRunner;
-import com.yahoo.vespa.testrunner.legacy.TestProfile;
import com.yahoo.yolean.Exceptions;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.logging.Level;
import java.util.logging.LogRecord;
-import java.util.stream.Collectors;
import static com.yahoo.jdisc.Response.Status;
@@ -39,18 +32,16 @@ import static com.yahoo.jdisc.Response.Status;
*/
public class TestRunnerHandler extends LoggingRequestHandler {
- private static final String CONTENT_TYPE_APPLICATION_JSON = "application/json";
-
- private final TestRunner junitRunner;
- private final LegacyTestRunner testRunner;
- private final boolean useOsgiMode;
+ private final TestRunner testRunner;
@Inject
- public TestRunnerHandler(Executor executor, TestRunner junitRunner, LegacyTestRunner testRunner) {
+ public TestRunnerHandler(Executor executor, ComponentRegistry<TestRunner> testRunners) {
+ this(executor, AggregateTestRunner.of(testRunners.allComponents()));
+ }
+
+ TestRunnerHandler(Executor executor, TestRunner testRunner) {
super(executor);
- this.junitRunner = junitRunner;
this.testRunner = testRunner;
- this.useOsgiMode = junitRunner.isSupported();
}
@Override
@@ -60,81 +51,48 @@ public class TestRunnerHandler extends LoggingRequestHandler {
case GET: return handleGET(request);
case POST: return handlePOST(request);
- default: return new Response(Status.METHOD_NOT_ALLOWED, "Method '" + request.getMethod() + "' is not supported");
+ default: return new MessageResponse(Status.METHOD_NOT_ALLOWED, "Method '" + request.getMethod() + "' is not supported");
}
} catch (IllegalArgumentException e) {
- return new Response(Status.BAD_REQUEST, Exceptions.toMessageString(e));
+ return new MessageResponse(Status.BAD_REQUEST, Exceptions.toMessageString(e));
} catch (Exception e) {
log.log(Level.WARNING, "Unexpected error handling '" + request.getUri() + "'", e);
- return new Response(Status.INTERNAL_SERVER_ERROR, Exceptions.toMessageString(e));
+ return new MessageResponse(Status.INTERNAL_SERVER_ERROR, Exceptions.toMessageString(e));
}
}
private HttpResponse handleGET(HttpRequest request) {
String path = request.getUri().getPath();
- if (path.equals("/tester/v1/log")) {
- if (useOsgiMode) {
+ switch (path) {
+ case "/tester/v1/log":
long fetchRecordsAfter = Optional.ofNullable(request.getProperty("after"))
- .map(Long::parseLong)
- .orElse(-1L);
-
- List<LogRecord> logRecords = Optional.ofNullable(junitRunner.getReport())
- .map(TestReport::logLines)
- .orElse(Collections.emptyList()).stream()
- .filter(record -> record.getSequenceNumber()>fetchRecordsAfter)
- .collect(Collectors.toList());
- return new SlimeJsonResponse(logToSlime(logRecords));
- } else {
- return new SlimeJsonResponse(logToSlime(testRunner.getLog(request.hasProperty("after")
- ? Long.parseLong(request.getProperty("after"))
- : -1)));
- }
- } else if (path.equals("/tester/v1/status")) {
- if (useOsgiMode) {
- log.info("Responding with status " + junitRunner.getStatus());
- return new Response(junitRunner.getStatus().name());
- } else {
+ .map(Long::parseLong)
+ .orElse(-1L);
+ return new SlimeJsonResponse(logToSlime(testRunner.getLog(fetchRecordsAfter)));
+ case "/tester/v1/status":
log.info("Responding with status " + testRunner.getStatus());
- return new Response(testRunner.getStatus().name());
- }
- } else if (path.equals("/tester/v1/report")) {
- if (useOsgiMode) {
- String report = junitRunner.getReportAsJson();
- return new SlimeJsonResponse(SlimeUtils.jsonToSlime(report));
- } else {
- return new EmptyResponse(200);
- }
+ return new MessageResponse(testRunner.getStatus().name());
+ case "/tester/v1/report":
+ TestReport report = testRunner.getReport();
+ if (report == null)
+ return new EmptyResponse(200);
+
+ return new SlimeJsonResponse(toSlime(report));
}
- return new Response(Status.NOT_FOUND, "Not found: " + request.getUri().getPath());
+ return new MessageResponse(Status.NOT_FOUND, "Not found: " + request.getUri().getPath());
}
private HttpResponse handlePOST(HttpRequest request) throws IOException {
final String path = request.getUri().getPath();
if (path.startsWith("/tester/v1/run/")) {
String type = lastElement(path);
- TestProfile testProfile = TestProfile.valueOf(type.toUpperCase() + "_TEST");
+ TestRunner.Suite testSuite = TestRunner.Suite.valueOf(type.toUpperCase() + "_TEST");
byte[] config = request.getData().readAllBytes();
- if (useOsgiMode) {
- junitRunner.executeTests(categoryFromProfile(testProfile), config);
- log.info("Started tests of type " + type + " and status is " + junitRunner.getStatus());
- return new Response("Successfully started " + type + " tests");
- } else {
- testRunner.test(testProfile, config);
- log.info("Started tests of type " + type + " and status is " + testRunner.getStatus());
- return new Response("Successfully started " + type + " tests");
- }
- }
- return new Response(Status.NOT_FOUND, "Not found: " + request.getUri().getPath());
- }
-
- TestDescriptor.TestCategory categoryFromProfile(TestProfile testProfile) {
- switch(testProfile) {
- case SYSTEM_TEST: return TestDescriptor.TestCategory.systemtest;
- case STAGING_SETUP_TEST: return TestDescriptor.TestCategory.stagingsetuptest;
- case STAGING_TEST: return TestDescriptor.TestCategory.stagingtest;
- case PRODUCTION_TEST: return TestDescriptor.TestCategory.productiontest;
- default: throw new RuntimeException("Unknown test profile: " + testProfile.name());
+ testRunner.test(testSuite, config);
+ log.info("Started tests of type " + type + " and status is " + testRunner.getStatus());
+ return new MessageResponse("Successfully started " + type + " tests");
}
+ return new MessageResponse(Status.NOT_FOUND, "Not found: " + request.getUri().getPath());
}
private static String lastElement(String path) {
@@ -177,48 +135,31 @@ public class TestRunnerHandler extends LoggingRequestHandler {
: "error";
}
- private static class SlimeJsonResponse extends HttpResponse {
- private final Slime slime;
+ private static Slime toSlime(TestReport testReport) {
+ var slime = new Slime();
+ var root = slime.setObject();
+ if (testReport == null)
+ return slime;
- private SlimeJsonResponse(Slime slime) {
- super(200);
- this.slime = slime;
- }
+ var summary = root.setObject("summary");
+ summary.setLong("total", testReport.totalCount);
+ summary.setLong("success", testReport.successCount);
+ summary.setLong("failed", testReport.failedCount);
+ summary.setLong("ignored", testReport.ignoredCount);
+ summary.setLong("aborted", testReport.abortedCount);
+ var failureRoot = summary.setArray("failures");
+ testReport.failures.forEach(failure -> serializeFailure(failure, failureRoot.addObject()));
- @Override
- public void render(OutputStream outputStream) throws IOException {
- new JsonFormat(true).encode(outputStream, slime);
- }
+ var output = root.setArray("output");
+ testReport.logLines.forEach(lr -> output.addString(lr.getMessage()));
- @Override
- public String getContentType() {
- return CONTENT_TYPE_APPLICATION_JSON;
- }
+ return slime;
}
- private static class Response extends HttpResponse {
- private static final ObjectMapper objectMapper = new ObjectMapper();
- private final String message;
-
- private Response(String response) {
- this(200, response);
- }
-
- private Response(int statusCode, String message) {
- super(statusCode);
- this.message = message;
- }
-
- @Override
- public void render(OutputStream outputStream) throws IOException {
- ObjectNode objectNode = objectMapper.createObjectNode();
- objectNode.put("message", message);
- objectMapper.writeValue(outputStream, objectNode);
- }
-
- @Override
- public String getContentType() {
- return CONTENT_TYPE_APPLICATION_JSON;
- }
+ private static void serializeFailure(TestReport.Failure failure, Cursor slime) {
+ slime.setString("testName", failure.testId());
+ slime.setString("testError",failure.exception().getMessage());
+ slime.setString("exception", ExceptionUtils.getStackTraceAsString(failure.exception()));
}
+
}