summaryrefslogtreecommitdiffstats
path: root/controller-server/src/test
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2017-11-29 14:00:12 +0100
committerMartin Polden <mpolden@mpolden.no>2017-11-29 15:31:25 +0100
commit5c0c4397759b944b5dcd2b8c645ba898f4567746 (patch)
treedb52ce2090d5676bec6a90bfe775458acb06ace4 /controller-server/src/test
parent3d3c9227385b428cb3d2041103b5ec11dd615bd0 (diff)
Move rotation to application
Diffstat (limited to 'controller-server/src/test')
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java36
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java11
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java106
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java22
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java171
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/rotation/ControllerRotationRepositoryTest.java212
11 files changed, 291 insertions, 283 deletions
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 d0c1fd95427..b0fb820ca4c 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
@@ -11,9 +11,7 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
-import com.yahoo.slime.Slime;
import com.yahoo.vespa.config.SlimeUtils;
-import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.hosted.controller.api.Tenant;
import com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions;
import com.yahoo.vespa.hosted.controller.api.application.v4.model.EndpointStatus;
@@ -601,6 +599,7 @@ public class ControllerTest {
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.environment(Environment.prod)
+ .globalServiceId("foo")
.region("us-west-1")
.region("us-central-1") // Two deployments should result in DNS alias being registered once
.build();
@@ -610,7 +609,7 @@ public class ControllerTest {
Optional<Record> record = tester.controllerTester().nameService().findRecord(Record.Type.CNAME, "app1.tenant1.global.vespa.yahooapis.com");
assertTrue(record.isPresent());
assertEquals("app1.tenant1.global.vespa.yahooapis.com", record.get().name());
- assertEquals("fake-global-rotation-tenant1.app1", record.get().value());
+ assertEquals("rotation-fqdn-01", record.get().value());
}
@Test
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 8f9c22f8b81..f202deafa8a 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
@@ -41,7 +41,7 @@ import com.yahoo.vespa.hosted.controller.persistence.MemoryControllerDb;
import com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb;
import com.yahoo.vespa.hosted.controller.routing.MockRoutingGenerator;
import com.yahoo.vespa.hosted.controller.versions.VersionStatus;
-import com.yahoo.vespa.hosted.rotation.MemoryRotationRepository;
+import com.yahoo.vespa.hosted.rotation.config.RotationsConfig;
import java.util.Optional;
@@ -63,22 +63,31 @@ public final class ControllerTester {
private final GitHubMock gitHub;
private final CuratorDb curator;
private final MemoryNameService nameService;
+ private final RotationsConfig rotationsConfig;
private Controller controller;
public ControllerTester() {
this(new MemoryControllerDb(), new AthenzDbMock(), new ManualClock(), new ConfigServerClientMock(),
- new ZoneRegistryMock(), new GitHubMock(), new MockCuratorDb(), new MemoryNameService());
+ new ZoneRegistryMock(), new GitHubMock(), new MockCuratorDb(), defaultRotationsConfig(),
+ new MemoryNameService());
}
public ControllerTester(ManualClock clock) {
this(new MemoryControllerDb(), new AthenzDbMock(), clock, new ConfigServerClientMock(),
- new ZoneRegistryMock(), new GitHubMock(), new MockCuratorDb(), new MemoryNameService());
+ new ZoneRegistryMock(), new GitHubMock(), new MockCuratorDb(), defaultRotationsConfig(),
+ new MemoryNameService());
+ }
+
+ public ControllerTester(RotationsConfig rotationsConfig) {
+ this(new MemoryControllerDb(), new AthenzDbMock(), new ManualClock(), new ConfigServerClientMock(),
+ new ZoneRegistryMock(), new GitHubMock(), new MockCuratorDb(), rotationsConfig, new MemoryNameService());
}
private ControllerTester(ControllerDb db, AthenzDbMock athenzDb, ManualClock clock,
ConfigServerClientMock configServer, ZoneRegistryMock zoneRegistry,
- GitHubMock gitHub, CuratorDb curator, MemoryNameService nameService) {
+ GitHubMock gitHub, CuratorDb curator, RotationsConfig rotationsConfig,
+ MemoryNameService nameService) {
this.db = db;
this.athenzDb = athenzDb;
this.clock = clock;
@@ -87,7 +96,8 @@ public final class ControllerTester {
this.gitHub = gitHub;
this.curator = curator;
this.nameService = nameService;
- this.controller = createController(db, curator, configServer, clock, gitHub, zoneRegistry,
+ this.rotationsConfig = rotationsConfig;
+ this.controller = createController(db, curator, rotationsConfig, configServer, clock, gitHub, zoneRegistry,
athenzDb, nameService);
}
@@ -109,7 +119,8 @@ public final class ControllerTester {
/** Create a new controller instance. Useful to verify that controller state is rebuilt from persistence */
public final void createNewController() {
- controller = createController(db, curator, configServer, clock, gitHub, zoneRegistry, athenzDb, nameService);
+ controller = createController(db, curator, rotationsConfig, configServer, clock, gitHub, zoneRegistry, athenzDb,
+ nameService);
}
/** Creates the given tenant and application and deploys it */
@@ -214,13 +225,13 @@ public final class ControllerTester {
return new LockedApplication(application, new Lock("/test", new MockCurator()));
}
- private static Controller createController(ControllerDb db, CuratorDb curator,
+ private static Controller createController(ControllerDb db, CuratorDb curator, RotationsConfig rotationsConfig,
ConfigServerClientMock configServerClientMock, ManualClock clock,
GitHubMock gitHubClientMock, ZoneRegistryMock zoneRegistryMock,
AthenzDbMock athensDb, MemoryNameService nameService) {
Controller controller = new Controller(db,
curator,
- new MemoryRotationRepository(),
+ rotationsConfig,
gitHubClientMock,
new MemoryEntityService(),
new MockOrganization(clock),
@@ -237,4 +248,13 @@ public final class ControllerTester {
return controller;
}
+ private static RotationsConfig defaultRotationsConfig() {
+ RotationsConfig.Builder builder = new RotationsConfig.Builder();
+ for (int i = 1; i <= 10; i++) {
+ String id = String.format("%02d", i);
+ builder = builder.rotations("rotation-id-" + id, "rotation-fqdn-" + id);
+ }
+ return new RotationsConfig(builder);
+ }
+
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java
index 72bfa238094..96b096ccdd8 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/ApplicationPackageBuilder.java
@@ -26,6 +26,7 @@ public class ApplicationPackageBuilder {
private String upgradePolicy = null;
private Environment environment = Environment.prod;
+ private String globalServiceId = null;
private final StringBuilder environmentBody = new StringBuilder();
private final StringBuilder validationOverridesBody = new StringBuilder();
private final StringBuilder blockChange = new StringBuilder();
@@ -41,6 +42,11 @@ public class ApplicationPackageBuilder {
return this;
}
+ public ApplicationPackageBuilder globalServiceId(String globalServiceId) {
+ this.globalServiceId = globalServiceId;
+ return this;
+ }
+
public ApplicationPackageBuilder region(String regionName) {
environmentBody.append(" <region active='true'>");
environmentBody.append(regionName);
@@ -99,6 +105,11 @@ public class ApplicationPackageBuilder {
xml.append(blockChange);
xml.append(" <");
xml.append(environment.value());
+ if (globalServiceId != null) {
+ xml.append(" global-service-id='");
+ xml.append(globalServiceId);
+ xml.append("'");
+ }
xml.append(">\n");
xml.append(environmentBody);
xml.append(" </");
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 2c1471b29b6..bf869230e8d 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
@@ -25,6 +25,7 @@ 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 com.yahoo.vespa.hosted.controller.rotation.RotationId;
import org.junit.Test;
import java.io.IOException;
@@ -86,7 +87,8 @@ public class ApplicationSerializerTest {
Optional.of(new Change.VersionChange(Version.fromString("6.7"))),
true,
Optional.of(IssueId.from("1234")),
- new MetricsService.ApplicationMetrics(0.5, 0.9));
+ new MetricsService.ApplicationMetrics(0.5, 0.9),
+ Optional.of(new RotationId("my-rotation")));
Application serialized = applicationSerializer.fromSlime(applicationSerializer.toSlime(original));
@@ -115,6 +117,7 @@ public class ApplicationSerializerTest {
assertEquals(original.ownershipIssueId(), serialized.ownershipIssueId());
assertEquals(original.deploying(), serialized.deploying());
+ assertEquals(original.rotation().get().id(), serialized.rotation().get().id());
// Test cluster utilization
assertEquals(0, serialized.deployments().get(zone1).clusterUtils().size());
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 044c5d75d12..631ceab98a5 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
@@ -25,60 +25,70 @@ import static org.junit.Assert.assertEquals;
public class ControllerContainerTest {
protected JDisc container;
+
@Before
public void startContainer() { container = JDisc.fromServicesXml(controllerServicesXml, Networking.disable); }
+
@After
public void stopContainer() { container.close(); }
private final String controllerServicesXml =
- "<jdisc version='1.0'>" +
- " <config name='vespa.hosted.zone.config.zone'>" +
- " <system>main</system>" +
- " </config>" +
- " <component id='com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb'/>" +
- " <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'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.api.integration.github.GitHubMock'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.api.integration.routing.MemoryGlobalRoutingService'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.LoggingDeploymentIssues'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.DummyOwnershipIssues'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.api.integration.organization.MockOrganization'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.ConfigServerClientMock'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.ZoneRegistryMock'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.Controller'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.ConfigServerProxyMock'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.integration.MockMetricsService'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.maintenance.ControllerMaintenance'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.maintenance.JobControl'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.persistence.MemoryControllerDb'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.restapi.application.MockAuthorizer'/>" +
- " <component id='com.yahoo.vespa.hosted.controller.routing.MockRoutingGenerator'/>" +
- " <component id='com.yahoo.vespa.hosted.rotation.MemoryRotationRepository'/>" +
- " <handler id='com.yahoo.vespa.hosted.controller.restapi.RootHandler'>" +
- " <binding>http://*/</binding>" +
- " </handler>" +
- " <handler id='com.yahoo.vespa.hosted.controller.restapi.application.ApplicationApiHandler'>" +
- " <binding>http://*/application/v4/*</binding>" +
- " </handler>" +
- " <handler id='com.yahoo.vespa.hosted.controller.restapi.deployment.DeploymentApiHandler'>" +
- " <binding>http://*/deployment/v1/*</binding>" +
- " </handler>" +
- " <handler id='com.yahoo.vespa.hosted.controller.restapi.controller.ControllerApiHandler'>" +
- " <binding>http://*/controller/v1/*</binding>" +
- " </handler>" +
- " <handler id='com.yahoo.vespa.hosted.controller.restapi.screwdriver.ScrewdriverApiHandler'>" +
- " <binding>http://*/screwdriver/v1/*</binding>" +
- " </handler>" +
- " <handler id='com.yahoo.vespa.hosted.controller.restapi.zone.v1.ZoneApiHandler'>" +
- " <binding>http://*/zone/v1</binding>" +
- " <binding>http://*/zone/v1/*</binding>" +
- " </handler>" +
- " <handler id='com.yahoo.vespa.hosted.controller.restapi.zone.v2.ZoneApiHandler'>" +
- " <binding>http://*/zone/v2</binding>" +
- " <binding>http://*/zone/v2/*</binding>" +
- " </handler>" +
+ "<jdisc version='1.0'>\n" +
+ " <config name='vespa.hosted.zone.config.zone'>\n" +
+ " <system>main</system>\n" +
+ " </config>\n" +
+ " <config name=\"vespa.hosted.rotation.config.rotations\">\n" +
+ " <rotations>\n" +
+ " <item key=\"rotation-id-1\">rotation-fqdn-1</item>\n" +
+ " <item key=\"rotation-id-2\">rotation-fqdn-2</item>\n" +
+ " <item key=\"rotation-id-3\">rotation-fqdn-3</item>\n" +
+ " <item key=\"rotation-id-4\">rotation-fqdn-4</item>\n" +
+ " <item key=\"rotation-id-5\">rotation-fqdn-5</item>\n" +
+ " </rotations>\n" +
+ " </config>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.integration.chef.ChefMock'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.integration.dns.MemoryNameService'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.integration.entity.MemoryEntityService'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.integration.github.GitHubMock'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.integration.routing.MemoryGlobalRoutingService'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.LoggingDeploymentIssues'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.DummyOwnershipIssues'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.integration.organization.MockOrganization'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.ConfigServerClientMock'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.ZoneRegistryMock'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.Controller'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.ConfigServerProxyMock'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.integration.MockMetricsService'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.maintenance.ControllerMaintenance'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.maintenance.JobControl'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.persistence.MemoryControllerDb'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.restapi.application.MockAuthorizer'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.routing.MockRoutingGenerator'/>\n" +
+ " <handler id='com.yahoo.vespa.hosted.controller.restapi.RootHandler'>\n" +
+ " <binding>http://*/</binding>\n" +
+ " </handler>\n" +
+ " <handler id='com.yahoo.vespa.hosted.controller.restapi.application.ApplicationApiHandler'>\n" +
+ " <binding>http://*/application/v4/*</binding>\n" +
+ " </handler>\n" +
+ " <handler id='com.yahoo.vespa.hosted.controller.restapi.deployment.DeploymentApiHandler'>\n" +
+ " <binding>http://*/deployment/v1/*</binding>\n" +
+ " </handler>\n" +
+ " <handler id='com.yahoo.vespa.hosted.controller.restapi.controller.ControllerApiHandler'>\n" +
+ " <binding>http://*/controller/v1/*</binding>\n" +
+ " </handler>\n" +
+ " <handler id='com.yahoo.vespa.hosted.controller.restapi.screwdriver.ScrewdriverApiHandler'>\n" +
+ " <binding>http://*/screwdriver/v1/*</binding>\n" +
+ " </handler>\n" +
+ " <handler id='com.yahoo.vespa.hosted.controller.restapi.zone.v1.ZoneApiHandler'>\n" +
+ " <binding>http://*/zone/v1</binding>\n" +
+ " <binding>http://*/zone/v1/*</binding>\n" +
+ " </handler>\n" +
+ " <handler id='com.yahoo.vespa.hosted.controller.restapi.zone.v2.ZoneApiHandler'>\n" +
+ " <binding>http://*/zone/v2</binding>\n" +
+ " <binding>http://*/zone/v2/*</binding>\n" +
+ " </handler>\n" +
"</jdisc>";
protected void assertResponse(Request request, int responseStatus, String responseMessage) throws IOException {
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 bf4586f9fd0..3d73b5b110d 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
@@ -61,13 +61,18 @@ import static com.yahoo.application.container.handler.Request.Method.PUT;
public class ApplicationApiTest extends ControllerContainerTest {
private static final String responseFiles = "src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/";
+
private static final ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.environment(Environment.prod)
+ .globalServiceId("foo")
.region("corp-us-east-1")
+ .region("us-east-3")
+ .region("us-west-1")
.build();
+
private static final String athenzUserDomain = "domain1";
- private static final String athenzScrewdriverDomain = AthenzUtils.SCREWDRIVER_DOMAIN.id();
+ private static final String athenzScrewdriverDomain = AthenzUtils.SCREWDRIVER_DOMAIN.id();
@Test
public void testApplicationApi() throws Exception {
@@ -260,13 +265,6 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default", DELETE),
"Deactivated tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default");
- // DELETE an application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE),
- "");
- // DELETE a tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
- new File("tenant-without-applications.json"));
-
// PUT (create) the authenticated user
byte[] data = new byte[0];
tester.assertResponse(request("/application/v4/user?user=newuser&domain=by", PUT)
@@ -300,6 +298,13 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/promote", POST),
"{\"message\":\"Successfully copied environment hosted-instance_tenant1_application1_placeholder_component_default to hosted-instance_tenant1_application1_us-west-1_prod_default\"}");
+ // DELETE an application
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE),
+ "");
+ // DELETE a tenant
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
+ new File("tenant-without-applications.json"));
+
controllerTester.controller().deconstruct();
}
@@ -373,6 +378,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// New zone is added before us-east-3
applicationPackage = new ApplicationPackageBuilder()
+ .globalServiceId("foo")
// These decides the ordering of deploymentJobs and instances in the response
.region("us-west-1")
.region("us-east-3")
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json
index 6442ddf5c02..961e005bfbd 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json
@@ -205,7 +205,7 @@
],
"compileVersion": "(ignore)",
"globalRotations": [
- "http://fake-global-rotation-tenant1.application1"
+ "http://application1.tenant1.global.vespa.yahooapis.com:4080/"
],
"instances": [
{
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json
index fdd3dcc4d5c..3924cf51ca9 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json
@@ -146,7 +146,7 @@
],
"compileVersion": "(ignore)",
"globalRotations": [
- "http://fake-global-rotation-tenant1.application1"
+ "http://application1.tenant1.global.vespa.yahooapis.com:4080/"
],
"instances": [
{
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json
index 41556c04209..5030fc7d0a6 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json
@@ -146,7 +146,7 @@
],
"compileVersion": "6.1.0",
"globalRotations": [
- "http://fake-global-rotation-tenant1.application1"
+ "http://application1.tenant1.global.vespa.yahooapis.com:4080/"
],
"instances": [
@include(dev-us-west-1.json),
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java
new file mode 100644
index 00000000000..8fc41b8daa6
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java
@@ -0,0 +1,171 @@
+// 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.rotation;
+
+import com.yahoo.vespa.hosted.controller.Application;
+import com.yahoo.vespa.hosted.controller.ControllerTester;
+import com.yahoo.vespa.hosted.controller.application.ApplicationRotation;
+import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
+import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
+import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
+import com.yahoo.vespa.hosted.rotation.config.RotationsConfig;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.net.URI;
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * @author Oyvind Gronnesby
+ * @author mpolden
+ */
+public class RotationTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private final RotationsConfig rotationsConfig = new RotationsConfig(
+ new RotationsConfig.Builder()
+ .rotations("foo-1", "foo-1.com")
+ .rotations("foo-2", "foo-2.com")
+ );
+
+ private final RotationsConfig rotationsConfigWhitespaces = new RotationsConfig(
+ new RotationsConfig.Builder()
+ .rotations("foo-1", "\n foo-1.com \n")
+ .rotations("foo-2", "foo-2.com")
+ );
+
+ private final ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
+ .globalServiceId("foo")
+ .region("us-east-3")
+ .region("us-west-1")
+ .build();
+
+ private DeploymentTester tester;
+ private RotationRepository repository;
+ private Application application;
+
+ @Before
+ public void before() {
+ tester = new DeploymentTester(new ControllerTester(rotationsConfig));
+ repository = tester.controller().applications().rotationRepository();
+ application = tester.createApplication("app1", "tenant1", 11L,1L);
+ }
+
+ @Test
+ public void assigns_and_reuses_rotation() {
+ // Deploying assigns a rotation
+ tester.deployCompletely(application, applicationPackage);
+ Rotation expected = new Rotation(new RotationId("foo-1"), "foo-1.com");
+
+ application = tester.applications().require(application.id());
+ assertEquals(expected.id(), application.rotation().get().id());
+ assertEquals(URI.create("http://app1.tenant1.global.vespa.yahooapis.com:4080/"),
+ application.rotation().get().url());
+ Rotation rotation = repository.getRotation(tester.applications().require(application.id()));
+ assertEquals(expected, rotation);
+
+ // Deploying once more assigns same rotation
+ ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
+ .globalServiceId("foo")
+ .region("us-east-3")
+ .region("us-west-1")
+ .searchDefinition("search foo { }") // Update application package so there is something to deploy
+ .build();
+ tester.deployCompletely(application, applicationPackage);
+ assertEquals(expected.id(), tester.applications().require(application.id()).rotation().get().id());
+ }
+
+ @Test
+ public void strips_whitespace_in_rotation_fqdn() {
+ DeploymentTester tester = new DeploymentTester(new ControllerTester(rotationsConfigWhitespaces));
+ RotationRepository repository = tester.controller().applications().rotationRepository();
+ Application application = tester.createApplication("app2", "tenant2", 22L,
+ 2L);
+ tester.deployCompletely(application, applicationPackage);
+ application = tester.applications().require(application.id());
+
+ Rotation rotation = repository.getRotation(application);
+ Rotation assignedRotation = new Rotation(new RotationId("foo-1"), "foo-1.com");
+ assertEquals(assignedRotation, rotation);
+ }
+
+
+ @Test
+ public void out_of_rotations() {
+ // Assigns 1 rotation
+ tester.deployCompletely(application, applicationPackage);
+
+ // Assigns 1 more
+ Application application2 = tester.createApplication("app2", "tenant2", 22L,
+ 2L);
+ tester.deployCompletely(application2, applicationPackage);
+
+ // We're now out of rotations
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("no rotations available");
+ Application application3 = tester.createApplication("app3", "tenant3", 33L,
+ 3L);
+ tester.deployCompletely(application3, applicationPackage);
+ }
+
+ @Test
+ public void too_few_zones() {
+ ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
+ .globalServiceId("foo")
+ .region("us-east-3")
+ .build();
+ Application application = tester.createApplication("app2", "tenant2", 22L,
+ 2L);
+ thrown.expect(RuntimeException.class);
+ thrown.expectMessage("less than 2 prod zones are defined");
+ tester.deployCompletely(application, applicationPackage);
+ }
+
+ @Test
+ public void no_rotation_assigned_for_application_without_service_id() {
+ ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
+ .region("us-east-3")
+ .region("us-west-1")
+ .build();
+ tester.deployCompletely(application, applicationPackage);
+ Application app = tester.applications().require(application.id());
+ Optional<ApplicationRotation> rotation = app.rotation();
+ assertFalse(rotation.isPresent());
+ }
+
+ @Test
+ public void application_with_only_one_non_corp_region() {
+ ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
+ .globalServiceId("foo")
+ .region("us-east-3")
+ .region("corp-us-east-1")
+ .build();
+ Application application = tester.createApplication("app2", "tenant2", 22L,
+ 2L);
+ thrown.expect(RuntimeException.class);
+ thrown.expectMessage("less than 2 prod zones are defined");
+ tester.deployCompletely(application, applicationPackage);
+ }
+
+ @Test
+ public void application_with_corp_region_and_two_non_corp_region() {
+ ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
+ .globalServiceId("foo")
+ .region("us-east-3")
+ .region("corp-us-east-1")
+ .region("us-west-1")
+ .build();
+ Application application = tester.createApplication("app2", "tenant2", 22L,
+ 2L);
+ tester.deployCompletely(application, applicationPackage);
+ assertEquals(new RotationId("foo-1"), tester.applications().require(application.id())
+ .rotation().get().id());
+ }
+
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/rotation/ControllerRotationRepositoryTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/rotation/ControllerRotationRepositoryTest.java
deleted file mode 100644
index b4074fc1944..00000000000
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/rotation/ControllerRotationRepositoryTest.java
+++ /dev/null
@@ -1,212 +0,0 @@
-// 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.rotation;
-
-import com.yahoo.config.application.api.DeploymentSpec;
-import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.jdisc.Metric;
-import com.yahoo.vespa.hosted.controller.api.identifiers.RotationId;
-import com.yahoo.vespa.hosted.controller.api.rotation.Rotation;
-import com.yahoo.vespa.hosted.controller.persistence.ControllerDb;
-import com.yahoo.vespa.hosted.controller.persistence.MemoryControllerDb;
-import com.yahoo.vespa.hosted.rotation.config.RotationsConfig;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import java.io.StringReader;
-import java.net.URI;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-/**
- * @author Oyvind Gronnesby
- */
-public class ControllerRotationRepositoryTest {
-
- private final RotationsConfig rotationsConfig = new RotationsConfig(
- new RotationsConfig.Builder()
- .rotations("foo-1", "foo-1.com")
- .rotations("foo-2", "foo-2.com")
- );
- private final RotationsConfig rotationsConfigWhitespaces = new RotationsConfig(
- new RotationsConfig.Builder()
- .rotations("foo-1", "\n foo-1.com \n")
- .rotations("foo-2", "foo-2.com")
- );
- private final ControllerDb controllerDb = new MemoryControllerDb();
- private final ApplicationId applicationId = ApplicationId.from("msbe", "tumblr-search", "default");
-
- @Rule public ExpectedException thrown = ExpectedException.none();
-
- private final DeploymentSpec deploymentSpec = DeploymentSpec.fromXml(
- new StringReader(
- "<deployment>" +
- " <prod global-service-id='foo'>" +
- " <region active='true'>us-east</region>" +
- " <region active='true'>us-west</region>" +
- " </prod>" +
- "</deployment>"
- )
- );
-
- private final DeploymentSpec deploymentSpecOneRegion = DeploymentSpec.fromXml(
- new StringReader(
- "<deployment>" +
- " <prod global-service-id='nalle'>" +
- " <region active='true'>us-east</region>" +
- " </prod>" +
- "</deployment>"
- )
- );
-
- private final DeploymentSpec deploymentSpecNoServiceId = DeploymentSpec.fromXml(
- new StringReader(
- "<deployment>" +
- " <prod>" +
- " <region active='true'>us-east</region>" +
- " <region active='true'>us-west</region>" +
- " </prod>" +
- "</deployment>"
- )
- );
-
- private final DeploymentSpec deploymentSpecOnlyOneNonCorpRegion = DeploymentSpec.fromXml(
- new StringReader(
- "<deployment>" +
- " <prod global-service-id='nalle'>" +
- " <region active='true'>us-east</region>" +
- " <region active='true'>corp-us-west</region>" +
- " </prod>" +
- "</deployment>"
- )
- );
-
- private final DeploymentSpec deploymentSpecWithAdditionalCorpZone = DeploymentSpec.fromXml(
- new StringReader(
- "<deployment>" +
- " <prod global-service-id='nalle'>" +
- " <region active='true'>us-east</region>" +
- " <region active='true'>corp-us-west</region>" +
- " <region active='true'>us-west</region>" +
- " </prod>" +
- "</deployment>"
- )
- );
-
- private ControllerRotationRepository repository;
- private ControllerRotationRepository repositoryWhitespaces;
- private Metric metric;
-
- @Before
- public void setup_repository() {
- metric = mock(Metric.class);
- repository = new ControllerRotationRepository(rotationsConfig, controllerDb, metric);
- repositoryWhitespaces = new ControllerRotationRepository(rotationsConfigWhitespaces, controllerDb, metric);
- controllerDb.assignRotation(new RotationId("foo-1"), applicationId);
- }
-
- @Test
- public void application_with_rotation_reused() {
- Set<Rotation> rotations = repository.getOrAssignRotation(applicationId, deploymentSpec);
- Rotation assignedRotation = new Rotation(new RotationId("foo-1"), "foo-1.com");
- assertContainsOnly(assignedRotation, rotations);
- }
-
- @Test
- public void names_stripped() {
- Set<Rotation> rotations = repositoryWhitespaces.getOrAssignRotation(applicationId, deploymentSpec);
- Rotation assignedRotation = new Rotation(new RotationId("foo-1"), "foo-1.com");
- assertContainsOnly(assignedRotation, rotations);
- }
-
- @Test
- public void application_without_rotation() {
- ApplicationId other = ApplicationId.from("othertenant", "otherapplication", "default");
- Set<Rotation> rotations = repository.getOrAssignRotation(other, deploymentSpec);
- Rotation assignedRotation = new Rotation(new RotationId("foo-2"), "foo-2.com");
- assertContainsOnly(assignedRotation, rotations);
- verify(metric).set(eq(ControllerRotationRepository.REMAINING_ROTATIONS_METRIC_NAME), eq(1), any());
- }
-
- @Test
- public void application_without_rotation_but_none_left() {
- application_without_rotation(); // run this test to assign last rotation
- ApplicationId third = ApplicationId.from("thirdtenant", "thirdapplication", "default");
-
- thrown.expect(RuntimeException.class);
- thrown.expectMessage("no rotations available");
-
- repository.getOrAssignRotation(third, deploymentSpec);
- verify(metric).set(eq(ControllerRotationRepository.REMAINING_ROTATIONS_METRIC_NAME), eq(0), any());
- }
-
- @Test
- public void application_without_rotation_but_does_not_qualify() {
- ApplicationId other = ApplicationId.from("othertenant", "otherapplication", "default");
-
- thrown.expect(RuntimeException.class);
- thrown.expectMessage("less than 2 prod zones are defined");
-
- repository.getOrAssignRotation(other, deploymentSpecOneRegion);
- }
-
- @Test
- public void application_with_rotation_but_does_not_qualify() {
- Set<Rotation> rotations = repository.getOrAssignRotation(applicationId, deploymentSpecOneRegion);
- Rotation assignedRotation = new Rotation(new RotationId("foo-1"), "foo-1.com");
- assertContainsOnly(assignedRotation, rotations);
- }
-
- @Test
- public void application_with_rotation_is_listed() {
- repository.getOrAssignRotation(applicationId, deploymentSpec);
- Set<URI> uris = repository.getRotationUris(applicationId);
- assertEquals(Collections.singleton(URI.create("http://tumblr-search.msbe.global.vespa.yahooapis.com:4080/")), uris);
- }
-
- @Test
- public void application_without_rotation_is_empty() {
- ApplicationId other = ApplicationId.from("othertenant", "otherapplication", "default");
- Set<URI> uris = repository.getRotationUris(other);
- assertTrue(uris.isEmpty());
- }
-
- @Test
- public void application_without_serviceid_and_two_regions() {
- ApplicationId other = ApplicationId.from("othertenant", "otherapplication", "default");
- Set<Rotation> rotations = repository.getOrAssignRotation(other, deploymentSpecNoServiceId);
- assertTrue(rotations.isEmpty());
- }
-
- @Test
- public void application_with_only_one_non_corp_region() {
- ApplicationId other = ApplicationId.from("othertenant", "otherapplication", "default");
-
- thrown.expect(RuntimeException.class);
- thrown.expectMessage("less than 2 prod zones are defined");
-
- repository.getOrAssignRotation(other, deploymentSpecOnlyOneNonCorpRegion);
- }
-
- @Test
- public void application_with_corp_region_and_two_non_corp_region() {
- ApplicationId other = ApplicationId.from("othertenant", "otherapplication", "default");
- Set<Rotation> rotations = repository.getOrAssignRotation(other, deploymentSpecWithAdditionalCorpZone);
- assertContainsOnly(new Rotation(new RotationId("foo-2"), "foo-2.com"), rotations);
- }
-
- private static <T> void assertContainsOnly(T item, Collection<T> items) {
- assertTrue("Collection contains only " + item.toString(),
- items.size() == 1 && items.contains(item));
- }
-
-}