summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2020-04-08 13:27:51 +0200
committerJon Bratseth <bratseth@gmail.com>2020-04-08 13:27:51 +0200
commitdf8cf4a64723a469916f4307c52de6ad62b7f577 (patch)
treebc484b7a73287ceeb61b9d331848c4067d11cb3e /config-model
parent2f736a2961ccbe3977877c143e390668ae7de8bf (diff)
Validate resource changes by the lower limit
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java13
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java16
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java23
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java39
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java57
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/MockModelContext.java4
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java7
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java4
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java4
10 files changed, 109 insertions, 59 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
index 696ce4195eb..3fb7ba6bc3a 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
@@ -16,6 +16,7 @@ import com.yahoo.config.model.api.EndpointCertificateSecrets;
import com.yahoo.config.model.api.HostProvisioner;
import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.api.ModelContext;
+import com.yahoo.config.model.api.Provisioned;
import com.yahoo.config.model.api.ValidationParameters;
import com.yahoo.config.model.application.provider.BaseDeployLogger;
import com.yahoo.config.model.application.provider.MockFileRegistry;
@@ -79,6 +80,7 @@ public class DeployState implements ConfigDefinitionStore {
private final Optional<String> wantedDockerImageRepo;
private final Instant now;
private final HostProvisioner provisioner;
+ private final Provisioned provisioned;
public static DeployState createTestState() {
return new Builder().build();
@@ -98,6 +100,7 @@ public class DeployState implements ConfigDefinitionStore {
FileRegistry fileRegistry,
DeployLogger deployLogger,
Optional<HostProvisioner> hostProvisioner,
+ Provisioned provisioned,
ModelContext.Properties properties,
Version vespaVersion,
Optional<ApplicationPackage> permanentApplicationPackage,
@@ -121,6 +124,7 @@ public class DeployState implements ConfigDefinitionStore {
this.previousModel = previousModel;
this.accessLoggingEnabledByDefault = accessLoggingEnabledByDefault;
this.provisioner = hostProvisioner.orElse(getDefaultModelHostProvisioner(applicationPackage));
+ this.provisioned = provisioned;
this.schemas = searchDocumentModel.getSchemas();
this.documentModel = searchDocumentModel.getDocumentModel();
this.permanentApplicationPackage = permanentApplicationPackage;
@@ -152,6 +156,8 @@ public class DeployState implements ConfigDefinitionStore {
}
}
+ public Provisioned provisioned() { return provisioned; }
+
/** Get the global rank profile registry for this application. */
public final RankProfileRegistry rankProfileRegistry() { return rankProfileRegistry; }
@@ -288,6 +294,7 @@ public class DeployState implements ConfigDefinitionStore {
private FileRegistry fileRegistry = new MockFileRegistry();
private DeployLogger logger = new BaseDeployLogger();
private Optional<HostProvisioner> hostProvisioner = Optional.empty();
+ private Provisioned provisioned = new Provisioned();
private Optional<ApplicationPackage> permanentApplicationPackage = Optional.empty();
private ModelContext.Properties properties = new TestProperties();
private Version version = new Version(1, 0, 0);
@@ -321,6 +328,11 @@ public class DeployState implements ConfigDefinitionStore {
return this;
}
+ public Builder provisioned(Provisioned provisioned) {
+ this.provisioned = provisioned;
+ return this;
+ }
+
public Builder permanentApplicationPackage(Optional<ApplicationPackage> permanentApplicationPackage) {
this.permanentApplicationPackage = permanentApplicationPackage;
return this;
@@ -400,6 +412,7 @@ public class DeployState implements ConfigDefinitionStore {
fileRegistry,
logger,
hostProvisioner,
+ provisioned,
properties,
version,
permanentApplicationPackage,
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
index 298517b85f6..8706bb44ded 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
@@ -4,6 +4,7 @@ package com.yahoo.config.model.provision;
import com.yahoo.collections.ListMap;
import com.yahoo.collections.Pair;
import com.yahoo.config.model.api.HostProvisioner;
+import com.yahoo.config.model.api.Provisioned;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterResources;
@@ -60,6 +61,8 @@ public class InMemoryProvisioner implements HostProvisioner {
private final boolean useMaxResources;
+ private Provisioned provisioned = new Provisioned();
+
/** Creates this with a number of nodes with resources 1, 3, 9, 1 */
public InMemoryProvisioner(int nodeCount) {
this(nodeCount, defaultResources);
@@ -85,9 +88,11 @@ public class InMemoryProvisioner implements HostProvisioner {
this(Map.of(defaultResources, hosts.asCollection()), failOnOutOfCapacity, false, startIndexForClusters, retiredHostNames);
}
- public InMemoryProvisioner(Map<NodeResources, Collection<Host>> hosts, boolean failOnOutOfCapacity,
+ public InMemoryProvisioner(Map<NodeResources, Collection<Host>> hosts,
+ boolean failOnOutOfCapacity,
boolean useMaxResources,
- int startIndexForClusters, String ... retiredHostNames) {
+ int startIndexForClusters,
+ String ... retiredHostNames) {
this.failOnOutOfCapacity = failOnOutOfCapacity;
this.useMaxResources = useMaxResources;
for (Map.Entry<NodeResources, Collection<Host>> hostsWithResources : hosts.entrySet())
@@ -125,6 +130,7 @@ public class InMemoryProvisioner implements HostProvisioner {
@Override
public List<HostSpec> prepare(ClusterSpec cluster, Capacity requested, ProvisionLogger logger) {
+ provisioned.add(cluster.id(), requested);
if (useMaxResources)
return prepare(cluster, requested.maxResources(), requested.isRequired(), requested.canFail());
else
@@ -165,6 +171,12 @@ public class InMemoryProvisioner implements HostProvisioner {
return allocation;
}
+ /** Create a new provisioned instance to record provision requests to this and returns it */
+ public Provisioned startProvisionedRecording() {
+ provisioned = new Provisioned();
+ return provisioned;
+ }
+
private HostSpec retire(HostSpec host) {
return new HostSpec(host.hostname(),
host.aliases(),
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
index c8f708e84f4..89cd5c2e735 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
@@ -23,11 +23,13 @@ import com.yahoo.config.model.api.FileDistribution;
import com.yahoo.config.model.api.HostInfo;
import ai.vespa.rankingexpression.importer.configmodelview.ImportedMlModels;
import com.yahoo.config.model.api.Model;
+import com.yahoo.config.model.api.Provisioned;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.AbstractConfigProducer;
import com.yahoo.config.model.producer.AbstractConfigProducerRoot;
import com.yahoo.config.model.producer.UserConfigRepo;
import com.yahoo.config.provision.AllocatedHosts;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.log.LogLevel;
import com.yahoo.searchdefinition.RankProfile;
import com.yahoo.searchdefinition.RankProfileRegistry;
@@ -122,6 +124,8 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
private final FileDistributor fileDistributor;
+ private final Provisioned provisioned;
+
/** Creates a Vespa Model from internal model types only */
public VespaModel(ApplicationPackage app) throws IOException, SAXException {
this(app, new NullConfigModelRegistry());
@@ -162,6 +166,7 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
configModelRegistry = new VespaConfigModelRegistry(configModelRegistry);
VespaModelBuilder builder = new VespaDomBuilder();
this.applicationPackage = deployState.getApplicationPackage();
+ this.provisioned = deployState.provisioned();
root = builder.getRoot(VespaModel.ROOT_CONFIGID, deployState, this);
createGlobalRankProfiles(deployState.getDeployLogger(), deployState.getImportedModels(),
@@ -611,11 +616,23 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
return Collections.unmodifiableMap(id2producer);
}
- /**
- * Returns this root's model repository
- */
+ /** Returns this root's model repository */
public ConfigModelRepo configModelRepo() {
return configModelRepo;
}
+ /** If provisioning through the node repo, returns the provision requests issued during build of this */
+ public Provisioned provisioned() { return provisioned; }
+
+ /** Returns the id of all clusters in this */
+ public Set<ClusterSpec.Id> allClusters() {
+ return hostSystem().getHosts().stream()
+ .map(HostResource::spec)
+ .filter(spec -> spec.membership().isPresent())
+ .map(spec -> spec.membership().get().cluster().id())
+ .collect(Collectors.toSet());
+ }
+
+
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
index f0e119606bf..631f4dab1a7 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
@@ -146,6 +146,7 @@ public class VespaModelFactory implements ModelFactory {
.properties(modelContext.properties())
.vespaVersion(version())
.modelHostProvisioner(createHostProvisioner(modelContext))
+ .provisioned(modelContext.provisioned())
.endpoints(modelContext.properties().endpoints())
.modelImporters(modelImporters)
.zone(zone)
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java
index d14fe91a53b..162f6798462 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java
@@ -2,6 +2,8 @@
package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeAction;
+import com.yahoo.config.provision.Capacity;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.config.application.api.ValidationId;
import com.yahoo.config.application.api.ValidationOverrides;
@@ -21,35 +23,32 @@ public class ClusterSizeReductionValidator implements ChangeValidator {
@Override
public List<ConfigChangeAction> validate(VespaModel current, VespaModel next, ValidationOverrides overrides, Instant now) {
- for (ContainerCluster currentCluster : current.getContainerClusters().values()) {
- ContainerCluster nextCluster = next.getContainerClusters().get(currentCluster.getName());
- if (nextCluster == null) continue;
- validate(currentCluster.getContainers().size(),
- nextCluster.getContainers().size(),
- currentCluster.getName(),
+ for (var clusterId : current.allClusters()) {
+ Capacity currentCapacity = current.provisioned().all().get(clusterId);
+ Capacity nextCapacity = next.provisioned().all().get(clusterId);
+ if (currentCapacity == null || nextCapacity == null) continue;
+ validate(currentCapacity,
+ nextCapacity,
+ clusterId,
overrides,
now);
}
-
- for (ContentCluster currentCluster : current.getContentClusters().values()) {
- ContentCluster nextCluster = next.getContentClusters().get(currentCluster.getName());
- if (nextCluster == null) continue;
- validate(currentCluster.getSearch().getSearchNodes().size(),
- nextCluster.getSearch().getSearchNodes().size(),
- currentCluster.getName(),
- overrides,
- now);
- }
-
return Collections.emptyList();
}
- private void validate(int currentSize, int nextSize, String clusterName, ValidationOverrides overrides, Instant now) {
+ private void validate(Capacity current,
+ Capacity next,
+ ClusterSpec.Id clusterId,
+ ValidationOverrides overrides,
+ Instant now) {
+ int currentSize = current.minResources().nodes();
+ int nextSize = next.minResources().nodes();
// don't allow more than 50% reduction, but always allow to reduce size with 1
if ( nextSize < ((double)currentSize) * 0.5 && nextSize != currentSize - 1)
overrides.invalid(ValidationId.clusterSizeReduction,
- "Size reduction in '" + clusterName + "' is too large. Current size: " + currentSize +
- ", new size: " + nextSize + ". New size must be at least 50% of the current size",
+ "Size reduction in '" + clusterId.value() + "' is too large: " +
+ "New min size must be at least 50% of the current min size. " +
+ "Current size: " + currentSize + ", new size: " + nextSize,
now);
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
index 8fdcf249bbc..5343a322382 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
@@ -5,6 +5,7 @@ import com.yahoo.collections.Pair;
import com.yahoo.config.application.api.ValidationId;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.model.api.ConfigChangeAction;
+import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.vespa.model.HostResource;
@@ -15,6 +16,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -27,35 +29,43 @@ public class ResourcesReductionValidator implements ChangeValidator {
@Override
public List<ConfigChangeAction> validate(VespaModel current, VespaModel next, ValidationOverrides overrides, Instant now) {
- var currentRequestedResourcesByClusterId = getRequestedResourcesByClusterId(current);
- var nextRequestedResourcesByClusterId = getRequestedResourcesByClusterId(next);
-
- for (var clusterTypeAndId : currentRequestedResourcesByClusterId.keySet()) {
- if (!nextRequestedResourcesByClusterId.containsKey(clusterTypeAndId)) continue;
- validate(currentRequestedResourcesByClusterId.get(clusterTypeAndId),
- nextRequestedResourcesByClusterId.get(clusterTypeAndId),
- clusterTypeAndId.getSecond(),
- overrides,
- now);
+ for (var clusterId : current.allClusters()) {
+ Capacity currentCapacity = current.provisioned().all().get(clusterId);
+ Capacity nextCapacity = next.provisioned().all().get(clusterId);
+ if (currentCapacity == null || nextCapacity == null) continue;
+ validate(currentCapacity, nextCapacity, clusterId, overrides, now);
}
return List.of();
}
- private void validate(NodeResources currentResources, NodeResources nextResources, ClusterSpec.Id clusterId,
- ValidationOverrides overrides, Instant now) {
+ private void validate(Capacity current,
+ Capacity next,
+ ClusterSpec.Id clusterId,
+ ValidationOverrides overrides,
+ Instant now) {
+ if (current.minResources().nodeResources() == NodeResources.unspecified) return;
+ if (next.minResources().nodeResources() == NodeResources.unspecified) return;
+
List<String> illegalChanges = Stream.of(
- validateResource("vCPU", currentResources.vcpu(), nextResources.vcpu()),
- validateResource("memory GB", currentResources.memoryGb(), nextResources.memoryGb()),
- validateResource("disk GB", currentResources.diskGb(), nextResources.diskGb()))
+ validateResource("vCPU",
+ current.minResources().nodeResources().vcpu(),
+ next.minResources().nodeResources().vcpu()),
+ validateResource("memory GB",
+ current.minResources().nodeResources().memoryGb(),
+ next.minResources().nodeResources().memoryGb()),
+ validateResource("disk GB",
+ current.minResources().nodeResources().diskGb(),
+ next.minResources().nodeResources().diskGb()))
.flatMap(Optional::stream)
.collect(Collectors.toList());
if (illegalChanges.isEmpty()) return;
overrides.invalid(ValidationId.resourcesReduction,
- "Resource reduction in '" + clusterId.value() + "' is too large. " +
- String.join(" ", illegalChanges) + " New resources must be at least 50% of the current resources",
- now);
+ "Resource reduction in '" + clusterId.value() + "' is too large. " +
+ String.join(" ", illegalChanges) +
+ " New min resources must be at least 50% of the current min resources",
+ now);
}
private static Optional<String> validateResource(String resourceName, double currentValue, double nextValue) {
@@ -64,15 +74,4 @@ public class ResourcesReductionValidator implements ChangeValidator {
return Optional.of(String.format(Locale.ENGLISH ,"Current %s: %.2f, new: %.2f.", resourceName, currentValue, nextValue));
}
- private static Map<Pair<ClusterSpec.Type, ClusterSpec.Id>, NodeResources> getRequestedResourcesByClusterId(VespaModel vespaModel) {
- return vespaModel.hostSystem().getHosts().stream()
- .map(HostResource::spec)
- .filter(spec -> spec.membership().isPresent() && spec.requestedResources().isPresent())
- .filter(spec -> !spec.membership().get().retired())
- .collect(Collectors.toMap(
- spec -> new Pair<>(spec.membership().get().cluster().type(), spec.membership().get().cluster().id()),
- spec -> spec.requestedResources().get(),
- (e1, e2) -> e1));
- }
-
}
diff --git a/config-model/src/test/java/com/yahoo/config/model/MockModelContext.java b/config-model/src/test/java/com/yahoo/config/model/MockModelContext.java
index 38e438e4d3a..f8ab3cc54c8 100644
--- a/config-model/src/test/java/com/yahoo/config/model/MockModelContext.java
+++ b/config-model/src/test/java/com/yahoo/config/model/MockModelContext.java
@@ -9,6 +9,7 @@ import com.yahoo.config.model.api.ConfigDefinitionRepo;
import com.yahoo.config.model.api.HostProvisioner;
import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.api.ModelContext;
+import com.yahoo.config.model.api.Provisioned;
import com.yahoo.config.model.application.provider.BaseDeployLogger;
import com.yahoo.config.model.application.provider.MockFileRegistry;
import com.yahoo.config.model.application.provider.StaticConfigDefinitionRepo;
@@ -53,6 +54,9 @@ public class MockModelContext implements ModelContext {
}
@Override
+ public Provisioned provisioned() { return new Provisioned(); }
+
+ @Override
public DeployLogger deployLogger() {
return new BaseDeployLogger();
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java
index 09e4b377085..915b3c01e1b 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java
@@ -6,6 +6,7 @@ import com.yahoo.collections.Pair;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.HostProvisioner;
+import com.yahoo.config.model.api.Provisioned;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.deploy.TestProperties;
import com.yahoo.config.model.provision.InMemoryProvisioner;
@@ -32,7 +33,7 @@ import static com.yahoo.config.model.test.MockApplicationPackage.MUSIC_SEARCHDEF
*/
public class ValidationTester {
- private final HostProvisioner hostProvisioner;
+ private final InMemoryProvisioner hostProvisioner;
/** Creates a validation tester with 1 node available */
public ValidationTester() {
@@ -45,7 +46,7 @@ public class ValidationTester {
}
/** Creates a validation tester with a given host provisioner */
- public ValidationTester(HostProvisioner hostProvisioner) {
+ public ValidationTester(InMemoryProvisioner hostProvisioner) {
this.hostProvisioner = hostProvisioner;
}
@@ -63,6 +64,7 @@ public class ValidationTester {
Environment environment,
String validationOverrides) {
Instant now = LocalDate.parse("2000-01-01", DateTimeFormatter.ISO_DATE).atStartOfDay().atZone(ZoneOffset.UTC).toInstant();
+ Provisioned provisioned = hostProvisioner.startProvisionedRecording();
ApplicationPackage newApp = new MockApplicationPackage.Builder()
.withServices(services)
.withSchemas(ImmutableList.of(MUSIC_SEARCHDEFINITION, BOOK_SEARCHDEFINITION))
@@ -77,6 +79,7 @@ public class ValidationTester {
.applicationPackage(newApp)
.properties(new TestProperties().setHostedVespa(true))
.modelHostProvisioner(hostProvisioner)
+ .provisioned(provisioned)
.now(now);
if (previousModel != null)
deployStateBuilder.previousModel(previousModel);
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java
index 895aa4f6a36..87684aca174 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java
@@ -27,7 +27,9 @@ public class ClusterSizeReductionValidatorTest {
fail("Expected exception due to cluster size reduction");
}
catch (IllegalArgumentException expected) {
- assertEquals("cluster-size-reduction: Size reduction in 'default' is too large. Current size: 30, new size: 14. New size must be at least 50% of the current size. " +
+ assertEquals("cluster-size-reduction: Size reduction in 'default' is too large: " +
+ "New min size must be at least 50% of the current min size. " +
+ "Current size: 30, new size: 14. " +
ValidationOverrides.toAllowMessage(ValidationId.clusterSizeReduction),
Exceptions.toMessageString(expected));
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java
index 1322a9061ed..9a363789798 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidatorTest.java
@@ -30,7 +30,7 @@ public class ResourcesReductionValidatorTest {
fail("Expected exception due to resources reduction");
} catch (IllegalArgumentException expected) {
assertEquals("resources-reduction: Resource reduction in 'default' is too large. " +
- "Current memory GB: 64.00, new: 16.00. New resources must be at least 50% of the current resources. " +
+ "Current memory GB: 64.00, new: 16.00. New min resources must be at least 50% of the current min resources. " +
ValidationOverrides.toAllowMessage(ValidationId.resourcesReduction),
Exceptions.toMessageString(expected));
}
@@ -45,7 +45,7 @@ public class ResourcesReductionValidatorTest {
} catch (IllegalArgumentException expected) {
assertEquals("resources-reduction: Resource reduction in 'default' is too large. " +
"Current vCPU: 8.00, new: 3.00. Current memory GB: 64.00, new: 16.00. Current disk GB: 800.00, new: 200.00. " +
- "New resources must be at least 50% of the current resources. " +
+ "New min resources must be at least 50% of the current min resources. " +
ValidationOverrides.toAllowMessage(ValidationId.resourcesReduction),
Exceptions.toMessageString(expected));
}