Search in sources :

Example 51 with ApplicationId

use of com.yahoo.config.provision.ApplicationId in project vespa by vespa-engine.

the class DynamicDockerProvisioningTest method relocate_nodes_from_headroom_hosts.

/**
 * Test relocation of nodes that violate headroom.
 * <p>
 * Setup 4 docker hosts and allocate one container on each (from two different applications)
 * No spares - only headroom (4xd-2)
 * <p>
 * One application is now violating headroom and need relocation
 * <p>
 * Initial allocation of app 1 and 2 --> final allocation (headroom marked as H):
 * <p>
 * | H  |  H  | H   | H   |        |    |    |    |    |
 * | H  |  H  | H1a | H1b |   -->  |    |    |    |    |
 * |    |     | 2a  | 2b  |        | 1a | 1b | 2a | 2b |
 */
@Test
public void relocate_nodes_from_headroom_hosts() {
    ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.perf, RegionName.from("us-east")), flavorsConfig(true));
    tester.makeReadyNodes(4, "host-small", NodeType.host, 32);
    deployZoneApp(tester);
    List<Node> dockerHosts = tester.nodeRepository().getNodes(NodeType.host, Node.State.active);
    Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-1");
    // Application 1
    ApplicationId application1 = makeApplicationId("t1", "a1");
    ClusterSpec clusterSpec1 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false);
    addAndAssignNode(application1, "1a", dockerHosts.get(2).hostname(), flavor, 0, tester);
    addAndAssignNode(application1, "1b", dockerHosts.get(3).hostname(), flavor, 1, tester);
    // Application 2
    ApplicationId application2 = makeApplicationId("t2", "a2");
    ClusterSpec clusterSpec2 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false);
    addAndAssignNode(application2, "2a", dockerHosts.get(2).hostname(), flavor, 0, tester);
    addAndAssignNode(application2, "2b", dockerHosts.get(3).hostname(), flavor, 1, tester);
    // Redeploy one of the applications
    deployapp(application1, clusterSpec1, flavor, tester, 2);
    // Assert that the nodes are spread across all hosts (to allow headroom)
    Set<String> hostsWithChildren = new HashSet<>();
    for (Node node : tester.nodeRepository().getNodes(NodeType.tenant, Node.State.active)) {
        if (!isInactiveOrRetired(node)) {
            hostsWithChildren.add(node.parentHostname().get());
        }
    }
    Assert.assertEquals(4, hostsWithChildren.size());
}
Also used : Zone(com.yahoo.config.provision.Zone) Node(com.yahoo.vespa.hosted.provision.Node) ClusterSpec(com.yahoo.config.provision.ClusterSpec) ApplicationId(com.yahoo.config.provision.ApplicationId) Flavor(com.yahoo.config.provision.Flavor) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 52 with ApplicationId

use of com.yahoo.config.provision.ApplicationId in project vespa by vespa-engine.

the class DynamicDockerProvisioningTest method new_docker_nodes_are_marked_as_headroom_violations.

/**
 * Test that new docker nodes that will result in headroom violations are
 * correctly marked as this.
 * <p>
 * When redeploying app1 - should not do anything (as moving app1 to host 0 and 1 would violate headroom).
 * Then redeploy app 2 - should cause a relocation.
 * <p>
 * | H  |  H  | H2a  | H2b  |         | H  |  H  |  H    |  H    |
 * | H  |  H  | H1a  | H1b  |  -->    | H  |  H  |  H1a  |  H1b  |
 * |    |     |  1a  |  1b  |         | 2a | 2b  |  1a   |  1b   |
 */
@Test
public void new_docker_nodes_are_marked_as_headroom_violations() {
    ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.perf, RegionName.from("us-east")), flavorsConfig(true));
    tester.makeReadyNodes(4, "host-small", NodeType.host, 32);
    deployZoneApp(tester);
    List<Node> dockerHosts = tester.nodeRepository().getNodes(NodeType.host, Node.State.active);
    Flavor flavorD2 = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-2");
    Flavor flavorD1 = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-1");
    // Application 1
    ApplicationId application1 = makeApplicationId("t1", "1");
    ClusterSpec clusterSpec1 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false);
    String hostParent2 = dockerHosts.get(2).hostname();
    String hostParent3 = dockerHosts.get(3).hostname();
    addAndAssignNode(application1, "1a", hostParent2, flavorD2, 0, tester);
    addAndAssignNode(application1, "1b", hostParent3, flavorD2, 1, tester);
    // Application 2
    ApplicationId application2 = makeApplicationId("t2", "2");
    ClusterSpec clusterSpec2 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false);
    addAndAssignNode(application2, "2a", hostParent2, flavorD1, 0, tester);
    addAndAssignNode(application2, "2b", hostParent3, flavorD1, 1, tester);
    // Assert allocation placement - prior to re-deployment
    assertApplicationHosts(tester.nodeRepository().getNodes(application1), hostParent2, hostParent3);
    assertApplicationHosts(tester.nodeRepository().getNodes(application2), hostParent2, hostParent3);
    // Redeploy application 1
    deployapp(application1, clusterSpec1, flavorD2, tester, 2);
    // Re-assert allocation placement
    assertApplicationHosts(tester.nodeRepository().getNodes(application1), hostParent2, hostParent3);
    assertApplicationHosts(tester.nodeRepository().getNodes(application2), hostParent2, hostParent3);
    // Redeploy application 2
    deployapp(application2, clusterSpec2, flavorD1, tester, 2);
    // Now app2 should have re-located
    assertApplicationHosts(tester.nodeRepository().getNodes(application1), hostParent2, hostParent3);
    assertApplicationHosts(tester.nodeRepository().getNodes(application2), dockerHosts.get(0).hostname(), dockerHosts.get(1).hostname());
}
Also used : Zone(com.yahoo.config.provision.Zone) Node(com.yahoo.vespa.hosted.provision.Node) ClusterSpec(com.yahoo.config.provision.ClusterSpec) ApplicationId(com.yahoo.config.provision.ApplicationId) Flavor(com.yahoo.config.provision.Flavor) Test(org.junit.Test)

