package com.yahoo.vespa.model;
import com.yahoo.config.model.NullConfigModelRegistry;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.deploy.TestProperties;
import com.yahoo.config.model.provision.InMemoryProvisioner;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author bratseth
*/
public class ClusterInfoTest {
@Test
void bcp_deadline_is_passed_in_cluster_info() throws Exception {
var servicesXml = """
2
""";
var deploymentXml = """
us-west-1
us-east-1
eu-west-1
us-east-1
us-west-1
us-east-1
eu-west-1
""";
var requestedInUsEast1 = requestedCapacityIn("default", "us-east-1", servicesXml, deploymentXml);
assertEquals(Duration.ofMinutes(0), requestedInUsEast1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofMinutes(0), requestedInUsEast1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
var requestedInUsWest1 = requestedCapacityIn("default", "us-west-1", servicesXml, deploymentXml);
assertEquals(Duration.ofMinutes(30), requestedInUsWest1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofMinutes(30), requestedInUsWest1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
var requestedInEuWest1 = requestedCapacityIn("default", "eu-west-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInEuWest1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInEuWest1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
}
/** A high default deadline only will cause no resources to be set aside for BCP. */
@Test
void specifying_only_default_deadline_is_possible() throws Exception {
var servicesXml = """
2
""";
var deploymentXml = """
us-east-1
us-west-1
""";
var requestedInUsEast1 = requestedCapacityIn("default", "us-east-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInUsEast1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInUsEast1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
var requestedInUsWest1 = requestedCapacityIn("default", "us-west-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInUsWest1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInUsWest1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
}
/** This implicitly creates one BCP group (which gives the same result as above). */
@Test
void specifying_bcp_without_explicit_groups() throws Exception {
var servicesXml = """
2
""";
var deploymentXml = """
us-east-1
us-west-1
""";
var requestedInUsEast1 = requestedCapacityIn("default", "us-east-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInUsEast1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInUsEast1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
var requestedInUsWest1 = requestedCapacityIn("default", "us-west-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInUsWest1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInUsWest1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
}
@Test
void default_bcp_with_multiple_instances() throws Exception {
var servicesXml = """
2
""";
var deploymentXml = """
us-east-1
us-west-1
us-east-1
eu-west-1
""";
var requestedInI1UsEast1 = requestedCapacityIn("i1", "us-east-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInI1UsEast1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInI1UsEast1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
var requestedInI1UsWest1 = requestedCapacityIn("i1", "us-west-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInI1UsWest1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInI1UsWest1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
var requestedInI2UsEast1 = requestedCapacityIn("i2", "us-east-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInI2UsEast1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInI2UsEast1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
var requestedInI2UsWest1 = requestedCapacityIn("i2", "eu-west-1", servicesXml, deploymentXml);
assertEquals(Duration.ofHours(48), requestedInI2UsWest1.get(new ClusterSpec.Id("testcontainer")).clusterInfo().bcpDeadline());
assertEquals(Duration.ofHours(48), requestedInI2UsWest1.get(new ClusterSpec.Id("testcontent")).clusterInfo().bcpDeadline());
}
private Map requestedCapacityIn(String instance, String region, String servicesXml, String deploymentXml) throws Exception {
var applicationPackage = new MockApplicationPackage.Builder()
.withServices(servicesXml)
.withDeploymentSpec(deploymentXml)
.build();
var provisioner = new InMemoryProvisioner(10, true);
var deployState = new DeployState.Builder()
.applicationPackage(applicationPackage)
.zone(new Zone(Environment.prod, RegionName.from(region)))
.properties(new TestProperties().setHostedVespa(true)
.setApplicationId(ApplicationId.from(TenantName.defaultName(), ApplicationName.defaultName(), InstanceName.from(instance)))
.setZone(new Zone(Environment.prod, RegionName.from(region))))
.modelHostProvisioner(provisioner)
.provisioned(provisioner.provisioned())
.build();
new VespaModel(new NullConfigModelRegistry(), deployState);
return deployState.provisioned().all();
}
}