summaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2020-05-26 11:26:38 +0200
committerJon Bratseth <bratseth@gmail.com>2020-05-26 11:26:38 +0200
commitc2f6a3263989d0d4943e7b42af515d152b125a3c (patch)
tree54eb3c0d920984e27c13ff9d323acc43a97a5b26 /node-repository
parent2269faa4bccda5e42fb6c9cc50eabf63873388f2 (diff)
Consider the lowest real resources we'll get when allocating
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java6
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java14
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java34
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java12
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java17
13 files changed, 72 insertions, 48 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java
index 3a3d3e4ec2e..e9e91910281 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Application.java
@@ -53,12 +53,12 @@ public class Application {
* Returns an application with the given cluster having the min and max resource limits of the given cluster.
* If the cluster has a target which is not inside the new limits, the target is removed.
*/
- public Application withClusterLimits(ClusterSpec.Id id, ClusterResources min, ClusterResources max) {
+ public Application withCluster(ClusterSpec.Id id, boolean exclusive, ClusterResources min, ClusterResources max) {
Cluster cluster = clusters.get(id);
if (cluster == null)
- cluster = new Cluster(id, min, max, Optional.empty(), Optional.empty());
+ cluster = new Cluster(id, exclusive, min, max, Optional.empty(), Optional.empty());
else
- cluster = cluster.withLimits(min, max);
+ cluster = cluster.withConfiguration(exclusive, min, max);
return with(cluster);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
index 847ec1290f6..3aae47a9088 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
@@ -19,16 +19,19 @@ import java.util.Optional;
public class Cluster {
private final ClusterSpec.Id id;
+ private final boolean exclusive;
private final ClusterResources min, max;
private final Optional<ClusterResources> suggested;
private final Optional<ClusterResources> target;
public Cluster(ClusterSpec.Id id,
+ boolean exclusive,
ClusterResources minResources,
ClusterResources maxResources,
Optional<ClusterResources> suggestedResources,
Optional<ClusterResources> targetResources) {
this.id = Objects.requireNonNull(id);
+ this.exclusive = exclusive;
this.min = Objects.requireNonNull(minResources);
this.max = Objects.requireNonNull(maxResources);
this.suggested = Objects.requireNonNull(suggestedResources);
@@ -47,6 +50,9 @@ public class Cluster {
/** Returns the configured maximal resources in this cluster */
public ClusterResources maxResources() { return max; }
+ /** Returns whether the nodes allocated to this cluster must be on host exclusively dedicated to this application */
+ public boolean exclusive() { return exclusive; }
+
/**
* Returns the computed resources (between min and max, inclusive) this cluster should
* have allocated at the moment (whether or not it actually has it),
@@ -60,16 +66,16 @@ public class Cluster {
*/
public Optional<ClusterResources> suggestedResources() { return suggested; }
- public Cluster withLimits(ClusterResources min, ClusterResources max) {
- return new Cluster(id, min, max, suggested, target);
+ public Cluster withConfiguration(boolean exclusive, ClusterResources min, ClusterResources max) {
+ return new Cluster(id, exclusive, min, max, suggested, target);
}
public Cluster withSuggested(Optional<ClusterResources> suggested) {
- return new Cluster(id, min, max, suggested, target);
+ return new Cluster(id, exclusive, min, max, suggested, target);
}
public Cluster withTarget(Optional<ClusterResources> target) {
- return new Cluster(id, min, max, suggested, target);
+ return new Cluster(id, exclusive, min, max, suggested, target);
}
@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 1637d99a07a..ff2ef433506 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
@@ -33,19 +33,19 @@ public class AllocatableClusterResources {
/** Fake allocatable resources from requested capacity */
public AllocatableClusterResources(ClusterResources requested, ClusterSpec.Type clusterType) {
- this.advertisedResources = requested.nodeResources();
- this.realResources = requested.nodeResources(); // we don't know
this.nodes = requested.nodes();
this.groups = requested.groups();
+ this.realResources = requested.nodeResources(); // we don't know
+ this.advertisedResources = requested.nodeResources();
this.clusterType = clusterType;
this.fulfilment = 1;
}
public AllocatableClusterResources(List<Node> nodes, NodeRepository nodeRepository) {
- this.advertisedResources = nodes.get(0).flavor().resources();
- this.realResources = nodeRepository.resourcesCalculator().realResourcesOf(nodes.get(0), nodeRepository);
this.nodes = nodes.size();
this.groups = (int)nodes.stream().map(node -> node.allocation().get().membership().cluster().group()).distinct().count();
+ this.realResources = nodeRepository.resourcesCalculator().realResourcesOf(nodes.get(0), nodeRepository);
+ this.advertisedResources = nodes.get(0).flavor().resources();
this.clusterType = nodes.get(0).allocation().get().membership().cluster().type();
this.fulfilment = 1;
}
@@ -54,23 +54,10 @@ public class AllocatableClusterResources {
NodeResources advertisedResources,
NodeResources idealResources,
ClusterSpec.Type clusterType) {
- this.realResources = realResources.nodeResources();
- this.advertisedResources = advertisedResources;
this.nodes = realResources.nodes();
this.groups = realResources.groups();
- this.clusterType = clusterType;
- this.fulfilment = fulfilment(realResources.nodeResources(), idealResources);
- }
-
- public AllocatableClusterResources(ClusterResources realResources,
- Flavor flavor,
- NodeResources idealResources,
- ClusterSpec.Type clusterType,
- HostResourcesCalculator calculator) {
this.realResources = realResources.nodeResources();
- this.advertisedResources = calculator.advertisedResourcesOf(flavor);
- this.nodes = realResources.nodes();
- this.groups = realResources.groups();
+ this.advertisedResources = advertisedResources;
this.clusterType = clusterType;
this.fulfilment = fulfilment(realResources.nodeResources(), idealResources);
}
@@ -127,7 +114,7 @@ public class AllocatableClusterResources {
public String toString() {
return nodes + " nodes " +
( groups > 1 ? "(in " + groups + " groups) " : "" ) +
- "with " + realResources() +
+ "with " + advertisedResources() +
" at cost $" + cost() +
(fulfilment < 1.0 ? " (fulfilment " + fulfilment + ")" : "");
}
@@ -137,6 +124,7 @@ public class AllocatableClusterResources {
* or empty if none available within the limits.
*/
public static Optional<AllocatableClusterResources> from(ClusterResources resources,
+ boolean exclusive,
ClusterSpec.Type clusterType,
Limits limits,
NodeRepository nodeRepository) {
@@ -146,8 +134,10 @@ public class AllocatableClusterResources {
if (nodeRepository.zone().getCloud().allowHostSharing()) {
// return the requested resources, or empty if they cannot fit on existing hosts
for (Flavor flavor : nodeRepository.flavors().getFlavors()) {
+ NodeResources realNodeResources = nodeRepository.resourcesCalculator().lowestRealResourcesAllocating(cappedNodeResources,
+ exclusive);
if (flavor.resources().satisfies(cappedNodeResources))
- return Optional.of(new AllocatableClusterResources(resources.with(cappedNodeResources),
+ return Optional.of(new AllocatableClusterResources(resources.with(realNodeResources),
cappedNodeResources,
resources.nodeResources(),
clusterType));
@@ -159,7 +149,8 @@ public class AllocatableClusterResources {
Optional<AllocatableClusterResources> best = Optional.empty();
for (Flavor flavor : nodeRepository.flavors().getFlavors()) {
NodeResources advertisedResources = nodeRepository.resourcesCalculator().advertisedResourcesOf(flavor);
- NodeResources realResources = flavor.resources();
+
+ NodeResources realResources = nodeRepository.resourcesCalculator().lowestRealResourcesAllocating(advertisedResources, exclusive);
// Adjust where we don't need exact match to the flavor
if (flavor.resources().storageType() == NodeResources.StorageType.remote) {
@@ -172,7 +163,6 @@ public class AllocatableClusterResources {
}
if ( ! between(limits.min().nodeResources(), limits.max().nodeResources(), advertisedResources)) continue;
-
var candidate = new AllocatableClusterResources(resources.with(realResources),
advertisedResources,
resources.nodeResources(),
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 475f2feaebd..d2589b15421 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
@@ -38,7 +38,8 @@ public class AllocationOptimizer {
*/
public Optional<AllocatableClusterResources> findBestAllocation(ResourceTarget target,
AllocatableClusterResources current,
- Limits limits) {
+ Limits limits,
+ boolean exclusive) {
if (limits.isEmpty())
limits = Limits.of(new ClusterResources(minimumNodes, 1, NodeResources.unspecified()),
new ClusterResources(maximumNodes, maximumNodes, NodeResources.unspecified()));
@@ -57,7 +58,7 @@ public class AllocationOptimizer {
groups,
nodeResourcesWith(nodesAdjustedForRedundancy, groupsAdjustedForRedundancy, limits, current, target));
- var allocatableResources = AllocatableClusterResources.from(next, current.clusterType(), limits, nodeRepository);
+ var allocatableResources = AllocatableClusterResources.from(next, exclusive, current.clusterType(), limits, nodeRepository);
if (allocatableResources.isEmpty()) continue;
if (bestAllocation.isEmpty() || allocatableResources.get().preferableTo(bestAllocation.get()))
bestAllocation = allocatableResources;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
index 8930bf34f4a..27731159e9f 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
@@ -53,7 +53,7 @@ public class Autoscaler {
* @return a new suggested allocation for this cluster, or empty if it should not be rescaled at this time
*/
public Optional<ClusterResources> suggest(Cluster cluster, List<Node> clusterNodes) {
- return autoscale(clusterNodes, Limits.empty())
+ return autoscale(clusterNodes, Limits.empty(), cluster.exclusive())
.map(AllocatableClusterResources::toAdvertisedClusterResources);
}
@@ -66,11 +66,11 @@ public class Autoscaler {
*/
public Optional<ClusterResources> autoscale(Cluster cluster, List<Node> clusterNodes) {
if (cluster.minResources().equals(cluster.maxResources())) return Optional.empty(); // Shortcut
- return autoscale(clusterNodes, Limits.of(cluster))
+ return autoscale(clusterNodes, Limits.of(cluster), cluster.exclusive())
.map(AllocatableClusterResources::toAdvertisedClusterResources);
}
- private Optional<AllocatableClusterResources> autoscale(List<Node> clusterNodes, Limits limits) {
+ private Optional<AllocatableClusterResources> autoscale(List<Node> clusterNodes, Limits limits, boolean exclusive) {
if (unstable(clusterNodes)) return Optional.empty();
ClusterSpec.Type clusterType = clusterNodes.get(0).allocation().get().membership().cluster().type();
@@ -82,7 +82,7 @@ public class Autoscaler {
var target = ResourceTarget.idealLoad(cpuLoad.get(), memoryLoad.get(), diskLoad.get(), currentAllocation);
Optional<AllocatableClusterResources> bestAllocation =
- allocationOptimizer.findBestAllocation(target, currentAllocation, limits);
+ allocationOptimizer.findBestAllocation(target, currentAllocation, limits, exclusive);
if (bestAllocation.isEmpty()) return Optional.empty();
if (similar(bestAllocation.get(), currentAllocation)) return Optional.empty();
return bestAllocation;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java
index b1453a9729a..3464e9dd881 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializer.java
@@ -35,6 +35,7 @@ public class ApplicationSerializer {
private static final String idKey = "id";
private static final String clustersKey = "clusters";
+ private static final String exclusiveKey = "exclusive";
private static final String minResourcesKey = "min";
private static final String maxResourcesKey = "max";
private static final String suggestedResourcesKey = "suggested";
@@ -80,6 +81,7 @@ public class ApplicationSerializer {
}
private static void toSlime(Cluster cluster, Cursor clusterObject) {
+ clusterObject.setBool(exclusiveKey, cluster.exclusive());
toSlime(cluster.minResources(), clusterObject.setObject(minResourcesKey));
toSlime(cluster.maxResources(), clusterObject.setObject(maxResourcesKey));
cluster.suggestedResources().ifPresent(suggested -> toSlime(suggested, clusterObject.setObject(suggestedResourcesKey)));
@@ -88,6 +90,7 @@ public class ApplicationSerializer {
private static Cluster clusterFromSlime(String id, Inspector clusterObject) {
return new Cluster(ClusterSpec.Id.from(id),
+ clusterObject.field(exclusiveKey).asBool(),
clusterResourcesFromSlime(clusterObject.field(minResourcesKey)),
clusterResourcesFromSlime(clusterObject.field(maxResourcesKey)),
optionalClusterResourcesFromSlime(clusterObject.field(suggestedResourcesKey)),
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java
index da54d89b4e5..9b2e63587b5 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java
@@ -39,6 +39,11 @@ public class EmptyProvisionServiceProvider implements ProvisionServiceProvider {
}
@Override
+ public NodeResources lowestRealResourcesAllocating(NodeResources advertisedResources, boolean exclusive) {
+ return advertisedResources;
+ }
+
+ @Override
public NodeResources advertisedResourcesOf(Flavor flavor) {
return flavor.resources();
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java
index 096e58e963e..8d2704e8572 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java
@@ -19,6 +19,9 @@ public interface HostResourcesCalculator {
/** Nodes use advertised resources. This returns the real resources for the node. */
NodeResources realResourcesOf(Node node, NodeRepository nodeRepository);
+ /** Returns the lowest possible real resources we may get if we request the given resources */
+ NodeResources lowestRealResourcesAllocating(NodeResources advertisedResources, boolean exclusive);
+
/** Flavors use real resources. This returns the advertised resources of the flavor. */
NodeResources advertisedResourcesOf(Flavor flavor);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
index 78ccf258675..09f7ad8f9c3 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
@@ -144,7 +144,7 @@ public class NodeRepositoryProvisioner implements Provisioner {
private ClusterResources decideTargetResources(ApplicationId applicationId, ClusterSpec clusterSpec, Capacity requested) {
try (Mutex lock = nodeRepository.lock(applicationId)) {
Application application = nodeRepository.applications().get(applicationId).orElse(new Application(applicationId));
- application = application.withClusterLimits(clusterSpec.id(), requested.minResources(), requested.maxResources());
+ application = application.withCluster(clusterSpec.id(), clusterSpec.isExclusive(), requested.minResources(), requested.maxResources());
nodeRepository.applications().put(application, lock);
return application.clusters().get(clusterSpec.id()).targetResources()
.orElseGet(() -> currentResources(applicationId, clusterSpec, requested));
@@ -163,15 +163,15 @@ public class NodeRepositoryProvisioner implements Provisioner {
AllocatableClusterResources currentResources =
nodes.isEmpty() ? new AllocatableClusterResources(requested.minResources(), clusterSpec.type()) // new deployment: Use min
: new AllocatableClusterResources(nodes, nodeRepository);
- return within(Limits.of(requested), currentResources);
+ return within(Limits.of(requested), clusterSpec.isExclusive(), currentResources);
}
/** Make the minimal adjustments needed to the current resources to stay within the limits */
- private ClusterResources within(Limits limits, AllocatableClusterResources current) {
+ private ClusterResources within(Limits limits, boolean exclusive, AllocatableClusterResources current) {
if (limits.isEmpty()) return current.toAdvertisedClusterResources();
if (limits.min().equals(limits.max())) return limits.min();
- return allocationOptimizer.findBestAllocation(ResourceTarget.preserve(current), current, limits)
+ return allocationOptimizer.findBestAllocation(ResourceTarget.preserve(current), current, limits, exclusive)
.orElseThrow(() -> new IllegalArgumentException("No allocation possible within " + limits))
.toAdvertisedClusterResources();
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java
index 032375943c8..e65abaa21ec 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingIntegrationTest.java
@@ -56,7 +56,7 @@ public class AutoscalingIntegrationTest {
ClusterResources max = new ClusterResources(2, 1, nodes);
Application application = tester.nodeRepository().applications().get(application1).orElse(new Application(application1))
- .withClusterLimits(cluster1.id(), min, max);
+ .withCluster(cluster1.id(), false, min, max);
tester.nodeRepository().applications().put(application, tester.nodeRepository().lock(application1));
var scaledResources = autoscaler.suggest(application.clusters().get(cluster1.id()),
tester.nodeRepository().getNodes(application1));
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 79d6b20dce8..bdea21cc4d3 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
@@ -147,7 +147,7 @@ class AutoscalingTester {
public Optional<ClusterResources> autoscale(ApplicationId applicationId, ClusterSpec.Id clusterId,
ClusterResources min, ClusterResources max) {
Application application = nodeRepository().applications().get(applicationId).orElse(new Application(applicationId))
- .withClusterLimits(clusterId, min, max);
+ .withCluster(clusterId, false, min, max);
nodeRepository().applications().put(application, nodeRepository().lock(applicationId));
return autoscaler.autoscale(application.clusters().get(clusterId),
nodeRepository().getNodes(applicationId, Node.State.active));
@@ -156,7 +156,7 @@ class AutoscalingTester {
public Optional<ClusterResources> suggest(ApplicationId applicationId, ClusterSpec.Id clusterId,
ClusterResources min, ClusterResources max) {
Application application = nodeRepository().applications().get(applicationId).orElse(new Application(applicationId))
- .withClusterLimits(clusterId, min, max);
+ .withCluster(clusterId, false, min, max);
nodeRepository().applications().put(application, nodeRepository().lock(applicationId));
return autoscaler.suggest(application.clusters().get(clusterId),
nodeRepository().getNodes(applicationId, Node.State.active));
@@ -203,6 +203,14 @@ class AutoscalingTester {
}
@Override
+ public NodeResources lowestRealResourcesAllocating(NodeResources resources, boolean exclusive) {
+ if (zone.getCloud().dynamicProvisioning())
+ return resources.withMemoryGb(resources.memoryGb() - 3);
+ else
+ return resources;
+ }
+
+ @Override
public NodeResources advertisedResourcesOf(Flavor flavor) {
if (zone.getCloud().dynamicProvisioning())
return flavor.resources().withMemoryGb(flavor.resources().memoryGb() + 3);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java
index c50805eebb8..598831d1eeb 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/ApplicationSerializerTest.java
@@ -26,11 +26,13 @@ public class ApplicationSerializerTest {
public void testApplicationSerialization() {
List<Cluster> clusters = new ArrayList<>();
clusters.add(new Cluster(ClusterSpec.Id.from("c1"),
+ false,
new ClusterResources( 8, 4, new NodeResources(1, 2, 3, 4)),
new ClusterResources(12, 6, new NodeResources(3, 6, 21, 24)),
Optional.empty(),
Optional.empty()));
clusters.add(new Cluster(ClusterSpec.Id.from("c2"),
+ true,
new ClusterResources( 8, 4, new NodeResources(1, 2, 3, 4)),
new ClusterResources(14, 7, new NodeResources(3, 6, 21, 24)),
Optional.of(new ClusterResources(20, 10, new NodeResources(0.5, 4, 14, 16))),
@@ -49,6 +51,7 @@ public class ApplicationSerializerTest {
assertNotSame(originalCluster, serializedCluster);
assertEquals(originalCluster, serializedCluster);
assertEquals(originalCluster.id(), serializedCluster.id());
+ assertEquals(originalCluster.exclusive(), serializedCluster.exclusive());
assertEquals(originalCluster.minResources(), serializedCluster.minResources());
assertEquals(originalCluster.maxResources(), serializedCluster.maxResources());
assertEquals(originalCluster.suggestedResources(), serializedCluster.suggestedResources());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
index 7ef780b8b7f..da2002bd488 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
@@ -314,8 +314,9 @@ public class DynamicDockerProvisionTest {
public void test_any_disk_prefers_remote() {
int memoryTax = 3;
int localDiskTax = 55;
- List<Flavor> flavors = List.of(new Flavor("2x", new NodeResources(2, 20 - memoryTax, 200 - localDiskTax, 0.1, fast, local)),
- new Flavor("4x", new NodeResources(4, 40 - memoryTax, 400 - localDiskTax, 0.1, fast, local)),
+ // Disk tax is not included in flavor resources but memory tax is
+ List<Flavor> flavors = List.of(new Flavor("2x", new NodeResources(2, 20 - memoryTax, 200, 0.1, fast, local)),
+ new Flavor("4x", new NodeResources(4, 40 - memoryTax, 400, 0.1, fast, local)),
new Flavor("2xl", new NodeResources(2, 20 - memoryTax, 200, 0.1, fast, remote)),
new Flavor("4xl", new NodeResources(4, 40 - memoryTax, 400, 0.1, fast, remote)));
@@ -382,11 +383,16 @@ public class DynamicDockerProvisionTest {
}
@Override
+ public NodeResources lowestRealResourcesAllocating(NodeResources resources, boolean exclusive) {
+ return resources.withMemoryGb(resources.memoryGb() - memoryTaxGb)
+ .withDiskGb(resources.diskGb() - ( resources.storageType() == local ? localDiskTax : 0));
+ }
+
+ @Override
public NodeResources advertisedResourcesOf(Flavor flavor) {
NodeResources resources = flavor.resources();
if ( ! flavor.isConfigured()) return resources;
- return resources.withMemoryGb(resources.memoryGb() + memoryTaxGb)
- .withDiskGb(resources.diskGb() + ( resources.storageType() == local ? localDiskTax : 0));
+ return resources.withMemoryGb(resources.memoryGb() + memoryTaxGb);
}
}
@@ -414,8 +420,7 @@ public class DynamicDockerProvisionTest {
}
private boolean compatible(Flavor hostFlavor, NodeResources resources) {
- NodeResources resourcesToVerify = resources.withMemoryGb(resources.memoryGb() - memoryTaxGb)
- .withDiskGb(resources.diskGb() - ( resources.storageType() == local ? localDiskTaxGb : 0));
+ NodeResources resourcesToVerify = resources.withMemoryGb(resources.memoryGb() - memoryTaxGb);
if (hostFlavor.resources().storageType() == NodeResources.StorageType.remote
&& hostFlavor.resources().diskGb() >= resources.diskGb())