summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2020-10-02 15:08:22 +0200
committerGitHub <noreply@github.com>2020-10-02 15:08:22 +0200
commit6867d23640ee3a1b1d037dd3a1316ca323701721 (patch)
treecd4da56f2ed4b4c2e26885eec3e009a4efaccccd
parent9b9235fc145b531a6fc776ed1498a1edfe597f4c (diff)
parent46c7dfbd75cbbdd71c710116dc6025040dc97d84 (diff)
Merge pull request #14679 from vespa-engine/bratseth/dont-reactivate-on-retired-hosts
Don't reactivate on retired hosts
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java14
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java148
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java35
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java122
5 files changed, 125 insertions, 197 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
index 7158ccc57e3..e36d5fa4075 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
@@ -20,7 +20,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
-import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
@@ -30,8 +29,6 @@ import java.util.stream.Collectors;
*/
class Activator {
- private static final Logger logger = Logger.getLogger(Activator.class.getName());
-
private final NodeRepository nodeRepository;
private final Optional<LoadBalancerProvisioner> loadBalancerProvisioner;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java
index 9925ba65324..b6b05949082 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java
@@ -136,6 +136,7 @@ public class NodePrioritizer {
.filter(node -> legalStates.contains(node.state()))
.filter(node -> node.allocation().isPresent())
.filter(node -> node.allocation().get().owner().equals(application))
+ .filter(node -> node.state() == Node.State.active || canStillAllocateToParentOf(node))
.map(node -> candidateFrom(node, false))
.forEach(candidate -> nodes.add(candidate));
}
@@ -177,6 +178,19 @@ public class NodePrioritizer {
return requestedNodes.fulfilledBy(nofNodesInCluster - nodeFailedNodes);
}
+ /**
+ * We may regret that a non-active node is allocated to a host and not offer it to the application
+ * now, e.g if we want to retire the host.
+ *
+ * @return true if we still want to allocate the given node to its parent
+ */
+ private boolean canStillAllocateToParentOf(Node node) {
+ if (node.parentHostname().isEmpty()) return true;
+ Optional<Node> parent = node.parentHostname().flatMap(nodeRepository::getNode);
+ if (parent.isEmpty()) return false;
+ return nodeRepository.canAllocateTenantNodeTo(parent.get());
+ }
+
private static NodeResources resources(NodeSpec requestedNodes) {
if ( ! (requestedNodes instanceof NodeSpec.CountNodeSpec)) return null;
return requestedNodes.resources().get();
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
index d2a5e06469a..5abe7134aa0 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
@@ -46,10 +46,8 @@ public class DockerProvisioningTest {
@Test
public void docker_application_deployment() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
- ApplicationId application1 = ProvisioningTester.makeApplicationId();
-
- for (int i = 1; i < 10; i++)
- tester.makeReadyVirtualDockerNodes(1, dockerResources, "dockerHost" + i);
+ tester.makeReadyHosts(10, dockerResources).activateTenantHosts();
+ ApplicationId application1 = ProvisioningTester.makeApplicationId("app1");
Version wantedVespaVersion = Version.fromString("6.39");
int nodeCount = 7;
@@ -86,13 +84,12 @@ public class DockerProvisioningTest {
ApplicationId application1 = ProvisioningTester.makeApplicationId();
Version wantedVespaVersion = Version.fromString("6.39");
int nodeCount = 7;
- List<HostSpec> nodes = tester.prepare(application1,
- ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent")).vespaVersion(wantedVespaVersion).build(),
- nodeCount, 1, dockerResources);
try {
- tester.activate(application1, new HashSet<>(nodes));
+ List<HostSpec> nodes = tester.prepare(application1,
+ ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent")).vespaVersion(wantedVespaVersion).build(),
+ nodeCount, 1, dockerResources);
fail("Expected the allocation to fail due to parent hosts not being active yet");
- } catch (ParentHostUnavailableException ignored) { }
+ } catch (OutOfCapacityException expected) { }
// Activate the zone-app, thereby allocating the parents
List<HostSpec> hosts = tester.prepare(zoneApplication,
@@ -101,9 +98,9 @@ public class DockerProvisioningTest {
tester.activate(zoneApplication, hosts);
// Try allocating tenants again
- nodes = tester.prepare(application1,
- ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent")).vespaVersion(wantedVespaVersion).build(),
- nodeCount, 1, dockerResources);
+ List<HostSpec> nodes = tester.prepare(application1,
+ ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent")).vespaVersion(wantedVespaVersion).build(),
+ nodeCount, 1, dockerResources);
tester.activate(application1, new HashSet<>(nodes));
NodeList activeNodes = tester.getNodes(application1, Node.State.active);
@@ -152,53 +149,49 @@ public class DockerProvisioningTest {
/** Exclusive app first, then non-exclusive: Should give the same result as below */
@Test
public void docker_application_deployment_with_exclusive_app_first() {
+ NodeResources hostResources = new NodeResources(10, 40, 1000, 10);
+ NodeResources nodeResources = new NodeResources(1, 4, 100, 1);
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
- for (int i = 1; i <= 4; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host1");
- for (int i = 5; i <= 8; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host2");
- for (int i = 9; i <= 12; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host3");
- for (int i = 13; i <= 16; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host4");
-
- ApplicationId application1 = ProvisioningTester.makeApplicationId();
- prepareAndActivate(application1, 2, true, tester);
- assertEquals(Set.of("host1", "host2"), hostsOf(tester.getNodes(application1, Node.State.active)));
-
- ApplicationId application2 = ProvisioningTester.makeApplicationId();
- prepareAndActivate(application2, 2, false, tester);
+ tester.makeReadyHosts(4, hostResources).activateTenantHosts();
+ ApplicationId application1 = ProvisioningTester.makeApplicationId("app1");
+ prepareAndActivate(application1, 2, true, nodeResources, tester);
+ assertEquals(Set.of("host-1.yahoo.com", "host-2.yahoo.com"),
+ hostsOf(tester.getNodes(application1, Node.State.active)));
+
+ ApplicationId application2 = ProvisioningTester.makeApplicationId("app2");
+ prepareAndActivate(application2, 2, false, nodeResources, tester);
assertEquals("Application is assigned to separate hosts",
- Set.of("host3", "host4"), hostsOf(tester.getNodes(application2, Node.State.active)));
+ Set.of("host-3.yahoo.com", "host-4.yahoo.com"),
+ hostsOf(tester.getNodes(application2, Node.State.active)));
}
/** Non-exclusive app first, then an exclusive: Should give the same result as above */
@Test
public void docker_application_deployment_with_exclusive_app_last() {
+ NodeResources hostResources = new NodeResources(10, 40, 1000, 10);
+ NodeResources nodeResources = new NodeResources(1, 4, 100, 1);
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
- for (int i = 1; i <= 4; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host1");
- for (int i = 5; i <= 8; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host2");
- for (int i = 9; i <= 12; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host3");
- for (int i = 13; i <= 16; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host4");
-
- ApplicationId application1 = ProvisioningTester.makeApplicationId();
- prepareAndActivate(application1, 2, false, tester);
- assertEquals(Set.of("host1", "host2"), hostsOf(tester.getNodes(application1, Node.State.active)));
-
- ApplicationId application2 = ProvisioningTester.makeApplicationId();
- prepareAndActivate(application2, 2, true, tester);
+ tester.makeReadyHosts(4, hostResources).activateTenantHosts();
+ ApplicationId application1 = ProvisioningTester.makeApplicationId("app1");
+ prepareAndActivate(application1, 2, false, nodeResources, tester);
+ assertEquals(Set.of("host-1.yahoo.com", "host-2.yahoo.com"),
+ hostsOf(tester.getNodes(application1, Node.State.active)));
+
+ ApplicationId application2 = ProvisioningTester.makeApplicationId("app2");
+ prepareAndActivate(application2, 2, true, nodeResources, tester);
assertEquals("Application is assigned to separate hosts",
- Set.of("host3", "host4"), hostsOf(tester.getNodes(application2, Node.State.active)));
+ Set.of("host-3.yahoo.com", "host-4.yahoo.com"),
+ hostsOf(tester.getNodes(application2, Node.State.active)));
}
/** Test making an application exclusive */
@Test
public void docker_application_deployment_change_to_exclusive_and_back() {
+ NodeResources hostResources = new NodeResources(10, 40, 1000, 10);
+ NodeResources nodeResources = new NodeResources(1, 4, 100, 1);
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
+ tester.makeReadyHosts(4, hostResources).activateTenantHosts();
+ /*
for (int i = 1; i <= 4; i++)
tester.makeReadyVirtualDockerNode(i, dockerResources, "host1");
for (int i = 5; i <= 8; i++)
@@ -207,19 +200,20 @@ public class DockerProvisioningTest {
tester.makeReadyVirtualDockerNode(i, dockerResources, "host3");
for (int i = 13; i <= 16; i++)
tester.makeReadyVirtualDockerNode(i, dockerResources, "host4");
+ */
ApplicationId application1 = ProvisioningTester.makeApplicationId();
- prepareAndActivate(application1, 2, false, tester);
+ prepareAndActivate(application1, 2, false, nodeResources, tester);
for (Node node : tester.getNodes(application1, Node.State.active))
assertFalse(node.allocation().get().membership().cluster().isExclusive());
- prepareAndActivate(application1, 2, true, tester);
- assertEquals(Set.of("host1", "host2"), hostsOf(tester.getNodes(application1, Node.State.active)));
+ prepareAndActivate(application1, 2, true, nodeResources, tester);
+ assertEquals(Set.of("host-1.yahoo.com", "host-2.yahoo.com"), hostsOf(tester.getNodes(application1, Node.State.active)));
for (Node node : tester.getNodes(application1, Node.State.active))
assertTrue(node.allocation().get().membership().cluster().isExclusive());
- prepareAndActivate(application1, 2, false, tester);
- assertEquals(Set.of("host1", "host2"), hostsOf(tester.getNodes(application1, Node.State.active)));
+ prepareAndActivate(application1, 2, false, nodeResources, tester);
+ assertEquals(Set.of("host-1.yahoo.com", "host-2.yahoo.com"), hostsOf(tester.getNodes(application1, Node.State.active)));
for (Node node : tester.getNodes(application1, Node.State.active))
assertFalse(node.allocation().get().membership().cluster().isExclusive());
}
@@ -227,56 +221,34 @@ public class DockerProvisioningTest {
/** Non-exclusive app first, then an exclusive: Should give the same result as above */
@Test
public void docker_application_deployment_with_exclusive_app_causing_allocation_failure() {
+ ApplicationId application1 = ApplicationId.from("tenant1", "app1", "default");
+ ApplicationId application2 = ApplicationId.from("tenant2", "app2", "default");
+ ApplicationId application3 = ApplicationId.from("tenant1", "app3", "default");
+ NodeResources hostResources = new NodeResources(10, 40, 1000, 10);
+ NodeResources nodeResources = new NodeResources(1, 4, 100, 1);
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
- for (int i = 1; i <= 4; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host1");
- for (int i = 5; i <= 8; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host2");
- for (int i = 9; i <= 12; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host3");
- for (int i = 13; i <= 16; i++)
- tester.makeReadyVirtualDockerNode(i, dockerResources, "host4");
+ tester.makeReadyHosts(4, hostResources).activateTenantHosts();
- ApplicationId application1 = ProvisioningTester.makeApplicationId();
- prepareAndActivate(application1, 2, true, tester);
- assertEquals(Set.of("host1", "host2"), hostsOf(tester.getNodes(application1, Node.State.active)));
+ prepareAndActivate(application1, 2, true, nodeResources, tester);
+ assertEquals(Set.of("host-1.yahoo.com", "host-2.yahoo.com"),
+ hostsOf(tester.getNodes(application1, Node.State.active)));
try {
- ApplicationId application2 = ApplicationId.from("tenant1", "app1", "default");
- prepareAndActivate(application2, 3, false, tester);
+ prepareAndActivate(application2, 3, false, nodeResources, tester);
fail("Expected allocation failure");
}
catch (Exception e) {
assertEquals("No room for 3 nodes as 2 of 4 hosts are exclusive",
"Could not satisfy request for 3 nodes with " +
- "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, storage type: local] " +
- "in tenant1.app1 container cluster 'myContainer' 6.39: " +
+ "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps] " +
+ "in tenant2.app2 container cluster 'myContainer' 6.39: " +
"Out of capacity on group 0: " +
- "Not enough nodes available due to host exclusivity constraints, " +
- "insufficient nodes available on separate physical hosts",
+ "Not enough nodes available due to host exclusivity constraints",
e.getMessage());
}
// Adding 3 nodes of another application for the same tenant works
- ApplicationId application3 = ApplicationId.from(application1.tenant(), ApplicationName.from("app3"), InstanceName.from("default"));
- prepareAndActivate(application3, 2, true, tester);
- }
-
- // In dev, test and staging you get nodes with default flavor, but we should get specified flavor for docker nodes
- @Test
- public void get_specified_flavor_not_default_flavor_for_docker() {
- ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.test, RegionName.from("corp-us-east-1"))).build();
- ApplicationId application1 = ProvisioningTester.makeApplicationId();
- tester.makeReadyVirtualDockerNodes(1, dockerResources, "dockerHost");
-
- List<HostSpec> hosts = tester.prepare(application1,
- ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent")).vespaVersion("6.42").build(),
- 1, 1, dockerResources);
- tester.activate(application1, new HashSet<>(hosts));
-
- NodeList nodes = tester.getNodes(application1, Node.State.active);
- assertEquals(1, nodes.size());
- assertEquals("[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", nodes.asList().get(0).flavor().name());
+ prepareAndActivate(application3, 2, true, nodeResources, tester);
}
@Test
@@ -442,9 +414,13 @@ public class DockerProvisioningTest {
}
private void prepareAndActivate(ApplicationId application, int nodeCount, boolean exclusive, ProvisioningTester tester) {
+ prepareAndActivate(application, nodeCount, exclusive, dockerResources, tester);
+ }
+
+ private void prepareAndActivate(ApplicationId application, int nodeCount, boolean exclusive, NodeResources resources, ProvisioningTester tester) {
Set<HostSpec> hosts = new HashSet<>(tester.prepare(application,
ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer")).vespaVersion("6.39").exclusive(exclusive).build(),
- Capacity.from(new ClusterResources(nodeCount, 1, dockerResources), false, true)));
+ Capacity.from(new ClusterResources(nodeCount, 1, resources), false, true)));
tester.activate(application, hosts);
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
index 88f5d41a4f0..3d784c403f3 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
@@ -6,6 +6,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeResources;
@@ -158,9 +159,10 @@ public class LoadBalancerProvisionerTest {
@Test
public void provision_load_balancers_with_dynamic_node_provisioning() {
- var nodes = prepare(app1, Capacity.from(new ClusterResources(2, 1, new NodeResources(1, 4, 10, 0.3)), false, true),
- true,
- clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("qrs")));
+ NodeResources resources = new NodeResources(1, 4, 10, 0.3);
+ tester.makeReadyHosts(2, resources);
+ tester.activateTenantHosts();
+ var nodes = tester.prepare(app1, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("qrs")), 2 , 1, resources);
Supplier<LoadBalancer> lb = () -> tester.nodeRepository().loadBalancers(app1).asList().get(0);
assertTrue("Load balancer provisioned with empty reals", tester.loadBalancerService().instances().get(lb.get().id()).reals().isEmpty());
assignIps(tester.nodeRepository().getNodes(app1));
@@ -171,14 +173,12 @@ public class LoadBalancerProvisionerTest {
NestedTransaction removeTransaction = new NestedTransaction();
tester.provisioner().remove(removeTransaction, app1);
removeTransaction.commit();
- tester.nodeRepository().database().removeNodes(tester.nodeRepository().getNodes());
- assertTrue("Nodes are deleted", tester.nodeRepository().getNodes().isEmpty());
+ tester.nodeRepository().database().removeNodes(tester.nodeRepository().getNodes(NodeType.tenant));
+ assertTrue("Nodes are deleted", tester.nodeRepository().getNodes(NodeType.tenant).isEmpty());
assertSame("Load balancer is deactivated", LoadBalancer.State.inactive, lb.get().state());
// Application is redeployed
- nodes = prepare(app1, Capacity.from(new ClusterResources(2, 1, new NodeResources(1, 4, 10, 0.3)), false, true),
- true,
- clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("qrs")));
+ nodes = tester.prepare(app1, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("qrs")), 2 , 1, resources);
assertTrue("Load balancer is reconfigured with empty reals", tester.loadBalancerService().instances().get(lb.get().id()).reals().isEmpty());
assignIps(tester.nodeRepository().getNodes(app1));
tester.activate(app1, nodes);
@@ -188,7 +188,6 @@ public class LoadBalancerProvisionerTest {
@Test
public void does_not_provision_load_balancers_for_non_tenant_node_type() {
tester.activate(infraApp1, prepare(infraApp1, Capacity.fromRequiredNodeType(NodeType.host),
- false,
clusterRequest(ClusterSpec.Type.container,
ClusterSpec.Id.from("tenant-host"))));
assertTrue("No load balancer provisioned", tester.loadBalancerService().instances().isEmpty());
@@ -220,7 +219,7 @@ public class LoadBalancerProvisionerTest {
ApplicationId configServerApp = ApplicationId.from("hosted-vespa", "zone-config-servers", "default");
Supplier<List<LoadBalancer>> lbs = () -> tester.nodeRepository().loadBalancers(configServerApp).asList();
var cluster = ClusterSpec.Id.from("zone-config-servers");
- var nodes = prepare(configServerApp, Capacity.fromRequiredNodeType(NodeType.config), false,
+ var nodes = prepare(configServerApp, Capacity.fromRequiredNodeType(NodeType.config),
clusterRequest(ClusterSpec.Type.admin, cluster));
assertEquals(1, lbs.get().size());
assertEquals("Prepare provisions load balancer with reserved nodes", 2, lbs.get().get(0).instance().reals().size());
@@ -235,7 +234,7 @@ public class LoadBalancerProvisionerTest {
ApplicationId controllerApp = ApplicationId.from("hosted-vespa", "controller", "default");
Supplier<List<LoadBalancer>> lbs = () -> tester.nodeRepository().loadBalancers(controllerApp).asList();
var cluster = ClusterSpec.Id.from("zone-config-servers");
- var nodes = prepare(controllerApp, Capacity.fromRequiredNodeType(NodeType.controller), false,
+ var nodes = prepare(controllerApp, Capacity.fromRequiredNodeType(NodeType.controller),
clusterRequest(ClusterSpec.Type.container, cluster));
assertEquals(1, lbs.get().size());
assertEquals("Prepare provisions load balancer with reserved nodes", 2, lbs.get().get(0).instance().reals().size());
@@ -249,15 +248,11 @@ public class LoadBalancerProvisionerTest {
}
private Set<HostSpec> prepare(ApplicationId application, ClusterSpec... specs) {
- return prepare(application, Capacity.from(new ClusterResources(2, 1, new NodeResources(1, 4, 10, 0.3)), false, true), false, specs);
+ return prepare(application, Capacity.from(new ClusterResources(2, 1, new NodeResources(1, 4, 10, 0.3)), false, true), specs);
}
- private Set<HostSpec> prepare(ApplicationId application, Capacity capacity, boolean dynamicDockerNodes, ClusterSpec... specs) {
- if (dynamicDockerNodes) {
- makeDynamicDockerNodes(specs.length * 2, capacity.type());
- } else {
- tester.makeReadyNodes(specs.length * 2, new NodeResources(1, 4, 10, 0.3), capacity.type());
- }
+ private Set<HostSpec> prepare(ApplicationId application, Capacity capacity, ClusterSpec... specs) {
+ tester.makeReadyNodes(specs.length * 2, new NodeResources(1, 4, 10, 0.3), capacity.type());
Set<HostSpec> allNodes = new LinkedHashSet<>();
for (ClusterSpec spec : specs) {
allNodes.addAll(tester.prepare(application, spec, capacity));
@@ -266,9 +261,11 @@ public class LoadBalancerProvisionerTest {
}
private void makeDynamicDockerNodes(int n, NodeType nodeType) {
+ tester.makeReadyHosts(n, new NodeResources(1, 4, 10, 0.3));
List<Node> nodes = new ArrayList<>(n);
for (int i = 1; i <= n; i++) {
- var node = Node.createDockerNode(Set.of(), "node" + i, "parent" + i,
+ var node = Node.createDockerNode(Set.of(), "vnode" + i,
+ tester.nodeRepository().getNodes(NodeType.host).get(n - 1).hostname(),
new NodeResources(1, 4, 10, 0.3),
nodeType);
nodes.add(node);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
index b5e31e7cbdb..d1446cd8bc1 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
@@ -34,40 +34,37 @@ import static org.junit.Assert.assertNotNull;
// to remove these tests
public class VirtualNodeProvisioningTest {
- private static final NodeResources flavor = new NodeResources(4, 8, 100, 1);
+ private static final NodeResources resources = new NodeResources(4, 8, 100, 1);
private static final ClusterSpec contentClusterSpec = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent")).vespaVersion("6.42").build();
private static final ClusterSpec containerClusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer")).vespaVersion("6.42").build();
private ProvisioningTester tester = new ProvisioningTester.Builder().build();
- private ApplicationId applicationId = ProvisioningTester.makeApplicationId();
+ private ApplicationId applicationId = ProvisioningTester.makeApplicationId("test");
@Test
public void distinct_parent_host_for_each_node_in_a_cluster() {
- tester.makeReadyVirtualDockerNodes(2, flavor, "parentHost1");
- tester.makeReadyVirtualDockerNodes(2, flavor, "parentHost2");
- tester.makeReadyVirtualDockerNodes(2, flavor, "parentHost3");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost4");
-
- final int containerNodeCount = 4;
- final int contentNodeCount = 3;
- final int groups = 1;
- List<HostSpec> containerHosts = prepare(containerClusterSpec, containerNodeCount, groups);
- List<HostSpec> contentHosts = prepare(contentClusterSpec, contentNodeCount, groups);
+ tester.makeReadyHosts(4, new NodeResources(8, 16, 200, 2))
+ .activateTenantHosts();
+ int containerNodeCount = 4;
+ int contentNodeCount = 3;
+ int groups = 1;
+ List<HostSpec> containerHosts = tester.prepare(applicationId, containerClusterSpec, containerNodeCount, groups, resources);
+ List<HostSpec> contentHosts = tester.prepare(applicationId, contentClusterSpec, contentNodeCount, groups, resources);
activate(containerHosts, contentHosts);
- final List<Node> nodes = getNodes(applicationId);
+ List<Node> nodes = getNodes(applicationId);
assertEquals(contentNodeCount + containerNodeCount, nodes.size());
assertDistinctParentHosts(nodes, ClusterSpec.Type.container, containerNodeCount);
assertDistinctParentHosts(nodes, ClusterSpec.Type.content, contentNodeCount);
// Go down to 3 nodes in container cluster
- List<HostSpec> containerHosts2 = prepare(containerClusterSpec, containerNodeCount - 1, groups);
+ List<HostSpec> containerHosts2 = tester.prepare(applicationId, containerClusterSpec, containerNodeCount - 1, groups, resources);
activate(containerHosts2);
List<Node> nodes2 = getNodes(applicationId);
assertDistinctParentHosts(nodes2, ClusterSpec.Type.container, containerNodeCount - 1);
// Go up to 4 nodes again in container cluster
- List<HostSpec> containerHosts3 = prepare(containerClusterSpec, containerNodeCount, groups);
+ List<HostSpec> containerHosts3 = tester.prepare(applicationId, containerClusterSpec, containerNodeCount, groups, resources);
activate(containerHosts3);
List<Node> nodes3 = getNodes(applicationId);
assertDistinctParentHosts(nodes3, ClusterSpec.Type.container, containerNodeCount);
@@ -97,7 +94,7 @@ public class VirtualNodeProvisioningTest {
// Allowed to use same parent host for several nodes in same cluster in CD (even if prod env)
{
tester = new ProvisioningTester.Builder().zone(new Zone(SystemName.cd, Environment.prod, RegionName.from("us-east"))).build();
- tester.makeReadyNodes(4, flavor, NodeType.host, 1);
+ tester.makeReadyNodes(4, resources, NodeType.host, 1);
tester.prepareAndActivateInfraApplication(ProvisioningTester.makeApplicationId(), NodeType.host);
List<HostSpec> containerHosts = prepare(containerClusterSpec, containerNodeCount, groups);
@@ -110,19 +107,13 @@ public class VirtualNodeProvisioningTest {
@Test
public void will_retire_clashing_active() {
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost1");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost2");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost3");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost4");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost5");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost6");
-
+ tester.makeReadyHosts(4, resources).activateTenantHosts();
int containerNodeCount = 2;
int contentNodeCount = 2;
int groups = 1;
- List<HostSpec> containerHosts = prepare(containerClusterSpec, containerNodeCount, groups);
- List<HostSpec> contentHosts = prepare(contentClusterSpec, contentNodeCount, groups);
- activate(containerHosts, contentHosts);
+ List<HostSpec> containerNodes = tester.prepare(applicationId, containerClusterSpec, containerNodeCount, groups, resources);
+ List<HostSpec> contentNodes = tester.prepare(applicationId, contentClusterSpec, contentNodeCount, groups, resources);
+ activate(containerNodes, contentNodes);
List<Node> nodes = getNodes(applicationId);
assertEquals(4, nodes.size());
@@ -130,48 +121,19 @@ public class VirtualNodeProvisioningTest {
assertDistinctParentHosts(nodes, ClusterSpec.Type.content, contentNodeCount);
tester.patchNodes(nodes, (n) -> n.withParentHostname("clashing"));
- containerHosts = prepare(containerClusterSpec, containerNodeCount, groups);
- contentHosts = prepare(contentClusterSpec, contentNodeCount, groups);
- activate(containerHosts, contentHosts);
+ containerNodes = prepare(containerClusterSpec, containerNodeCount, groups);
+ contentNodes = prepare(contentClusterSpec, contentNodeCount, groups);
+ activate(containerNodes, contentNodes);
nodes = getNodes(applicationId);
assertEquals(6, nodes.size());
assertEquals(2, nodes.stream().filter(n -> n.allocation().get().membership().retired()).count());
}
- @Test
- public void fail_when_all_hosts_become_clashing() {
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost1");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost2");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost3");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost4");
-
- int containerNodeCount = 2;
- int contentNodeCount = 2;
- int groups = 1;
- List<HostSpec> containerHosts = prepare(containerClusterSpec, containerNodeCount, groups);
- List<HostSpec> contentHosts = prepare(contentClusterSpec, contentNodeCount, groups);
- activate(containerHosts, contentHosts);
-
- List<Node> nodes = getNodes(applicationId);
- assertEquals(4, nodes.size());
- assertDistinctParentHosts(nodes, ClusterSpec.Type.container, containerNodeCount);
- assertDistinctParentHosts(nodes, ClusterSpec.Type.content, contentNodeCount);
-
- tester.patchNodes(nodes, (n) -> n.withParentHostname("clashing"));
- OutOfCapacityException expected = null;
- try {
- containerHosts = prepare(containerClusterSpec, containerNodeCount, groups);
- } catch (OutOfCapacityException e) {
- expected = e;
- }
- assertNotNull(expected);
- }
-
@Test(expected = OutOfCapacityException.class)
public void fail_when_too_few_distinct_parent_hosts() {
- tester.makeReadyVirtualDockerNodes(2, flavor, "parentHost1");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost2");
+ tester.makeReadyVirtualDockerNodes(2, resources, "parentHost1");
+ tester.makeReadyVirtualDockerNodes(1, resources, "parentHost2");
int contentNodeCount = 3;
List<HostSpec> hosts = prepare(contentClusterSpec, contentNodeCount, 1);
@@ -182,26 +144,8 @@ public class VirtualNodeProvisioningTest {
}
@Test
- public void incomplete_parent_hosts_has_distinct_distribution() {
- tester.makeReadyVirtualDockerNode(1, flavor, "parentHost1");
- tester.makeReadyVirtualDockerNode(1, flavor, "parentHost2");
- tester.makeReadyVirtualNodes(1, flavor);
-
- final int contentNodeCount = 3;
- final int groups = 1;
- final List<HostSpec> contentHosts = prepare(contentClusterSpec, contentNodeCount, groups);
- activate(contentHosts);
- assertEquals(3, getNodes(applicationId).size());
-
- tester.makeReadyVirtualDockerNode(2, flavor, "parentHost1");
- tester.makeReadyVirtualDockerNode(2, flavor, "parentHost2");
-
- assertEquals(contentHosts, prepare(contentClusterSpec, contentNodeCount, groups));
- }
-
- @Test
public void indistinct_distribution_with_known_ready_nodes() {
- tester.makeReadyVirtualNodes(3, flavor);
+ tester.makeReadyVirtualNodes(3, resources);
final int contentNodeCount = 3;
final int groups = 1;
@@ -218,8 +162,8 @@ public class VirtualNodeProvisioningTest {
nodes = getNodes(applicationId);
assertEquals(3, nodes.stream().filter(n -> n.parentHostname().isPresent()).count());
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost1");
- tester.makeReadyVirtualDockerNodes(2, flavor, "parentHost2");
+ tester.makeReadyVirtualDockerNodes(1, resources, "parentHost1");
+ tester.makeReadyVirtualDockerNodes(2, resources, "parentHost2");
OutOfCapacityException expectedException = null;
try {
@@ -232,7 +176,7 @@ public class VirtualNodeProvisioningTest {
@Test
public void unknown_distribution_with_known_ready_nodes() {
- tester.makeReadyVirtualNodes(3, flavor);
+ tester.makeReadyVirtualNodes(3, resources);
final int contentNodeCount = 3;
final int groups = 1;
@@ -240,15 +184,15 @@ public class VirtualNodeProvisioningTest {
activate(contentHosts);
assertEquals(3, getNodes(applicationId).size());
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost1");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost2");
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost3");
+ tester.makeReadyVirtualDockerNodes(1, resources, "parentHost1");
+ tester.makeReadyVirtualDockerNodes(1, resources, "parentHost2");
+ tester.makeReadyVirtualDockerNodes(1, resources, "parentHost3");
assertEquals(contentHosts, prepare(contentClusterSpec, contentNodeCount, groups));
}
@Test
public void unknown_distribution_with_known_and_unknown_ready_nodes() {
- tester.makeReadyVirtualNodes(3, flavor);
+ tester.makeReadyVirtualNodes(3, resources);
int contentNodeCount = 3;
int groups = 1;
@@ -256,8 +200,8 @@ public class VirtualNodeProvisioningTest {
activate(contentHosts);
assertEquals(3, getNodes(applicationId).size());
- tester.makeReadyVirtualDockerNodes(1, flavor, "parentHost1");
- tester.makeReadyVirtualNodes(1, flavor);
+ tester.makeReadyVirtualDockerNodes(1, resources, "parentHost1");
+ tester.makeReadyVirtualNodes(1, resources);
assertEquals(contentHosts, prepare(contentClusterSpec, contentNodeCount, groups));
}
@@ -289,7 +233,7 @@ public class VirtualNodeProvisioningTest {
}
private List<HostSpec> prepare(ClusterSpec clusterSpec, int nodeCount, int groups) {
- return tester.prepare(applicationId, clusterSpec, nodeCount, groups, flavor);
+ return tester.prepare(applicationId, clusterSpec, nodeCount, groups, resources);
}
private List<HostSpec> prepare(ClusterSpec clusterSpec, int nodeCount, int groups, NodeResources flavor) {