aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostFlavorUpgraderTest.java
blob: 9fe323201f098407f05f12bc591a6cdf728b665e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.yahoo.vespa.hosted.provision.maintenance;

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.NodeFlavors;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
import com.yahoo.vespa.hosted.provision.provisioning.FlavorConfigBuilder;
import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester;
import com.yahoo.vespa.hosted.provision.testutils.MockDeployer;
import com.yahoo.vespa.hosted.provision.testutils.MockHostProvisioner;
import com.yahoo.vespa.hosted.provision.testutils.MockHostProvisioner.Behaviour;
import org.junit.jupiter.api.Test;

import java.time.Duration;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
 * @author mpolden
 */
class HostFlavorUpgraderTest {

    @Test
    public void maintain() {
        String flavor0 = "host";
        String flavor1 = "host2";
        NodeFlavors flavors = FlavorConfigBuilder.createDummies(flavor0, flavor1);
        MockHostProvisioner hostProvisioner = new MockHostProvisioner(flavors.getFlavors());
        ProvisioningTester tester = new ProvisioningTester.Builder().dynamicProvisioning()
                                                                    .flavors(flavors.getFlavors())
                                                                    .hostProvisioner(hostProvisioner)
                                                                    .build();
        ApplicationId app = ProvisioningTester.applicationId();
        NodeResources resources = new NodeResources(4, 8, 100, 1,
                                                    NodeResources.DiskSpeed.fast, NodeResources.StorageType.remote);
        ClusterSpec spec = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("c1")).vespaVersion("1").build();
        Capacity capacity = Capacity.from(new ClusterResources(2, 1, resources));
        List<MockDeployer.ApplicationContext> applications = List.of(new MockDeployer.ApplicationContext(app, spec, capacity));
        MockDeployer deployer = new MockDeployer(tester.provisioner(), tester.clock(), applications);
        HostFlavorUpgrader upgrader = new HostFlavorUpgrader(tester.nodeRepository(), Duration.ofDays(1),
                                                             new TestMetric(), deployer, hostProvisioner);

        // Provision hosts and deploy application
        tester.makeReadyNodes(2, flavor0, NodeType.host);
        tester.activateTenantHosts();
        tester.deploy(app, spec, capacity);
        Node host = tester.nodeRepository().nodes().list().hosts().first().get();
        assertEquals(flavor0, host.flavor().name());

        // Nothing to upgrade initially
        assertEquals(1, upgrader.maintain());
        assertEquals(NodeList.of(), tester.nodeRepository().nodes().list()
                                          .matching(h -> h.status().wantToUpgradeFlavor()));

        // Mark flavor as upgradable, but fail all provisioning requests
        hostProvisioner.addUpgradableFlavor(flavor0)
                       .with(Behaviour.failProvisionRequest);
        assertEquals(1, upgrader.maintain());
        assertEquals(NodeList.of(),
                     tester.nodeRepository().nodes().list()
                           .matching(node -> node.status().wantToUpgradeFlavor() || node.status().wantToRetire()),
                     "No hosts marked for upgrade or retirement");

        // First provision request fails, but second succeeds and a replacement host starts provisioning
        hostProvisioner.with(Behaviour.failProvisionRequest, 1);
        assertEquals(1, upgrader.maintain());
        NodeList nodes = tester.nodeRepository().nodes().list();
        NodeList upgradingFlavor = nodes.matching(node -> node.status().wantToRetire() &&
                                                          node.status().wantToUpgradeFlavor());
        assertEquals(1, upgradingFlavor.size());
        assertEquals(1, nodes.state(Node.State.provisioned).size());

        // No more upgrades are started while host is retiring
        assertEquals(1, upgrader.maintain());
        assertEquals(upgradingFlavor, tester.nodeRepository().nodes().list()
                                            .matching(node -> node.status().wantToUpgradeFlavor()));
    }

}