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/ConfigServerClientMock.java67
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java20
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java6
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java9
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/ClusterCostTest.java35
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentCostTest.java38
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java123
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzTestUtils.java22
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java95
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTester.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainerTest.java41
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/FailureRedeployerTest.java8
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java17
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java53
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java16
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java42
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java11
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json14
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json25
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/responses/root.json2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java110
24 files changed, 592 insertions, 174 deletions
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java
index 9db852374b8..9228e83bbc6 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java
@@ -7,16 +7,16 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yahoo.component.AbstractComponent;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerClient;
-import com.yahoo.vespa.hosted.controller.api.integration.configserver.Log;
-import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeList;
-import com.yahoo.vespa.hosted.controller.api.integration.configserver.PrepareResponse;
import com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions;
import com.yahoo.vespa.hosted.controller.api.application.v4.model.EndpointStatus;
import com.yahoo.vespa.hosted.controller.api.application.v4.model.configserverbindings.ConfigChangeActions;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.identifiers.Hostname;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
+import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerClient;
+import com.yahoo.vespa.hosted.controller.api.integration.configserver.Log;
+import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeList;
+import com.yahoo.vespa.hosted.controller.api.integration.configserver.PrepareResponse;
import com.yahoo.vespa.hosted.controller.api.rotation.Rotation;
import com.yahoo.vespa.serviceview.bindings.ApplicationView;
import com.yahoo.vespa.serviceview.bindings.ClusterView;
@@ -28,7 +28,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -40,15 +39,11 @@ import java.util.UUID;
*/
public class ConfigServerClientMock extends AbstractComponent implements ConfigServerClient {
- private Map<ApplicationId, byte[]> applicationContent = new HashMap<>();
- private Map<ApplicationId, String> applicationInstances = new HashMap<>();
- private Map<ApplicationId, Boolean> applicationActivated = new HashMap<>();
- private Set<ApplicationId> applicationRestarted = new HashSet<>();
- private Set<String> hostsExplicitlyRestarted = new HashSet<>();
- private Map<String, EndpointStatus> endpoints = new HashMap<>();
-
- private Map<URI, Version> configServerVersions = new HashMap<>();
- private Version defaultConfigServerVersion = new Version(6, 1, 0);
+ private final Map<ApplicationId, String> applicationInstances = new HashMap<>();
+ private final Map<ApplicationId, Boolean> applicationActivated = new HashMap<>();
+ private final Map<String, EndpointStatus> endpoints = new HashMap<>();
+ private final Map<URI, Version> versions = new HashMap<>();
+ private Version defaultVersion = new Version(6, 1, 0);
/** The exception to throw on the next prepare run, or null to continue normally */
private RuntimeException prepareException = null;
@@ -64,18 +59,27 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
public Map<ApplicationId, Boolean> activated() {
return Collections.unmodifiableMap(applicationActivated);
}
+
+ public void throwOnNextPrepare(RuntimeException prepareException) {
+ this.prepareException = prepareException;
+ }
+
+ /**
+ * Returns the (initially empty) mutable map of config server urls to versions.
+ * This API will return defaultVersion as response to any version(url) call for versions not added to the map.
+ */
+ public Map<URI, Version> versions() {
+ return versions;
+ }
@Override
public PreparedApplication prepare(DeploymentId deployment, DeployOptions deployOptions, Set<String> rotationCnames, Set<Rotation> rotations, byte[] content) {
lastPrepareVersion = deployOptions.vespaVersion.map(Version::new);
-
if (prepareException != null) {
RuntimeException prepareException = this.prepareException;
this.prepareException = null;
throw prepareException;
}
-
- applicationContent.put(deployment.applicationId(), content);
applicationActivated.put(deployment.applicationId(), false);
applicationInstances.put(deployment.applicationId(), UUID.randomUUID() + ":4080");
@@ -111,20 +115,8 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
};
}
- public void throwOnNextPrepare(RuntimeException prepareException) {
- this.prepareException = prepareException;
- }
-
- /**
- * Returns the (initially empty) mutable map of config server urls to versions.
- * This API will return defaultConfigserverVersion as response to any version(url) call for versions not added to the map.
- */
- public Map<URI, Version> configServerVersions() {
- return configServerVersions;
- }
-
- public Version getDefaultConfigServerVersion() { return defaultConfigServerVersion; }
- public void setDefaultConfigServerVersion(Version version) { defaultConfigServerVersion = version; }
+ /** Set the default config server version */
+ public void setDefaultVersion(Version version) { this.defaultVersion = version; }
@Override
public List<String> getNodeQueryHost(DeploymentId deployment, String type) {
@@ -137,16 +129,11 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
@Override
public void restart(DeploymentId deployment, Optional<Hostname> hostname) {
- applicationRestarted.add(deployment.applicationId());
- if (hostname.isPresent()) {
- hostsExplicitlyRestarted.add(hostname.get().id());
- }
}
@Override
public void deactivate(DeploymentId deployment) {
applicationActivated.remove(deployment.applicationId());
- applicationContent.remove(deployment.applicationId());
applicationInstances.remove(deployment.applicationId());
}
@@ -197,7 +184,7 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
@Override
public Version version(URI configServerURI) {
- return configServerVersions.getOrDefault(configServerURI, defaultConfigServerVersion);
+ return versions.getOrDefault(configServerURI, defaultVersion);
}
@Override
@@ -207,10 +194,8 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
@Override
public EndpointStatus getGlobalRotationStatus(DeploymentId deployment, String endpoint) {
- EndpointStatus result = new EndpointStatus(EndpointStatus.Status.in, "", "", 1497618757l);
- return endpoints.containsKey(endpoint)
- ? endpoints.get(endpoint)
- : result;
+ EndpointStatus result = new EndpointStatus(EndpointStatus.Status.in, "", "", 1497618757L);
+ return endpoints.getOrDefault(endpoint, result);
}
@Override
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
index 6fc787d940e..408be6a49c2 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
@@ -24,9 +24,6 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserGroup;
import com.yahoo.vespa.hosted.controller.api.integration.BuildService.BuildJob;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.NToken;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensDbMock;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.NTokenMock;
import com.yahoo.vespa.hosted.controller.api.integration.dns.Record;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.application.ApplicationRevision;
@@ -36,6 +33,8 @@ import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobError;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobReport;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobType;
import com.yahoo.vespa.hosted.controller.application.JobStatus;
+import com.yahoo.vespa.hosted.controller.athenz.NToken;
+import com.yahoo.vespa.hosted.controller.athenz.mock.AthensDbMock;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.deployment.BuildSystem;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
@@ -260,16 +259,19 @@ public class ControllerTest {
Version systemVersion = controller.versionStatus().systemVersion().get().versionNumber();
Version newSystemVersion = new Version(systemVersion.getMajor(), systemVersion.getMinor()+1, 0);
VespaVersion newSystemVespaVersion = new VespaVersion(DeploymentStatistics.empty(newSystemVersion),
- "commit1",
+ "commit1",
Instant.now(),
true,
Collections.emptyList(),
- controller);
+ VespaVersion.Confidence.low
+ );
List<VespaVersion> versions = new ArrayList<>(controller.versionStatus().versions());
for (int i = 0; i < versions.size(); i++) {
VespaVersion c = versions.get(i);
if (c.isCurrentSystemVersion())
- versions.set(i, new VespaVersion(c.statistics(), c.releaseCommit(), c.releasedAt(), false, c.configServerHostnames(), controller));
+ versions.set(i, new VespaVersion(c.statistics(), c.releaseCommit(), c.releasedAt(),
+ false, c.configServerHostnames(),
+ c.confidence()));
}
versions.add(newSystemVespaVersion);
controller.updateVersionStatus(new VersionStatus(versions));
@@ -378,7 +380,7 @@ public class ControllerTest {
assertFalse(mockDomain.isVespaTenant);
// Migrate tenant to Athens
- NToken nToken = new NTokenMock("token");
+ NToken nToken = TestIdentities.userNToken;
tester.controller().tenants().migrateTenantToAthens(
tenantId, athensDomain, new PropertyId("1567"), new Property("vespa_dev.no"), nToken);
@@ -542,7 +544,7 @@ public class ControllerTest {
// Current system version, matches version in test data
Version version = Version.fromString("6.141.117");
- tester.configServer().setDefaultConfigServerVersion(version);
+ tester.configServer().setDefaultVersion(version);
tester.updateVersionStatus(version);
assertEquals(version, tester.controller().versionStatus().systemVersion().get().versionNumber());
@@ -572,7 +574,7 @@ public class ControllerTest {
// New version is released
version = Version.fromString("6.142.1");
- tester.configServer().setDefaultConfigServerVersion(version);
+ tester.configServer().setDefaultVersion(version);
tester.updateVersionStatus(version);
assertEquals(version, tester.controller().versionStatus().systemVersion().get().versionNumber());
tester.upgrader().maintain();
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 5184cde79c2..8e1234b7e96 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
@@ -21,8 +21,6 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.Property;
import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.identifiers.ScrewdriverId;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensDbMock;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensMock;
import com.yahoo.vespa.hosted.controller.api.integration.chef.ChefMock;
import com.yahoo.vespa.hosted.controller.api.integration.dns.MemoryNameService;
import com.yahoo.vespa.hosted.controller.api.integration.entity.MemoryEntityService;
@@ -30,6 +28,8 @@ import com.yahoo.vespa.hosted.controller.api.integration.github.GitHubMock;
import com.yahoo.vespa.hosted.controller.api.integration.jira.JiraMock;
import com.yahoo.vespa.hosted.controller.api.integration.routing.MemoryGlobalRoutingService;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
+import com.yahoo.vespa.hosted.controller.athenz.mock.AthensDbMock;
+import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock;
import com.yahoo.vespa.hosted.controller.integration.MockMetricsService;
import com.yahoo.vespa.hosted.controller.persistence.ControllerDb;
import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
@@ -214,7 +214,7 @@ public final class ControllerTester {
new MockRoutingGenerator(),
new ChefMock(),
clock,
- new AthensMock(athensDb));
+ new AthenzClientFactoryMock(athensDb));
controller.updateVersionStatus(VersionStatus.compute(controller));
return controller;
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java
index 1f52ebcadb7..355b63335c0 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.NTokenMock;
import com.yahoo.vespa.hosted.controller.api.Tenant;
import com.yahoo.vespa.hosted.controller.api.identifiers.EnvironmentId;
import com.yahoo.vespa.hosted.controller.api.identifiers.InstanceId;
@@ -10,7 +9,9 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.RegionId;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserGroup;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.NToken;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
+import com.yahoo.vespa.hosted.controller.athenz.NToken;
+import com.yahoo.vespa.hosted.controller.athenz.filter.AthenzTestUtils;
/**
* @author Tony Vaagenes
@@ -33,6 +34,8 @@ public class TestIdentities {
public static Tenant tenant = Tenant.createOpsDbTenant(tenantId, userGroup1, property);
- public static NToken userNToken = new NTokenMock("token");
+ public static NToken userNToken = new NToken.Builder(
+ "U1", AthenzUtils.createPrincipal(userId), AthenzTestUtils.generateRsaKeypair().getPrivate(), "0")
+ .build();
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/ClusterCostTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/ClusterCostTest.java
new file mode 100644
index 00000000000..313f565f546
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/ClusterCostTest.java
@@ -0,0 +1,35 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.application;
+
+import com.yahoo.config.provision.ClusterSpec;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author smorgrav
+ */
+public class ClusterCostTest {
+
+ @Test
+ public void clusterCost() throws Exception {
+ List<String> hostnames = new ArrayList<>();
+ hostnames.add("host1");
+ hostnames.add("host2");
+ ClusterInfo info = new ClusterInfo("test", 100, 10, 10, 10, ClusterSpec.Type.container, hostnames);
+ ClusterUtilization util = new ClusterUtilization(0.3, 0.2, 0.5, 0.1);
+ ClusterCost cost = new ClusterCost(info, util);
+
+ // CPU is fully utilized
+ Assert.assertEquals(200, cost.getTco(), Double.MIN_VALUE);
+ Assert.assertEquals(0, cost.getWaste(), Double.MIN_VALUE);
+
+ // Set Disk as the most utilized resource
+ util = new ClusterUtilization(0.3, 0.1, 0.5, 0.1);
+ cost = new ClusterCost(info, util);
+ Assert.assertEquals(200, cost.getTco(), Double.MIN_NORMAL); // TCO is independent of utilization
+ Assert.assertEquals(57.1428571429, cost.getWaste(), 0.001); // Waste is not independent
+ }
+} \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentCostTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentCostTest.java
new file mode 100644
index 00000000000..2e58253d768
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentCostTest.java
@@ -0,0 +1,38 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.application;
+
+import com.yahoo.config.provision.ClusterSpec;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author smorgrav
+ */
+public class DeploymentCostTest {
+
+ @Test
+ public void deploymentCost() {
+ Map<String, ClusterCost> clusters = new HashMap<>();
+ clusters.put("cluster1", createClusterCost(100, 0.2));
+ clusters.put("cluster2", createClusterCost(50, 0.1));
+
+ DeploymentCost cost = new DeploymentCost(clusters);
+ Assert.assertEquals(300, cost.getTco(), Double.MIN_VALUE); // 2*100 + 2*50
+ Assert.assertEquals(28.5714285714, cost.getWaste(), 0.001); // from cluster2
+ Assert.assertEquals(0.7142857142857143, cost.getUtilization(), Double.MIN_VALUE); // from cluster2
+ }
+
+ private ClusterCost createClusterCost(int flavorCost, double cpuUtil) {
+ List<String> hostnames = new ArrayList<>();
+ hostnames.add("host1");
+ hostnames.add("host2");
+ ClusterInfo info = new ClusterInfo("test", flavorCost, 10, 10, 10, ClusterSpec.Type.container, hostnames);
+ ClusterUtilization util = new ClusterUtilization(0.3, cpuUtil, 0.5, 0.1);
+ return new ClusterCost(info, util);
+ }
+} \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java
new file mode 100644
index 00000000000..20db038485d
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java
@@ -0,0 +1,123 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.athenz.filter;
+
+import com.yahoo.jdisc.Response;
+import com.yahoo.jdisc.handler.ContentChannel;
+import com.yahoo.jdisc.handler.ReadableContentChannel;
+import com.yahoo.jdisc.handler.ResponseHandler;
+import com.yahoo.jdisc.http.filter.DiscFilterRequest;
+import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
+import com.yahoo.vespa.hosted.controller.athenz.InvalidTokenException;
+import com.yahoo.vespa.hosted.controller.athenz.NToken;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UncheckedIOException;
+import java.util.Objects;
+
+import static com.yahoo.jdisc.Response.Status.UNAUTHORIZED;
+import static java.util.stream.Collectors.joining;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author bjorncs
+ */
+public class AthenzPrincipalFilterTest {
+
+ private static final NToken NTOKEN = createDummyToken();
+ private static final String ATHENZ_PRINCIPAL_HEADER = "Athenz-Principal-Auth";
+
+ private NTokenValidator validator;
+ private AthenzPrincipal principal;
+
+ @Before
+ public void before() {
+ validator = mock(NTokenValidator.class);
+ principal = AthenzUtils.createPrincipal(new UserId("bob"));
+ }
+
+ @Test
+ public void valid_ntoken_is_accepted() throws Exception {
+ DiscFilterRequest request = mock(DiscFilterRequest.class);
+ when(request.getHeader(ATHENZ_PRINCIPAL_HEADER)).thenReturn(NTOKEN.getToken());
+
+ when(validator.validate(NTOKEN)).thenReturn(principal);
+
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER);
+ filter.filter(request, new ResponseHandlerMock());
+
+ verify(request).setUserPrincipal(principal);
+ }
+
+ @Test
+ public void missing_token_is_unauthorized() throws Exception {
+ DiscFilterRequest request = mock(DiscFilterRequest.class);
+ when(request.getHeader(ATHENZ_PRINCIPAL_HEADER)).thenReturn(null);
+
+ ResponseHandlerMock responseHandler = new ResponseHandlerMock();
+
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER);
+ filter.filter(request, responseHandler);
+
+ assertThat(responseHandler.response, notNullValue());
+ assertThat(responseHandler.response.getStatus(), equalTo(UNAUTHORIZED));
+ assertThat(responseHandler.getResponseContent(), containsString("NToken is missing"));
+ }
+
+ @Test
+ public void invalid_token_is_unauthorized() throws Exception {
+ DiscFilterRequest request = mock(DiscFilterRequest.class);
+ when(request.getHeader(ATHENZ_PRINCIPAL_HEADER)).thenReturn(NTOKEN.getToken());
+
+ when(validator.validate(NTOKEN)).thenThrow(new InvalidTokenException("Invalid token"));
+
+ ResponseHandlerMock responseHandler = new ResponseHandlerMock();
+
+ AthenzPrincipalFilter filter = new AthenzPrincipalFilter(validator, Runnable::run, ATHENZ_PRINCIPAL_HEADER);
+ filter.filter(request, responseHandler);
+
+ assertThat(responseHandler.response, notNullValue());
+ assertThat(responseHandler.response.getStatus(), equalTo(UNAUTHORIZED));
+ assertThat(responseHandler.getResponseContent(), containsString("Invalid token"));
+ }
+
+ private static NToken createDummyToken() {
+ return new NToken.Builder(
+ "U1", AthenzUtils.createPrincipal(new UserId("bob")), AthenzTestUtils.generateRsaKeypair().getPrivate(), "0")
+ .build();
+ }
+
+ private static class ResponseHandlerMock implements ResponseHandler {
+
+ public Response response;
+ public ReadableContentChannel contentChannel;
+
+ @Override
+ public ContentChannel handleResponse(Response r) {
+ response = Objects.requireNonNull(r);
+ contentChannel = new ReadableContentChannel();
+ return contentChannel;
+ }
+
+ public String getResponseContent() {
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(contentChannel.toStream()))) {
+ return br.lines().collect(joining(System.lineSeparator()));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ }
+
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzTestUtils.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzTestUtils.java
new file mode 100644
index 00000000000..40b38254dda
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzTestUtils.java
@@ -0,0 +1,22 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.athenz.filter;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @author bjorncs
+ */
+public class AthenzTestUtils {
+ public static KeyPair generateRsaKeypair() {
+ try {
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+ keyGen.initialize(512);
+ return keyGen.genKeyPair();
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java
new file mode 100644
index 00000000000..e269f2842e2
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java
@@ -0,0 +1,95 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.athenz.filter;
+
+import com.yahoo.vespa.hosted.controller.api.identifiers.AthensDomain;
+import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
+import com.yahoo.vespa.hosted.controller.athenz.InvalidTokenException;
+import com.yahoo.vespa.hosted.controller.athenz.NToken;
+import com.yahoo.vespa.hosted.controller.athenz.ZmsKeystore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.util.Optional;
+
+import static com.yahoo.vespa.hosted.controller.athenz.AthenzUtils.ZMS_ATHENZ_SERVICE;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author bjorncs
+ */
+public class NTokenValidatorTest {
+
+ private static final KeyPair TRUSTED_KEY = AthenzTestUtils.generateRsaKeypair();
+ private static final KeyPair UNKNOWN_KEY = AthenzTestUtils.generateRsaKeypair();
+ private static final AthenzPrincipal PRINCIPAL = new AthenzPrincipal(new AthensDomain("yby"), new UserId("user"));
+
+ @Rule
+ public ExpectedException exceptionRule = ExpectedException.none();
+
+ @Test
+ public void valid_token_is_accepted() throws NoSuchAlgorithmException, InvalidTokenException {
+ NTokenValidator validator = new NTokenValidator(createKeystore());
+ NToken token = createNToken(PRINCIPAL, System.currentTimeMillis(), TRUSTED_KEY, "0");
+ AthenzPrincipal principal = validator.validate(token);
+ assertEquals("yby.user", principal.toYRN());
+ }
+
+ @Test
+ public void invalid_signature_is_not_accepted() throws InvalidTokenException {
+ NTokenValidator validator = new NTokenValidator(createKeystore());
+ NToken token = createNToken(PRINCIPAL, System.currentTimeMillis(), UNKNOWN_KEY, "0");
+ exceptionRule.expect(InvalidTokenException.class);
+ exceptionRule.expectMessage("NToken is expired or has invalid signature");
+ validator.validate(token);
+ }
+
+ @Test
+ public void expired_token_is_not_accepted() throws InvalidTokenException {
+ NTokenValidator validator = new NTokenValidator(createKeystore());
+ NToken token = createNToken(PRINCIPAL, 1234 /*long time ago*/, TRUSTED_KEY, "0");
+ exceptionRule.expect(InvalidTokenException.class);
+ exceptionRule.expectMessage("NToken is expired or has invalid signature");
+ validator.validate(token);
+ }
+
+ @Test
+ public void unknown_keyId_is_not_accepted() throws InvalidTokenException {
+ NTokenValidator validator = new NTokenValidator(createKeystore());
+ NToken token = createNToken(PRINCIPAL, System.currentTimeMillis(), TRUSTED_KEY, "unknown-key-id");
+ exceptionRule.expect(InvalidTokenException.class);
+ exceptionRule.expectMessage("NToken has an unknown keyId");
+ validator.validate(token);
+ }
+
+ @Test
+ public void failing_to_find_key_should_throw_exception() throws InvalidTokenException {
+ ZmsKeystore keystore = (athensService, keyId) -> { throw new RuntimeException(); };
+ NTokenValidator validator = new NTokenValidator(keystore);
+ NToken token = createNToken(PRINCIPAL, System.currentTimeMillis(), TRUSTED_KEY, "0");
+ exceptionRule.expect(InvalidTokenException.class);
+ exceptionRule.expectMessage("Failed to retrieve public key");
+ validator.validate(token);
+ }
+
+ private static ZmsKeystore createKeystore() {
+ return (athensService, keyId) ->
+ athensService.equals(ZMS_ATHENZ_SERVICE) && keyId.equals("0")
+ ? Optional.of(TRUSTED_KEY.getPublic())
+ : Optional.empty();
+ }
+
+ private static NToken createNToken(AthenzPrincipal principal, long issueTime, KeyPair keyPair, String keyId) {
+ return new NToken.Builder("U1", principal, keyPair.getPrivate(), keyId)
+ .salt("1234")
+ .hostname("host")
+ .ip("1.2.3.4")
+ .issueTime(issueTime / 1000)
+ .expirationWindow(1000)
+ .build();
+ }
+
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTester.java
index be14947de2b..e45166b1c16 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTester.java
@@ -90,12 +90,17 @@ public class DeploymentTester {
.filter(c -> c instanceof Change.VersionChange)
.map(Change.VersionChange.class::cast);
}
+
+ public void updateVersionStatus() {
+ controller().updateVersionStatus(VersionStatus.compute(controller(), tester.controller().systemVersion()));
+ }
public void updateVersionStatus(Version currentVersion) {
controller().updateVersionStatus(VersionStatus.compute(controller(), currentVersion));
}
public void upgradeSystem(Version version) {
+ controllerTester().configServer().setDefaultVersion(version);
updateVersionStatus(version);
upgrader().maintain();
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java
index 7ae89082660..13919cefd3b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java
@@ -31,7 +31,7 @@ public class ClusterInfoMaintainerTest {
deployment = tester.controller().applications().get(app).get().deployments().values().stream().findAny().get();
Assert.assertEquals(2, deployment.clusterInfo().size());
- Assert.assertEquals(10, deployment.clusterInfo().get(ClusterSpec.Id.from("clusterA")).getCost());
+ Assert.assertEquals(10, deployment.clusterInfo().get(ClusterSpec.Id.from("clusterA")).getFlavorCost());
}
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
new file mode 100644
index 00000000000..cb503fc1fb7
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainerTest.java
@@ -0,0 +1,41 @@
+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.yahoo.config.provision.ApplicationId;
+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.persistence.MockCuratorDb;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.time.Duration;
+
+/**
+ * @author smorgrav
+ */
+public class DeploymentMetricsMaintainerTest {
+
+ @Test
+ public void maintain() {
+ ControllerTester tester = new ControllerTester();
+ ApplicationId app = tester.createAndDeploy("tenant1", "domain1", "app1", Environment.dev, 123).id();
+
+ // Pre condition: no metric info on the deployment
+ Deployment deployment = tester.controller().applications().get(app).get().deployments().values().stream().findAny().get();
+ Assert.assertEquals(0, deployment.metrics().documentCount(), Double.MIN_VALUE);
+
+ DeploymentMetricsMaintainer maintainer = new DeploymentMetricsMaintainer(tester.controller(), Duration.ofMinutes(10), new JobControl(new MockCuratorDb()));
+ maintainer.maintain();
+
+ // Post condition:
+ deployment = tester.controller().applications().get(app).get().deployments().values().stream().findAny().get();
+ Assert.assertEquals(1, deployment.metrics().queriesPerSecond(), Double.MIN_VALUE);
+ Assert.assertEquals(2, deployment.metrics().writesPerSecond(), Double.MIN_VALUE);
+ Assert.assertEquals(3, deployment.metrics().documentCount(), Double.MIN_VALUE);
+ Assert.assertEquals(4, deployment.metrics().queryLatencyMillis(), Double.MIN_VALUE);
+ Assert.assertEquals(5, deployment.metrics().writeLatencyMillis(), Double.MIN_VALUE);
+ }
+
+} \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/FailureRedeployerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/FailureRedeployerTest.java
index 286db864c22..4c935747ac6 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/FailureRedeployerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/FailureRedeployerTest.java
@@ -181,7 +181,7 @@ public class FailureRedeployerTest {
// Current system version, matches version in test data
Version version = Version.fromString("6.141.117");
- tester.configServer().setDefaultConfigServerVersion(version);
+ tester.configServer().setDefaultVersion(version);
tester.updateVersionStatus(version);
assertEquals(version, tester.controller().versionStatus().systemVersion().get().versionNumber());
@@ -200,7 +200,7 @@ public class FailureRedeployerTest {
// New version is released
version = Version.fromString("6.142.1");
- tester.configServer().setDefaultConfigServerVersion(version);
+ tester.configServer().setDefaultVersion(version);
tester.updateVersionStatus(version);
assertEquals(version, tester.controller().versionStatus().systemVersion().get().versionNumber());
tester.upgrader().maintain();
@@ -237,7 +237,7 @@ public class FailureRedeployerTest {
// Current system version, matches version in test data
Version version = Version.fromString("6.42.1");
- tester.configServer().setDefaultConfigServerVersion(version);
+ tester.configServer().setDefaultVersion(version);
tester.updateVersionStatus(version);
assertEquals(version, tester.controller().versionStatus().systemVersion().get().versionNumber());
@@ -262,7 +262,7 @@ public class FailureRedeployerTest {
// Current system version, matches version in test data
Version version = Version.fromString("6.42.1");
- tester.configServer().setDefaultConfigServerVersion(version);
+ tester.configServer().setDefaultVersion(version);
tester.updateVersionStatus(version);
assertEquals(version, tester.controller().versionStatus().systemVersion().get().versionNumber());
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 3e73bf4445b..f7fd7cb6fb1 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
@@ -20,6 +20,7 @@ import com.yahoo.vespa.hosted.controller.application.ClusterUtilization;
import com.yahoo.vespa.hosted.controller.application.Deployment;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobError;
+import com.yahoo.vespa.hosted.controller.application.DeploymentMetrics;
import com.yahoo.vespa.hosted.controller.application.JobStatus;
import com.yahoo.vespa.hosted.controller.application.SourceRevision;
import org.junit.Test;
@@ -61,7 +62,7 @@ public class ApplicationSerializerTest {
ApplicationRevision revision2 = ApplicationRevision.from("appHash2", new SourceRevision("repo1", "branch1", "commit1"));
deployments.add(new Deployment(zone1, revision1, Version.fromString("1.2.3"), Instant.ofEpochMilli(3))); // One deployment without cluster info and utils
deployments.add(new Deployment(zone2, revision2, Version.fromString("1.2.3"), Instant.ofEpochMilli(5),
- createClusterUtils(3, 0.2), createClusterInfo(3, 4)));
+ createClusterUtils(3, 0.2), createClusterInfo(3, 4),new DeploymentMetrics(2,3,4,5,6)));
Optional<Long> projectId = Optional.of(123L);
List<JobStatus> statusList = new ArrayList<>();
@@ -118,10 +119,20 @@ public class ApplicationSerializerTest {
// Test cluster info
assertEquals(3, serialized.deployments().get(zone2).clusterInfo().size());
- assertEquals(10, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getCost());
+ assertEquals(10, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getFlavorCost());
assertEquals(ClusterSpec.Type.content, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getClusterType());
assertEquals("flavor2", serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getFlavor());
assertEquals(4, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getHostnames().size());
+ assertEquals(2, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getFlavorCPU(), Double.MIN_VALUE);
+ assertEquals(4, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getFlavorMem(), Double.MIN_VALUE);
+ assertEquals(50, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getFlavorDisk(), Double.MIN_VALUE);
+
+ // Test metrics
+ assertEquals(2, serialized.deployments().get(zone2).metrics().queriesPerSecond(), Double.MIN_VALUE);
+ assertEquals(3, serialized.deployments().get(zone2).metrics().writesPerSecond(), Double.MIN_VALUE);
+ assertEquals(4, serialized.deployments().get(zone2).metrics().documentCount(), Double.MIN_VALUE);
+ assertEquals(5, serialized.deployments().get(zone2).metrics().queryLatencyMillis(), Double.MIN_VALUE);
+ assertEquals(6, serialized.deployments().get(zone2).metrics().writeLatencyMillis(), Double.MIN_VALUE);
{ // test more deployment serialization cases
Application original2 = original.withDeploying(Optional.of(Change.ApplicationChange.of(ApplicationRevision.from("hash1"))));
@@ -153,7 +164,7 @@ public class ApplicationSerializerTest {
}
result.put(ClusterSpec.Id.from("id" + cluster), new ClusterInfo("flavor" + cluster, 10,
- ClusterSpec.Type.content, hostnames));
+ 2, 4, 50, ClusterSpec.Type.content, hostnames));
}
return result;
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java
new file mode 100644
index 00000000000..feaf1289853
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java
@@ -0,0 +1,53 @@
+package com.yahoo.vespa.hosted.controller.persistence;
+
+import com.yahoo.component.Version;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.vespa.hosted.controller.versions.DeploymentStatistics;
+import com.yahoo.vespa.hosted.controller.versions.VersionStatus;
+import com.yahoo.vespa.hosted.controller.versions.VespaVersion;
+import org.junit.Test;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author mpolden
+ */
+public class VersionStatusSerializerTest {
+
+ @Test
+ public void testSerialization() throws Exception {
+ List<VespaVersion> vespaVersions = new ArrayList<>();
+ DeploymentStatistics statistics = new DeploymentStatistics(
+ Version.fromString("5.0"),
+ Arrays.asList(ApplicationId.from("tenant1", "failing1", "default")),
+ Arrays.asList(ApplicationId.from("tenant2", "success1", "default"),
+ ApplicationId.from("tenant2", "success2", "default"))
+ );
+ vespaVersions.add(new VespaVersion(statistics, "dead", Instant.now(), false,
+ Arrays.asList("cfg1", "cfg2", "cfg3"), VespaVersion.Confidence.normal));
+ vespaVersions.add(new VespaVersion(statistics, "cafe", Instant.now(), true,
+ Arrays.asList("cfg1", "cfg2", "cfg3"), VespaVersion.Confidence.normal));
+ VersionStatus status = new VersionStatus(vespaVersions);
+ VersionStatusSerializer serializer = new VersionStatusSerializer();
+ VersionStatus deserialized = serializer.fromSlime(serializer.toSlime(status));
+
+ assertEquals(status.versions().size(), deserialized.versions().size());
+ for (int i = 0; i < status.versions().size(); i++) {
+ VespaVersion a = status.versions().get(i);
+ VespaVersion b = deserialized.versions().get(i);
+ assertEquals(a.releaseCommit(), b.releaseCommit());
+ assertEquals(a.releasedAt(), b.releasedAt());
+ assertEquals(a.isCurrentSystemVersion(), b.isCurrentSystemVersion());
+ assertEquals(a.statistics(), b.statistics());
+ assertEquals(a.configServerHostnames(), b.configServerHostnames());
+ assertEquals(a.confidence(), b.confidence());
+ }
+
+ }
+
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
index a792626d691..99381d538d5 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
@@ -21,13 +21,11 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.identifiers.ScrewdriverId;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.Athens;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.AthensPrincipal;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensDbMock;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensMock;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.ZmsClientFactoryMock;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
+import com.yahoo.vespa.hosted.controller.athenz.mock.AthensDbMock;
+import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock;
import com.yahoo.vespa.hosted.controller.maintenance.JobControl;
import com.yahoo.vespa.hosted.controller.maintenance.Upgrader;
import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
@@ -97,14 +95,12 @@ public class ContainerControllerTester {
}
public AthensDomain addTenantAthensDomain(String domainName, String userName) {
- Athens athens = (AthensMock) containerTester.container().components().getComponent(
- "com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensMock"
- );
- ZmsClientFactoryMock mock = (ZmsClientFactoryMock) athens.zmsClientFactory();
+ AthenzClientFactoryMock mock = (AthenzClientFactoryMock) containerTester.container().components()
+ .getComponent(AthenzClientFactoryMock.class.getName());
AthensDomain athensDomain = new AthensDomain(domainName);
AthensDbMock.Domain domain = new AthensDbMock.Domain(athensDomain);
domain.markAsVespaTenant();
- domain.admin(new AthensPrincipal(new AthensDomain("domain"), new UserId(userName)));
+ domain.admin(new AthenzPrincipal(new AthensDomain("domain"), new UserId(userName)));
mock.getSetup().addDomain(domain);
return athensDomain;
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java
index fd07428126a..5c102b0d9df 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java
@@ -36,7 +36,7 @@ public class ControllerContainerTest {
" <system>main</system>" +
" </config>" +
" <component id='com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensMock'/>" +
+ " <component id='com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock'/>" +
" <component id='com.yahoo.vespa.hosted.controller.api.integration.chef.ChefMock'/>" +
" <component id='com.yahoo.vespa.hosted.controller.api.integration.dns.MemoryNameService'/>" +
" <component id='com.yahoo.vespa.hosted.controller.api.integration.entity.MemoryEntityService'/>" +
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 13b1165ccb2..0c9ebedc09b 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
@@ -10,17 +10,17 @@ import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.ConfigServerClientMock;
import com.yahoo.vespa.hosted.controller.api.identifiers.AthensDomain;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.Athens;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.AthensPrincipal;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensDbMock;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensMock;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.ZmsClientFactoryMock;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.application.ClusterInfo;
import com.yahoo.vespa.hosted.controller.application.ClusterUtilization;
import com.yahoo.vespa.hosted.controller.application.Deployment;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs;
+import com.yahoo.vespa.hosted.controller.application.DeploymentMetrics;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
+import com.yahoo.vespa.hosted.controller.athenz.mock.AthensDbMock;
+import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.restapi.ContainerControllerTester;
import com.yahoo.vespa.hosted.controller.restapi.ContainerTester;
@@ -54,7 +54,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
.region("corp-us-east-1")
.build();
private static final String athensUserDomain = "domain1";
- private static final String athensScrewdriverDomain = "screwdriver-domain";
+ private static final String athensScrewdriverDomain = AthenzUtils.SCREWDRIVER_DOMAIN.id();
@Test
@@ -173,7 +173,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", "", Request.Method.GET),
new File("application.json"));
// GET an application deployment
- addMockObservedApplicationCost(controllerTester);
+ setDeploymentMaintainedInfo(controllerTester);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default", "", Request.Method.GET),
new File("deployment.json"));
// POST a 'restart application' command
@@ -671,14 +671,12 @@ public class ApplicationApiTest extends ControllerContainerTest {
* mock setup to replicate the action.
*/
private AthensDomain addTenantAthensDomain(String domainName, String userName) {
- Athens athens = (AthensMock) container.components().getComponent(
- "com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensMock"
- );
- ZmsClientFactoryMock mock = (ZmsClientFactoryMock) athens.zmsClientFactory();
+ AthenzClientFactoryMock mock = (AthenzClientFactoryMock) container.components()
+ .getComponent(AthenzClientFactoryMock.class.getName());
AthensDomain athensDomain = new AthensDomain(domainName);
AthensDbMock.Domain domain = new AthensDbMock.Domain(athensDomain);
domain.markAsVespaTenant();
- domain.admin(new AthensPrincipal(new AthensDomain(athensUserDomain), new UserId(userName)));
+ domain.admin(AthenzUtils.createPrincipal(new UserId(userName)));
mock.getSetup().addDomain(domain);
return athensDomain;
}
@@ -688,12 +686,10 @@ public class ApplicationApiTest extends ControllerContainerTest {
* mock setup to replicate the action.
*/
private void addScrewdriverUserToDomain(String screwdriverUserId, String domainName) {
- Athens athens = (AthensMock) container.components().getComponent(
- "com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensMock"
- );
- ZmsClientFactoryMock mock = (ZmsClientFactoryMock) athens.zmsClientFactory();
+ AthenzClientFactoryMock mock = (AthenzClientFactoryMock) container.components()
+ .getComponent(AthenzClientFactoryMock.class.getName());
AthensDbMock.Domain domain = mock.getSetup().domains.get(new AthensDomain(domainName));
- domain.admin(new AthensPrincipal(new AthensDomain(athensScrewdriverDomain), new UserId(screwdriverUserId)));
+ domain.admin(new AthenzPrincipal(new AthensDomain(athensScrewdriverDomain), new UserId(screwdriverUserId)));
}
private void startAndTestChange(ContainerControllerTester controllerTester, ApplicationId application, long projectId,
@@ -732,7 +728,14 @@ public class ApplicationApiTest extends ControllerContainerTest {
controllerTester.notifyJobCompletion(application, projectId, true, DeploymentJobs.JobType.stagingTest);
}
- private void addMockObservedApplicationCost(ContainerControllerTester controllerTester) {
+ /**
+ * Cluster info, utilization and deployment metrics are maintained async by maintainers.
+ *
+ * This sets these values as if the maintainers has been ran.
+ *
+ * @param controllerTester
+ */
+ private void setDeploymentMaintainedInfo(ContainerControllerTester controllerTester) {
for (Application application : controllerTester.controller().applications().asList()) {
try (Lock lock = controllerTester.controller().applications().lock(application.id())) {
for (Deployment deployment : application.deployments().values()) {
@@ -740,11 +743,12 @@ public class ApplicationApiTest extends ControllerContainerTest {
List<String> hostnames = new ArrayList<>();
hostnames.add("host1");
hostnames.add("host2");
- clusterInfo.put(ClusterSpec.Id.from("cluster1"), new ClusterInfo("flavor1", 37, ClusterSpec.Type.content, hostnames));
+ clusterInfo.put(ClusterSpec.Id.from("cluster1"), new ClusterInfo("flavor1", 37, 2, 4, 50, ClusterSpec.Type.content, hostnames));
Map<ClusterSpec.Id, ClusterUtilization> clusterUtils = new HashMap<>();
clusterUtils.put(ClusterSpec.Id.from("cluster1"), new ClusterUtilization(0.3, 0.6, 0.4, 0.3));
deployment = deployment.withClusterInfo(clusterInfo);
deployment = deployment.withClusterUtils(clusterUtils);
+ deployment = deployment.withMetrics(new DeploymentMetrics(1,2,3,4,5));
application = application.with(deployment);
controllerTester.controller().applications().store(application, lock);
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java
index 16557157cf5..6f8dfc681ac 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java
@@ -6,9 +6,10 @@ import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.TestIdentities;
import com.yahoo.vespa.hosted.controller.api.identifiers.AthensDomain;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.AthensPrincipal;
-import com.yahoo.vespa.hosted.controller.api.integration.athens.NToken;
import com.yahoo.vespa.hosted.controller.api.integration.entity.EntityService;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzClientFactory;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
+import com.yahoo.vespa.hosted.controller.athenz.NToken;
import javax.ws.rs.core.SecurityContext;
import java.security.Principal;
@@ -23,15 +24,15 @@ import java.util.Optional;
@SuppressWarnings("unused") // injected
public class MockAuthorizer extends Authorizer {
- public MockAuthorizer(Controller controller, EntityService entityService) {
- super(controller, entityService);
+ public MockAuthorizer(Controller controller, EntityService entityService, AthenzClientFactory athenzClientFactory) {
+ super(controller, entityService, athenzClientFactory);
}
/** Returns a principal given by the request parameters 'domain' and 'user' */
@Override
public Optional<Principal> getPrincipalIfAny(HttpRequest request) {
if (request.getProperty("user") == null) return Optional.empty();
- return Optional.of(new AthensPrincipal(new AthensDomain(request.getProperty("domain")),
+ return Optional.of(new AthenzPrincipal(new AthensDomain(request.getProperty("domain")),
new UserId(request.getProperty("user"))));
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json
index 67fc48d4646..9174e7dd8b2 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json
@@ -17,17 +17,21 @@
"gitBranch": "master",
"gitCommit": "commit1",
"cost": {
- "tco": 37,
- "utilization": 5.999999999999999,
- "waste": 0.0,
+ "tco": 74,
+ "waste": 0,
+ "utilization": 2.999999999999999,
"cluster": {
"cluster1": {
"count": 2,
"resource": "cpu",
"utilization": 2.999999999999999,
- "tco": 37,
- "flavor": "flavor1",
+ "tco": 74,
"waste": 0,
+ "flavor": "flavor1",
+ "flavorCost":37.0,
+ "flavorCpu":2.0,
+ "flavorMem":4.0,
+ "flavorDisk":50.0,
"type": "content",
"util": {
"cpu": 2.999999999999999,
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json
index e974c315eb2..3633860772b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json
@@ -4,10 +4,7 @@
"name": "DelayedDeployer"
},
{
- "name": "ClusterUtilizationMaintainer"
- },
- {
- "name":"BlockedChangeDeployer"
+ "name": "BlockedChangeDeployer"
},
{
"name": "Upgrader"
@@ -16,25 +13,31 @@
"name": "FailureRedeployer"
},
{
- "name": "ClusterInfoMaintainer"
+ "name": "VersionStatusUpdater"
},
{
- "name": "DeploymentExpirer"
+ "name": "DeploymentIssueReporter"
},
{
- "name": "MetricsReporter"
+ "name": "DeploymentMetricsMaintainer"
},
{
- "name": "VersionStatusUpdater"
+ "name": "OutstandingChangeDeployer"
},
{
- "name": "DeploymentIssueReporter"
+ "name": "ClusterUtilizationMaintainer"
},
{
- "name": "OutstandingChangeDeployer"
+ "name": "ClusterInfoMaintainer"
+ },
+ {
+ "name": "DeploymentExpirer"
+ },
+ {
+ "name": "MetricsReporter"
}
],
"inactive": [
"DeploymentExpirer"
]
-}
+} \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiTest.java
index c002c7fb24a..55a4b46f4a7 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiTest.java
@@ -85,7 +85,8 @@ public class DeploymentApiTest extends ControllerContainerTest {
version.releasedAt(),
version.isCurrentSystemVersion(),
ImmutableSet.of("config1.test", "config2.test"),
- controller);
+ VespaVersion.confidenceFrom(version.statistics(), controller, version.releasedAt())
+ );
censored.add(version);
}
return new VersionStatus(censored);
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/responses/root.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/responses/root.json
index c2e83373cf7..00bd1ed8208 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/responses/root.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/responses/root.json
@@ -2,7 +2,7 @@
"versions": [
{
"version": "(ignore)",
- "confidence": "normal",
+ "confidence": "high",
"commit": "(ignore)",
"date": 0,
"controllerVersion": false,
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java
index 7bbbf8f0499..17935906186 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/versions/VersionStatusTest.java
@@ -6,6 +6,7 @@ import com.yahoo.component.Vtag;
import com.yahoo.config.provision.Environment;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.ApplicationController;
+import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.ControllerTester;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
@@ -13,6 +14,7 @@ import com.yahoo.vespa.hosted.controller.application.DeploymentJobs;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobError;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
+import com.yahoo.vespa.hosted.controller.versions.VespaVersion.Confidence;
import org.junit.Test;
import java.net.URI;
@@ -46,7 +48,7 @@ public class VersionStatusTest {
public void testSystemVersionIsControllerVersionIfConfigserversAreNewer() {
ControllerTester tester = new ControllerTester();
Version largerThanCurrent = new Version(Vtag.currentVersion.getMajor() + 1);
- tester.configServer().setDefaultConfigServerVersion(largerThanCurrent);
+ tester.configServer().setDefaultVersion(largerThanCurrent);
VersionStatus versionStatus = VersionStatus.compute(tester.controller());
assertEquals(Vtag.currentVersion, versionStatus.systemVersion().get().versionNumber());
}
@@ -55,7 +57,7 @@ public class VersionStatusTest {
public void testSystemVersionIsVersionOfOldestConfigServer() throws URISyntaxException {
ControllerTester tester = new ControllerTester();
Version oldest = new Version(5);
- tester.configServer().configServerVersions().put(new URI("http://cfg.prod.corp-us-east-1.test"), oldest);
+ tester.configServer().versions().put(new URI("http://cfg.prod.corp-us-east-1.test"), oldest);
VersionStatus versionStatus = VersionStatus.compute(tester.controller());
assertEquals(oldest, versionStatus.systemVersion().get().versionNumber());
}
@@ -70,7 +72,6 @@ public class VersionStatusTest {
.region("us-east-3")
.build();
- // Application versions which are older than the current version
Version version1 = new Version("5.1");
Version version2 = new Version("5.2");
tester.upgradeSystem(version1);
@@ -90,14 +91,9 @@ public class VersionStatusTest {
// - app3 is in production on version1, but then fails in staging test on version2
tester.completeUpgradeWithError(app3, version2, applicationPackage, stagingTest);
- VersionStatus versionStatus = VersionStatus.compute(tester.controller());
- List<VespaVersion> versions = versionStatus.versions();
- assertEquals("The version of this controller, the default config server version, plus the two versions above exist", 4, versions.size());
-
- VespaVersion v0 = versions.get(2);
- assertEquals(tester.configServer().getDefaultConfigServerVersion(), v0.versionNumber());
- assertEquals(0, v0.statistics().failing().size());
- assertEquals(0, v0.statistics().production().size());
+ tester.updateVersionStatus();
+ List<VespaVersion> versions = tester.controller().versionStatus().versions();
+ assertEquals("The two versions above exist", 2, versions.size());
VespaVersion v1 = versions.get(0);
assertEquals(version1, v1.versionNumber());
@@ -116,11 +112,6 @@ public class VersionStatusTest {
// Only one application is on v2 in at least one zone
assertEquals(1, v2.statistics().production().size());
assertTrue(v2.statistics().production().contains(app2.id()));
-
- VespaVersion v3 = versions.get(3);
- assertEquals(Vtag.currentVersion, v3.versionNumber());
- assertEquals(0, v3.statistics().failing().size());
- assertEquals(0, v3.statistics().production().size());
}
@Test
@@ -130,7 +121,7 @@ public class VersionStatusTest {
Version version0 = new Version("5.0");
tester.upgradeSystem(version0);
- // Setup applications
+ // Setup applications - all running on version0
Application canary0 = tester.createAndDeploy("canary0", 1, "canary");
Application canary1 = tester.createAndDeploy("canary1", 2, "canary");
Application canary2 = tester.createAndDeploy("canary2", 3, "canary");
@@ -146,8 +137,7 @@ public class VersionStatusTest {
Application default9 = tester.createAndDeploy("default9", 13, "default");
Application conservative0 = tester.createAndDeploy("conservative1", 14, "conservative");
-
- // The following applications should not affect confidence calculation:
+ // Applications that do not affect confidence calculation:
// Application without deployment
Application ignored0 = tester.createApplication("ignored0", "tenant1", 1000, 1000L);
@@ -157,30 +147,40 @@ public class VersionStatusTest {
"ignored1",
"default-pr42", 1000);
+ assertEquals("All applications running on this version: High",
+ Confidence.high, confidence(tester.controller(), version0));
+
+ // New version is released
Version version1 = new Version("5.1");
- Version version2 = new Version("5.2");
tester.upgradeSystem(version1);
// Canaries upgrade to new versions and fail
tester.completeUpgrade(canary0, version1, "canary");
tester.completeUpgradeWithError(canary1, version1, "canary", productionUsWest1);
- tester.upgradeSystem(version2);
- tester.completeUpgrade(canary2, version2, "canary");
-
- VersionStatus versionStatus = VersionStatus.compute(tester.controller());
- List<VespaVersion> versions = versionStatus.versions();
-
+ tester.updateVersionStatus();
assertEquals("One canary failed: Broken",
- VespaVersion.Confidence.broken, confidence(versions, version1));
- assertEquals("Nothing has failed but not all canaries has deployed: Low",
- VespaVersion.Confidence.low, confidence(versions, version2));
- assertEquals("Current version of this - no deployments: Low",
- VespaVersion.Confidence.low, confidence(versions, Vtag.currentVersion));
+ Confidence.broken, confidence(tester.controller(), version1));
- // All canaries are upgraded to version2 which raises confidence to normal and more apps upgrade
+ // New version is released
+ Version version2 = new Version("5.2");
+ tester.upgradeSystem(version2);
+ assertEquals("Confidence defaults to low for version with no applications",
+ Confidence.low, confidence(tester.controller(), version2));
+
+ // All canaries upgrade successfully
tester.completeUpgrade(canary0, version2, "canary");
tester.completeUpgrade(canary1, version2, "canary");
+
+ assertEquals("Confidence for remains unchanged for version1: Broken",
+ Confidence.broken, confidence(tester.controller(), version1));
+ assertEquals("Nothing has failed but not all canaries have upgraded: Low",
+ Confidence.low, confidence(tester.controller(), version2));
+
+ // Remaining canary upgrades to version2 which raises confidence to normal and more apps upgrade
+ tester.completeUpgrade(canary2, version2, "canary");
tester.upgradeSystem(version2);
+ assertEquals("Canaries have upgraded: Normal",
+ Confidence.normal, confidence(tester.controller(), version2));
tester.completeUpgrade(default0, version2, "default");
tester.completeUpgrade(default1, version2, "default");
tester.completeUpgrade(default2, version2, "default");
@@ -189,29 +189,27 @@ public class VersionStatusTest {
tester.completeUpgrade(default5, version2, "default");
tester.completeUpgrade(default6, version2, "default");
tester.completeUpgrade(default7, version2, "default");
+ tester.updateVersionStatus();
- versionStatus = VersionStatus.compute(tester.controller());
- versions = versionStatus.versions();
+ // Remember confidence across restart
+ tester.restartController();
- assertEquals("No deployments: Low",
- VespaVersion.Confidence.low, confidence(versions, version0));
+ assertEquals("Confidence remains unchanged for version0: High",
+ Confidence.high, confidence(tester.controller(), version0));
assertEquals("All canaries deployed + < 90% of defaults: Normal",
- VespaVersion.Confidence.normal, confidence(versions, version2));
- assertEquals("Current version of this - no deployments: Low",
- VespaVersion.Confidence.low, confidence(versions, Vtag.currentVersion));
+ Confidence.normal, confidence(tester.controller(), version2));
+ assertTrue("Status for version without applications is removed",
+ tester.controller().versionStatus().versions().stream()
+ .noneMatch(vespaVersion -> vespaVersion.versionNumber().equals(version1)));
// Another default application upgrades, raising confidence to high
tester.completeUpgrade(default8, version2, "default");
+ tester.updateVersionStatus();
- versionStatus = VersionStatus.compute(tester.controller());
- versions = versionStatus.versions();
-
- assertEquals("No deployments: Low",
- VespaVersion.Confidence.low, confidence(versions, version0));
+ assertEquals("Confidence remains unchanged for version0: High",
+ Confidence.high, confidence(tester.controller(), version0));
assertEquals("90% of defaults deployed successfully: High",
- VespaVersion.Confidence.high, confidence(versions, version2));
- assertEquals("Current version of this - no deployments: Low",
- VespaVersion.Confidence.low, confidence(versions, Vtag.currentVersion));
+ VespaVersion.Confidence.high, confidence(tester.controller(), version2));
// A new version is released, all canaries upgrade successfully, but enough "default" apps fail to mark version
// as broken
@@ -225,16 +223,14 @@ public class VersionStatusTest {
tester.completeUpgradeWithError(default1, version3, "default", stagingTest);
tester.completeUpgradeWithError(default2, version3, "default", stagingTest);
tester.completeUpgradeWithError(default9, version3, "default", stagingTest);
+ tester.updateVersionStatus();
- versionStatus = VersionStatus.compute(tester.controller());
- versions = versionStatus.versions();
-
- assertEquals("No deployments: Low",
- VespaVersion.Confidence.low, confidence(versions, version0));
+ assertEquals("Confidence remains unchanged for version0: High",
+ Confidence.high, confidence(tester.controller(), version0));
+ assertEquals("Confidence remains unchanged for version2: High",
+ Confidence.high, confidence(tester.controller(), version2));
assertEquals("40% of defaults failed: Broken",
- VespaVersion.Confidence.broken, confidence(versions, version3));
- assertEquals("Current version of this - no deployments: Low",
- VespaVersion.Confidence.low, confidence(versions, Vtag.currentVersion));
+ VespaVersion.Confidence.broken, confidence(tester.controller(), version3));
}
@Test
@@ -260,8 +256,8 @@ public class VersionStatusTest {
vespaVersions.stream().noneMatch(v -> v.versionNumber().equals(versionWithUnknownTag)));
}
- private VespaVersion.Confidence confidence(List<VespaVersion> versions, Version version) {
- return versions.stream()
+ private Confidence confidence(Controller controller, Version version) {
+ return controller.versionStatus().versions().stream()
.filter(v -> v.statistics().version().equals(version))
.findFirst()
.map(VespaVersion::confidence)