summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorJon Marius Venstad <venstad@gmail.com>2019-12-27 11:37:41 +0100
committerJon Marius Venstad <venstad@gmail.com>2019-12-27 11:37:41 +0100
commitc93162f6ca2ff99193b1b50648bf09bf08b2364d (patch)
tree434738d0fc6830394edb263e572f1d106f1cfe7c /controller-server
parent729fe27b010f75179f03778094b27033cee446f6 (diff)
Tidy up a little in DeploymentStatus
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java98
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java4
2 files changed, 42 insertions, 60 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java
index 509ac87b08e..a716530a564 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java
@@ -1,6 +1,5 @@
package com.yahoo.vespa.hosted.controller.deployment;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.yahoo.component.Version;
import com.yahoo.config.application.api.DeploymentInstanceSpec;
@@ -25,7 +24,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -40,7 +38,6 @@ import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toUnmodifiableList;
-import static java.util.stream.Collectors.toUnmodifiableMap;
/**
* Status of the deployment jobs of an {@link Application}.
@@ -107,7 +104,7 @@ public class DeploymentStatus {
return Stream.concat(jobs.entrySet().stream(), testJobs)
.collect(collectingAndThen(toMap(Map.Entry::getKey,
Map.Entry::getValue,
- (l1, l2) -> ImmutableList.<Versions>builder().addAll(l1).addAll(l2).build(),
+ DeploymentStatus::union,
LinkedHashMap::new),
ImmutableMap::copyOf));
}
@@ -115,10 +112,8 @@ public class DeploymentStatus {
/** Returns the set of jobs that need to run for the given change to be considered complete. */
public Map<JobId, List<Versions>> jobsToRun(Change change) {
Map<JobId, List<Versions>> jobs = new LinkedHashMap<>();
-
addProductionJobs(jobs, change);
addTests(jobs);
-
return ImmutableMap.copyOf(jobs);
}
@@ -136,38 +131,30 @@ public class DeploymentStatus {
private void addTests(Map<JobId, List<Versions>> jobs) {
Map<JobId, List<Versions>> testJobs = new HashMap<>();
- jobs.forEach((job, versions) -> {
- if ( ! job.type().isTest()) {
- declaredTest(job.application(), systemTest).ifPresent(test -> {
- testJobs.merge(test,
- versions.stream()
- .filter(version -> allJobs.successOn(version).get(test).isEmpty())
- .collect(toUnmodifiableList()),
- DeploymentStatus::union);
- });
- declaredTest(job.application(), stagingTest).ifPresent(test -> {
- testJobs.merge(test,
- versions.stream()
- .filter(version -> allJobs.successOn(version).get(test).isEmpty())
- .collect(toUnmodifiableList()),
+ for (JobType testType : List.of(systemTest, stagingTest)) {
+ jobs.forEach((job, versions) -> {
+ if (job.type().isDeployment()) {
+ declaredTest(job.application(), testType).ifPresent(testJob -> {
+ testJobs.merge(testJob,
+ versions.stream()
+ .filter(version -> allJobs.successOn(version).get(testJob).isEmpty())
+ .collect(toUnmodifiableList()),
+ DeploymentStatus::union);
+ });
+ }
+ });
+ jobs.forEach((job, versionsList) -> {
+ if (job.type().isDeployment())
+ testJobs.merge(new JobId(job.application(), testType),
+ versionsList.stream()
+ .filter(versions -> testJobs.keySet().stream()
+ .noneMatch(test -> test.type() == testType
+ && testJobs.get(test).contains(versions)))
+ .filter(versions -> allJobs.successOn(versions).type(testType).isEmpty())
+ .collect(toUnmodifiableList()),
DeploymentStatus::union);
- });
- }
- });
- jobs.forEach((job, versions) -> {
- if ( ! job.type().isTest() && ! testedOn(versions, systemTest, testJobs))
- testJobs.merge(new JobId(job.application(), systemTest),
- versions.stream()
- .filter(version -> allJobs.successOn(version).type(systemTest).isEmpty())
- .collect(toUnmodifiableList()),
- DeploymentStatus::union);
- if ( ! job.type().isTest() && ! testedOn(versions, stagingTest, testJobs))
- testJobs.merge(new JobId(job.application(), stagingTest),
- versions.stream()
- .filter(version -> allJobs.successOn(version).type(stagingTest).isEmpty())
- .collect(toUnmodifiableList()),
- DeploymentStatus::union);
- });
+ });
+ }
jobs.putAll(testJobs);
}
@@ -176,15 +163,6 @@ public class DeploymentStatus {
return jobSteps.get(jobId).isDeclared() ? Optional.of(jobId) : Optional.empty();
}
- private boolean testedOn(List<Versions> versions, JobType testJob, Map<JobId, List<Versions>> testJobs) {
- return testJobs.keySet().stream()
- .anyMatch(job -> job.type() == testJob && testJobs.get(job).containsAll(versions));
- }
-
- private static <T> List<T> union(List<T> first, List<T> second) {
- return Stream.concat(first.stream(), second.stream()).distinct().collect(toUnmodifiableList());
- }
-
public Optional<Deployment> deploymentFor(JobId job) {
return Optional.ofNullable(application.require(job.application().instance())
.deployments().get(job.type().zone(system)));
@@ -215,7 +193,7 @@ public class DeploymentStatus {
JobType jobType;
StepStatus stepStatus;
- if (step.concerns(test) || step.concerns(staging)) { // SKIP?
+ if (step.concerns(test) || step.concerns(staging)) {
jobType = JobType.from(system, ((DeclaredZone) step).environment(), null)
.orElseThrow(() -> new IllegalStateException(application + " specifies " + step + ", but this has no job in " + system));
stepStatus = JobStepStatus.ofTestDeployment((DeclaredZone) step, List.of(), this, instance, jobType, true);
@@ -236,7 +214,7 @@ public class DeploymentStatus {
stepStatus = JobStepStatus.ofProductionDeployment((DeclaredZone) step, previous, this, instance, jobType);
previous = List.of(stepStatus);
}
- else return previous; // Empty container steps end up here.
+ else return previous; // Empty container steps end up here, and are simply ignored.
allSteps.add(stepStatus);
dependencies.put(new JobId(application.id().instance(instance), jobType), stepStatus);
return previous;
@@ -266,16 +244,17 @@ public class DeploymentStatus {
return List.copyOf(parallel);
}
+ /**
+ * True if the job has already been triggered on the given versions, or if all test types (systemTest, stagingTest),
+ * restricted to the job's instance if declared in that instance, have successful runs on the given versions.
+ */
public boolean isTested(JobId job, Versions versions) {
- return allJobs.triggeredOn(versions).get(job).isPresent()
- || ! declaredTest(job.application(), systemTest).map(__ -> allJobs.instance(job.application().instance()))
- .orElse(allJobs)
- .type(systemTest)
- .successOn(versions).isEmpty()
- && ! declaredTest(job.application(), stagingTest).map(__ -> allJobs.instance(job.application().instance()))
- .orElse(allJobs)
- .type(stagingTest)
- .successOn(versions).isEmpty();
+ return allJobs.triggeredOn(versions).get(job).isPresent()
+ || Stream.of(systemTest, stagingTest)
+ .noneMatch(testType -> declaredTest(job.application(), testType).map(__ -> allJobs.instance(job.application().instance()))
+ .orElse(allJobs)
+ .type(testType)
+ .successOn(versions).isEmpty());
}
@@ -304,7 +283,6 @@ public class DeploymentStatus {
*
* The completion criterion for each type of step is implemented in subclasses of this.
*/
- // TODO jonmv: Make the step status expose _what it is_.
public static abstract class StepStatus {
private final StepType type;
@@ -537,4 +515,8 @@ public class DeploymentStatus {
return step instanceof DeploymentSpec.Steps ? step.steps().stream().flatMap(DeploymentStatus::flatten) : Stream.of(step);
}
+ private static <T> List<T> union(List<T> first, List<T> second) {
+ return Stream.concat(first.stream(), second.stream()).distinct().collect(toUnmodifiableList());
+ }
+
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java
index 4abbf5be09b..fcf2ef97b49 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java
@@ -302,7 +302,7 @@ public class DeploymentContext {
var job = jobId(type);
triggerJobs();
doDeploy(job);
- if ( ! job.type().isTest()) {
+ if (job.type().isDeployment()) {
doUpgrade(job);
doConverge(job);
if (job.type().environment().isManuallyDeployed())
@@ -517,7 +517,7 @@ public class DeploymentContext {
ZoneId zone = zone(job);
// All installation is complete and endpoints are ready, so tests may begin.
- if ( ! job.type().isTest())
+ if (job.type().isDeployment())
assertEquals(Step.Status.succeeded, jobs.run(id).get().stepStatuses().get(Step.installReal));
assertEquals(Step.Status.succeeded, jobs.run(id).get().stepStatuses().get(Step.installTester));
assertEquals(Step.Status.succeeded, jobs.run(id).get().stepStatuses().get(Step.startTests));