aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server/src/test/java/com
diff options
context:
space:
mode:
authorJon Marius Venstad <jonmv@users.noreply.github.com>2019-10-28 11:39:22 +0100
committerGitHub <noreply@github.com>2019-10-28 11:39:22 +0100
commit4477bd67bf158fb4e3ec16719a6cce505cf5d2fe (patch)
tree3a03912bd29911bd24561ef6ad072f8eeb961f86 /controller-server/src/test/java/com
parente8932525b4f6039b2164bf7cebcba1fa2db50284 (diff)
parentc721ba4969bc9e39681964261a4dfc9ab3b0f08f (diff)
Merge pull request #11110 from vespa-engine/mpolden/deployment-context
Extract DeploymentContext from InternalDeploymentTester
Diffstat (limited to 'controller-server/src/test/java/com')
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java14
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java490
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java461
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java10
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java7
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java118
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OutstandingChangeDeployerTest.java9
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelperTest.java4
10 files changed, 643 insertions, 476 deletions
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
index ce357a68ae2..6e204a418ad 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
@@ -49,6 +49,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Handler;
@@ -73,6 +75,9 @@ public final class ControllerTester {
private final ServiceRegistryMock serviceRegistry;
private final CuratorDb curator;
private final RotationsConfig rotationsConfig;
+ private final AtomicLong nextPropertyId = new AtomicLong(1000);
+ private final AtomicInteger nextProjectId = new AtomicInteger(1000);
+ private final AtomicInteger nextDomainId = new AtomicInteger(1000);
private Controller controller;
@@ -262,6 +267,11 @@ public final class ControllerTester {
return name;
}
+ public TenantName createTenant(String tenantName) {
+ return createTenant(tenantName, "domain" + nextDomainId.getAndIncrement(),
+ nextPropertyId.getAndIncrement());
+ }
+
public TenantName createTenant(String tenantName, String domainName, Long propertyId) {
return createTenant(tenantName, domainName, propertyId, Optional.empty());
}
@@ -272,6 +282,10 @@ public final class ControllerTester {
new OktaAccessToken("okta-token")));
}
+ public Application createApplication(TenantName tenant, String applicationName, String instanceName) {
+ return createApplication(tenant, applicationName, instanceName, nextProjectId.getAndIncrement());
+ }
+
public Application createApplication(TenantName tenant, String applicationName, String instanceName, long projectId) {
TenantAndApplicationId applicationId = TenantAndApplicationId.from(tenant.value(), applicationName);
controller().applications().createApplication(applicationId, credentialsFor(applicationId));
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
new file mode 100644
index 00000000000..3c3a09bf5a7
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java
@@ -0,0 +1,490 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.deployment;
+
+import com.yahoo.component.Version;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.AthenzDomain;
+import com.yahoo.config.provision.AthenzService;
+import com.yahoo.config.provision.zone.ZoneId;
+import com.yahoo.security.KeyAlgorithm;
+import com.yahoo.security.KeyUtils;
+import com.yahoo.security.SignatureAlgorithm;
+import com.yahoo.security.X509CertificateBuilder;
+import com.yahoo.vespa.hosted.controller.Application;
+import com.yahoo.vespa.hosted.controller.ControllerTester;
+import com.yahoo.vespa.hosted.controller.Instance;
+import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobId;
+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.deployment.SourceRevision;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterId;
+import com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingEndpoint;
+import com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingGeneratorMock;
+import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockTesterCloud;
+import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
+import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId;
+import com.yahoo.vespa.hosted.controller.integration.ConfigServerMock;
+import com.yahoo.vespa.hosted.controller.maintenance.JobRunner;
+import com.yahoo.vespa.hosted.controller.maintenance.NameServiceDispatcher;
+import com.yahoo.vespa.hosted.controller.maintenance.ReadyJobsTrigger;
+
+import javax.security.auth.x500.X500Principal;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.cert.X509Certificate;
+import java.time.Instant;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.yahoo.vespa.hosted.controller.deployment.Step.Status.unfinished;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * A deployment context for an application. This allows fine-grained control of the deployment of an application's
+ * instances.
+ *
+ * References to this should be acquired through {@link InternalDeploymentTester#deploymentContext}.
+ *
+ * Tester code that is not specific to deployments should be added to either {@link ControllerTester} or
+ * {@link InternalDeploymentTester} instead of this class.
+ *
+ * @author mpolden
+ */
+public class DeploymentContext {
+
+ public static final ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
+ .athenzIdentity(AthenzDomain.from("domain"), AthenzService.from("service"))
+ .upgradePolicy("default")
+ .region("us-central-1")
+ .parallel("us-west-1", "us-east-3")
+ .emailRole("author")
+ .emailAddress("b@a")
+ .build();
+
+ public static final ApplicationPackage publicCdApplicationPackage = new ApplicationPackageBuilder()
+ .athenzIdentity(AthenzDomain.from("domain"), AthenzService.from("service"))
+ .upgradePolicy("default")
+ .region("aws-us-east-1c")
+ .emailRole("author")
+ .emailAddress("b@a")
+ .trust(generateCertificate())
+ .build();
+
+ private final TenantAndApplicationId applicationId;
+ private final ApplicationId instanceId;
+ private final TesterId testerId;
+ private final JobController jobs;
+ private final RoutingGeneratorMock routing;
+ private final MockTesterCloud cloud;
+ private final JobRunner runner;
+ private final ControllerTester tester;
+ private final ReadyJobsTrigger readyJobsTrigger;
+ private final NameServiceDispatcher nameServiceDispatcher;;
+
+ private ApplicationVersion lastSubmission = null;
+ private boolean deferDnsUpdates = false;
+
+ public DeploymentContext(ApplicationId instanceId, InternalDeploymentTester tester) {
+
+ this.applicationId = TenantAndApplicationId.from(instanceId);
+ this.instanceId = instanceId;
+ this.testerId = TesterId.of(instanceId);
+ this.jobs = tester.controller().jobController();
+ this.runner = tester.runner();
+ this.tester = tester.controllerTester();
+ this.routing = this.tester.serviceRegistry().routingGeneratorMock();
+ this.cloud = this.tester.serviceRegistry().testerCloud();
+ this.readyJobsTrigger = tester.readyJobsTrigger();
+ this.nameServiceDispatcher = tester.nameServiceDispatcher();
+ createTenantAndApplication();
+ }
+
+ private void createTenantAndApplication() {
+ try {
+ var tenant = tester.createTenant(instanceId.tenant().value());
+ tester.createApplication(tenant, instanceId.application().value(), instanceId.instance().value());
+ } catch (IllegalArgumentException ignored) {
+ // TODO(mpolden): Application already exists. Remove this once InternalDeploymentTester stops implicitly creating applications
+ }
+ }
+
+ public Application application() {
+ return tester.controller().applications().requireApplication(applicationId);
+ }
+
+ public Instance instance() {
+ return tester.controller().applications().requireInstance(instanceId);
+ }
+
+ public ApplicationId instanceId() {
+ return instanceId;
+ }
+
+ public DeploymentId deploymentIdIn(ZoneId zone) {
+ return new DeploymentId(instanceId, zone);
+ }
+
+
+ /** Completely deploy the latest change */
+ public DeploymentContext deploy() {
+ assertNotNull("Application package submitted", lastSubmission);
+ assertFalse("Submission is not already deployed", application().instances().values().stream()
+ .anyMatch(instance -> instance.deployments().values().stream()
+ .anyMatch(deployment -> deployment.applicationVersion().equals(lastSubmission))));
+ assertEquals(lastSubmission, application().change().application().get());
+ assertFalse(application().change().platform().isPresent());
+ completeRollout();
+ assertFalse(application().change().hasTargets());
+ return this;
+ }
+
+ /** Upgrade platform of this to given version */
+ public DeploymentContext deployPlatform(Version version) {
+ assertEquals(tester.controller().systemVersion(), version);
+ assertFalse(application().instances().values().stream()
+ .anyMatch(instance -> instance.deployments().values().stream()
+ .anyMatch(deployment -> deployment.version().equals(version))));
+ assertEquals(version, application().change().platform().get());
+ assertFalse(application().change().application().isPresent());
+
+ completeRollout();
+
+ assertTrue(application().productionDeployments().values().stream()
+ .allMatch(deployments -> deployments.stream()
+ .allMatch(deployment -> deployment.version().equals(version))));
+
+ for (JobType type : new DeploymentSteps(application().deploymentSpec(), tester.controller()::system).productionJobs())
+ assertTrue(tester.configServer().nodeRepository()
+ .list(type.zone(tester.controller().system()), applicationId.defaultInstance()).stream() // TODO jonmv: support more
+ .allMatch(node -> node.currentVersion().equals(version)));
+
+ assertFalse(application().change().hasTargets());
+ return this;
+ }
+
+
+ /** Defer DNS updates */
+ public DeploymentContext deferDnsUpdates() {
+ deferDnsUpdates = true;
+ return this;
+ }
+
+ /** Flush all pending DNS updates */
+ public DeploymentContext flushDnsUpdates() {
+ nameServiceDispatcher.run();
+ assertTrue("All name service requests dispatched",
+ tester.controller().curator().readNameServiceQueue().requests().isEmpty());
+ return this;
+ }
+
+ /** Submit given application package for deployment */
+ public DeploymentContext submit(ApplicationPackage applicationPackage) {
+ return submit(applicationPackage, BuildJob.defaultSourceRevision);
+ }
+
+ /** Submit given application package for deployment */
+ public DeploymentContext submit(ApplicationPackage applicationPackage, SourceRevision sourceRevision) {
+ var projectId = tester.controller().applications()
+ .requireApplication(applicationId)
+ .projectId()
+ .orElseThrow(() -> new IllegalArgumentException("No project ID set for " + applicationId));
+ lastSubmission = jobs.submit(applicationId, sourceRevision, "a@b", projectId, applicationPackage, new byte[0]);
+ return this;
+ }
+
+
+ /** Submit the default application package for deployment */
+ public DeploymentContext submit() {
+ return submit(tester.controller().system().isPublic() ? publicCdApplicationPackage : applicationPackage);
+ }
+
+ /** Trigger all outstanding jobs, if any */
+ public DeploymentContext triggerJobs() {
+ while (tester.controller().applications().deploymentTrigger().triggerReadyJobs() > 0);
+ return this;
+ }
+
+ /** Fail current deployment in given job */
+ public DeploymentContext failDeployment(JobType type) {
+ triggerJobs();
+ var job = jobId(type);
+ RunId id = currentRun(job).id();
+ configServer().throwOnNextPrepare(new IllegalArgumentException("Exception"));
+ runner.advance(currentRun(job));
+ assertTrue(jobs.run(id).get().hasFailed());
+ assertTrue(jobs.run(id).get().hasEnded());
+ doTeardown(job);
+ return this;
+ }
+
+ /** Returns the last submitted application version */
+ public Optional<ApplicationVersion> lastSubmission() {
+ return Optional.ofNullable(lastSubmission);
+ }
+
+ /** Runs and returns all remaining jobs for the application, at most once, and asserts the current change is rolled out. */
+ public DeploymentContext completeRollout() {
+ triggerJobs();
+ Set<JobType> jobs = new HashSet<>();
+ List<Run> activeRuns;
+ while ( ! (activeRuns = this.jobs.active(applicationId)).isEmpty())
+ for (Run run : activeRuns)
+ if (jobs.add(run.id().type())) {
+ runJob(run.id().type());
+ readyJobsTrigger.run();
+ }
+ else
+ throw new AssertionError("Job '" + run.id().type() + "' was run twice for '" + instanceId + "'");
+
+ assertFalse("Change should have no targets, but was " + application().change(), application().change().hasTargets());
+ if (!deferDnsUpdates) {
+ flushDnsUpdates();
+ }
+ return this;
+ }
+
+ /** Pulls the ready job trigger, and then runs the whole of the given job, successfully. */
+ public DeploymentContext runJob(JobType type) {
+ var job = jobId(type);
+ triggerJobs();
+ doDeploy(job);
+ doUpgrade(job);
+ doConverge(job);
+ if (job.type().environment().isManuallyDeployed())
+ return this;
+ doInstallTester(job);
+ doTests(job);
+ doTeardown(job);
+ return this;
+ }
+
+ /** Simulate upgrade time out in given job */
+ public DeploymentContext timeOutUpgrade(JobType type) {
+ var job = jobId(type);
+ triggerJobs();
+ RunId id = currentRun(job).id();
+ doDeploy(job);
+ tester.clock().advance(InternalStepRunner.installationTimeout.plusSeconds(1));
+ runner.advance(currentRun(job));
+ assertTrue(jobs.run(id).get().hasFailed());
+ assertTrue(jobs.run(id).get().hasEnded());
+ doTeardown(job);
+ return this;
+ }
+
+ /** Simulate convergence time out in given job */
+ public void timeOutConvergence(JobType type) {
+ var job = jobId(type);
+ triggerJobs();
+ RunId id = currentRun(job).id();
+ doDeploy(job);
+ doUpgrade(job);
+ tester.clock().advance(InternalStepRunner.installationTimeout.plusSeconds(1));
+ runner.advance(currentRun(job));
+ assertTrue(jobs.run(id).get().hasFailed());
+ assertTrue(jobs.run(id).get().hasEnded());
+ doTeardown(job);
+ }
+
+ /** Sets a single endpoint in the routing layer for the instance in this */
+ public DeploymentContext setEndpoints(ZoneId zone) {
+ return setEndpoints(zone, false);
+ }
+
+ /** Deploy default application package, start a run for that change and return its ID */
+ public RunId newRun(JobType type) {
+ assertFalse(application().internal()); // Use this only once per test.
+ submit();
+ readyJobsTrigger.maintain();
+
+ if (type.isProduction()) {
+ runJob(JobType.systemTest);
+ runJob(JobType.stagingTest);
+ readyJobsTrigger.maintain();
+ }
+
+ Run run = jobs.active().stream()
+ .filter(r -> r.id().type() == type)
+ .findAny()
+ .orElseThrow(() -> new AssertionError(type + " is not among the active: " + jobs.active()));
+ return run.id();
+ }
+
+ /** Start tests in system test stage */
+ public RunId startSystemTestTests() {
+ RunId id = newRun(JobType.systemTest);
+ runner.run();
+ configServer().convergeServices(instanceId, JobType.systemTest.zone(tester.controller().system()));
+ configServer().convergeServices(testerId.id(), JobType.systemTest.zone(tester.controller().system()));
+ setEndpoints(JobType.systemTest.zone(tester.controller().system()));
+ setTesterEndpoints(JobType.systemTest.zone(tester.controller().system()));
+ runner.run();
+ assertEquals(unfinished, jobs.run(id).get().steps().get(Step.endTests));
+ return id;
+ }
+
+ /** Deploys tester and real app, and completes initial staging installation first if needed. */
+ private void doDeploy(JobId job) {
+ RunId id = currentRun(job).id();
+ ZoneId zone = zone(job);
+ DeploymentId deployment = new DeploymentId(job.application(), zone);
+
+ // First steps are always deployments.
+ runner.advance(currentRun(job));
+
+ if (job.type() == JobType.stagingTest) { // Do the initial deployment and installation of the real application.
+ assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installInitialReal));
+ Versions versions = currentRun(job).versions();
+ tester.configServer().nodeRepository().doUpgrade(deployment, Optional.empty(), versions.sourcePlatform().orElse(versions.targetPlatform()));
+ configServer().convergeServices(id.application(), zone);
+ setEndpoints(zone);
+ runner.advance(currentRun(job));
+ assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installInitialReal));
+ }
+ }
+
+ /** Upgrades nodes to target version. */
+ private void doUpgrade(JobId job) {
+ RunId id = currentRun(job).id();
+ ZoneId zone = zone(job);
+ DeploymentId deployment = new DeploymentId(job.application(), zone);
+
+ assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installReal));
+ configServer().nodeRepository().doUpgrade(deployment, Optional.empty(), currentRun(job).versions().targetPlatform());
+ runner.advance(currentRun(job));
+ }
+
+ /** Returns the current run for the given job type, and verifies it is still running normally. */
+ private Run currentRun(JobId job) {
+ Run run = jobs.last(job)
+ .filter(r -> r.id().type() == job.type())
+ .orElseThrow(() -> new AssertionError(job.type() + " is not among the active: " + jobs.active()));
+ assertFalse(run.hasFailed());
+ assertFalse(run.hasEnded());
+ return run;
+ }
+
+ /** Sets a single endpoint in the routing layer for the tester instance in this */
+ private DeploymentContext setTesterEndpoints(ZoneId zone) {
+ return setEndpoints(zone, true);
+ }
+
+ /** Sets a single endpoint in the routing layer; this matches that required for the tester */
+ private DeploymentContext setEndpoints(ZoneId zone, boolean tester) {
+ var id = instanceId;
+ if (tester) {
+ id = testerId.id();
+ }
+ routing.putEndpoints(new DeploymentId(id, zone),
+ Collections.singletonList(new RoutingEndpoint(String.format("https://%s--%s--%s.%s.%s.vespa:43",
+ id.instance().value(),
+ id.application().value(),
+ id.tenant().value(),
+ zone.region().value(),
+ zone.environment().value()),
+ "host1",
+ false,
+ String.format("cluster1.%s.%s.%s.%s",
+ id.application().value(),
+ id.tenant().value(),
+ zone.region().value(),
+ zone.environment().value()))));
+ return this;
+ }
+
+ /** Lets nodes converge on new application version. */
+ private void doConverge(JobId job) {
+ RunId id = currentRun(job).id();
+ ZoneId zone = zone(job);
+
+ assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installReal));
+ configServer().convergeServices(id.application(), zone);
+ setEndpoints(zone);
+ runner.advance(currentRun(job));
+ if (job.type().environment().isManuallyDeployed()) {
+ assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installReal));
+ assertTrue(jobs.run(id).get().hasEnded());
+ return;
+ }
+ assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installReal));
+ }
+
+ /** Installs tester and starts tests. */
+ private void doInstallTester(JobId job) {
+ RunId id = currentRun(job).id();
+ ZoneId zone = zone(job);
+
+ assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installTester));
+ configServer().nodeRepository().doUpgrade(new DeploymentId(TesterId.of(job.application()).id(), zone), Optional.empty(), currentRun(job).versions().targetPlatform());
+ runner.advance(currentRun(job));
+ assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installTester));
+ configServer().convergeServices(TesterId.of(id.application()).id(), zone);
+ runner.advance(currentRun(job));
+ assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installTester));
+ setTesterEndpoints(zone);
+ runner.advance(currentRun(job));
+ }
+
+ /** Completes tests with success. */
+ private void doTests(JobId job) {
+ RunId id = currentRun(job).id();
+ ZoneId zone = zone(job);
+
+ // All installation is complete and endpoints are ready, so tests may begin.
+ assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installReal));
+ assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installTester));
+ assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.startTests));
+
+ assertEquals(unfinished, jobs.run(id).get().steps().get(Step.endTests));
+ cloud.set(TesterCloud.Status.SUCCESS);
+ runner.advance(currentRun(job));
+ assertTrue(jobs.run(id).get().hasEnded());
+ assertFalse(jobs.run(id).get().hasFailed());
+ assertEquals(job.type().isProduction(), instance().deployments().containsKey(zone));
+ assertTrue(configServer().nodeRepository().list(zone, TesterId.of(id.application()).id()).isEmpty());
+ }
+
+ /** Removes endpoints from routing layer — always call this. */
+ private void doTeardown(JobId job) {
+ ZoneId zone = zone(job);
+ DeploymentId deployment = new DeploymentId(job.application(), zone);
+
+ if ( ! instance().deployments().containsKey(zone))
+ routing.removeEndpoints(deployment);
+ routing.removeEndpoints(new DeploymentId(TesterId.of(job.application()).id(), zone));
+ }
+
+ private JobId jobId(JobType type) {
+ return new JobId(instanceId, type);
+ }
+
+ private ZoneId zone(JobId job) {
+ return job.type().zone(tester.controller().system());
+ }
+
+ private ConfigServerMock configServer() {
+ return tester.configServer();
+ }
+
+ private static X509Certificate generateCertificate() {
+ KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC, 256);
+ X500Principal subject = new X500Principal("CN=subject");
+ return X509CertificateBuilder.fromKeypair(keyPair,
+ subject,
+ Instant.now(),
+ Instant.now().plusSeconds(1),
+ SignatureAlgorithm.SHA512_WITH_ECDSA,
+ BigInteger.valueOf(1))
+ .build();
+ }
+
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
index 7018e063efc..fb5f0bd94c0 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
@@ -161,7 +161,7 @@ public class DeploymentTriggerTest {
public void abortsInternalJobsOnNewApplicationChange() {
Instance instance = iTester.instance();
Application application = iTester.application();
- ApplicationPackage applicationPackage = InternalDeploymentTester.applicationPackage;
+ ApplicationPackage applicationPackage = DeploymentContext.applicationPackage;
tester.jobCompletion(component).application(application).uploadArtifact(applicationPackage).submit();
tester.deployAndNotify(instance.id(), Optional.empty(), true, systemTest);
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java
index 206db46ac27..fb9367cc020 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalDeploymentTester.java
@@ -3,14 +3,8 @@ package com.yahoo.vespa.hosted.controller.deployment;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.AthenzDomain;
-import com.yahoo.config.provision.AthenzService;
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.test.ManualClock;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.ApplicationController;
@@ -20,13 +14,10 @@ import com.yahoo.vespa.hosted.controller.Instance;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzDbMock;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
-import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobId;
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.deployment.SourceRevision;
-import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterId;
-import com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingEndpoint;
import com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingGeneratorMock;
import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockTesterCloud;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
@@ -36,67 +27,43 @@ import com.yahoo.vespa.hosted.controller.maintenance.JobControl;
import com.yahoo.vespa.hosted.controller.maintenance.JobRunner;
import com.yahoo.vespa.hosted.controller.maintenance.JobRunnerTest;
import com.yahoo.vespa.hosted.controller.maintenance.NameServiceDispatcher;
+import com.yahoo.vespa.hosted.controller.maintenance.ReadyJobsTrigger;
import com.yahoo.vespa.hosted.controller.maintenance.Upgrader;
-import javax.security.auth.x500.X500Principal;
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.cert.X509Certificate;
import java.time.Duration;
-import java.time.Instant;
import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;
-import static com.yahoo.vespa.hosted.controller.deployment.RunStatus.aborted;
-import static com.yahoo.vespa.hosted.controller.deployment.Step.Status.unfinished;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
+/**
+ * @author jonmv
+ */
public class InternalDeploymentTester {
+ // Set a long interval so that maintainers never do scheduled runs during tests
+ private static final Duration maintenanceInterval = Duration.ofDays(1);
+
private static final String ATHENZ_DOMAIN = "domain";
private static final String ATHENZ_SERVICE = "service";
- public static final ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
- .athenzIdentity(AthenzDomain.from(ATHENZ_DOMAIN), AthenzService.from(ATHENZ_SERVICE))
- .upgradePolicy("default")
- .region("us-central-1")
- .parallel("us-west-1", "us-east-3")
- .emailRole("author")
- .emailAddress("b@a")
- .build();
- public static final ApplicationPackage publicCdApplicationPackage = new ApplicationPackageBuilder()
- .athenzIdentity(AthenzDomain.from(ATHENZ_DOMAIN), AthenzService.from(ATHENZ_SERVICE))
- .upgradePolicy("default")
- .region("aws-us-east-1c")
- .emailRole("author")
- .emailAddress("b@a")
- .trust(generateCertificate())
- .build();
public static final TenantAndApplicationId appId = TenantAndApplicationId.from("tenant", "application");
public static final ApplicationId instanceId = appId.defaultInstance();
public static final TesterId testerId = TesterId.of(instanceId);
public static final String athenzDomain = "domain";
+ private final DeploymentContext defaultContext;
private final DeploymentTester tester;
private final JobController jobs;
private final RoutingGeneratorMock routing;
private final MockTesterCloud cloud;
private final JobRunner runner;
+ private final ReadyJobsTrigger readyJobsTrigger;
private final NameServiceDispatcher nameServiceDispatcher;
- private final AtomicLong nextPropertyId = new AtomicLong(1);
- private final AtomicInteger nextProjectId = new AtomicInteger(1);
- private final AtomicInteger nextDomainId = new AtomicInteger(100);
-
public DeploymentTester tester() { return tester; }
public JobController jobs() { return jobs; }
public RoutingGeneratorMock routing() { return routing; }
@@ -116,15 +83,16 @@ public class InternalDeploymentTester {
public InternalDeploymentTester() {
tester = new DeploymentTester();
- createApplication(instanceId.tenant().value(), instanceId.application().value(), instanceId.instance().value());
jobs = tester.controller().jobController();
routing = tester.controllerTester().serviceRegistry().routingGeneratorMock();
cloud = (MockTesterCloud) tester.controller().jobController().cloud();
- runner = new JobRunner(tester.controller(), Duration.ofDays(1), new JobControl(tester.controller().curator()),
+ var jobControl = new JobControl(tester.controller().curator());
+ runner = new JobRunner(tester.controller(), Duration.ofDays(1), jobControl,
JobRunnerTest.inThreadExecutor(), new InternalStepRunner(tester.controller()));
- this.nameServiceDispatcher = new NameServiceDispatcher(tester.controller(), Duration.ofHours(12),
- new JobControl(tester.controller().curator()),
- Integer.MAX_VALUE);
+ readyJobsTrigger = new ReadyJobsTrigger(tester.controller(), maintenanceInterval, jobControl);
+ nameServiceDispatcher = new NameServiceDispatcher(tester.controller(), maintenanceInterval, jobControl,
+ Integer.MAX_VALUE);
+ defaultContext = newDeploymentContext(instanceId);
routing.putEndpoints(new DeploymentId(null, null), Collections.emptyList()); // Turn off default behaviour for the mock.
// Get deployment job logs to stderr.
@@ -137,26 +105,41 @@ public class InternalDeploymentTester {
domain.services.put(ATHENZ_SERVICE, new AthenzDbMock.Service(true));
}
+ public ReadyJobsTrigger readyJobsTrigger() {
+ return readyJobsTrigger;
+ }
+
+ public NameServiceDispatcher nameServiceDispatcher() {
+ return nameServiceDispatcher;
+ }
+
+ /** Returns the default deployment context owned by this */
+ public DeploymentContext deploymentContext() {
+ return defaultContext;
+ }
+
+ /** Create a new deployment context for given application */
+ public DeploymentContext newDeploymentContext(String tenantName, String applicationName, String instanceName) {
+ return newDeploymentContext(ApplicationId.from(tenantName, applicationName, instanceName));
+ }
+
+ /** Create a new deployment context for given application */
+ public DeploymentContext newDeploymentContext(ApplicationId instance) {
+ return new DeploymentContext(instance, this);
+ }
+
/** Create a new application with given tenant and application name */
public Application createApplication(String tenantName, String applicationName, String instanceName) {
- return tester.controllerTester().createApplication(tester.controllerTester().createTenant(tenantName,
- athenzDomain + nextDomainId.getAndIncrement(),
- nextPropertyId.getAndIncrement()),
- applicationName,
- instanceName,
- nextProjectId.getAndIncrement());
+ return newDeploymentContext(tenantName, applicationName, instanceName).application();
}
/** Submits a new application, and returns the version of the new submission. */
- public ApplicationVersion newSubmission(TenantAndApplicationId id, ApplicationPackage applicationPackage,
- SourceRevision revision, String authorEmail, long projectId) {
- return jobs.submit(id, revision, authorEmail, projectId, applicationPackage, new byte[0]);
+ public ApplicationVersion newSubmission(TenantAndApplicationId id, ApplicationPackage applicationPackage, SourceRevision sourceRevision) {
+ return newDeploymentContext(id.defaultInstance()).submit(applicationPackage, sourceRevision).lastSubmission().get();
}
- /** Submits a new application, and returns the version of the new submission. */
public ApplicationVersion newSubmission(TenantAndApplicationId id, ApplicationPackage applicationPackage) {
- var projectId = tester.application(id).projectId().orElseThrow(() -> new IllegalArgumentException("No project ID set for " + id));
- return newSubmission(id, applicationPackage, BuildJob.defaultSourceRevision, "a@b", projectId);
+ return newSubmission(id, applicationPackage, BuildJob.defaultSourceRevision);
}
/**
@@ -170,45 +153,14 @@ public class InternalDeploymentTester {
* Submits a new application, and returns the version of the new submission.
*/
public ApplicationVersion newSubmission() {
- return newSubmission(appId, tester.controller().system().isPublic() ? publicCdApplicationPackage : applicationPackage);
+ return defaultContext.submit().lastSubmission().get();
}
/**
* Sets a single endpoint in the routing mock; this matches that required for the tester.
*/
public void setEndpoints(ApplicationId id, ZoneId zone) {
- routing.putEndpoints(new DeploymentId(id, zone),
- Collections.singletonList(new RoutingEndpoint(String.format("https://%s--%s--%s.%s.%s.vespa:43",
- id.instance().value(),
- id.application().value(),
- id.tenant().value(),
- zone.region().value(),
- zone.environment().value()),
- "host1",
- false,
- String.format("cluster1.%s.%s.%s.%s",
- id.application().value(),
- id.tenant().value(),
- zone.region().value(),
- zone.environment().value()))));
- }
-
- /** Runs and returns all remaining jobs for the application, at most once, and asserts the current change is rolled out. */
- public List<JobType> completeRollout(TenantAndApplicationId id) {
- tester.readyJobTrigger().run();
- Set<JobType> jobs = new HashSet<>();
- List<Run> activeRuns;
- while ( ! (activeRuns = jobs().active(id)).isEmpty())
- for (Run run : activeRuns)
- if (jobs.add(run.id().type())) {
- runJob(run.id().job());
- tester.readyJobTrigger().run();
- }
- else
- throw new AssertionError("Job '" + run.id().type() + "' was run twice for '" + instanceId + "'");
-
- assertFalse("Change should have no targets, but was " + application().change(), application().change().hasTargets());
- return List.copyOf(jobs);
+ newDeploymentContext(id).setEndpoints(zone);
}
/** Completely deploys the given application version, assuming it is the last to be submitted. */
@@ -218,13 +170,15 @@ public class InternalDeploymentTester {
/** Completely deploys the given application version, assuming it is the last to be submitted. */
public void deployNewSubmission(TenantAndApplicationId id, ApplicationVersion version) {
- assertFalse(tester.application(id).instances().values().stream()
- .anyMatch(instance -> instance.deployments().values().stream()
- .anyMatch(deployment -> deployment.applicationVersion().equals(version))));
- assertEquals(version, tester.application(id).change().application().get());
- assertFalse(tester.application(id).change().platform().isPresent());
- completeRollout(id);
- assertFalse(tester.application(id).change().hasTargets());
+ var context = newDeploymentContext(id.defaultInstance());
+ var application = context.application();
+ assertFalse(application.instances().values().stream()
+ .anyMatch(instance -> instance.deployments().values().stream()
+ .anyMatch(deployment -> deployment.applicationVersion().equals(version))));
+ assertEquals(version, application.change().application().get());
+ assertFalse(application.change().platform().isPresent());
+ context.completeRollout();
+ assertFalse(context.application().change().hasTargets());
}
/** Completely deploys the given, new platform. */
@@ -234,340 +188,62 @@ public class InternalDeploymentTester {
/** Completely deploys the given, new platform. */
public void deployNewPlatform(TenantAndApplicationId id, Version version) {
- assertEquals(tester.controller().systemVersion(), version);
- assertFalse(tester.application(id).instances().values().stream()
- .anyMatch(instance -> instance.deployments().values().stream()
- .anyMatch(deployment -> deployment.version().equals(version))));
- assertEquals(version, tester.application(id).change().platform().get());
- assertFalse(tester.application(id).change().application().isPresent());
-
- completeRollout(id);
-
- assertTrue(tester.application(id).productionDeployments().values().stream()
- .allMatch(deployments -> deployments.stream()
- .allMatch(deployment -> deployment.version().equals(version))));
-
- for (JobType type : new DeploymentSteps(application().deploymentSpec(), tester.controller()::system).productionJobs())
- assertTrue(tester.configServer().nodeRepository()
- .list(type.zone(tester.controller().system()), id.defaultInstance()).stream() // TODO jonmv: support more
- .allMatch(node -> node.currentVersion().equals(version)));
-
- assertFalse(tester.application(id).change().hasTargets());
+ newDeploymentContext(id.defaultInstance()).deployPlatform(version);
}
public void triggerJobs() {
tester.triggerUntilQuiescence();
}
- /** Returns the current run for the given job type, and verifies it is still running normally. */
- public Run currentRun(JobId job) {
- Run run = jobs.last(job)
- .filter(r -> r.id().type() == job.type())
- .orElseThrow(() -> new AssertionError(job.type() + " is not among the active: " + jobs.active()));
- assertFalse(run.hasFailed());
- assertFalse(run.hasEnded());
- return run;
- }
-
- /** Deploys tester and real app, and completes initial staging installation first if needed. */
- public void doDeploy(JobType type) {
- doDeploy(new JobId(instanceId, type));
- }
-
- /** Deploys tester and real app, and completes initial staging installation first if needed. */
- public void doDeploy(ApplicationId instanceId, JobType type) {
- doDeploy(new JobId(instanceId, type));
- }
-
- /** Deploys tester and real app, and completes initial staging installation first if needed. */
- public void doDeploy(JobId job) {
- RunId id = currentRun(job).id();
- ZoneId zone = job.type().zone(tester.controller().system());
- DeploymentId deployment = new DeploymentId(job.application(), zone);
-
- // First steps are always deployments.
- runner.advance(currentRun(job));
-
- if (job.type() == JobType.stagingTest) { // Do the initial deployment and installation of the real application.
- assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installInitialReal));
- Versions versions = currentRun(job).versions();
- tester.configServer().nodeRepository().doUpgrade(deployment, Optional.empty(), versions.sourcePlatform().orElse(versions.targetPlatform()));
- tester.configServer().convergeServices(id.application(), zone);
- setEndpoints(id.application(), zone);
- runner.advance(currentRun(job));
- assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installInitialReal));
- }
- }
-
- /** Upgrades nodes to target version. */
- public void doUpgrade(JobType type) {
- doUpgrade(new JobId(instanceId, type));
- }
-
- /** Upgrades nodes to target version. */
- public void doUpgrade(ApplicationId instanceId, JobType type) {
- doUpgrade(new JobId(instanceId, type));
- }
-
- /** Upgrades nodes to target version. */
- public void doUpgrade(JobId job) {
- RunId id = currentRun(job).id();
- ZoneId zone = job.type().zone(tester.controller().system());
- DeploymentId deployment = new DeploymentId(job.application(), zone);
-
- assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installReal));
- tester.configServer().nodeRepository().doUpgrade(deployment, Optional.empty(), currentRun(job).versions().targetPlatform());
- runner.advance(currentRun(job));
- }
-
- /** Lets nodes converge on new application version. */
- public void doConverge(JobType type) {
- doConverge(new JobId(instanceId, type));
- }
-
- /** Lets nodes converge on new application version. */
- public void doConverge(ApplicationId instanceId, JobType type) {
- doConverge(new JobId(instanceId, type));
- }
-
- /** Lets nodes converge on new application version. */
- public void doConverge(JobId job) {
- RunId id = currentRun(job).id();
- ZoneId zone = job.type().zone(tester.controller().system());
-
- assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installReal));
- tester.configServer().convergeServices(id.application(), zone);
- setEndpoints(id.application(), zone);
- runner.advance(currentRun(job));
- if (job.type().environment().isManuallyDeployed()) {
- assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installReal));
- assertTrue(jobs.run(id).get().hasEnded());
- return;
- }
- assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installReal));
- }
-
- /** Installs tester and starts tests. */
- public void doInstallTester(JobType type) {
- doInstallTester(new JobId(instanceId, type));
- }
-
- /** Installs tester and starts tests. */
- public void doInstallTester(ApplicationId instanceId, JobType type) {
- doInstallTester(new JobId(instanceId, type));
- }
-
- /** Installs tester and starts tests. */
- public void doInstallTester(JobId job) {
- RunId id = currentRun(job).id();
- ZoneId zone = job.type().zone(tester.controller().system());
-
- assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installTester));
- tester.configServer().nodeRepository().doUpgrade(new DeploymentId(TesterId.of(job.application()).id(), zone), Optional.empty(), currentRun(job).versions().targetPlatform());
- runner.advance(currentRun(job));
- assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installTester));
- tester.configServer().convergeServices(TesterId.of(id.application()).id(), zone);
- runner.advance(currentRun(job));
- assertEquals(unfinished, jobs.run(id).get().steps().get(Step.installTester));
- setEndpoints(TesterId.of(id.application()).id(), zone);
- runner.advance(currentRun(job));
- }
-
- /** Completes tests with success. */
- public void doTests(JobType type) {
- doTests(new JobId(instanceId, type));
- }
-
- /** Completes tests with success. */
- public void doTests(ApplicationId instanceId, JobType type) {
- doTests(new JobId(instanceId, type));
- }
-
- /** Completes tests with success. */
- public void doTests(JobId job) {
- RunId id = currentRun(job).id();
- ZoneId zone = job.type().zone(tester.controller().system());
-
- // All installation is complete and endpoints are ready, so tests may begin.
- assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installReal));
- assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.installTester));
- assertEquals(Step.Status.succeeded, jobs.run(id).get().steps().get(Step.startTests));
-
- assertEquals(unfinished, jobs.run(id).get().steps().get(Step.endTests));
- cloud.set(TesterCloud.Status.SUCCESS);
- runner.advance(currentRun(job));
- assertTrue(jobs.run(id).get().hasEnded());
- assertFalse(jobs.run(id).get().hasFailed());
- assertEquals(job.type().isProduction(), tester.instance(job.application()).deployments().containsKey(zone));
- assertTrue(tester.configServer().nodeRepository().list(zone, TesterId.of(id.application()).id()).isEmpty());
- }
-
- /** Removes endpoints from routing layer — always call this. */
- public void doTeardown(JobType type) {
- doTeardown(new JobId(instanceId, type));
- }
-
- /** Removes endpoints from routing layer — always call this. */
- public void doTeardown(ApplicationId instanceId, JobType type) {
- doTeardown(new JobId(instanceId, type));
- }
-
- /** Removes endpoints from routing layer — always call this. */
- public void doTeardown(JobId job) {
- ZoneId zone = job.type().zone(tester.controller().system());
- DeploymentId deployment = new DeploymentId(job.application(), zone);
-
- if ( ! instance().deployments().containsKey(zone))
- routing.removeEndpoints(deployment);
- routing.removeEndpoints(new DeploymentId(TesterId.of(job.application()).id(), zone));
- }
-
/** Starts a manual deployment of the given package, and then runs the whole of the given job, successfully. */
public void runJob(ApplicationId instanceId, JobType type, ApplicationPackage applicationPackage) {
jobs.deploy(instanceId, type, Optional.empty(), applicationPackage);
- runJob(new JobId(instanceId, type));
+ newDeploymentContext(instanceId).runJob(type);
}
/** Pulls the ready job trigger, and then runs the whole of the given job, successfully. */
public void runJob(JobType type) {
- runJob(instanceId, type);
+ defaultContext.runJob(type);
}
/** Pulls the ready job trigger, and then runs the whole of the given job, successfully. */
public void runJob(ApplicationId instanceId, JobType type) {
if (type.environment().isManuallyDeployed())
throw new IllegalArgumentException("Use overload with application package for dev/perf jobs");
- runJob(new JobId(instanceId, type));
- }
-
- /** Pulls the ready job trigger, and then runs the whole of the given job, successfully. */
- private void runJob(JobId job) {
- triggerJobs();
- doDeploy(job);
- doUpgrade(job);
- doConverge(job);
- if (job.type().environment().isManuallyDeployed())
- return;
-
- doInstallTester(job);
- doTests(job);
- doTeardown(job);
- }
-
- public void jobAborted(JobType type) {
- jobAborted(new JobId(instanceId, type));
- }
-
- public void jobAborted(ApplicationId instanceId, JobType type) {
- jobAborted(new JobId(instanceId, type));
- }
-
- public void jobAborted(JobId job) {
- triggerJobs();
- RunId id = currentRun(job).id();
- runner.advance(currentRun(job));
- assertEquals(aborted, jobs.run(id).get().status());
- assertTrue(jobs.run(id).get().hasEnded());
+ newDeploymentContext(instanceId).runJob(type);
}
public void failDeployment(JobType type) {
- failDeployment(new JobId(instanceId, type));
+ defaultContext.failDeployment(type);
}
public void failDeployment(ApplicationId instanceId, JobType type) {
- failDeployment(new JobId(instanceId, type));
- }
-
- public void failDeployment(JobId job) {
- triggerJobs();
- RunId id = currentRun(job).id();
- tester.configServer().throwOnNextPrepare(new IllegalArgumentException("Exception"));
- runner.advance(currentRun(job));
- assertTrue(jobs.run(id).get().hasFailed());
- assertTrue(jobs.run(id).get().hasEnded());
- doTeardown(job);
+ newDeploymentContext(instanceId).failDeployment(type);
}
public void timeOutUpgrade(JobType type) {
- timeOutUpgrade(new JobId(instanceId, type));
+ defaultContext.timeOutUpgrade(type);
}
public void timeOutUpgrade(ApplicationId instanceId, JobType type) {
- timeOutUpgrade(new JobId(instanceId, type));
- }
-
- public void timeOutUpgrade(JobId job) {
- triggerJobs();
- RunId id = currentRun(job).id();
- doDeploy(job);
- clock().advance(InternalStepRunner.installationTimeout.plusSeconds(1));
- runner.advance(currentRun(job));
- assertTrue(jobs.run(id).get().hasFailed());
- assertTrue(jobs.run(id).get().hasEnded());
- doTeardown(job);
+ newDeploymentContext(instanceId).timeOutConvergence(type);
}
public void timeOutConvergence(JobType type) {
- timeOutConvergence(new JobId(instanceId, type));
+ defaultContext.timeOutConvergence(type);
}
public void timeOutConvergence(ApplicationId instanceId, JobType type) {
- timeOutConvergence(new JobId(instanceId, type));
- }
-
- public void timeOutConvergence(JobId job) {
- triggerJobs();
- RunId id = currentRun(job).id();
- doDeploy(job);
- doUpgrade(job);
- clock().advance(InternalStepRunner.installationTimeout.plusSeconds(1));
- runner.advance(currentRun(job));
- assertTrue(jobs.run(id).get().hasFailed());
- assertTrue(jobs.run(id).get().hasEnded());
- doTeardown(job);
+ newDeploymentContext(instanceId).timeOutConvergence(type);
}
public RunId startSystemTestTests() {
- RunId id = newRun(JobType.systemTest);
- runner.run();
- tester.configServer().convergeServices(instanceId, JobType.systemTest.zone(tester.controller().system()));
- tester.configServer().convergeServices(testerId.id(), JobType.systemTest.zone(tester.controller().system()));
- setEndpoints(instanceId, JobType.systemTest.zone(tester.controller().system()));
- setEndpoints(testerId.id(), JobType.systemTest.zone(tester.controller().system()));
- runner.run();
- assertEquals(unfinished, jobs.run(id).get().steps().get(Step.endTests));
- return id;
+ return defaultContext.startSystemTestTests();
}
/** Creates and submits a new application, and then starts the job of the given type. Use only once per test. */
public RunId newRun(JobType type) {
- assertFalse(application().internal()); // Use this only once per test.
- newSubmission();
- tester.readyJobTrigger().maintain();
-
- if (type.isProduction()) {
- runJob(new JobId(instanceId, JobType.systemTest));
- runJob(new JobId(instanceId, JobType.stagingTest));
- tester.readyJobTrigger().maintain();
- }
-
- Run run = jobs.active().stream()
- .filter(r -> r.id().type() == type)
- .findAny()
- .orElseThrow(() -> new AssertionError(type + " is not among the active: " + jobs.active()));
- return run.id();
- }
-
- static X509Certificate generateCertificate() {
- KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC, 256);
- X500Principal subject = new X500Principal("CN=subject");
- return X509CertificateBuilder.fromKeypair(keyPair,
- subject,
- Instant.now(),
- Instant.now().plusSeconds(1),
- SignatureAlgorithm.SHA512_WITH_ECDSA,
- BigInteger.valueOf(1))
- .build();
+ return defaultContext.newRun(type);
}
public void assertRunning(JobType type) {
@@ -578,11 +254,4 @@ public class InternalDeploymentTester {
assertTrue(jobs.active().stream().anyMatch(run -> run.id().application().equals(id) && run.id().type() == type));
}
- /** Flush all pending name services requests */
- public void flushDnsRequests() {
- nameServiceDispatcher.run();
- assertTrue("All name service requests dispatched",
- controller().curator().readNameServiceQueue().requests().isEmpty());
- }
-
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java
index 0188bb0e5ae..fc73af6acf7 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java
@@ -52,8 +52,8 @@ import static com.yahoo.vespa.hosted.controller.api.integration.LogEntry.Type.in
import static com.yahoo.vespa.hosted.controller.api.integration.LogEntry.Type.warning;
import static com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester.appId;
import static com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester.instanceId;
-import static com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester.applicationPackage;
-import static com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester.publicCdApplicationPackage;
+import static com.yahoo.vespa.hosted.controller.deployment.DeploymentContext.applicationPackage;
+import static com.yahoo.vespa.hosted.controller.deployment.DeploymentContext.publicCdApplicationPackage;
import static com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester.testerId;
import static com.yahoo.vespa.hosted.controller.deployment.Step.Status.failed;
import static com.yahoo.vespa.hosted.controller.deployment.Step.Status.succeeded;
@@ -93,7 +93,7 @@ public class InternalStepRunnerTest {
@Test
public void canSwitchFromScrewdriverAndBackAgain() {
// Deploys a default application package with default build number.
- tester.tester().deployCompletely(tester.application(), InternalDeploymentTester.applicationPackage);
+ tester.tester().deployCompletely(tester.application(), DeploymentContext.applicationPackage);
tester.setEndpoints(instanceId, JobType.productionUsCentral1.zone(system()));
tester.setEndpoints(instanceId, JobType.productionUsWest1.zone(system()));
tester.setEndpoints(instanceId, JobType.productionUsEast3.zone(system()));
@@ -111,11 +111,11 @@ public class InternalStepRunnerTest {
tester.jobs().unregister(appId);
try {
- tester.tester().deployCompletely(tester.application(), InternalDeploymentTester.applicationPackage, BuildJob.defaultBuildNumber + 1);
+ tester.tester().deployCompletely(tester.application(), DeploymentContext.applicationPackage, BuildJob.defaultBuildNumber + 1);
throw new IllegalStateException("Component job should get even again with build numbers to produce a change.");
}
catch (AssertionError expected) { }
- tester.tester().deployCompletely(tester.application(), InternalDeploymentTester.applicationPackage, BuildJob.defaultBuildNumber + 2);
+ tester.tester().deployCompletely(tester.application(), DeploymentContext.applicationPackage, BuildJob.defaultBuildNumber + 2);
}
@Test
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java
index 416f2ee89ad..672017bec3e 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java
@@ -12,21 +12,21 @@ import com.yahoo.vespa.hosted.controller.api.integration.certificates.Applicatio
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServer;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationStore;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ArtifactRepository;
-import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud;
import com.yahoo.vespa.hosted.controller.api.integration.dns.MemoryNameService;
import com.yahoo.vespa.hosted.controller.api.integration.dns.NameService;
import com.yahoo.vespa.hosted.controller.api.integration.entity.EntityService;
import com.yahoo.vespa.hosted.controller.api.integration.entity.MemoryEntityService;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Billing;
import com.yahoo.vespa.hosted.controller.api.integration.organization.ContactRetriever;
-import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueHandler;
import com.yahoo.vespa.hosted.controller.api.integration.organization.DeploymentIssues;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueHandler;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Mailer;
import com.yahoo.vespa.hosted.controller.api.integration.organization.MockBilling;
import com.yahoo.vespa.hosted.controller.api.integration.organization.MockContactRetriever;
import com.yahoo.vespa.hosted.controller.api.integration.organization.MockIssueHandler;
import com.yahoo.vespa.hosted.controller.api.integration.organization.OwnershipIssues;
import com.yahoo.vespa.hosted.controller.api.integration.resource.CostReportConsumer;
+import com.yahoo.vespa.hosted.controller.api.integration.resource.CostReportConsumerMock;
import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringClient;
import com.yahoo.vespa.hosted.controller.api.integration.resource.MockTenantCost;
import com.yahoo.vespa.hosted.controller.api.integration.resource.TenantCost;
@@ -41,7 +41,6 @@ import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockMailer;
import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockMeteringClient;
import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockRunDataStore;
import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockTesterCloud;
-import com.yahoo.vespa.hosted.controller.api.integration.resource.CostReportConsumerMock;
/**
* A mock implementation of a {@link ServiceRegistry} for testing purposes.
@@ -149,7 +148,7 @@ public class ServiceRegistryMock extends AbstractComponent implements ServiceReg
}
@Override
- public TesterCloud testerCloud() {
+ public MockTesterCloud testerCloud() {
return mockTesterCloud;
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java
index 68c95739ec6..18acd91969b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java
@@ -1,7 +1,6 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.maintenance;
-import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.LockedTenant;
@@ -11,6 +10,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.OwnershipIssues;
import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId;
+import com.yahoo.vespa.hosted.controller.deployment.DeploymentContext;
import com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester;
import com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb;
import com.yahoo.vespa.hosted.controller.tenant.UserTenant;
@@ -56,7 +56,7 @@ public class ApplicationOwnershipConfirmerTest {
tester.createApplication(user.name().value(), "application", "default");
TenantAndApplicationId userAppId = TenantAndApplicationId.from("by-user", "application");
Supplier<Application> userApp = () -> tester.controller().applications().requireApplication(userAppId);
- tester.deployNewSubmission(userAppId, tester.newSubmission(userAppId, InternalDeploymentTester.applicationPackage));
+ tester.deployNewSubmission(userAppId, tester.newSubmission(userAppId, DeploymentContext.applicationPackage));
assertFalse("No issue is initially stored for a new application.", propertyApp.get().ownershipIssueId().isPresent());
assertFalse("No issue is initially stored for a new application.", userApp.get().ownershipIssueId().isPresent());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java
index 24420d4590a..af6017c1188 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/MetricsReporterTest.java
@@ -7,11 +7,8 @@ import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.zone.UpgradePolicy;
import com.yahoo.config.provision.zone.ZoneId;
-import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.ControllerTester;
-import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
-import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.application.SystemApplication;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
@@ -50,23 +47,22 @@ public class MetricsReporterTest {
assertEquals(0.0, metrics.getMetric(MetricsReporter.DEPLOYMENT_FAIL_METRIC));
// Deploy all apps successfully
- Application app1 = tester.createApplication("app1", "tenant1", "default");
- Application app2 = tester.createApplication("app2", "tenant1", "default");
- Application app3 = tester.createApplication("app3", "tenant1", "default");
- Application app4 = tester.createApplication("app4", "tenant1", "default");
- var version1 = tester.newSubmission(app1.id(), applicationPackage);
- tester.deployNewSubmission(app1.id(), version1);
- tester.deployNewSubmission(app2.id(), tester.newSubmission(app2.id(), applicationPackage));
- tester.deployNewSubmission(app3.id(), tester.newSubmission(app3.id(), applicationPackage));
- tester.deployNewSubmission(app4.id(), tester.newSubmission(app4.id(), applicationPackage));
+ var context1 = tester.newDeploymentContext("app1", "tenant1", "default");
+ var context2 = tester.newDeploymentContext("app2", "tenant1", "default");
+ var context3 = tester.newDeploymentContext("app3", "tenant1", "default");
+ var context4 = tester.newDeploymentContext("app4", "tenant1", "default");
+ context1.submit(applicationPackage).deploy();
+ context2.submit(applicationPackage).deploy();
+ context3.submit(applicationPackage).deploy();
+ context4.submit(applicationPackage).deploy();
metricsReporter.maintain();
assertEquals(0.0, metrics.getMetric(MetricsReporter.DEPLOYMENT_FAIL_METRIC));
// 1 app fails system-test
- tester.newSubmission(app4.id(), applicationPackage);
- tester.triggerJobs();
- tester.failDeployment(app4.id().defaultInstance(), systemTest);
+ context1.submit(applicationPackage)
+ .triggerJobs()
+ .failDeployment(systemTest);
metricsReporter.maintain();
assertEquals(25.0, metrics.getMetric(MetricsReporter.DEPLOYMENT_FAIL_METRIC));
@@ -82,30 +78,31 @@ public class MetricsReporterTest {
MetricsReporter reporter = createReporter(tester.controller());
- Application app = tester.createApplication("app1", "tenant1", "default");
- tester.deployNewSubmission(app.id(), tester.newSubmission(app.id(), applicationPackage));
+ var context = tester.deploymentContext()
+ .submit(applicationPackage)
+ .deploy();
reporter.maintain();
- assertEquals(Duration.ZERO, getAverageDeploymentDuration(app.id().defaultInstance())); // An exceptionally fast deployment :-)
+ assertEquals(Duration.ZERO, getAverageDeploymentDuration(context.instanceId())); // An exceptionally fast deployment :-)
// App spends 3 hours deploying
- tester.newSubmission(app.id(), applicationPackage);
+ context.submit(applicationPackage);
tester.clock().advance(Duration.ofHours(1));
- tester.runJob(app.id().defaultInstance(), systemTest);
+ context.runJob(systemTest);
tester.clock().advance(Duration.ofMinutes(30));
- tester.runJob(app.id().defaultInstance(), stagingTest);
+ context.runJob(stagingTest);
tester.triggerJobs();
tester.clock().advance(Duration.ofMinutes(90));
- tester.runJob(app.id().defaultInstance(), productionUsWest1);
+ context.runJob(productionUsWest1);
reporter.maintain();
// Average time is 1 hour (system-test) + 90 minutes (staging-test runs in parallel with system-test) + 90 minutes (production) / 3 jobs
- assertEquals(Duration.ofMinutes(80), getAverageDeploymentDuration(app.id().defaultInstance()));
+ assertEquals(Duration.ofMinutes(80), getAverageDeploymentDuration(context.instanceId()));
// Another deployment starts and stalls for 12 hours
- tester.newSubmission(app.id(), applicationPackage);
- tester.triggerJobs();
+ context.submit(applicationPackage)
+ .triggerJobs();
tester.clock().advance(Duration.ofHours(12));
reporter.maintain();
@@ -113,7 +110,7 @@ public class MetricsReporterTest {
.plus(Duration.ofHours(12)) // hanging staging-test
.plus(Duration.ofMinutes(90)) // previous production job
.dividedBy(3), // Total number of orchestrated jobs
- getAverageDeploymentDuration(app.id().defaultInstance()));
+ getAverageDeploymentDuration(context.instanceId()));
}
@Test
@@ -125,47 +122,47 @@ public class MetricsReporterTest {
.build();
MetricsReporter reporter = createReporter(tester.controller());
- Application app = tester.createApplication("app1", "tenant1", "default");
+ var context = tester.deploymentContext();
// Initial deployment without failures
- tester.deployNewSubmission(app.id(), tester.newSubmission(app.id(), applicationPackage));
+ context.submit(applicationPackage).deploy();
reporter.maintain();
- assertEquals(0, getDeploymentsFailingUpgrade(app.id().defaultInstance()));
+ assertEquals(0, getDeploymentsFailingUpgrade(context.instanceId()));
// Failing application change is not counted
- var submission = tester.newSubmission(app.id(), applicationPackage);
- tester.triggerJobs();
- tester.failDeployment(app.id().defaultInstance(), systemTest);
+ context.submit(applicationPackage)
+ .triggerJobs()
+ .failDeployment(systemTest);
reporter.maintain();
- assertEquals(0, getDeploymentsFailingUpgrade(app.id().defaultInstance()));
+ assertEquals(0, getDeploymentsFailingUpgrade(context.instanceId()));
// Application change completes
- tester.deployNewSubmission(app.id(), submission);
- assertFalse("Change deployed", tester.controller().applications().requireApplication(app.id()).change().hasTargets());
+ context.deploy();
+ assertFalse("Change deployed", context.application().change().hasTargets());
// New versions is released and upgrade fails in test environments
Version version = Version.fromString("7.1");
tester.controllerTester().upgradeSystem(version);
tester.upgrader().maintain();
- tester.triggerJobs();
- tester.failDeployment(app.id().defaultInstance(), systemTest);
- tester.failDeployment(app.id().defaultInstance(), stagingTest);
+ context.triggerJobs()
+ .failDeployment(systemTest)
+ .failDeployment(stagingTest);
reporter.maintain();
- assertEquals(2, getDeploymentsFailingUpgrade(app.id().defaultInstance()));
+ assertEquals(2, getDeploymentsFailingUpgrade(context.instanceId()));
// Test and staging pass and upgrade fails in production
- tester.runJob(app.id().defaultInstance(), systemTest);
- tester.runJob(app.id().defaultInstance(), stagingTest);
- tester.triggerJobs();
- tester.failDeployment(app.id().defaultInstance(), productionUsWest1);
+ context.runJob(systemTest)
+ .runJob(stagingTest)
+ .triggerJobs()
+ .failDeployment(productionUsWest1);
reporter.maintain();
- assertEquals(1, getDeploymentsFailingUpgrade(app.id().defaultInstance()));
+ assertEquals(1, getDeploymentsFailingUpgrade(context.instanceId()));
// Upgrade eventually succeeds
- tester.runJob(app.id().defaultInstance(), productionUsWest1);
- assertFalse("Upgrade deployed", tester.controller().applications().requireApplication(app.id()).change().hasTargets());
+ context.runJob(productionUsWest1);
+ assertFalse("Upgrade deployed", context.application().change().hasTargets());
reporter.maintain();
- assertEquals(0, getDeploymentsFailingUpgrade(app.id().defaultInstance()));
+ assertEquals(0, getDeploymentsFailingUpgrade(context.instanceId()));
}
@Test
@@ -177,25 +174,27 @@ public class MetricsReporterTest {
.region("us-east-3")
.build();
MetricsReporter reporter = createReporter(tester.controller());
- Application application = tester.createApplication("app1", "tenant1", "default");
- tester.configServer().generateWarnings(new DeploymentId(application.id().defaultInstance(), ZoneId.from("prod", "us-west-1")), 3);
- tester.configServer().generateWarnings(new DeploymentId(application.id().defaultInstance(), ZoneId.from("prod", "us-east-3")), 4);
- tester.deployNewSubmission(application.id(), tester.newSubmission(application.id(), applicationPackage));
+ var context = tester.deploymentContext();
+ tester.configServer().generateWarnings(context.deploymentIdIn(ZoneId.from("prod", "us-west-1")), 3);
+ tester.configServer().generateWarnings(context.deploymentIdIn(ZoneId.from("prod", "us-west-1")), 4);
+ context.submit(applicationPackage).deploy();
reporter.maintain();
- assertEquals(4, getDeploymentWarnings(application.id().defaultInstance()));
+ assertEquals(4, getDeploymentWarnings(context.instanceId()));
}
@Test
public void build_time_reporting() {
var tester = new InternalDeploymentTester();
- ApplicationVersion version = tester.newSubmission();
- tester.deployNewSubmission(version);
- assertEquals(1000, version.buildTime().get().toEpochMilli());
+ var applicationPackage = new ApplicationPackageBuilder().region("us-west-1").build();
+ var context = tester.deploymentContext()
+ .submit(applicationPackage)
+ .deploy();
+ assertEquals(1000, context.lastSubmission().get().buildTime().get().toEpochMilli());
MetricsReporter reporter = createReporter(tester.tester().controller());
reporter.maintain();
assertEquals(tester.clock().instant().getEpochSecond() - 1,
- getMetric(MetricsReporter.DEPLOYMENT_BUILD_AGE_SECONDS, tester.instance().id()));
+ getMetric(MetricsReporter.DEPLOYMENT_BUILD_AGE_SECONDS, context.instanceId()));
}
@Test
@@ -208,15 +207,16 @@ public class MetricsReporterTest {
.region("us-east-3")
.build();
MetricsReporter reporter = createReporter(tester.controller());
- Application application = tester.createApplication("app1", "tenant1", "default");
+ var context = tester.deploymentContext()
+ .deferDnsUpdates();
reporter.maintain();
assertEquals("Queue is empty initially", 0, metrics.getMetric(MetricsReporter.NAME_SERVICE_REQUESTS_QUEUED).intValue());
- tester.deployNewSubmission(application.id(), tester.newSubmission(application.id(), applicationPackage));
+ context.submit(applicationPackage).deploy();
reporter.maintain();
assertEquals("Deployment queues name services requests", 6, metrics.getMetric(MetricsReporter.NAME_SERVICE_REQUESTS_QUEUED).intValue());
- tester.flushDnsRequests();
+ context.flushDnsUpdates();
reporter.maintain();
assertEquals("Queue consumed", 0, metrics.getMetric(MetricsReporter.NAME_SERVICE_REQUESTS_QUEUED).intValue());
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OutstandingChangeDeployerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OutstandingChangeDeployerTest.java
index 92ee2a2ebdb..0a6d5d7698d 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OutstandingChangeDeployerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OutstandingChangeDeployerTest.java
@@ -5,14 +5,11 @@ import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
import com.yahoo.vespa.hosted.controller.Application;
-import com.yahoo.vespa.hosted.controller.Instance;
-import com.yahoo.vespa.hosted.controller.api.integration.BuildService;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.application.Change;
-import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
-import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
import com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester;
import com.yahoo.vespa.hosted.controller.deployment.Run;
import com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb;
@@ -20,7 +17,6 @@ import org.junit.Test;
import java.time.Duration;
import java.util.List;
-import java.util.Optional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -52,8 +48,7 @@ public class OutstandingChangeDeployerTest {
assertFalse(tester.application(app1.id()).outstandingChange().hasTargets());
assertEquals(1, tester.application(app1.id()).latestVersion().get().buildNumber().getAsLong());
- tester.newSubmission(app1.id(), applicationPackage, new SourceRevision("repository1","master", "cafed00d"),
- "author@domain", app1.projectId().getAsLong());
+ tester.newSubmission(app1.id(), applicationPackage, new SourceRevision("repository1", "master", "cafed00d"));
ApplicationId instanceId = app1.id().defaultInstance();
assertTrue(tester.application(app1.id()).outstandingChange().hasTargets());
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 184f75bfd18..1105a478e14 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
@@ -34,7 +34,7 @@ import static com.yahoo.vespa.hosted.controller.api.integration.deployment.JobTy
import static com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType.systemTest;
import static com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud.Status.FAILURE;
import static com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester.instanceId;
-import static com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester.applicationPackage;
+import static com.yahoo.vespa.hosted.controller.deployment.DeploymentContext.applicationPackage;
import static com.yahoo.vespa.hosted.controller.deployment.InternalDeploymentTester.testerId;
import static com.yahoo.vespa.hosted.controller.deployment.RunStatus.deploymentFailed;
import static com.yahoo.vespa.hosted.controller.deployment.RunStatus.installationFailed;
@@ -56,7 +56,7 @@ public class JobControllerApiHandlerHelperTest {
// Revision 1 gets deployed everywhere.
ApplicationVersion revision1 = tester.newSubmission();
tester.deployNewSubmission(revision1);
- assertEquals(1, tester.application().projectId().getAsLong());
+ assertEquals(1000, tester.application().projectId().getAsLong());
tester.clock().advance(Duration.ofMillis(1000));
// Revision 2 gets deployed everywhere except in us-east-3.