diff options
author | Valerij Fredriksen <freva@users.noreply.github.com> | 2022-11-16 16:04:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-16 16:04:54 +0100 |
commit | 13d183d40b6c24aca38e05b4b6c17aa925a567ce (patch) | |
tree | 92107f1ec5e1d8717585117f54ac868403b244a1 | |
parent | 73dc53c96162318db101d508fd4f4b287e4651e3 (diff) | |
parent | e595c0cf98f1caecd70dbc5ed14ff03967a3ced0 (diff) |
Merge pull request #24894 from vespa-engine/bratseth/dynamic-shared-autoscaling
Support autoscaling in dynamic shared zones
16 files changed, 108 insertions, 73 deletions
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java index 1ae4974a4c2..313ae0d99ed 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java @@ -111,6 +111,7 @@ public class Flavor { public Type getType() { return type; } /** Convenience, returns getType() == Type.DOCKER_CONTAINER */ + // TODO: Remove after December 2022 public boolean isDocker() { return type == Type.DOCKER_CONTAINER; } @Override diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java index fc6ff3d0c56..0e9683a1a78 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java @@ -156,7 +156,7 @@ public class AllocatableClusterResources { public static Optional<AllocatableClusterResources> from(ClusterResources wantedResources, ClusterSpec clusterSpec, Limits applicationLimits, - NodeList hosts, + List<NodeResources> availableRealHostResources, NodeRepository nodeRepository) { var systemLimits = new NodeResourceLimits(nodeRepository); boolean exclusive = nodeRepository.exclusiveAllocation(clusterSpec); @@ -168,8 +168,7 @@ public class AllocatableClusterResources { var realResources = nodeRepository.resourcesCalculator().requestToReal(advertisedResources, exclusive); // What we'll really get if ( ! systemLimits.isWithinRealLimits(realResources, clusterSpec.type())) return Optional.empty(); - - if (matchesAny(hosts, advertisedResources)) + if (anySatisfies(realResources, availableRealHostResources)) return Optional.of(new AllocatableClusterResources(wantedResources.with(realResources), advertisedResources, wantedResources, @@ -212,11 +211,8 @@ public class AllocatableClusterResources { } /** Returns true if the given resources could be allocated on any of the given host flavors */ - private static boolean matchesAny(NodeList hosts, NodeResources advertisedResources) { - // Tenant nodes should not consume more than half the resources of the biggest hosts - // to make it easier to shift them between hosts. - return hosts.stream().anyMatch(host -> host.resources().withVcpu(host.resources().vcpu() / 2) - .satisfies(advertisedResources)); + private static boolean anySatisfies(NodeResources realResources, List<NodeResources> availableRealHostResources) { + return availableRealHostResources.stream().anyMatch(realHostResources -> realHostResources.satisfies(realResources)); } private static boolean between(NodeResources min, NodeResources max, NodeResources r) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java index 9a8b01f33af..1c99ea7dc08 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java @@ -6,6 +6,7 @@ import com.yahoo.config.provision.NodeResources; import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; +import java.util.List; import java.util.Optional; /** @@ -43,7 +44,11 @@ public class AllocationOptimizer { else limits = atLeast(minimumNodes, limits).fullySpecified(current.clusterSpec(), nodeRepository, clusterModel.application().id()); Optional<AllocatableClusterResources> bestAllocation = Optional.empty(); - NodeList hosts = nodeRepository.nodes().list().hosts(); + var availableRealHostResources = nodeRepository.zone().cloud().dynamicProvisioning() + ? nodeRepository.flavors().getFlavors().stream().map(flavor -> flavor.resources()).toList() + : nodeRepository.nodes().list().hosts().stream().map(host -> host.flavor().resources()) + .map(hostResources -> maxResourcesOf(hostResources, clusterModel)) + .toList(); for (int groups = limits.min().groups(); groups <= limits.max().groups(); groups++) { for (int nodes = limits.min().nodes(); nodes <= limits.max().nodes(); nodes++) { if (nodes % groups != 0) continue; @@ -53,7 +58,7 @@ public class AllocationOptimizer { nodeResourcesWith(nodes, groups, limits, targetLoad, current, clusterModel)); var allocatableResources = AllocatableClusterResources.from(resources, current.clusterSpec(), limits, - hosts, nodeRepository); + availableRealHostResources, nodeRepository); if (allocatableResources.isEmpty()) continue; if (bestAllocation.isEmpty() || allocatableResources.get().preferableTo(bestAllocation.get())) bestAllocation = allocatableResources; @@ -62,6 +67,13 @@ public class AllocationOptimizer { return bestAllocation; } + /** Returns the max resources of a host one node may allocate. */ + private NodeResources maxResourcesOf(NodeResources hostResources, ClusterModel clusterModel) { + if (nodeRepository.exclusiveAllocation(clusterModel.clusterSpec())) return hostResources; + // static, shared hosts: Allocate at most half of the host cpu to simplify management + return hostResources.withVcpu(hostResources.vcpu() / 2); + } + /** * For the observed load this instance is initialized with, returns the resources needed per node to be at * the target relative load, given a target node and group count. diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java index 46dd88b78d0..5ee4bdddd02 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java @@ -127,14 +127,14 @@ class NodeAllocation { boolean resizeable = requestedNodes.considerRetiring() && candidate.isResizable; boolean acceptToRetire = acceptToRetire(candidate); - if ((! saturated() && hasCompatibleFlavor(candidate) && requestedNodes.acceptable(candidate)) || acceptToRetire) { + if ((! saturated() && hasCompatibleResources(candidate) && requestedNodes.acceptable(candidate)) || acceptToRetire) { candidate = candidate.withNode(); if (candidate.isValid()) { acceptNode(candidate, shouldRetire(candidate, candidates), resizeable); } } } - else if (! saturated() && hasCompatibleFlavor(candidate)) { + else if (! saturated() && hasCompatibleResources(candidate)) { if (! nodeResourceLimits.isWithinRealLimits(candidate, cluster)) { ++rejectedDueToInsufficientRealResources; continue; @@ -169,7 +169,7 @@ class NodeAllocation { } if ( ! nodeResourceLimits.isWithinRealLimits(candidate, cluster)) return Retirement.outsideRealLimits; if (violatesParentHostPolicy(candidate)) return Retirement.violatesParentHostPolicy; - if ( ! hasCompatibleFlavor(candidate)) return Retirement.incompatibleFlavor; + if ( ! hasCompatibleResources(candidate)) return Retirement.incompatibleResources; if (candidate.wantToRetire()) return Retirement.hardRequest; if (candidate.preferToRetire() && candidate.replaceableBy(candidates)) return Retirement.softRequest; if (violatesExclusivity(candidate)) return Retirement.violatesExclusivity; @@ -241,11 +241,11 @@ class NodeAllocation { if (! requestedNodes.considerRetiring()) return false; return cluster.isStateful() || - (cluster.type() == ClusterSpec.Type.container && !hasCompatibleFlavor(candidate)); + (cluster.type() == ClusterSpec.Type.container && !hasCompatibleResources(candidate)); } - private boolean hasCompatibleFlavor(NodeCandidate candidate) { - return requestedNodes.isCompatible(candidate.flavor(), nodeRepository.flavors()) || candidate.isResizable; + private boolean hasCompatibleResources(NodeCandidate candidate) { + return requestedNodes.isCompatible(candidate.resources()) || candidate.isResizable; } private Node acceptNode(NodeCandidate candidate, Retirement retirement, boolean resizeable) { @@ -391,7 +391,7 @@ class NodeAllocation { } else if (deltaRetiredCount < 0) { // unretire until deltaRetiredCount is 0 for (NodeCandidate candidate : byUnretiringPriority(nodes.values())) { - if ( candidate.allocation().get().membership().retired() && hasCompatibleFlavor(candidate) ) { + if (candidate.allocation().get().membership().retired() && hasCompatibleResources(candidate) ) { candidate = candidate.withNode(); if (candidate.isResizable) candidate = candidate.withNode(resize(candidate.toNode())); @@ -482,7 +482,7 @@ class NodeAllocation { alreadyRetired("node is already retired"), outsideRealLimits("node real resources is outside limits"), violatesParentHostPolicy("node violates parent host policy"), - incompatibleFlavor("node flavor is incompatible"), + incompatibleResources("node resources are incompatible"), hardRequest("node is requested to retire"), softRequest("node is requested to retire (soft)"), violatesExclusivity("node violates host exclusivity"), diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java index a2f5eabf447..54c24977fef 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java @@ -28,8 +28,8 @@ public interface NodeSpec { /** Returns whether the hosts running the nodes of this application can also run nodes of other applications. */ boolean isExclusive(); - /** Returns whether the given flavor is compatible with this spec */ - boolean isCompatible(Flavor flavor, NodeFlavors flavors); + /** Returns whether the given node resources is compatible with this spec */ + boolean isCompatible(NodeResources resources); /** Returns whether the given node count is sufficient to consider this spec fulfilled to the maximum amount */ boolean saturatedBy(int count); @@ -115,12 +115,8 @@ public interface NodeSpec { public NodeType type() { return NodeType.tenant; } @Override - public boolean isCompatible(Flavor flavor, NodeFlavors flavors) { - if (flavor.isDocker()) { // Docker nodes can satisfy a request for parts of their resources - return flavor.resources().compatibleWith(requestedNodeResources); - } else { // Other nodes must be matched exactly - return requestedNodeResources.equals(flavor.resources()); - } + public boolean isCompatible(NodeResources resources) { + return requestedNodeResources.compatibleWith(resources); } @Override @@ -208,7 +204,7 @@ public interface NodeSpec { public boolean isExclusive() { return false; } @Override - public boolean isCompatible(Flavor flavor, NodeFlavors flavors) { return true; } + public boolean isCompatible(NodeResources resources) { return true; } @Override public boolean saturatedBy(int count) { return false; } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java index aa4c763fcdc..5a8c5221c47 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.provision.testutils; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.Cloud; import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Flavor; @@ -45,19 +46,21 @@ public class MockHostProvisioner implements HostProvisioner { private int deprovisionedHosts = 0; private EnumSet<Behaviour> behaviours = EnumSet.noneOf(Behaviour.class); private Optional<Flavor> hostFlavor = Optional.empty(); + private Cloud cloud; - public MockHostProvisioner(List<Flavor> flavors, MockNameResolver nameResolver, int memoryTaxGb) { + public MockHostProvisioner(List<Flavor> flavors, MockNameResolver nameResolver, int memoryTaxGb, Cloud cloud) { this.flavors = List.copyOf(flavors); this.nameResolver = nameResolver; this.memoryTaxGb = memoryTaxGb; + this.cloud = cloud; } - public MockHostProvisioner(List<Flavor> flavors) { - this(flavors, 0); + public MockHostProvisioner(List<Flavor> flavors, Cloud cloud) { + this(flavors, 0, cloud); } - public MockHostProvisioner(List<Flavor> flavors, int memoryTaxGb) { - this(flavors, new MockNameResolver().mockAnyLookup(), memoryTaxGb); + public MockHostProvisioner(List<Flavor> flavors, int memoryTaxGb, Cloud cloud) { + this(flavors, new MockNameResolver().mockAnyLookup(), memoryTaxGb, cloud); } @Override @@ -65,8 +68,10 @@ public class MockHostProvisioner implements HostProvisioner { ApplicationId applicationId, Version osVersion, HostSharing sharing, Optional<ClusterSpec.Type> clusterType, CloudAccount cloudAccount, Consumer<List<ProvisionedHost>> provisionedHostsConsumer) { + boolean exclusive = sharing == HostSharing.exclusive || ! cloud.allowHostSharing(); Flavor hostFlavor = this.hostFlavor.orElseGet(() -> flavors.stream() - .filter(f -> compatible(f, resources)) + .filter(f -> exclusive ? compatible(f, resources) + : f.resources().satisfies(resources)) .findFirst() .orElseThrow(() -> new NodeAllocationException("No host flavor matches " + resources, true))); List<ProvisionedHost> hosts = new ArrayList<>(); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java index 4f3a3fd5afa..1b76f0a36fd 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java @@ -34,12 +34,12 @@ public class AutoscalingTest { @Test public void test_autoscaling_single_content_group() { - var fixture = AutoscalingTester.fixture().hostCount(20).build(); + var fixture = AutoscalingTester.fixture().awsProdSetup(true).build(); fixture.loader().applyCpuLoad(0.7f, 10); - ClusterResources scaledResources = fixture.tester().assertResources("Scaling up since resource usage is too high", - 9, 1, 3.6, 8, 37.5, - fixture.autoscale()); + var scaledResources = fixture.tester().assertResources("Scaling up since resource usage is too high", + 9, 1, 3.6, 8.3, 37.7, + fixture.autoscale()); fixture.deploy(Capacity.from(scaledResources)); assertTrue("Cluster in flux -> No further change", fixture.autoscale().isEmpty()); @@ -55,14 +55,22 @@ public class AutoscalingTest { fixture.tester().clock().advance(Duration.ofDays(2)); fixture.loader().applyCpuLoad(0.1f, 10); fixture.tester().assertResources("Scaling cpu down since usage has gone down significantly", - 8, 1, 1.0, 8.1, 38.1, + 8, 1, 1.0, 8.5, 38.5, fixture.autoscale()); } /** Using too many resources for a short period is proof we should scale up regardless of the time that takes. */ @Test - public void test_no_autoscaling_with_no_measurements() { + public void test_no_autoscaling_with_no_measurements_shared_hosts() { + var fixture = AutoscalingTester.fixture().awsProdSetup(true).build(); + assertTrue(fixture.autoscale().target().isEmpty()); + } + + /** Using too many resources for a short period is proof we should scale up regardless of the time that takes. */ + @Test + public void test_no_autoscaling_with_no_measurements_exclusive_hosts() { var fixture = AutoscalingTester.fixture().awsProdSetup(false).build(); + System.out.println(fixture.autoscale().target()); assertTrue(fixture.autoscale().target().isEmpty()); } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java index 0eb65511299..56f23e62f90 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.provision.autoscale; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Capacity; +import com.yahoo.config.provision.Cloud; import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Flavor; @@ -53,7 +54,7 @@ class AutoscalingTester { provisioningTester = new ProvisioningTester.Builder().zone(zone) .flavors(flavors) .resourcesCalculator(resourcesCalculator) - .hostProvisioner(zone.cloud().dynamicProvisioning() ? new MockHostProvisioner(flavors) : null) + .hostProvisioner(zone.cloud().dynamicProvisioning() ? new MockHostProvisioner(flavors, zone.cloud()) : null) .build(); hostResourcesCalculator = resourcesCalculator; @@ -209,7 +210,7 @@ class AutoscalingTester { public static class MockHostResourcesCalculator implements HostResourcesCalculator { private final Zone zone; - private double memoryTax = 0; + private double memoryTax; public MockHostResourcesCalculator(Zone zone, double memoryTax) { this.zone = zone; @@ -249,8 +250,8 @@ class AutoscalingTester { private class MockHostProvisioner extends com.yahoo.vespa.hosted.provision.testutils.MockHostProvisioner { - public MockHostProvisioner(List<Flavor> flavors) { - super(flavors); + public MockHostProvisioner(List<Flavor> flavors, Cloud cloud) { + super(flavors, cloud); } @Override diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/awsnodes/AwsHostResourcesCalculatorImpl.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/awsnodes/AwsHostResourcesCalculatorImpl.java index deb6f41c383..4609c0a4023 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/awsnodes/AwsHostResourcesCalculatorImpl.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/awsnodes/AwsHostResourcesCalculatorImpl.java @@ -9,6 +9,7 @@ import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.Nodelike; import com.yahoo.vespa.hosted.provision.provisioning.HostResourcesCalculator; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -44,9 +45,9 @@ public class AwsHostResourcesCalculatorImpl implements HostResourcesCalculator { @Override public NodeResources requestToReal(NodeResources advertisedResources, boolean exclusive) { - double memoryOverhead = compatibleFlavors(advertisedResources, exclusive) + double memoryOverhead = flavorsCompatibleWithAdvertised(advertisedResources, exclusive) .mapToDouble(flavor -> resourcesCalculator.memoryOverhead(flavor, advertisedResources, false)).max().orElse(0); - double diskOverhead = compatibleFlavors(advertisedResources, exclusive) + double diskOverhead = flavorsCompatibleWithAdvertised(advertisedResources, exclusive) .mapToDouble(flavor -> resourcesCalculator.diskOverhead(flavor, advertisedResources, false, exclusive)).max().orElse(0); return advertisedResources.withMemoryGb(advertisedResources.memoryGb() - memoryOverhead) .withDiskGb(advertisedResources.diskGb() - diskOverhead); @@ -56,7 +57,7 @@ public class AwsHostResourcesCalculatorImpl implements HostResourcesCalculator { public NodeResources realToRequest(NodeResources realResources, boolean exclusive) { double worstMemoryOverhead = 0; double worstDiskOverhead = 0; - for (VespaFlavor flavor : flavors.values()) { + for (VespaFlavor flavor : flavorsCompatibleWithReal(realResources, exclusive)) { double memoryOverhead = resourcesCalculator.memoryOverhead(flavor, realResources, true); double diskOverhead = resourcesCalculator.diskOverhead(flavor, realResources, true, exclusive); NodeResources advertised = realResources.withMemoryGb(realResources.memoryGb() + memoryOverhead) @@ -77,11 +78,20 @@ public class AwsHostResourcesCalculatorImpl implements HostResourcesCalculator { } /** Returns the flavors of hosts which are eligible and matches the given advertised resources */ - private Stream<VespaFlavor> compatibleFlavors(NodeResources advertisedResources, boolean exclusive) { + private Stream<VespaFlavor> flavorsCompatibleWithAdvertised(NodeResources advertisedResources, boolean exclusive) { return flavors.values().stream() .filter(flavor -> exclusive ? flavor.advertisedResources().compatibleWith(advertisedResources) : flavor.advertisedResources().satisfies(advertisedResources)); } + /** Returns the flavors of hosts which are eligible and matches the given real resources */ + private List<VespaFlavor> flavorsCompatibleWithReal(NodeResources realResources, boolean exclusive) { + return flavors.values().stream() + .filter(flavor -> exclusive + ? flavor.realResources().compatibleWith(realResources) + : flavor.realResources().satisfies(realResources)) + .collect(Collectors.toList()); + } + } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/awsnodes/AwsResourcesCalculator.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/awsnodes/AwsResourcesCalculator.java index b16fcfc2739..63f6d50ab2e 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/awsnodes/AwsResourcesCalculator.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/awsnodes/AwsResourcesCalculator.java @@ -27,7 +27,7 @@ public class AwsResourcesCalculator { } /** - * Returns the memory overhead resulting if the given advertised resources are placed on the given node + * Returns the memory overhead resulting if the given resources are placed on the given node * * @param real true if the given resources are in real values, false if they are in advertised */ @@ -37,10 +37,11 @@ public class AwsResourcesCalculator { + hostMemory; // Approximate cost of host administration processes if (hostMemoryOverhead > hostFlavor.advertisedResources().memoryGb()) // An unusably small flavor, - hostMemoryOverhead = hostFlavor.advertisedResources().memoryGb(); // overhead cannot exceed what's available - + return resources.memoryGb(); // all will be overhead double memoryShare = resources.memoryGb() / ( hostFlavor.advertisedResources().memoryGb() - ( real ? hostMemoryOverhead : 0)); + if (memoryShare > 1) // The real resources of the host cannot fit the requested real resources after overhead + memoryShare = 1; return hostMemoryOverhead * memoryShare; } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DirtyExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DirtyExpirerTest.java index ac20b9164f8..8bdb0fb2daf 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DirtyExpirerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DirtyExpirerTest.java @@ -39,7 +39,7 @@ public class DirtyExpirerTest { private void assertAllocationAfterExpiry(boolean dynamicProvisioning) { Zone zone = new Zone(Cloud.builder().dynamicProvisioning(dynamicProvisioning).build(), SystemName.main, Environment.prod, RegionName.from("us-east")); ProvisioningTester tester = new ProvisioningTester.Builder().zone(zone) - .hostProvisioner(dynamicProvisioning ? new MockHostProvisioner(List.of()) : null) + .hostProvisioner(dynamicProvisioning ? new MockHostProvisioner(List.of(), zone.cloud()) : null) .build(); Node node = Node.create("id", "node1.domain.tld", new Flavor(NodeResources.unspecified()), Node.State.dirty, NodeType.tenant) diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DiskReplacerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DiskReplacerTest.java index ef0c524c48e..599303bb098 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DiskReplacerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DiskReplacerTest.java @@ -1,5 +1,6 @@ package com.yahoo.vespa.hosted.provision.maintenance; +import com.yahoo.config.provision.Cloud; import com.yahoo.config.provision.NodeResources; import com.yahoo.vespa.hosted.provision.node.Agent; import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester; @@ -17,7 +18,7 @@ import static org.junit.Assert.assertEquals; public class DiskReplacerTest { private final ProvisioningTester tester = new ProvisioningTester.Builder().build(); - private final MockHostProvisioner hostProvisioner = new MockHostProvisioner(List.of()); + private final MockHostProvisioner hostProvisioner = new MockHostProvisioner(List.of(), Cloud.defaultCloud()); private final DiskReplacer diskReplacer = new DiskReplacer(tester.nodeRepository(), Duration.ofDays(1), new TestMetric(), hostProvisioner); @Test diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainerTest.java index 4b90923efc2..409dc4dac1a 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainerTest.java @@ -274,6 +274,7 @@ public class HostCapacityMaintainerTest { tester.maintain(); // Hosts are provisioned + // TODO: Not thread safe as HostCapacityMaintainer may count hoists before we are done provisioning assertEquals(2, tester.provisionedHostsMatching(resources1)); assertEquals(0, tester.hostProvisioner.deprovisionedHosts()); @@ -623,10 +624,11 @@ public class HostCapacityMaintainerTest { } public DynamicProvisioningTester(Cloud cloud, MockNameResolver nameResolver) { - this.hostProvisioner = new MockHostProvisioner(flavors.getFlavors(), nameResolver, 0); - this.provisioningTester = new ProvisioningTester.Builder().zone(new Zone(cloud, SystemName.defaultSystem(), - Environment.defaultEnvironment(), - RegionName.defaultName())) + Zone zone = new Zone(cloud, SystemName.defaultSystem(), + Environment.defaultEnvironment(), + RegionName.defaultName()); + this.hostProvisioner = new MockHostProvisioner(flavors.getFlavors(), nameResolver, 0, cloud); + this.provisioningTester = new ProvisioningTester.Builder().zone(zone) .flavors(flavors.getFlavors()) .nameResolver(nameResolver) .flagSource(flagSource) diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisionerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisionerTest.java index bf51d80877c..64b32276ca2 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisionerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostResumeProvisionerTest.java @@ -38,12 +38,13 @@ public class HostResumeProvisionerTest { private final List<Flavor> flavors = FlavorConfigBuilder.createDummies("default").getFlavors(); private final MockNameResolver nameResolver = new MockNameResolver(); - private final MockHostProvisioner hostProvisioner = new MockHostProvisioner(flavors, nameResolver, 0); + private final Zone zone = new Zone(Cloud.builder().dynamicProvisioning(true).allowHostSharing(false).build(), + SystemName.defaultSystem(), + Environment.dev, + RegionName.defaultName()); + private final MockHostProvisioner hostProvisioner = new MockHostProvisioner(flavors, nameResolver, 0, zone.cloud()); private final ProvisioningTester tester = new ProvisioningTester.Builder() - .zone(new Zone(Cloud.builder().dynamicProvisioning(true).allowHostSharing(false).build(), - SystemName.defaultSystem(), - Environment.dev, - RegionName.defaultName())) + .zone(zone) .hostProvisioner(hostProvisioner) .nameResolver(nameResolver) .flavors(flavors) diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostRetirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostRetirerTest.java index a46946b7cee..c7e06676a2e 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostRetirerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/HostRetirerTest.java @@ -30,14 +30,15 @@ public class HostRetirerTest { @Test public void retire_hosts() { NodeFlavors flavors = FlavorConfigBuilder.createDummies("default"); - MockHostProvisioner hostProvisioner = new MockHostProvisioner(flavors.getFlavors()); + Zone zone = new Zone(Cloud.builder() + .dynamicProvisioning(true) + .build(), SystemName.defaultSystem(), + Environment.defaultEnvironment(), + RegionName.defaultName()); + MockHostProvisioner hostProvisioner = new MockHostProvisioner(flavors.getFlavors(), zone.cloud()); ProvisioningTester tester = new ProvisioningTester.Builder().hostProvisioner(hostProvisioner) .flavors(flavors.getFlavors()) - .zone(new Zone(Cloud.builder() - .dynamicProvisioning(true) - .build(), SystemName.defaultSystem(), - Environment.defaultEnvironment(), - RegionName.defaultName())) + .zone(zone) .build(); HostRetirer retirer = new HostRetirer(tester.nodeRepository(), Duration.ofDays(1), new MockMetric(), hostProvisioner); tester.makeReadyHosts(3, new NodeResources(24, 48, 1000, 10)) diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicProvisioningTest.java index 55c41cae1d4..53ce516c072 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicProvisioningTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicProvisioningTest.java @@ -226,7 +226,7 @@ public class DynamicProvisioningTest { ProvisioningTester tester = new ProvisioningTester.Builder().zone(zone) .flavors(flavors) - .hostProvisioner(new MockHostProvisioner(flavors, memoryTax)) + .hostProvisioner(new MockHostProvisioner(flavors, memoryTax, zone.cloud())) .nameResolver(nameResolver) .resourcesCalculator(memoryTax, 0) .build(); @@ -268,7 +268,7 @@ public class DynamicProvisioningTest { InMemoryFlagSource flagSource = new InMemoryFlagSource(); List<Flavor> flavors = List.of(new Flavor("x86", new NodeResources(1, 4, 50, 0.1, fast, local, Architecture.x86_64)), new Flavor("arm", new NodeResources(1, 4, 50, 0.1, fast, local, Architecture.arm64))); - MockHostProvisioner hostProvisioner = new MockHostProvisioner(flavors); + MockHostProvisioner hostProvisioner = new MockHostProvisioner(flavors, zone.cloud()); ProvisioningTester tester = new ProvisioningTester.Builder().zone(zone) .flavors(flavors) .hostProvisioner(hostProvisioner) @@ -315,7 +315,7 @@ public class DynamicProvisioningTest { ProvisioningTester tester = new ProvisioningTester.Builder().zone(zone) .flavors(flavors) - .hostProvisioner(new MockHostProvisioner(flavors, memoryTax)) + .hostProvisioner(new MockHostProvisioner(flavors, memoryTax, zone.cloud())) .nameResolver(nameResolver) .resourcesCalculator(memoryTax, 0) .build(); @@ -325,7 +325,7 @@ public class DynamicProvisioningTest { ApplicationId app1 = ProvisioningTester.applicationId("app1"); ClusterSpec cluster1 = ClusterSpec.request(ClusterSpec.Type.content, new ClusterSpec.Id("cluster1")).vespaVersion("7").build(); - // Limits where each number is within flavor limits but but which don't contain any flavor leads to an error + // Limits where each number is within flavor limits but which don't contain any flavor leads to an error try { tester.activate(app1, cluster1, Capacity.from(resources(8, 4, 3.8, 20, 40), resources(10, 5, 5, 25, 50))); @@ -390,7 +390,7 @@ public class DynamicProvisioningTest { ProvisioningTester tester = new ProvisioningTester.Builder().zone(zone) .flavors(flavors) - .hostProvisioner(new MockHostProvisioner(flavors, memoryTax)) + .hostProvisioner(new MockHostProvisioner(flavors, memoryTax, zone.cloud())) .nameResolver(nameResolver) .resourcesCalculator(memoryTax, 0) .build(); @@ -425,7 +425,7 @@ public class DynamicProvisioningTest { ProvisioningTester tester = new ProvisioningTester.Builder().zone(zone) .flavors(flavors) - .hostProvisioner(new MockHostProvisioner(flavors, memoryTax)) + .hostProvisioner(new MockHostProvisioner(flavors, memoryTax, zone.cloud())) .nameResolver(nameResolver) .resourcesCalculator(memoryTax, localDiskTax) .build(); |