summaryrefslogtreecommitdiffstats
path: root/controller-server/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'controller-server/src/test/java')
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java31
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunnerTest.java11
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterUtilizationMaintainerTest.java35
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainerTest.java37
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainerTest.java166
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java48
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-deployment.json2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java2
9 files changed, 184 insertions, 151 deletions
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 53ab488949e..db58ef1830f 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
@@ -526,6 +526,37 @@ public class DeploymentTriggerTest {
}
@Test
+ public void testJobPause() {
+ Application app = tester.createAndDeploy("app", 3, "default");
+ tester.upgradeSystem(new Version("9.8.7"));
+
+ tester.applications().deploymentTrigger().pauseJob(app.id(), productionUsWest1, tester.clock().instant().plus(Duration.ofSeconds(1)));
+ tester.applications().deploymentTrigger().pauseJob(app.id(), productionUsEast3, tester.clock().instant().plus(Duration.ofSeconds(3)));
+
+ // us-west-1 does not trigger when paused.
+ tester.deployAndNotify(app, true, systemTest);
+ tester.deployAndNotify(app, true, stagingTest);
+ tester.assertNotRunning(productionUsWest1, app.id());
+
+ // us-west-1 triggers when no longer paused, but does not retry when paused again.
+ tester.clock().advance(Duration.ofMillis(1500));
+ tester.readyJobTrigger().run();
+ tester.assertRunning(productionUsWest1, app.id());
+ tester.applications().deploymentTrigger().pauseJob(app.id(), productionUsWest1, tester.clock().instant().plus(Duration.ofSeconds(1)));
+ tester.deployAndNotify(app, false, productionUsWest1);
+ tester.assertNotRunning(productionUsWest1, app.id());
+ tester.clock().advance(Duration.ofMillis(1000));
+ tester.readyJobTrigger().run();
+ tester.deployAndNotify(app, true, productionUsWest1);
+
+ // us-east-3 does not automatically trigger when paused, but does when forced.
+ tester.assertNotRunning(productionUsEast3, app.id());
+ tester.deploymentTrigger().forceTrigger(app.id(), productionUsEast3, "mrTrigger");
+ tester.assertRunning(productionUsEast3, app.id());
+ assertFalse(tester.application(app.id()).deploymentJobs().jobStatus().get(productionUsEast3).pausedUntil().isPresent());
+ }
+
+ @Test
public void testUpgradingButNoJobStarted() {
ReadyJobsTrigger readyJobsTrigger = new ReadyJobsTrigger(tester.controller(),
Duration.ofHours(1),
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 b87458e6ecf..e1a557f26f1 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
@@ -43,6 +43,7 @@ import static com.yahoo.vespa.hosted.controller.deployment.Step.Status.succeeded
import static com.yahoo.vespa.hosted.controller.deployment.Step.Status.unfinished;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* @author jonmv
@@ -65,7 +66,7 @@ public class InternalStepRunnerTest {
}
@Test
- public void canSwitchFromScrewdriver() {
+ public void canSwitchFromScrewdriverAndBackAgain() {
// Deploys a default application package with default build number.
tester.tester().deployCompletely(tester.app(), InternalDeploymentTester.applicationPackage);
tester.setEndpoints(InternalDeploymentTester.appId, JobType.productionUsCentral1.zone(tester.tester().controller().system()));
@@ -75,6 +76,14 @@ public class InternalStepRunnerTest {
tester.deployNewSubmission();
tester.deployNewPlatform(new Version("7.1"));
+
+ tester.jobs().unregister(InternalDeploymentTester.appId);
+ try {
+ tester.tester().deployCompletely(tester.app(), InternalDeploymentTester.applicationPackage, BuildJob.defaultBuildNumber + 1);
+ throw new IllegalStateException("Component job should get ahead again with build numbers to produce a change.");
+ }
+ catch (AssertionError expected) { }
+ tester.tester().deployCompletely(tester.app(), InternalDeploymentTester.applicationPackage, BuildJob.defaultBuildNumber + 2);
}
@Test
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterUtilizationMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterUtilizationMaintainerTest.java
index 71d2690bb4a..66be2d09797 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterUtilizationMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterUtilizationMaintainerTest.java
@@ -3,45 +3,24 @@ package com.yahoo.vespa.hosted.controller.maintenance;
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
-import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
-import com.github.tomakehurst.wiremock.verification.LoggedRequest;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.vespa.hosted.controller.ControllerTester;
import com.yahoo.vespa.hosted.controller.application.Deployment;
-import com.yahoo.vespa.hosted.controller.authority.config.ApiAuthorityConfig;
import com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb;
import org.junit.Assert;
-import org.junit.Rule;
import org.junit.Test;
import java.time.Duration;
-import java.util.List;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.findAll;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.getAllServeEvents;
-import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
-import static com.github.tomakehurst.wiremock.client.WireMock.post;
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
-import static org.junit.Assert.assertEquals;
/**
* @author smorgrav
*/
public class ClusterUtilizationMaintainerTest {
- @Rule
- public WireMockRule wireMockRule = new WireMockRule(4443);
-
@Test
public void maintain() {
- wireMockRule.stubFor(post(urlEqualTo("/metricforwarding/v1/clusterutilization"))
- .willReturn(aResponse().withStatus(200)));
ControllerTester tester = new ControllerTester();
ApplicationId app = tester.createAndDeploy("tenant1", "domain1", "app1", Environment.dev, 123).id();
@@ -49,16 +28,12 @@ public class ClusterUtilizationMaintainerTest {
Deployment deployment = tester.controller().applications().get(app).get().deployments().values().stream().findAny().get();
Assert.assertEquals(0, deployment.clusterUtils().size());
- ApiAuthorityConfig.Builder apiAuthorityConfigBuilder = new ApiAuthorityConfig.Builder().authorities("http://localhost:4443/");
- ApiAuthorityConfig apiAuthorityConfig = new ApiAuthorityConfig(apiAuthorityConfigBuilder);
- ClusterUtilizationMaintainer maintainer = new ClusterUtilizationMaintainer(tester.controller(), Duration.ofHours(1), new JobControl(new MockCuratorDb()), apiAuthorityConfig);
- maintainer.maintain();
+ ClusterUtilizationMaintainer mainainer = new ClusterUtilizationMaintainer(tester.controller(), Duration.ofHours(1), new JobControl(new MockCuratorDb()));
+ mainainer.maintain();
- List<ServeEvent> allServeEvents = getAllServeEvents();
- assertEquals(allServeEvents.size(), 1);
- LoggedRequest request = findAll(postRequestedFor(urlEqualTo("/metricforwarding/v1/clusterutilization"))).get(0);
- String expectedBody = "[{\"applicationId\":\"tenant1:app1:default\",\"deployments\":[{\"zoneId\":\"dev.us-east-1\",\"clusterUtil\":[{\"clusterSpecId\":\"default\",\"cpu\":0.5554,\"memory\":0.6990000000000001,\"disk\":0.34590000000000004,\"diskBusy\":0.0}]}]}]";
- assertEquals(expectedBody, new String(request.getBody()));
+ deployment = tester.controller().applications().get(app).get().deployments().values().stream().findAny().get();
+ Assert.assertEquals(1, deployment.clusterUtils().size());
+ Assert.assertEquals(0.5554, deployment.clusterUtils().get(ClusterSpec.Id.from("default")).getCpu(), Double.MIN_VALUE);
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainerTest.java
index a46215eaf22..cbaa37b15e3 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ContactInformationMaintainerTest.java
@@ -1,17 +1,13 @@
// 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.github.tomakehurst.wiremock.junit.WireMockRule;
-import com.github.tomakehurst.wiremock.verification.LoggedRequest;
import com.yahoo.config.provision.TenantName;
import com.yahoo.vespa.hosted.controller.ControllerTester;
-import com.yahoo.vespa.hosted.controller.authority.config.ApiAuthorityConfig;
import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
import com.yahoo.vespa.hosted.controller.tenant.AthenzTenant;
import com.yahoo.vespa.hosted.controller.tenant.Contact;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import java.net.URI;
@@ -22,16 +18,9 @@ import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.findAll;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
-import static com.github.tomakehurst.wiremock.client.WireMock.post;
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
-import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
* @author mpolden
@@ -40,27 +29,13 @@ public class ContactInformationMaintainerTest {
private ControllerTester tester;
private ContactInformationMaintainer maintainer;
- private String contactInfoPath = "/contactinfo/v1/tenant/tenant1";
- private String tenantPath = "/application/v4/tenant/";
-
- @Rule
- public WireMockRule wireMockRule = new WireMockRule(4443);
-
@Before
public void before() {
tester = new ControllerTester();
- ApiAuthorityConfig.Builder apiAuthorityConfigBuilder = new ApiAuthorityConfig.Builder().authorities("http://localhost:4443/");
- ApiAuthorityConfig apiAuthorityConfig = new ApiAuthorityConfig(apiAuthorityConfigBuilder);
maintainer = new ContactInformationMaintainer(tester.controller(), Duration.ofDays(1),
new JobControl(tester.controller().curator()),
- tester.organization(), apiAuthorityConfig);
- wireMockRule.stubFor(post(urlEqualTo(contactInfoPath))
- .willReturn(aResponse().withStatus(200)));
- wireMockRule.stubFor(get(urlEqualTo(tenantPath))
- .willReturn(okJson("[{\"tenant\":\"tenant1\"}]")));
- wireMockRule.stubFor(get(urlEqualTo(tenantPath + "tenant1"))
- .willReturn(okJson("{\"tenant\":\"tenant1\", \"athensDomain\":\"domain\", \"property\":\"property\", \"propertyId\":\"1\"}")));
+ tester.organization());
}
@Test
@@ -69,13 +44,13 @@ public class ContactInformationMaintainerTest {
TenantName name = tester.createTenant("tenant1", "domain1", propertyId);
Supplier<AthenzTenant> tenant = () -> tester.controller().tenants().requireAthenzTenant(name);
assertFalse("No contact information initially", tenant.get().contact().isPresent());
+
Contact contact = testContact();
registerContact(propertyId, contact);
maintainer.run();
- verify(1, postRequestedFor(urlEqualTo(contactInfoPath)));
- LoggedRequest request = findAll(postRequestedFor(urlEqualTo(contactInfoPath))).get(0);
- String expectedBody = "{\"url\":\"http://contact1.test\",\"issueTrackerUrl\":\"http://issue-tracker1.test\",\"propertyUrl\":\"http://property1.test\",\"persons\":[[\"alice\"],[\"bob\"]]}";
- assertEquals(expectedBody, new String(request.getBody()));
+
+ assertTrue("Contact information added", tenant.get().contact().isPresent());
+ assertEquals(contact, tenant.get().contact().get());
}
private void registerContact(long propertyId, Contact contact) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainerTest.java
index 5014f796933..e11440a372c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainerTest.java
@@ -1,38 +1,27 @@
// 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.github.tomakehurst.wiremock.junit.WireMockRule;
-import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
-import com.github.tomakehurst.wiremock.verification.LoggedRequest;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
-import com.yahoo.slime.ArrayTraverser;
-import com.yahoo.slime.Inspector;
-import com.yahoo.slime.Slime;
-import com.yahoo.vespa.config.SlimeUtils;
import com.yahoo.vespa.hosted.controller.Application;
-import com.yahoo.vespa.hosted.controller.api.integration.MetricsService;
+import com.yahoo.vespa.hosted.controller.Controller;
+import com.yahoo.vespa.hosted.controller.ControllerTester;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
-import com.yahoo.vespa.hosted.controller.authority.config.ApiAuthorityConfig;
+import com.yahoo.vespa.hosted.controller.application.Deployment;
+import com.yahoo.vespa.hosted.controller.application.RotationStatus;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
import com.yahoo.vespa.hosted.controller.integration.MetricsServiceMock;
-import org.junit.Rule;
import org.junit.Test;
import java.time.Duration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.findAll;
-import static com.github.tomakehurst.wiremock.client.WireMock.getAllServeEvents;
-import static com.github.tomakehurst.wiremock.client.WireMock.post;
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
-import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
+import java.time.Instant;
+import java.util.function.Supplier;
+
+import static java.time.temporal.ChronoUnit.MILLIS;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
/**
* @author smorgrav
@@ -40,18 +29,69 @@ import static org.junit.Assert.assertEquals;
*/
public class DeploymentMetricsMaintainerTest {
- private static final double DELTA = 0.0000001;
-
- @Rule
- public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort(), true);
+ @Test
+ public void updates_metrics() {
+ ControllerTester tester = new ControllerTester();
+ ApplicationId appId = tester.createAndDeploy("tenant1", "domain1", "app1",
+ Environment.dev, 123).id();
+ DeploymentMetricsMaintainer maintainer = maintainer(tester.controller());
+ Supplier<Application> app = tester.application(appId);
+ Supplier<Deployment> deployment = () -> app.get().deployments().values().stream().findFirst().get();
+
+ // No metrics gathered yet
+ assertEquals(0, app.get().metrics().queryServiceQuality(), 0);
+ assertEquals(0, deployment.get().metrics().documentCount(), 0);
+ assertFalse("Never received any queries", deployment.get().activity().lastQueried().isPresent());
+ assertFalse("Never received any writes", deployment.get().activity().lastWritten().isPresent());
+
+ // Metrics are gathered and saved to application
+ maintainer.maintain();
+ assertEquals(0.5, app.get().metrics().queryServiceQuality(), Double.MIN_VALUE);
+ assertEquals(0.7, app.get().metrics().writeServiceQuality(), Double.MIN_VALUE);
+ assertEquals(1, deployment.get().metrics().queriesPerSecond(), Double.MIN_VALUE);
+ assertEquals(2, deployment.get().metrics().writesPerSecond(), Double.MIN_VALUE);
+ assertEquals(3, deployment.get().metrics().documentCount(), Double.MIN_VALUE);
+ assertEquals(4, deployment.get().metrics().queryLatencyMillis(), Double.MIN_VALUE);
+ assertEquals(5, deployment.get().metrics().writeLatencyMillis(), Double.MIN_VALUE);
+ Instant t1 = tester.clock().instant().truncatedTo(MILLIS);
+ assertEquals(t1, deployment.get().activity().lastQueried().get());
+ assertEquals(t1, deployment.get().activity().lastWritten().get());
+
+ // Time passes. Activity is updated as app is still receiving traffic
+ tester.clock().advance(Duration.ofHours(1));
+ Instant t2 = tester.clock().instant().truncatedTo(MILLIS);
+ maintainer.maintain();
+ assertEquals(t2, deployment.get().activity().lastQueried().get());
+ assertEquals(t2, deployment.get().activity().lastWritten().get());
+ assertEquals(1, deployment.get().activity().lastQueriesPerSecond().getAsDouble(), Double.MIN_VALUE);
+ assertEquals(2, deployment.get().activity().lastWritesPerSecond().getAsDouble(), Double.MIN_VALUE);
+
+ // Query traffic disappears. Query activity stops updating
+ tester.clock().advance(Duration.ofHours(1));
+ Instant t3 = tester.clock().instant().truncatedTo(MILLIS);
+ tester.metricsService().setMetric("queriesPerSecond", 0D);
+ tester.metricsService().setMetric("writesPerSecond", 5D);
+ maintainer.maintain();
+ assertEquals(t2, deployment.get().activity().lastQueried().get());
+ assertEquals(t3, deployment.get().activity().lastWritten().get());
+ assertEquals(1, deployment.get().activity().lastQueriesPerSecond().getAsDouble(), Double.MIN_VALUE);
+ assertEquals(5, deployment.get().activity().lastWritesPerSecond().getAsDouble(), Double.MIN_VALUE);
+
+ // Feed traffic disappears. Feed activity stops updating
+ tester.clock().advance(Duration.ofHours(1));
+ tester.metricsService().setMetric("writesPerSecond", 0D);
+ maintainer.maintain();
+ assertEquals(t2, deployment.get().activity().lastQueried().get());
+ assertEquals(t3, deployment.get().activity().lastWritten().get());
+ assertEquals(1, deployment.get().activity().lastQueriesPerSecond().getAsDouble(), Double.MIN_VALUE);
+ assertEquals(5, deployment.get().activity().lastWritesPerSecond().getAsDouble(), Double.MIN_VALUE);
+ }
@Test
- public void maintain() {
+ public void updates_rotation_status() {
DeploymentTester tester = new DeploymentTester();
MetricsServiceMock metricsService = tester.controllerTester().metricsService();
- ApiAuthorityConfig.Builder apiAuthorityConfigBuilder = new ApiAuthorityConfig.Builder().authorities("http://localhost:" + wireMockRule.port() + "/");
- ApiAuthorityConfig apiAuthorityConfig = new ApiAuthorityConfig(apiAuthorityConfigBuilder);
- DeploymentMetricsMaintainer maintainer = new DeploymentMetricsMaintainer(tester.controller(), Duration.ofDays(1), new JobControl(tester.controller().curator()), apiAuthorityConfig);
+ DeploymentMetricsMaintainer maintainer = maintainer(tester.controller());
Application application = tester.createApplication("app1", "tenant1", 1, 1L);
ZoneId zone1 = ZoneId.from("prod", "us-west-1");
ZoneId zone2 = ZoneId.from("prod", "us-east-3");
@@ -65,68 +105,32 @@ public class DeploymentMetricsMaintainerTest {
.build();
tester.deployCompletely(application, applicationPackage);
+ Supplier<Application> app = () -> tester.application(application.id());
+ Supplier<Deployment> deployment1 = () -> app.get().deployments().get(zone1);
+ Supplier<Deployment> deployment2 = () -> app.get().deployments().get(zone2);
String assignedRotation = "rotation-fqdn-01";
tester.controllerTester().metricsService().addRotation(assignedRotation);
+ // No status gathered yet
+ assertEquals(RotationStatus.unknown, app.get().rotationStatus(deployment1.get()));
+ assertEquals(RotationStatus.unknown, app.get().rotationStatus(deployment2.get()));
+
// One rotation out, one in
metricsService.setZoneIn(assignedRotation, "proxy.prod.us-west-1.vip.test");
metricsService.setZoneOut(assignedRotation,"proxy.prod.us-east-3.vip.test");
-
- wireMockRule.stubFor(post(urlEqualTo("/metricforwarding/v1/deploymentmetrics/"))
- .willReturn(aResponse().withStatus(200)));
maintainer.maintain();
+ assertEquals(RotationStatus.in, app.get().rotationStatus(deployment1.get()));
+ assertEquals(RotationStatus.out, app.get().rotationStatus(deployment2.get()));
- List<ServeEvent> allServeEvents = getAllServeEvents();
- assertEquals(1, allServeEvents.size());
- LoggedRequest request = findAll(postRequestedFor(urlEqualTo("/metricforwarding/v1/deploymentmetrics/"))).get(0);
-
- Slime slime = SlimeUtils.jsonToSlime(request.getBody());
- Inspector inspector = slime.get().entry(0);
- assertEquals("tenant1:app1:default", inspector.field("applicationId").asString());
- MetricsService.ApplicationMetrics applicationMetrics = applicationMetricsFromInspector(inspector.field("applicationMetrics"));
- assertEquals(0.5, applicationMetrics.queryServiceQuality(), DELTA);
- assertEquals(0.7, applicationMetrics.writeServiceQuality(), DELTA);
-
- Map<String, String> rotationStatus = rotationsStatusFromInspector(inspector.field("rotationStatus"));
- assertEquals("in", rotationStatus.get("proxy.prod.us-west-1.vip.test"));
- assertEquals("out", rotationStatus.get("proxy.prod.us-east-3.vip.test"));
-
- Map<String, MetricsService.DeploymentMetrics> deploymentMetricsByZone = deploymentMetricsFromInspector(inspector.field("deploymentMetrics"));
- MetricsService.DeploymentMetrics deploymentMetrics = deploymentMetricsByZone.get("prod.us-west-1");
- assertEquals(1.0, deploymentMetrics.queriesPerSecond(), DELTA);
- assertEquals(2.0, deploymentMetrics.writesPerSecond(), DELTA);
- assertEquals(3.0, deploymentMetrics.documentCount(), DELTA);
- assertEquals(4.0, deploymentMetrics.queryLatencyMillis(), DELTA);
- assertEquals(5.0, deploymentMetrics.writeLatencyMillis(), DELTA);
-
- deploymentMetrics = deploymentMetricsByZone.get("prod.us-east-3");
- assertEquals(1.0, deploymentMetrics.queriesPerSecond(), DELTA);
- assertEquals(2.0, deploymentMetrics.writesPerSecond(), DELTA);
- assertEquals(3.0, deploymentMetrics.documentCount(), DELTA);
- assertEquals(4.0, deploymentMetrics.queryLatencyMillis(), DELTA);
- assertEquals(5.0, deploymentMetrics.writeLatencyMillis(), DELTA);
- }
-
- private MetricsService.ApplicationMetrics applicationMetricsFromInspector(Inspector inspector) {
- return new MetricsService.ApplicationMetrics(inspector.field("queryServiceQuality").asDouble(), inspector.field("writeServiceQuality").asDouble());
+ // All rotations in
+ metricsService.setZoneIn(assignedRotation,"proxy.prod.us-east-3.vip.test");
+ maintainer.maintain();
+ assertEquals(RotationStatus.in, app.get().rotationStatus(deployment1.get()));
+ assertEquals(RotationStatus.in, app.get().rotationStatus(deployment2.get()));
}
- private Map<String, String> rotationsStatusFromInspector(Inspector inspector) {
- HashMap<String, String> rotationStatus = new HashMap<>();
- inspector.traverse((ArrayTraverser) (index, entry) -> {
- rotationStatus.put(entry.field("hostname").asString(), entry.field("rotationStatus").asString());
- });
- return rotationStatus;
+ private static DeploymentMetricsMaintainer maintainer(Controller controller) {
+ return new DeploymentMetricsMaintainer(controller, Duration.ofDays(1), new JobControl(controller.curator()));
}
- private Map<String, MetricsService.DeploymentMetrics> deploymentMetricsFromInspector(Inspector inspector) {
- Map<String, MetricsService.DeploymentMetrics> deploymentMetricByZone = new HashMap<>();
- inspector.traverse((ArrayTraverser) (index, entry) -> {
- String zone = entry.field("zoneId").asString();
- MetricsService.DeploymentMetrics deploymentMetrics = new MetricsService.DeploymentMetrics(entry.field("queriesPerSecond").asDouble(), entry.field("writesPerSecond").asDouble(),
- entry.field("documentCount").asLong(), entry.field("queryLatencyMillis").asDouble(), entry.field("writeLatencyMillis").asDouble());
- deploymentMetricByZone.put(zone, deploymentMetrics);
- });
- return deploymentMetricByZone;
- }
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
index 094f8989530..e06578a545f 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
@@ -83,7 +83,8 @@ public class ApplicationSerializerTest {
statusList.add(JobStatus.initial(JobType.systemTest)
.withTriggering(Version.fromString("5.6.7"), ApplicationVersion.unknown, empty(), "Test", Instant.ofEpochMilli(7))
- .withCompletion(30, empty(), Instant.ofEpochMilli(8)));
+ .withCompletion(30, empty(), Instant.ofEpochMilli(8))
+ .withPause(OptionalLong.of(1L << 32)));
statusList.add(JobStatus.initial(JobType.stagingTest)
.withTriggering(Version.fromString("5.6.6"), ApplicationVersion.unknown, empty(), "Test 2", Instant.ofEpochMilli(5))
.withCompletion(11, Optional.of(JobError.unknown), Instant.ofEpochMilli(6)));
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index 36d92620fa2..b82462ad595 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -49,6 +49,7 @@ import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzDbMock;
import com.yahoo.vespa.hosted.controller.authority.config.ApiAuthorityConfig;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.deployment.BuildJob;
+import com.yahoo.vespa.hosted.controller.deployment.DeploymentTrigger;
import com.yahoo.vespa.hosted.controller.integration.ConfigServerMock;
import com.yahoo.vespa.hosted.controller.integration.MetricsServiceMock;
import com.yahoo.vespa.hosted.controller.maintenance.DeploymentMetricsMaintainer;
@@ -347,15 +348,25 @@ public class ApplicationApiTest extends ControllerContainerTest {
// DELETE (cancel) again is a no-op
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", DELETE)
- .userIdentity(HOSTED_VESPA_OPERATOR),
+ .userIdentity(USER_ID),
new File("application-deployment-cancelled-no-op.json"));
// POST triggering of a full deployment to an application (if version is omitted, current system version is used)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", POST)
- .userIdentity(HOSTED_VESPA_OPERATOR)
+ .userIdentity(USER_ID)
.data("6.1.0"),
new File("application-deployment.json"));
+ // POST a pause to a production job
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/default/job/production-us-west-1/pause", POST)
+ .userIdentity(USER_ID),
+ "{\"message\":\"production-us-west-1 for tenant1.application1 paused for " + DeploymentTrigger.maxPause + "\"}");
+
+ // POST a triggering to the same production job
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/default/job/production-us-west-1", POST)
+ .userIdentity(USER_ID),
+ "{\"message\":\"Triggered production-us-west-1 for tenant1.application1\"}");
+
// POST a 'restart application' command
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/restart", POST)
.screwdriverIdentity(SCREWDRIVER_ID),
@@ -429,10 +440,38 @@ public class ApplicationApiTest extends ControllerContainerTest {
.data(createApplicationSubmissionData(packageWithService)),
"{\"version\":\"1.0.43-d00d\"}");
+ ApplicationId app1 = ApplicationId.from("tenant1", "application1", "default");
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/jobreport", POST)
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .data(asJson(new DeploymentJobs.JobReport(app1,
+ JobType.component,
+ 1234,
+ 123,
+ Optional.of(BuildJob.defaultSourceRevision),
+ Optional.empty()))),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"" + app1 + " is set up to be deployed from internally," +
+ " and no longer accepts reports from Screwdriver v3 jobs. If you need to revert " +
+ "to the old pipeline, please file a ticket at yo/vespa-support and request this.\"}",
+ 400);
+
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/default/job/production-us-west-1", DELETE)
.userIdentity(USER_ID),
"{\"message\":\"Nothing to abort.\"}");
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/submit", DELETE)
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"message\":\"Unregistered 'tenant1.application1' from internal deployment pipeline.\"}");
+
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/jobreport", POST)
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .data(asJson(new DeploymentJobs.JobReport(app1,
+ JobType.component,
+ 1234,
+ 123,
+ Optional.of(BuildJob.defaultSourceRevision),
+ Optional.empty()))),
+ "{\"message\":\"ok\"}");
+
// PUT (create) the authenticated user
byte[] data = new byte[0];
tester.assertResponse(request("/application/v4/user?user=new_user&domain=by", PUT)
@@ -469,9 +508,8 @@ public class ApplicationApiTest extends ControllerContainerTest {
private void addIssues(ContainerControllerTester tester, ApplicationId id) {
tester.controller().applications().lockOrThrow(id, application ->
- tester.controller().applications().store(application
- .withDeploymentIssueId(IssueId.from("123"))
- .withOwnershipIssueId(IssueId.from("321"))));
+ tester.controller().applications().store(application.withDeploymentIssueId(IssueId.from("123"))
+ .withOwnershipIssueId(IssueId.from("321"))));
}
@Test
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-deployment.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-deployment.json
index e3c0bbe0679..d2531638a93 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-deployment.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-deployment.json
@@ -1 +1 @@
-{"message":"Triggered upgrade to 6.1 for application 'tenant1.application1'"} \ No newline at end of file
+{"message":"Triggered upgrade to 6.1 for tenant1.application1"} \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java
index 22a527bf3d3..19aa247edb4 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java
@@ -70,7 +70,7 @@ public class ControllerAuthorizationFilterTest {
List<AthenzIdentity> allowed = singletonList(HOSTED_OPERATOR);
List<AthenzIdentity> forbidden = singletonList(USER);
- testApiAccess(PUT, "/application/v4/tenant/mytenant/application/myapp/deploying",
+ testApiAccess(PUT, "/zone/v2/hello-proxy-path",
allowed, forbidden, filter);
testApiAccess(POST, "/screwdriver/v1/trigger/tenant/mytenant/application/myapp/",
allowed, forbidden, filter);