summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java11
-rw-r--r--vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/AggregateTestRunner.java91
-rw-r--r--vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/JunitRunner.java34
-rw-r--r--vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/AggregateTestRunnerTest.java9
-rw-r--r--vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/TestRunnerHandlerTest.java3
5 files changed, 74 insertions, 74 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java
index 52e5431b552..fb7a3fc4ba5 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java
@@ -13,11 +13,6 @@ import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.zone.RoutingMethod;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.log.LogLevel;
-import com.yahoo.security.KeyAlgorithm;
-import com.yahoo.security.KeyUtils;
-import com.yahoo.security.SignatureAlgorithm;
-import com.yahoo.security.X509CertificateBuilder;
-import com.yahoo.security.X509CertificateUtils;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.Instance;
@@ -48,12 +43,9 @@ import com.yahoo.vespa.hosted.controller.routing.RoutingPolicy;
import com.yahoo.vespa.hosted.controller.routing.context.DeploymentRoutingContext;
import com.yahoo.yolean.Exceptions;
-import javax.security.auth.x500.X500Principal;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.UncheckedIOException;
-import java.math.BigInteger;
-import java.security.KeyPair;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
@@ -65,7 +57,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
@@ -95,7 +86,6 @@ import static com.yahoo.vespa.hosted.controller.deployment.Step.deployReal;
import static com.yahoo.vespa.hosted.controller.deployment.Step.deployTester;
import static com.yahoo.vespa.hosted.controller.deployment.Step.installTester;
import static com.yahoo.vespa.hosted.controller.deployment.Step.report;
-import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
@@ -671,6 +661,7 @@ public class InternalStepRunner implements StepRunner {
logger.log(INFO, "The test package should either contain basic HTTP tests under 'tests/<suite-name>/', " +
"or a Java test bundle under 'components/' with at least one test with the annotation " +
"for this suite. See docs.vespa.ai/en/testing.html for details.");
+ controller.jobController().updateTestReport(id);
return Optional.of(noTests);
}
case SUCCESS:
diff --git a/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/AggregateTestRunner.java b/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/AggregateTestRunner.java
index 6e3393b2761..15aeef18013 100644
--- a/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/AggregateTestRunner.java
+++ b/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/AggregateTestRunner.java
@@ -4,9 +4,7 @@ package com.yahoo.vespa.testrunner;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.LogRecord;
/**
@@ -15,7 +13,8 @@ import java.util.logging.LogRecord;
public class AggregateTestRunner implements TestRunner {
private final List<TestRunner> wrapped;
- private final AtomicInteger current = new AtomicInteger(-1);
+ private int current = -1;
+ private final Object monitor = new Object();
private AggregateTestRunner(List<TestRunner> testRunners) {
this.wrapped = testRunners;
@@ -28,65 +27,77 @@ public class AggregateTestRunner implements TestRunner {
@Override
public Collection<LogRecord> getLog(long after) {
ArrayList<LogRecord> records = new ArrayList<>();
- for (int i = 0; i <= current.get() && i < wrapped.size(); i++)
- records.addAll(wrapped.get(i).getLog(after));
-
+ synchronized (monitor) {
+ for (int i = 0; i <= current && i < wrapped.size(); i++)
+ records.addAll(wrapped.get(i).getLog(after));
+ }
return records;
}
@Override
public Status getStatus() {
- if (current.get() == -1)
- return Status.NOT_STARTED;
-
- Status status = Status.NO_TESTS;
- for (int i = 0; i <= current.get(); i++) {
- if (i == wrapped.size())
- return status;
-
- Status next = wrapped.get(i).getStatus();
- status = status.ordinal() < next.ordinal() ? status : next;
+ synchronized (monitor) {
+ if (current == -1)
+ return Status.NOT_STARTED;
+
+ Status status = Status.NO_TESTS;
+ for (int i = 0; i <= current; i++) {
+ if (i == wrapped.size())
+ return status;
+
+ Status next = wrapped.get(i).getStatus();
+ status = status.ordinal() < next.ordinal() ? status : next;
+ }
+ return Status.RUNNING;
}
- return Status.RUNNING;
}
@Override
public CompletableFuture<?> test(Suite suite, byte[] config) {
- if (0 <= current.get() && current.get() < wrapped.size())
- throw new IllegalStateException("Tests already running, should not attempt to start now");
-
- current.set(-1);
- CompletableFuture<?> aggregate = new CompletableFuture<>();
- CompletableFuture<?> vessel = CompletableFuture.completedFuture(null);
- runNext(suite, config, vessel, aggregate);
- return aggregate;
+ synchronized (monitor) {
+ if (0 <= current && current < wrapped.size())
+ throw new IllegalStateException("Tests already running, should not attempt to start now");
+
+ current = -1;
+ CompletableFuture<?> aggregate = new CompletableFuture<>();
+ CompletableFuture<?> vessel = CompletableFuture.completedFuture(null);
+ runNext(suite, config, vessel, aggregate);
+ return aggregate;
+ }
}
private void runNext(Suite suite, byte[] config, CompletableFuture<?> vessel, CompletableFuture<?> aggregate) {
vessel.whenComplete((__, ___) -> {
- int next = current.incrementAndGet();
- if (next == wrapped.size())
- aggregate.complete(null);
- else
- runNext(suite, config, wrapped.get(next).test(suite, config), aggregate);
+ synchronized (monitor) {
+ if (++current < wrapped.size())
+ runNext(suite, config, wrapped.get(current).test(suite, config), aggregate);
+ else
+ aggregate.complete(null);
+ }
});
}
@Override
public TestReport getReport() {
- return wrapped.stream().map(TestRunner::getReport).filter(Objects::nonNull)
- .reduce(AggregateTestRunner::merge).orElse(null);
+ TestReport report = null;
+ synchronized (monitor) {
+ for (int i = 0; i < current && i < wrapped.size(); i++)
+ report = merge(report, wrapped.get(i).getReport());
+ }
+ return report;
}
static TestReport merge(TestReport first, TestReport second) {
- return TestReport.builder()
- .withAbortedCount(first.abortedCount + second.abortedCount)
- .withFailedCount(first.failedCount + second.failedCount)
- .withIgnoredCount(first.ignoredCount + second.ignoredCount)
- .withSuccessCount(first.successCount + second.successCount)
- .withFailures(merged(first.failures, second.failures))
- .withLogs(merged(first.logLines, second.logLines))
- .build();
+ return first == null ? second
+ : second == null ? first
+ : TestReport.builder()
+ .withAbortedCount(first.abortedCount + second.abortedCount)
+ .withFailedCount(first.failedCount + second.failedCount)
+ .withIgnoredCount(first.ignoredCount + second.ignoredCount)
+ .withSuccessCount(first.successCount + second.successCount)
+ .withFailures(merged(first.failures, second.failures))
+ .withLogs(merged(first.logLines, second.logLines))
+ .build();
}
static <T> List<T> merged(List<T> first, List<T> second) {
diff --git a/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/JunitRunner.java b/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/JunitRunner.java
index 90b3f972a3a..9bbba2d6c2a 100644
--- a/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/JunitRunner.java
+++ b/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/JunitRunner.java
@@ -7,16 +7,14 @@ import ai.vespa.cloud.Zone;
import ai.vespa.hosted.api.TestDescriptor;
import ai.vespa.hosted.cd.InconclusiveTestException;
import ai.vespa.hosted.cd.internal.TestRuntimeProvider;
-import com.yahoo.component.annotation.Inject;
import com.yahoo.component.AbstractComponent;
+import com.yahoo.component.annotation.Inject;
import com.yahoo.io.IOUtils;
import com.yahoo.jdisc.application.OsgiFramework;
import com.yahoo.vespa.defaults.Defaults;
import org.junit.jupiter.engine.JupiterTestEngine;
-import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.Launcher;
-import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.core.LauncherConfig;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
@@ -37,9 +35,10 @@ import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static java.util.stream.Collectors.toList;
+
/**
* @author mortent
*/
@@ -163,7 +162,7 @@ public class JunitRunner extends AbstractComponent implements TestRunner {
private List<Class<?>> loadClasses(Bundle bundle, TestDescriptor testDescriptor, TestDescriptor.TestCategory testCategory) {
List<Class<?>> testClasses = testDescriptor.getConfiguredTests(testCategory).stream()
.map(className -> loadClass(bundle, className))
- .collect(Collectors.toList());
+ .collect(toList());
StringBuffer buffer = new StringBuffer();
testClasses.forEach(cl -> buffer.append("\t").append(cl.toString()).append(" / ").append(cl.getClassLoader().toString()).append("\n"));
@@ -180,24 +179,18 @@ public class JunitRunner extends AbstractComponent implements TestRunner {
}
private TestReport launchJunit(List<Class<?>> testClasses, boolean isProductionTest) {
- LauncherDiscoveryRequest discoveryRequest = LauncherDiscoveryRequestBuilder.request()
- .selectors(testClasses.stream().map(DiscoverySelectors::selectClass).collect(Collectors.toList()))
- .build();
-
- var launcherConfig = LauncherConfig.builder()
- .addTestEngines(new JupiterTestEngine())
-
- .build();
- Launcher launcher = LauncherFactory.create(launcherConfig);
-
- // Create log listener:
var logListener = new VespaJunitLogListener(record -> logRecords.put(record.getSequenceNumber(), record));
- // Create a summary listener:
var summaryListener = new SummaryGeneratingListener();
+
+ Launcher launcher = LauncherFactory.create(LauncherConfig.builder().addTestEngines(new JupiterTestEngine()).build());
launcher.registerTestExecutionListeners(logListener, summaryListener);
- // Execute request
- launcher.execute(discoveryRequest);
+ launcher.execute(LauncherDiscoveryRequestBuilder.request()
+ .selectors(testClasses.stream()
+ .map(DiscoverySelectors::selectClass)
+ .collect(toList()))
+ .build());
+
var report = summaryListener.getSummary();
var failures = report.getFailures().stream()
.map(failure -> {
@@ -205,11 +198,12 @@ public class JunitRunner extends AbstractComponent implements TestRunner {
return new TestReport.Failure(VespaJunitLogListener.toString(failure.getTestIdentifier().getUniqueIdObject()),
failure.getException());
})
- .collect(Collectors.toList());
+ .collect(toList());
long inconclusive = isProductionTest ? failures.stream()
.filter(failure -> failure.exception() instanceof InconclusiveTestException)
.count()
: 0;
+
return TestReport.builder()
.withSuccessCount(report.getTestsSucceededCount())
.withAbortedCount(report.getTestsAbortedCount())
diff --git a/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/AggregateTestRunnerTest.java b/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/AggregateTestRunnerTest.java
index 14e139b3fbf..8bd72d35737 100644
--- a/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/AggregateTestRunnerTest.java
+++ b/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/AggregateTestRunnerTest.java
@@ -136,8 +136,10 @@ class AggregateTestRunnerTest {
.build();
first.report = report;
assertSame(report, runner.getReport());
-
second.report = report;
+ assertSame(report, runner.getReport());
+
+ second.future.complete(null);
TestReport merged = runner.getReport();
assertEquals(List.of(record1, record1), merged.logLines);
assertEquals(List.of(failure, failure), merged.failures);
@@ -145,6 +147,7 @@ class AggregateTestRunnerTest {
assertEquals(8, merged.ignoredCount);
assertEquals(4, merged.failedCount);
assertEquals(2, merged.abortedCount);
+
}
@Test
@@ -171,9 +174,9 @@ class AggregateTestRunnerTest {
catch (Exception e) {
TestReport.trimStackTraces(e, "org.junit.platform.launcher.core.SessionPerRequestLauncher");
assertEquals("java.lang.RuntimeException: java.lang.RuntimeException: inner\n" +
- "\tat com.yahoo.vespa.testrunner.AggregateTestRunnerTest.testStackTrimming(AggregateTestRunnerTest.java:168)\n" +
+ "\tat com.yahoo.vespa.testrunner.AggregateTestRunnerTest.testStackTrimming(AggregateTestRunnerTest.java:171)\n" +
"Caused by: java.lang.RuntimeException: inner\n" +
- "\tat com.yahoo.vespa.testrunner.AggregateTestRunnerTest.testStackTrimming(AggregateTestRunnerTest.java:165)\n",
+ "\tat com.yahoo.vespa.testrunner.AggregateTestRunnerTest.testStackTrimming(AggregateTestRunnerTest.java:168)\n",
ExceptionUtils.getStackTraceAsString(e));
}
}
diff --git a/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/TestRunnerHandlerTest.java b/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/TestRunnerHandlerTest.java
index 49dd2b20797..7b75f1cd4bd 100644
--- a/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/TestRunnerHandlerTest.java
+++ b/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/TestRunnerHandlerTest.java
@@ -6,6 +6,7 @@ import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.test.json.JsonTestHelper;
+import com.yahoo.vespa.testrunner.TestRunner.Suite;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -23,7 +24,6 @@ import java.util.stream.Collectors;
import static com.yahoo.jdisc.http.HttpRequest.Method.GET;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -57,6 +57,7 @@ class TestRunnerHandlerTest {
@Test
public void createsCorrectTestReport() throws IOException {
+ aggregateRunner.test(Suite.SYSTEM_TEST, new byte[0]);
HttpResponse response = testRunnerHandler.handle(HttpRequest.createTestRequest("http://localhost:1234/tester/v1/report", GET));
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.render(out);