Example 53 with ApplicationId

use of com.yahoo.config.provision.ApplicationId in project vespa by vespa-engine.

the class DynamicDockerProvisioningTest method spare_capacity_used_only_when_replacement.

@Test
public void spare_capacity_used_only_when_replacement() {
    // Use spare capacity only when replacement (i.e one node is failed)
    // Test should allocate as much capacity as possible, verify that it is not possible to allocate one more unit
    // Verify that there is still capacity (available spare)
    // Fail one node and redeploy, Verify that one less node is empty.
    ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.prod, RegionName.from("us-east")), flavorsConfig());
    // Only run test if there _is_ spare capacity
    if (tester.provisioner().getSpareCapacityProd() == 0) {
        return;
    }
    // Setup test
    ApplicationId application1 = tester.makeApplicationId();
    tester.makeReadyNodes(5, "host-small", NodeType.host, 32);
    deployZoneApp(tester);
    Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-3");
    // Deploy initial state (can max deploy 3 nodes due to redundancy requirements)
    List<HostSpec> hosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false), 3, 1, flavor.canonicalName());
    tester.activate(application1, ImmutableSet.copyOf(hosts));
    DockerHostCapacity capacity = new DockerHostCapacity(tester.nodeRepository().getNodes(Node.State.values()));
    assertThat(capacity.freeCapacityInFlavorEquivalence(flavor), greaterThan(0));
    List<Node> initialSpareCapacity = findSpareCapacity(tester);
    assertThat(initialSpareCapacity.size(), is(2));
    try {
        hosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false), 4, 1, flavor.canonicalName());
        fail("Was able to deploy with 4 nodes, should not be able to use spare capacity");
    } catch (OutOfCapacityException e) {
    }
    tester.fail(hosts.get(0));
    hosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false), 3, 1, flavor.canonicalName());
    tester.activate(application1, ImmutableSet.copyOf(hosts));
    List<Node> finalSpareCapacity = findSpareCapacity(tester);
    assertThat(finalSpareCapacity.size(), is(1));
}
Also used : Zone(com.yahoo.config.provision.Zone) Node(com.yahoo.vespa.hosted.provision.Node) OutOfCapacityException(com.yahoo.config.provision.OutOfCapacityException) ApplicationId(com.yahoo.config.provision.ApplicationId) HostSpec(com.yahoo.config.provision.HostSpec) Flavor(com.yahoo.config.provision.Flavor) Test(org.junit.Test)

Example 54 with ApplicationId

use of com.yahoo.config.provision.ApplicationId in project vespa by vespa-engine.

the class DynamicDockerProvisioningTest method deployZoneApp.

private List<HostSpec> deployZoneApp(ProvisioningTester tester) {
    ApplicationId applicationId = tester.makeApplicationId();
    List<HostSpec> list = tester.prepare(applicationId, ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("node-admin"), Version.fromString("6.42"), false), Capacity.fromRequiredNodeType(NodeType.host), 1);
    tester.activate(applicationId, ImmutableSet.copyOf(list));
    return list;
}
Also used : ApplicationId(com.yahoo.config.provision.ApplicationId) HostSpec(com.yahoo.config.provision.HostSpec)

Example 55 with ApplicationId

use of com.yahoo.config.provision.ApplicationId in project vespa by vespa-engine.

the class DynamicDockerProvisioningTest method multiple_groups_are_on_separate_parent_hosts.

@Test(expected = OutOfCapacityException.class)
public void multiple_groups_are_on_separate_parent_hosts() {
    ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.prod, RegionName.from("us-east")), flavorsConfig());
    tester.makeReadyNodes(5, "host-small", NodeType.host, 32);
    deployZoneApp(tester);
    Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-1");
    // Deploy an application of 6 nodes of 3 nodes in each cluster. We only have 3 docker hosts available
    ApplicationId application1 = tester.makeApplicationId();
    tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false), 6, 2, flavor.canonicalName());
    fail("Two groups have been allocated to the same parent host");
}
Also used : Zone(com.yahoo.config.provision.Zone) ApplicationId(com.yahoo.config.provision.ApplicationId) Flavor(com.yahoo.config.provision.Flavor) Test(org.junit.Test)

Aggregations

ApplicationId (com.yahoo.config.provision.ApplicationId)173 Test (org.junit.Test)102 Zone (com.yahoo.config.provision.Zone)52 Node (com.yahoo.vespa.hosted.provision.Node)30 ClusterSpec (com.yahoo.config.provision.ClusterSpec)22 TenantName (com.yahoo.config.provision.TenantName)20 Flavor (com.yahoo.config.provision.Flavor)19 List (java.util.List)16 HashSet (java.util.HashSet)15 HostSpec (com.yahoo.config.provision.HostSpec)12 Duration (java.time.Duration)12 HashMap (java.util.HashMap)12 Map (java.util.Map)12 Set (java.util.Set)12 Collectors (java.util.stream.Collectors)12 Version (com.yahoo.component.Version)11 OutOfCapacityException (com.yahoo.config.provision.OutOfCapacityException)11 Slime (com.yahoo.slime.Slime)11 ArrayList (java.util.ArrayList)11 Optional (java.util.Optional)11