summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Marius Venstad <jvenstad@yahoo-inc.com>2018-08-08 16:46:27 +0200
committerJon Marius Venstad <jvenstad@yahoo-inc.com>2018-08-08 16:46:27 +0200
commit67d8c4a95b13798c3d721a4c8fec6ee289665379 (patch)
treec36f120a31afc85569fd871118dc1850280508af
parentad4e3a8ca7dd8d6a90555de93c37b04107f10df0 (diff)
Store version information in run status
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunStatus.java23
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Versions.java14
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java118
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java32
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json36
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java14
8 files changed, 177 insertions, 70 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
index 3bfce2725a2..72bc1c61eae 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
@@ -170,7 +170,10 @@ public class DeploymentTrigger {
try {
applications().lockOrThrow(job.applicationId(), application -> {
if (application.get().deploymentJobs().builtInternally())
- jobs.start(job.applicationId(), job.jobType);
+ jobs.start(job.applicationId(), job.jobType, new Versions(job.triggering.platform(),
+ job.triggering.application(),
+ job.triggering.sourcePlatform(),
+ job.triggering.sourceApplication()));
else
buildService.trigger(job);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
index ba79364fa34..06af36a2e26 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
@@ -1,6 +1,7 @@
package com.yahoo.vespa.hosted.controller.deployment;
import com.google.common.collect.ImmutableMap;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.hosted.controller.Application;
@@ -195,7 +196,7 @@ public class JobController {
}
/** Orders a run of the given type, or throws an IllegalStateException if that job type is already running. */
- public void start(ApplicationId id, JobType type) {
+ public void start(ApplicationId id, JobType type, Versions versions) {
controller.applications().lockIfPresent(id, application -> {
if ( ! application.get().deploymentJobs().builtInternally())
throw new IllegalArgumentException(id + " is not built here!");
@@ -206,7 +207,7 @@ public class JobController {
throw new IllegalStateException("Can not start " + type + " for " + id + "; it is already running!");
RunId newId = new RunId(id, type, last.map(run -> run.id().number()).orElse(0L) + 1);
- curator.writeLastRun(RunStatus.initial(newId, controller.clock().instant()));
+ curator.writeLastRun(RunStatus.initial(newId, versions, controller.clock().instant()));
});
});
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunStatus.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunStatus.java
index c6724255a58..c30b1aee7f1 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunStatus.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunStatus.java
@@ -1,7 +1,9 @@
package com.yahoo.vespa.hosted.controller.deployment;
import com.google.common.collect.ImmutableList;
+import com.yahoo.component.Version;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+import com.yahoo.vespa.hosted.controller.application.ApplicationVersion;
import java.time.Instant;
import java.util.Collections;
@@ -24,24 +26,26 @@ public class RunStatus {
private final RunId id;
private final Map<Step, Step.Status> steps;
+ private final Versions versions;
private final Instant start;
private final Optional<Instant> end;
private final boolean aborted;
- // TODO jvenstad: Add a Versions object and a reason String. Requires shortcutting of triggering of these runs.
// For deserialisation only -- do not use!
- public RunStatus(RunId id, Map<Step, Step.Status> steps, Instant start, Optional<Instant> end, boolean aborted) {
+ public RunStatus(RunId id, Map<Step, Step.Status> steps, Versions versions,
+ Instant start, Optional<Instant> end, boolean aborted) {
this.id = id;
this.steps = Collections.unmodifiableMap(new EnumMap<>(steps));
+ this.versions = versions;
this.start = start;
this.end = end;
this.aborted = aborted;
}
- public static RunStatus initial(RunId id, Instant now) {
+ public static RunStatus initial(RunId id, Versions versions, Instant now) {
EnumMap<Step, Step.Status> steps = new EnumMap<>(Step.class);
JobProfile.of(id.type()).steps().forEach(step -> steps.put(step, unfinished));
- return new RunStatus(id, steps, requireNonNull(now), Optional.empty(), false);
+ return new RunStatus(id, steps, requireNonNull(versions), requireNonNull(now), Optional.empty(), false);
}
public RunStatus with(Step.Status status, LockedStep step) {
@@ -50,21 +54,21 @@ public class RunStatus {
EnumMap<Step, Step.Status> steps = new EnumMap<>(this.steps);
steps.put(step.get(), requireNonNull(status));
- return new RunStatus(id, steps, start, end, aborted);
+ return new RunStatus(id, steps, versions, start, end, aborted);
}
public RunStatus finished(Instant now) {
if (hasEnded())
throw new AssertionError("This step ended at " + end.get() + " -- it can't be ended again!");
- return new RunStatus(id, new EnumMap<>(steps), start, Optional.of(now), aborted);
+ return new RunStatus(id, new EnumMap<>(steps), versions, start, Optional.of(now), aborted);
}
public RunStatus aborted() {
if (hasEnded())
throw new AssertionError("This step ended at " + end.get() + " -- it can't be aborted now!");
- return new RunStatus(id, new EnumMap<>(steps), start, end, true);
+ return new RunStatus(id, new EnumMap<>(steps), versions, start, end, true);
}
/** Returns the id of this run. */
@@ -116,6 +120,11 @@ public class RunStatus {
return end.isPresent();
}
+ /** Returns the target, and possibly source, versions for this run. */
+ public Versions versions() {
+ return versions;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Versions.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Versions.java
index bf58bac177c..e0f7a955a80 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Versions.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Versions.java
@@ -9,8 +9,11 @@ import com.yahoo.vespa.hosted.controller.application.Change;
import com.yahoo.vespa.hosted.controller.application.Deployment;
import com.yahoo.vespa.hosted.controller.application.JobStatus;
+import java.util.Objects;
import java.util.Optional;
+import static java.util.Objects.requireNonNull;
+
/**
* Source and target versions for an application.
*
@@ -26,10 +29,13 @@ public class Versions {
public Versions(Version targetPlatform, ApplicationVersion targetApplication, Optional<Version> sourcePlatform,
Optional<ApplicationVersion> sourceApplication) {
- this.targetPlatform = targetPlatform;
- this.targetApplication = targetApplication;
- this.sourcePlatform = sourcePlatform;
- this.sourceApplication = sourceApplication;
+ if (sourcePlatform.isPresent() ^ sourceApplication.isPresent())
+ throw new IllegalArgumentException("Sources must both be present or absent.");
+
+ this.targetPlatform = requireNonNull(targetPlatform);
+ this.targetApplication = requireNonNull(targetApplication);
+ this.sourcePlatform = requireNonNull(sourcePlatform);
+ this.sourceApplication = requireNonNull(sourceApplication);
}
/** Target platform version for this */
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
index 7df60278390..153f4e327a0 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
@@ -1,5 +1,6 @@
package com.yahoo.vespa.hosted.controller.persistence;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.slime.ArrayTraverser;
import com.yahoo.slime.Cursor;
@@ -8,9 +9,12 @@ import com.yahoo.slime.ObjectTraverser;
import com.yahoo.slime.Slime;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+import com.yahoo.vespa.hosted.controller.application.ApplicationVersion;
+import com.yahoo.vespa.hosted.controller.application.SourceRevision;
import com.yahoo.vespa.hosted.controller.deployment.RunStatus;
import com.yahoo.vespa.hosted.controller.deployment.Step;
import com.yahoo.vespa.hosted.controller.deployment.Step.Status;
+import com.yahoo.vespa.hosted.controller.deployment.Versions;
import java.time.Instant;
import java.util.EnumMap;
@@ -47,6 +51,13 @@ public class RunSerializer {
private static final String startField = "start";
private static final String endField = "end";
private static final String abortedField = "aborted";
+ private static final String versionsField = "versions";
+ private static final String platformVersionField = "platform";
+ private static final String repositoryField = "repository";
+ private static final String branchField = "branch";
+ private static final String commitField = "commit";
+ private static final String buildField = "build";
+ private static final String sourceField = "source";
RunStatus runFromSlime(Slime slime) {
return runFromSlime(slime.get());
@@ -71,6 +82,7 @@ public class RunSerializer {
JobType.fromJobName(runObject.field(jobTypeField).asString()),
runObject.field(numberField).asLong()),
steps,
+ versionsFromSlime(runObject.field(versionsField)),
Instant.ofEpochMilli(runObject.field(startField).asLong()),
Optional.of(runObject.field(endField))
.filter(Inspector::valid)
@@ -78,6 +90,25 @@ public class RunSerializer {
runObject.field(abortedField).asBool());
}
+ private Versions versionsFromSlime(Inspector versionsObject) {
+ Version targetPlatformVersion = Version.fromString(versionsObject.field(platformVersionField).asString());
+ ApplicationVersion targetApplicationVersion = ApplicationVersion.from(new SourceRevision(versionsObject.field(repositoryField).asString(),
+ versionsObject.field(branchField).asString(),
+ versionsObject.field(commitField).asString()),
+ versionsObject.field(buildField).asLong());
+ Optional<Version> sourcePlatformVersion = versionsObject.field(sourceField).valid()
+ ? Optional.of(Version.fromString(versionsObject.field(sourceField).field(platformVersionField).asString()))
+ : Optional.empty();
+ Optional<ApplicationVersion> sourceApplicationVersion = versionsObject.field(sourceField).valid()
+ ? Optional.of(ApplicationVersion.from(new SourceRevision(versionsObject.field(repositoryField).asString(),
+ versionsObject.field(branchField).asString(),
+ versionsObject.field(commitField).asString()),
+ versionsObject.field(buildField).asLong()))
+ : Optional.empty();
+
+ return new Versions(targetPlatformVersion, targetApplicationVersion, sourcePlatformVersion, sourceApplicationVersion);
+ }
+
Slime toSlime(Iterable<RunStatus> runs) {
Slime slime = new Slime();
Cursor runArray = slime.setArray();
@@ -98,59 +129,84 @@ public class RunSerializer {
runObject.setLong(startField, run.start().toEpochMilli());
run.end().ifPresent(end -> runObject.setLong(endField, end.toEpochMilli()));
if (run.isAborted()) runObject.setBool(abortedField, true);
+
Cursor stepsObject = runObject.setObject(stepsField);
run.steps().forEach((step, status) -> stepsObject.setString(valueOf(step), valueOf(status)));
+
+ Cursor versionsObject = runObject.setObject(versionsField);
+ toSlime(run.versions().targetPlatform(), run.versions().targetApplication(), versionsObject);
+ run.versions().sourcePlatform().ifPresent(sourcePlatformVersion -> {
+ toSlime(sourcePlatformVersion,
+ run.versions().sourceApplication()
+ .orElseThrow(() -> new IllegalArgumentException("Source versions must be both present or absent.")),
+ versionsObject.setObject(sourceField));
+ });
+ }
+
+ private void toSlime(Version platformVersion, ApplicationVersion applicationVersion, Cursor versionsObject) {
+ versionsObject.setString(platformVersionField, platformVersion.toString());
+ SourceRevision targetSourceRevision = applicationVersion.source()
+ .orElseThrow(() -> new IllegalArgumentException("Source revision must be present in target application version."));
+ versionsObject.setString(repositoryField, targetSourceRevision.repository());
+ versionsObject.setString(branchField, targetSourceRevision.branch());
+ versionsObject.setString(commitField, targetSourceRevision.commit());
+ versionsObject.setLong(buildField, applicationVersion.buildNumber()
+ .orElseThrow(() -> new IllegalArgumentException("Build number must be present in target application version.")));
}
static String valueOf(Step step) {
switch (step) {
- case deployInitialReal : return "DIR";
- case installInitialReal : return "IIR";
- case deployReal : return "DR" ;
- case installReal : return "IR" ;
- case deactivateReal : return "DAR";
- case deployTester : return "DT" ;
- case installTester : return "IT" ;
- case deactivateTester : return "DAT";
- case startTests : return "ST" ;
- case endTests : return "ET" ;
- case report : return "R" ;
+ case deployInitialReal : return "deployInitialReal";
+ case installInitialReal : return "installInitialReal";
+ case deployReal : return "deployReal";
+ case installReal : return "installReal";
+ case deactivateReal : return "deactivateReal";
+ case deployTester : return "deployTester";
+ case installTester : return "installTester";
+ case deactivateTester : return "deactivateTester";
+ case startTests : return "startTests";
+ case endTests : return "endTests";
+ case report : return "report";
+
default : throw new AssertionError("No value defined for '" + step + "'!");
}
}
static Step stepOf(String step) {
switch (step) {
- case "DIR" : return deployInitialReal ;
- case "IIR" : return installInitialReal;
- case "DR" : return deployReal ;
- case "IR" : return installReal ;
- case "DAR" : return deactivateReal ;
- case "DT" : return deployTester ;
- case "IT" : return installTester ;
- case "DAT" : return deactivateTester ;
- case "ST" : return startTests ;
- case "ET" : return endTests ;
- case "R" : return report ;
- default : throw new IllegalArgumentException("No step defined by '" + step + "'!");
+ case "deployInitialReal" : return deployInitialReal;
+ case "installInitialReal" : return installInitialReal;
+ case "deployReal" : return deployReal;
+ case "installReal" : return installReal;
+ case "deactivateReal" : return deactivateReal;
+ case "deployTester" : return deployTester;
+ case "installTester" : return installTester;
+ case "deactivateTester" : return deactivateTester;
+ case "startTests" : return startTests;
+ case "endTests" : return endTests;
+ case "report" : return report;
+
+ default : throw new IllegalArgumentException("No step defined by '" + step + "'!");
}
}
static String valueOf(Status status) {
switch (status) {
- case unfinished : return "U";
- case failed : return "F";
- case succeeded : return "S";
- default : throw new AssertionError("No value defined for '" + status + "'!");
+ case unfinished : return "unfinished";
+ case failed : return "failed";
+ case succeeded : return "succeeded";
+
+ default : throw new AssertionError("No value defined for '" + status + "'!");
}
}
static Status statusOf(String status) {
switch (status) {
- case "U" : return unfinished;
- case "F" : return failed ;
- case "S" : return succeeded ;
- default : throw new IllegalArgumentException("No status defined by '" + status + "'!");
+ case "unfinished" : return unfinished;
+ case "failed" : return failed;
+ case "succeeded" : return succeeded;
+
+ default : throw new IllegalArgumentException("No status defined by '" + status + "'!");
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java
index e084e9aa46d..e5416672bb7 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java
@@ -1,8 +1,10 @@
package com.yahoo.vespa.hosted.controller.maintenance;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.hosted.controller.TestIdentities;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+import com.yahoo.vespa.hosted.controller.application.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.application.SourceRevision;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
import com.yahoo.vespa.hosted.controller.deployment.JobController;
@@ -10,6 +12,7 @@ import com.yahoo.vespa.hosted.controller.deployment.RunStatus;
import com.yahoo.vespa.hosted.controller.deployment.Step;
import com.yahoo.vespa.hosted.controller.deployment.Step.Status;
import com.yahoo.vespa.hosted.controller.deployment.StepRunner;
+import com.yahoo.vespa.hosted.controller.deployment.Versions;
import org.junit.Test;
import java.time.Duration;
@@ -40,7 +43,6 @@ import static com.yahoo.vespa.hosted.controller.deployment.Step.deactivateReal;
import static com.yahoo.vespa.hosted.controller.deployment.Step.deactivateTester;
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.installInitialReal;
import static com.yahoo.vespa.hosted.controller.deployment.Step.installReal;
import static com.yahoo.vespa.hosted.controller.deployment.Step.installTester;
import static com.yahoo.vespa.hosted.controller.deployment.Step.report;
@@ -56,6 +58,14 @@ import static org.junit.Assert.fail;
*/
public class JobRunnerTest {
+ static final Versions versions = new Versions(Version.fromString("1.2.3"),
+ ApplicationVersion.from(new SourceRevision("repo",
+ "branch",
+ "bada55"),
+ 321),
+ Optional.empty(),
+ Optional.empty());
+
@Test
public void multiThreadedExecutionFinishes() throws InterruptedException {
DeploymentTester tester = new DeploymentTester();
@@ -67,15 +77,15 @@ public class JobRunnerTest {
Executors.newFixedThreadPool(32), notifying(stepRunner, latch));
ApplicationId id = tester.createApplication("real", "tenant", 1, 1L).id();
- jobs.submit(id, new SourceRevision("repo", "branch", "bada55"), new byte[0], new byte[0]);
+ jobs.submit(id, versions.targetApplication().source().get(), new byte[0], new byte[0]);
- jobs.start(id, systemTest);
+ jobs.start(id, systemTest, versions);
try {
- jobs.start(id, systemTest);
+ jobs.start(id, systemTest, versions);
fail("Job is already running, so this should not be allowed!");
}
catch (IllegalStateException e) { }
- jobs.start(id, stagingTest);
+ jobs.start(id, stagingTest, versions);
assertTrue(jobs.last(id, systemTest).get().steps().values().stream().allMatch(unfinished::equals));
runner.maintain();
@@ -100,10 +110,10 @@ public class JobRunnerTest {
inThreadExecutor(), mappedRunner(outcomes));
ApplicationId id = tester.createApplication("real", "tenant", 1, 1L).id();
- jobs.submit(id, new SourceRevision("repo", "branch", "bada55"), new byte[0], new byte[0]);
+ jobs.submit(id, versions.targetApplication().source().get(), new byte[0], new byte[0]);
Supplier<RunStatus> run = () -> jobs.last(id, systemTest).get();
- jobs.start(id, systemTest);
+ jobs.start(id, systemTest, versions);
RunId first = run.get().id();
Map<Step, Status> steps = run.get().steps();
@@ -155,7 +165,7 @@ public class JobRunnerTest {
assertTrue(run.get().isAborted());
// A new run is attempted.
- jobs.start(id, systemTest);
+ jobs.start(id, systemTest, versions);
assertEquals(first.number() + 1, run.get().id().number());
// Run fails on tester deployment -- remaining run-always steps succeed, and the run finishes.
@@ -171,7 +181,7 @@ public class JobRunnerTest {
assertEquals(2, jobs.runs(id, systemTest).size());
// Start a third run, then unregister and wait for data to be deleted.
- jobs.start(id, systemTest);
+ jobs.start(id, systemTest, versions);
jobs.unregister(id);
runner.maintain();
assertFalse(jobs.last(id, systemTest).isPresent());
@@ -188,10 +198,10 @@ public class JobRunnerTest {
Executors.newFixedThreadPool(32), waitingRunner(barrier));
ApplicationId id = tester.createApplication("real", "tenant", 1, 1L).id();
- jobs.submit(id, new SourceRevision("repo", "branch", "bada55"), new byte[0], new byte[0]);
+ jobs.submit(id, versions.targetApplication().source().get(), new byte[0], new byte[0]);
RunId runId = new RunId(id, systemTest, 1);
- jobs.start(id, systemTest);
+ jobs.start(id, systemTest, versions);
runner.maintain();
barrier.await();
try {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json
index d659bd9fff0..9b3de20acc4 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json
@@ -5,17 +5,31 @@
"number": 112358,
"start": 1196676930000,
"steps": {
- "DIR": "U",
- "IIR": "F",
- "DR": "S",
- "IR": "U",
- "DAR": "F",
- "DT": "S",
- "IT": "U",
- "DAT": "F",
- "ST": "S",
- "ET": "U",
- "R": "F"
+ "deployInitialReal": "unfinished",
+ "installInitialReal": "failed",
+ "deployReal": "succeeded",
+ "installReal": "unfinished",
+ "deactivateReal": "failed",
+ "deployTester": "succeeded",
+ "installTester": "unfinished",
+ "deactivateTester": "failed",
+ "startTests": "succeeded",
+ "endTests": "unfinished",
+ "report": "failed"
+ },
+ "versions": {
+ "platform": "1.2.3",
+ "repository": "git@github.com:user/repo.git",
+ "branch": "master",
+ "commit": "f00bad",
+ "build": 123,
+ "source": {
+ "platform": "1.2.3",
+ "repository": "git@github.com:user/repo.git",
+ "branch": "master",
+ "commit": "badb17",
+ "build": 122
+ }
}
}
] \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java
index 856b91b912e..f350cc8627b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java
@@ -1,5 +1,6 @@
package com.yahoo.vespa.hosted.controller.restapi.application;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
import com.yahoo.container.jdisc.HttpResponse;
@@ -7,10 +8,12 @@ import com.yahoo.vespa.hosted.controller.ControllerTester;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockLogStore;
+import com.yahoo.vespa.hosted.controller.application.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.application.SourceRevision;
import com.yahoo.vespa.hosted.controller.deployment.JobController;
import com.yahoo.vespa.hosted.controller.deployment.RunStatus;
import com.yahoo.vespa.hosted.controller.deployment.Step;
+import com.yahoo.vespa.hosted.controller.deployment.Versions;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
@@ -24,9 +27,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -38,6 +39,13 @@ public class JobControllerApiHandlerHelperTest {
private final ApplicationId appId = ApplicationId.from("vespa", "music", "default");
private final Instant start = Instant.parse("2018-06-27T10:12:35Z");
+ static final Versions versions = new Versions(Version.fromString("1.2.3"),
+ ApplicationVersion.from(new SourceRevision("repo",
+ "branch",
+ "bada55"),
+ 321),
+ Optional.empty(),
+ Optional.empty());
private static Step lastStep = Step.values()[Step.values().length - 1];
@@ -131,7 +139,7 @@ public class JobControllerApiHandlerHelperTest {
end = Optional.of(start.plusSeconds(duration));
}
- return new RunStatus(runId, stepStatusMap, start, end, false);
+ return new RunStatus(runId, stepStatusMap, versions, start, end, false);
}
private void compare(HttpResponse response, String expected) {