summaryrefslogtreecommitdiffstats
path: root/config-model/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'config-model/src/test')
-rw-r--r--config-model/src/test/cfg/application/embed/services.xml15
-rw-r--r--config-model/src/test/java/com/yahoo/schema/derived/AbstractExportingTestCase.java2
-rw-r--r--config-model/src/test/java/com/yahoo/schema/derived/IndexInfoTestCase.java55
-rw-r--r--config-model/src/test/java/com/yahoo/schema/derived/SchemaToDerivedConfigExporter.java2
-rw-r--r--config-model/src/test/java/com/yahoo/schema/parser/SchemaParserTestCase.java17
-rw-r--r--config-model/src/test/java/com/yahoo/schema/processing/IndexingScriptRewriterTestCase.java9
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterExcludeValidatorTest.java17
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterValidatorTest.java5
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java16
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudClientsValidatorTest.java54
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudDataPlaneFilterValidatorTest.java16
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudHttpConnectorValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudUserFilterValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/DeploymentSpecValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/EndpointCertificateSecretsValidatorTest.java6
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/InfrastructureDeploymentValidatorTest.java3
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java18
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/PublicApiBundleValidatorTest.java9
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/SecretStoreValidatorTest.java6
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java28
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java10
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java6
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidatorTest.java27
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java3
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java25
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSchemaClusterChangeValidatorTest.java4
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java3
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java5
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSchemaClusterChangeValidatorTest.java5
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/EmbedderTestCase.java30
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/ModelIdResolverTest.java35
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/content/utils/SchemaBuilder.java1
-rw-r--r--config-model/src/test/resources/cloud-clients-validator/cert-with-empty-sequence-of-extensions.pem9
-rw-r--r--config-model/src/test/resources/cloud-clients-validator/valid-cert.pem9
37 files changed, 367 insertions, 95 deletions
diff --git a/config-model/src/test/cfg/application/embed/services.xml b/config-model/src/test/cfg/application/embed/services.xml
index 1840063d70d..59c29aefc6a 100644
--- a/config-model/src/test/cfg/application/embed/services.xml
+++ b/config-model/src/test/cfg/application/embed/services.xml
@@ -19,6 +19,21 @@
<pooling-strategy>mean</pooling-strategy>
</component>
+ <component id="splade" type="splade-embedder">
+ <transformer-model model-id="e5-base-v2" url="https://my/url/model.onnx"/>
+ <tokenizer-model model-id="e5-base-v2-vocab" path="app/tokenizer.json"/>
+ <max-tokens>1024</max-tokens>
+ <transformer-input-ids>my_input_ids</transformer-input-ids>
+ <transformer-attention-mask>my_attention_mask</transformer-attention-mask>
+ <transformer-token-type-ids>my_token_type_ids</transformer-token-type-ids>
+ <transformer-output>my_output</transformer-output>
+ <term-score-threshold>0.2</term-score-threshold>
+ <onnx-execution-mode>parallel</onnx-execution-mode>
+ <onnx-intraop-threads>10</onnx-intraop-threads>
+ <onnx-interop-threads>8</onnx-interop-threads>
+ <onnx-gpu-device>1</onnx-gpu-device>
+ </component>
+
<component id="hf-tokenizer" type="hugging-face-tokenizer">
<model language="no" model-id="multilingual-e5-base-vocab" url="https://my/url/tokenizer.json"/>
</component>
diff --git a/config-model/src/test/java/com/yahoo/schema/derived/AbstractExportingTestCase.java b/config-model/src/test/java/com/yahoo/schema/derived/AbstractExportingTestCase.java
index 3bb129a4c32..7686289f11c 100644
--- a/config-model/src/test/java/com/yahoo/schema/derived/AbstractExportingTestCase.java
+++ b/config-model/src/test/java/com/yahoo/schema/derived/AbstractExportingTestCase.java
@@ -52,7 +52,7 @@ public abstract class AbstractExportingTestCase extends AbstractSchemaTestCase {
.deployLogger(logger)
.rankProfileRegistry(builder.getRankProfileRegistry())
.queryProfiles(builder.getQueryProfileRegistry())
- .build());
+ .build(), false);
return export(dirName, builder, config);
}
diff --git a/config-model/src/test/java/com/yahoo/schema/derived/IndexInfoTestCase.java b/config-model/src/test/java/com/yahoo/schema/derived/IndexInfoTestCase.java
new file mode 100644
index 00000000000..09450fa8023
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/schema/derived/IndexInfoTestCase.java
@@ -0,0 +1,55 @@
+package com.yahoo.schema.derived;
+
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.search.config.IndexInfoConfig;
+import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.content.utils.ApplicationPackageBuilder;
+import com.yahoo.vespa.model.content.utils.ContentClusterBuilder;
+import com.yahoo.vespa.model.content.utils.DocType;
+import com.yahoo.vespa.model.content.utils.SchemaBuilder;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class IndexInfoTestCase {
+ private static final String F = "f";
+ @Test
+ void testThatIndexingEnablesNormalizing() {
+ var cmds = createIndexCmds(false);
+ assertEquals(8, cmds.size());
+ assertEquals(1, cmds.stream().filter(c -> c.indexname().equals(F) && c.command().equals("normalize")).count());
+ }
+ @Test
+ void testThatStreamingDisablesNormalizing() {
+ var cmds = createIndexCmds(true);
+ assertEquals(7, cmds.size());
+ assertEquals(0, cmds.stream().filter(c -> c.indexname().equals(F) && c.command().equals("normalize")).count());
+ }
+
+ private static List<IndexInfoConfig.Indexinfo.Command> createIndexCmds(boolean isStreaming) {
+ final String SD = "sda";
+ String documentContent = "field " + F + " type string {indexing:index | summary}";
+ var cfg = createIndexInfo(SD, documentContent, isStreaming);
+ assertEquals(SD, cfg.indexinfo(0).name());
+ return cfg.indexinfo(0).command();
+ }
+
+ private static IndexInfoConfig createIndexInfo(String schemaName, String sdContent, boolean isStreaming) {
+ var model = createModel(schemaName, sdContent);
+ var schema = model.getSearchClusters().get(0).schemas().get(schemaName);
+ var indexInfo = new IndexInfo(schema.fullSchema(), isStreaming);
+ IndexInfoConfig.Builder builder = new IndexInfoConfig.Builder();
+ indexInfo.getConfig(builder);
+ return builder.build();
+ }
+
+ private static VespaModel createModel(String schemaName, String sdContent) {
+ var builder = new DeployState.Builder();
+ return new ApplicationPackageBuilder()
+ .addCluster(new ContentClusterBuilder().name("content").docTypes(List.of(DocType.index(schemaName))))
+ .addSchemas(new SchemaBuilder().name(schemaName).content(sdContent).build())
+ .buildCreator().create(builder);
+ }
+}
diff --git a/config-model/src/test/java/com/yahoo/schema/derived/SchemaToDerivedConfigExporter.java b/config-model/src/test/java/com/yahoo/schema/derived/SchemaToDerivedConfigExporter.java
index b219d84f108..2beab3d5ea9 100644
--- a/config-model/src/test/java/com/yahoo/schema/derived/SchemaToDerivedConfigExporter.java
+++ b/config-model/src/test/java/com/yahoo/schema/derived/SchemaToDerivedConfigExporter.java
@@ -46,7 +46,7 @@ public class SchemaToDerivedConfigExporter {
.deployLogger(logger)
.rankProfileRegistry(builder.getRankProfileRegistry())
.queryProfiles(builder.getQueryProfileRegistry())
- .build());
+ .build(), false);
exportConfig(dirPath, derived, builder);
}
}
diff --git a/config-model/src/test/java/com/yahoo/schema/parser/SchemaParserTestCase.java b/config-model/src/test/java/com/yahoo/schema/parser/SchemaParserTestCase.java
index c014f77d59a..5a2dc218da7 100644
--- a/config-model/src/test/java/com/yahoo/schema/parser/SchemaParserTestCase.java
+++ b/config-model/src/test/java/com/yahoo/schema/parser/SchemaParserTestCase.java
@@ -120,6 +120,23 @@ public class SchemaParserTestCase {
assertEquals("onnx(mymodel)", rp1.getGlobalPhaseExpression().get());
}
+ @Test
+ void maxOccurrencesCanBeParsed() throws Exception {
+ String input = joinLines
+ ("schema foo {",
+ " document foo {",
+ " field bar type string {",
+ " indexing: summary | index",
+ " match { max-occurrences: 11 }",
+ " }",
+ " }",
+ "}");
+ ParsedSchema schema = parseString(input);
+ var field = schema.getDocument().getFields().get(0);
+ assertEquals("bar", field.name());
+ assertEquals(11, field.matchSettings().getMaxTermOccurrences().get());
+ }
+
void checkFileParses(String fileName) throws Exception {
var schema = parseFile(fileName);
assertNotNull(schema);
diff --git a/config-model/src/test/java/com/yahoo/schema/processing/IndexingScriptRewriterTestCase.java b/config-model/src/test/java/com/yahoo/schema/processing/IndexingScriptRewriterTestCase.java
index 87e91acfb67..c2cc28ea6b3 100644
--- a/config-model/src/test/java/com/yahoo/schema/processing/IndexingScriptRewriterTestCase.java
+++ b/config-model/src/test/java/com/yahoo/schema/processing/IndexingScriptRewriterTestCase.java
@@ -147,6 +147,15 @@ public class IndexingScriptRewriterTestCase extends AbstractSchemaTestCase {
createPredicateField("test", DataType.PREDICATE, "{ attribute; }", 2, OptionalLong.of(0L), OptionalLong.of(1023L)));
}
+ @Test
+ void requireThatMaxTermOccurrencesIsPropagated() {
+ var field = new SDField("test", DataType.STRING);
+ field.getMatching().maxTermOccurrences(10);
+ field.parseIndexingScript("{ summary | index }");
+ assertIndexingScript("{ input test | tokenize normalize stem:\"BEST\" max-occurrences:10 | summary test | index test; }",
+ field);
+ }
+
private static void assertIndexingScript(String expectedScript, SDField unprocessedField) {
assertEquals(expectedScript,
processField(unprocessedField).toString());
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterExcludeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterExcludeValidatorTest.java
index 25053c536da..4e88753b732 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterExcludeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterExcludeValidatorTest.java
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Set;
+import static com.yahoo.vespa.model.application.validation.ValidationTester.expect;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -56,9 +57,8 @@ public class AccessControlFilterExcludeValidatorTest {
MapConfigModelRegistry.createFromList(new ModelBuilderAddingAccessControlFilter()),
deployState);
- IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> new AccessControlFilterExcludeValidator().validate(model, deployState));
- String expectedMessage = "Application cluster container-cluster-with-access-control excludes paths from access control, this is not allowed and should be removed.";
- assertEquals(expectedMessage, exception.getMessage());
+ expect(new AccessControlFilterExcludeValidator(), model, deployState,
+ "Application cluster container-cluster-with-access-control excludes paths from access control, this is not allowed and should be removed.");
}
@Test
@@ -69,9 +69,8 @@ public class AccessControlFilterExcludeValidatorTest {
MapConfigModelRegistry.createFromList(new ModelBuilderAddingAccessControlFilter()),
deployState);
- new AccessControlFilterExcludeValidator().validate(model, deployState);
- String expectedMessage = "Application cluster container-cluster-with-access-control excludes paths from access control, this is not allowed and should be removed.";
- assertTrue(logOutput.toString().contains(expectedMessage));
+ ValidationTester.validate(new AccessControlFilterExcludeValidator(), model, deployState);
+ assertTrue(logOutput.toString().contains("Application cluster container-cluster-with-access-control excludes paths from access control, this is not allowed and should be removed."));
}
@Test
@@ -80,7 +79,7 @@ public class AccessControlFilterExcludeValidatorTest {
VespaModel model = new VespaModel(
MapConfigModelRegistry.createFromList(new ModelBuilderAddingAccessControlFilter()),
deployState);
- new AccessControlFilterExcludeValidator().validate(model, deployState);
+ ValidationTester.validate(new AccessControlFilterExcludeValidator(), model, deployState);
}
@Test
@@ -90,7 +89,7 @@ public class AccessControlFilterExcludeValidatorTest {
MapConfigModelRegistry.createFromList(new ModelBuilderAddingAccessControlFilter()),
deployState);
- new AccessControlFilterExcludeValidator().validate(model, deployState);
+ ValidationTester.validate(new AccessControlFilterExcludeValidator(), model, deployState);
}
private static DeployState createDeployState(Zone zone, StringBuffer buffer, boolean allowExcludes) {
@@ -112,6 +111,6 @@ public class AccessControlFilterExcludeValidatorTest {
Cloud.Builder cloudBuilder = Cloud.builder().name(cloudName);
if (cloudName == CloudName.AWS) cloudBuilder.account(CloudAccount.from("123456789012"));
return new Zone(cloudBuilder.build(), systemName, Environment.prod, RegionName.defaultName());
-
}
+
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterValidatorTest.java
index aa42fbbf827..1bc59e118d4 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/AccessControlFilterValidatorTest.java
@@ -39,7 +39,7 @@ public class AccessControlFilterValidatorTest {
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
try {
- new AccessControlFilterValidator().validate(model, deployState);
+ ValidationTester.validate(new AccessControlFilterValidator(), model, deployState);
fail();
} catch (IllegalArgumentException e) {
assertEquals("The 'access-control' feature is not available in open-source Vespa.", e.getMessage());
@@ -53,7 +53,7 @@ public class AccessControlFilterValidatorTest {
MapConfigModelRegistry.createFromList(new ModelBuilderAddingAccessControlFilter()),
deployState);
- new AccessControlFilterValidator().validate(model, deployState);
+ ValidationTester.validate(new AccessControlFilterValidator(), model, deployState);
}
private static DeployState createDeployState() {
@@ -61,4 +61,5 @@ public class AccessControlFilterValidatorTest {
.applicationPackage(new MockApplicationPackage.Builder().withServices(SERVICES_XML).build())
.build();
}
+
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java
index f41cc266db3..1aca0c2fe47 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.model.application.validation;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.vespa.model.application.validation.AbstractBundleValidator.JarContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -29,7 +30,7 @@ public class BundleValidatorTest {
// Valid jar file
JarFile ok = createTemporaryJarFile(tempDir, "ok");
BundleValidator bundleValidator = new BundleValidator();
- bundleValidator.validateJarFile(DeployState.createTestState(), ok);
+ bundleValidator.validateJarFile(contextOf(DeployState.createTestState()), ok);
// No manifest
validateWithException("nomanifest", "Non-existing or invalid manifest in nomanifest.jar");
@@ -39,7 +40,7 @@ public class BundleValidatorTest {
try {
JarFile jarFile = createTemporaryJarFile(tempDir, jarName);
BundleValidator bundleValidator = new BundleValidator();
- bundleValidator.validateJarFile(DeployState.createTestState(), jarFile);
+ bundleValidator.validateJarFile(contextOf(DeployState.createTestState()), jarFile);
assert (false);
} catch (IllegalArgumentException e) {
assertEquals(exceptionMessage, e.getMessage());
@@ -52,7 +53,7 @@ public class BundleValidatorTest {
DeployState state = createDeployState(buffer);
JarFile jarFile = createTemporaryJarFile(tempDir, "snapshot_bundle");
- new BundleValidator().validateJarFile(state, jarFile);
+ new BundleValidator().validateJarFile(contextOf(state), jarFile);
assertTrue(buffer.toString().contains("Deploying snapshot bundle"));
}
@@ -62,7 +63,7 @@ public class BundleValidatorTest {
DeployState state = createDeployState(buffer);
BundleValidator validator = new BundleValidator();
JarFile jarFile = createTemporaryJarFile(tempDir, "import-warnings");
- validator.validateJarFile(state, jarFile);
+ validator.validateJarFile(contextOf(state), jarFile);
String output = buffer.toString();
assertTrue(output
.contains("JAR file 'import-warnings.jar' imports the packages [org.json] from 'org.json:json'. \n" +
@@ -123,5 +124,12 @@ public class BundleValidatorTest {
List.of("org.json", "version", "[0.0.0,1)", "org.eclipse.jetty.client.api", "version", "[9.4.46,10)"));
}
+ private static JarContext contextOf(DeployState state) {
+ return new JarContext() {
+ @Override public void illegal(String error) { throw new IllegalArgumentException(error); }
+ @Override public void illegal(String error, Throwable cause) { throw new IllegalArgumentException(error, cause); }
+ @Override public DeployState deployState() { return state; }
+ };
+ }
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudClientsValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudClientsValidatorTest.java
new file mode 100644
index 00000000000..6fbca76ccbc
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudClientsValidatorTest.java
@@ -0,0 +1,54 @@
+package com.yahoo.vespa.model.application.validation;
+
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.security.X509CertificateUtils;
+import com.yahoo.vespa.model.test.utils.DeployLoggerStub;
+import org.junit.jupiter.api.Test;
+
+import java.security.cert.X509Certificate;
+
+import static com.yahoo.yolean.Exceptions.uncheck;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * @author bjorncs
+ */
+class CloudClientsValidatorTest {
+
+ @Test
+ void logs_deployment_warning_on_certificate_with_empty_sequence_of_extensions() {
+ // Test should fail on BouncyCastle 1.77 or later
+
+ var logger = new DeployLoggerStub();
+ var state = new DeployState.Builder().deployLogger(logger).build();
+ var cert = readTestCertificate("cert-with-empty-sequence-of-extensions.pem");
+ CloudClientsValidator.validateCertificate("default", "my-feed-client", cert,
+ (msg, cause) -> { throw new IllegalArgumentException(msg, cause); },
+ state);
+ var expected = "Client **my-feed-client** defined for cluster **default** contains an invalid certificate: " +
+ "The certificate's ASN.1 structure contains an empty sequence of extensions, " +
+ "which is a violation of the ASN.1 specification. " +
+ "Please update the application package with a new certificate, " +
+ "e.g by generating a new one using the Vespa CLI `$ vespa auth cert`. " +
+ "Such certificate will no longer be accepted in near future.";
+ assertEquals(expected, logger.getLast().message);
+ }
+
+ @Test
+ void accepts_valid_certificate() {
+ var logger = new DeployLoggerStub();
+ var state = new DeployState.Builder().deployLogger(logger).build();
+ var cert = readTestCertificate("valid-cert.pem");
+ assertDoesNotThrow(() -> CloudClientsValidator.validateCertificate("default", "my-feed-client", cert,
+ (msg, cause) -> { throw new IllegalArgumentException(msg, cause); },
+ state));
+ assertEquals(0, logger.entries.size());
+ }
+
+ private static X509Certificate readTestCertificate(String filename) {
+ return X509CertificateUtils.fromPem(new String(uncheck(
+ () -> CloudClientsValidatorTest.class.getResourceAsStream(
+ "/cloud-clients-validator/%s".formatted(filename)).readAllBytes())));
+ }
+}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudDataPlaneFilterValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudDataPlaneFilterValidatorTest.java
index 8acbf00a5a3..80ef81ee6d7 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudDataPlaneFilterValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudDataPlaneFilterValidatorTest.java
@@ -71,7 +71,7 @@ public class CloudDataPlaneFilterValidatorTest {
certFile2, List.of(createCertificate("bar"))));
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new CloudDataPlaneFilterValidator().validate(model, deployState);
+ ValidationTester.validate(new CloudDataPlaneFilterValidator(), model, deployState);
}
@Test
@@ -100,11 +100,8 @@ public class CloudDataPlaneFilterValidatorTest {
certFile2, List.of(certificate)));
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- IllegalArgumentException illegalArgumentException = Assertions.assertThrows(IllegalArgumentException.class, () ->
- new CloudDataPlaneFilterValidator().validate(model, deployState));
- assertEquals(
- "Duplicate certificate(s) detected in files: [%s, %s]. Certificate subject of duplicates: [%s]".formatted(certFile1, certFile2, certificate.getSubjectX500Principal().getName()),
- illegalArgumentException.getMessage());
+ ValidationTester.expect(new CloudDataPlaneFilterValidator(), model, deployState,
+ "Duplicate certificate(s) detected in files: [%s, %s]. Certificate subject of duplicates: [%s]".formatted(certFile1, certFile2, certificate.getSubjectX500Principal().getName()));
}
@Test
@@ -127,11 +124,8 @@ public class CloudDataPlaneFilterValidatorTest {
Map.of(certFile1, List.of(certificate, certificate)));
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- IllegalArgumentException illegalArgumentException = Assertions.assertThrows(IllegalArgumentException.class, () ->
- new CloudDataPlaneFilterValidator().validate(model, deployState));
- assertEquals(
- "Duplicate certificate(s) detected in files: [%s]. Certificate subject of duplicates: [%s]".formatted(certFile1, certificate.getSubjectX500Principal().getName()),
- illegalArgumentException.getMessage());
+ ValidationTester.expect(new CloudDataPlaneFilterValidator(), model, deployState,
+ "Duplicate certificate(s) detected in files: [%s]. Certificate subject of duplicates: [%s]".formatted(certFile1, certificate.getSubjectX500Principal().getName()));
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudHttpConnectorValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudHttpConnectorValidatorTest.java
index 58aa0e8625e..3be1cbd44e3 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudHttpConnectorValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudHttpConnectorValidatorTest.java
@@ -104,7 +104,7 @@ class CloudHttpConnectorValidatorTest {
.endpoints(Set.of(new ContainerEndpoint("container", ApplicationClusterEndpoint.Scope.zone, List.of("c.example.com"))))
.build();
var model = new VespaModel(new NullConfigModelRegistry(), state);
- new CloudHttpConnectorValidator().validate(model, state);
+ ValidationTester.validate(new CloudHttpConnectorValidator(), model, state);
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudUserFilterValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudUserFilterValidatorTest.java
index 2aa678fd34b..ac5a08b1394 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudUserFilterValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/CloudUserFilterValidatorTest.java
@@ -67,7 +67,7 @@ class CloudUserFilterValidatorTest {
.properties(new TestProperties().setHostedVespa(isHosted).setAllowUserFilters(false))
.build();
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new CloudUserFilterValidator().validate(model, deployState);
+ ValidationTester.validate(new CloudUserFilterValidator(), model, deployState);
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java
index 43c51bea04a..b6484049eaf 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java
@@ -61,7 +61,7 @@ public class ContainerInCloudValidatorTest {
}
DeployState deployState = builder.build();
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new ContainerInCloudValidator().validate(model, deployState);
+ ValidationTester.validate(new ContainerInCloudValidator(), model, deployState);
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/DeploymentSpecValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/DeploymentSpecValidatorTest.java
index 4e388df3ef8..c9b014d9301 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/DeploymentSpecValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/DeploymentSpecValidatorTest.java
@@ -63,7 +63,7 @@ public class DeploymentSpecValidatorTest {
try {
var deployState = builder.build();
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new DeploymentSpecValidator().validate(model, deployState);
+ ValidationTester.validate(new DeploymentSpecValidator(), model, deployState);
fail("Did not get expected exception");
} catch (IllegalArgumentException e) {
assertEquals(message, e.getMessage());
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/EndpointCertificateSecretsValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/EndpointCertificateSecretsValidatorTest.java
index 821ad1be8fa..3b6a559ce31 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/EndpointCertificateSecretsValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/EndpointCertificateSecretsValidatorTest.java
@@ -48,7 +48,7 @@ public class EndpointCertificateSecretsValidatorTest {
DeployState deployState = deployState(servicesXml(), deploymentXml(), Optional.of(EndpointCertificateSecrets.missing(1)));
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new EndpointCertificateSecretsValidator().validate(model, deployState);
+ ValidationTester.validate(new EndpointCertificateSecretsValidator(), model, deployState);
});
assertTrue(exception.getMessage().contains("TLS enabled, but could not yet retrieve certificate version 1 for application default:default:default"));
}
@@ -58,7 +58,7 @@ public class EndpointCertificateSecretsValidatorTest {
DeployState deployState = deployState(servicesXml(), deploymentXml(), Optional.of(new EndpointCertificateSecrets("cert", "key")));
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new EndpointCertificateSecretsValidator().validate(model, deployState);
+ ValidationTester.validate(new EndpointCertificateSecretsValidator(), model, deployState);
}
@Test
@@ -66,7 +66,7 @@ public class EndpointCertificateSecretsValidatorTest {
DeployState deployState = deployState(servicesXml(), deploymentXml(), Optional.empty());
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new EndpointCertificateSecretsValidator().validate(model, deployState);
+ ValidationTester.validate(new EndpointCertificateSecretsValidator(), model, deployState);
}
private static DeployState deployState(String servicesXml, String deploymentXml, Optional<EndpointCertificateSecrets> endpointCertificateSecretsSecrets) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/InfrastructureDeploymentValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/InfrastructureDeploymentValidatorTest.java
index bcec73432b3..190f68e6956 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/InfrastructureDeploymentValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/InfrastructureDeploymentValidatorTest.java
@@ -43,6 +43,7 @@ public class InfrastructureDeploymentValidatorTest {
var model = new VespaModel(new NullConfigModelRegistry(), deployState);
var validator = new InfrastructureDeploymentValidator();
- validator.validate(model, deployState);
+ ValidationTester.validate(validator, model, deployState);
}
+
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java
index 31e4c661151..a53ef233746 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/JvmHeapSizeValidatorTest.java
@@ -13,6 +13,7 @@ import com.yahoo.config.model.deploy.TestProperties;
import com.yahoo.config.model.provision.InMemoryProvisioner;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.text.Text;
import com.yahoo.vespa.model.VespaModel;
@@ -38,27 +39,25 @@ class JvmHeapSizeValidatorTest {
@Test
void fails_on_too_low_jvm_percentage() throws IOException, SAXException {
- var deployState = createDeployState(8, 7L * 1024 * 1024 * 1024);
+ var deployState = createDeployState(9, 7L * 1024 * 1024 * 1024);
var model = new VespaModel(new NullConfigModelRegistry(), deployState);
- var e = assertThrows(IllegalArgumentException.class, () -> new JvmHeapSizeValidator().validate(model, deployState));
- String expectedMessage = "Allocated percentage of memory of JVM in cluster 'container' is too low (3% < 15%). Estimated cost of ONNX models is 7.00GB";
- assertTrue(e.getMessage().contains(expectedMessage), e.getMessage());
+ ValidationTester.expect(new JvmHeapSizeValidator(), model, deployState,
+ "Allocated percentage of memory of JVM in cluster 'container' is too low (12% < 15%). Estimated cost of ONNX models is 7.00GB");
}
@Test
void fails_on_too_low_heap_size() throws IOException, SAXException {
var deployState = createDeployState(2.2, 1024L * 1024 * 1024);
var model = new VespaModel(new NullConfigModelRegistry(), deployState);
- var e = assertThrows(IllegalArgumentException.class, () -> new JvmHeapSizeValidator().validate(model, deployState));
- String expectedMessage = "Allocated memory to JVM in cluster 'container' is too low (0.50GB < 0.60GB). Estimated cost of ONNX models is 1.00GB.";
- assertTrue(e.getMessage().contains(expectedMessage), e.getMessage());
+ ValidationTester.expect(new JvmHeapSizeValidator(), model, deployState,
+ "Allocated memory to JVM in cluster 'container' is too low (0.50GB < 0.60GB). Estimated cost of ONNX models is 1.00GB.");
}
@Test
void accepts_adequate_heap_size() throws IOException, SAXException {
var deployState = createDeployState(8, 1024L * 1024 * 1024);
var model = new VespaModel(new NullConfigModelRegistry(), deployState);
- assertDoesNotThrow(() -> new JvmHeapSizeValidator().validate(model, deployState));
+ assertDoesNotThrow(() -> ValidationTester.validate(new JvmHeapSizeValidator(), model, deployState));
}
@Test
@@ -80,7 +79,7 @@ class JvmHeapSizeValidatorTest {
</services>""";
var deployState = createDeployState(servicesXml, 2, 1024L * 1024 * 1024);
var model = new VespaModel(new NullConfigModelRegistry(), deployState);
- assertDoesNotThrow(() -> new JvmHeapSizeValidator().validate(model, deployState));
+ assertDoesNotThrow(() -> ValidationTester.validate(new JvmHeapSizeValidator(), model, deployState));
}
private static DeployState createDeployState(String servicesXml, double nodeGb, long modelCostBytes) {
@@ -121,6 +120,7 @@ class JvmHeapSizeValidatorTest {
ModelCostDummy(long modelCost) { this.modelCost = modelCost; }
@Override public Calculator newCalculator(ApplicationPackage appPkg, ApplicationId applicationId) { return this; }
+ @Override public Calculator newCalculator(ApplicationPackage appPkg, ApplicationId applicationId, ClusterSpec.Id clusterId) { return this; }
@Override public Map<String, ModelInfo> models() { return Map.of(); }
@Override public void setRestartOnDeploy() {}
@Override public boolean restartOnDeploy() { return false;}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/PublicApiBundleValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/PublicApiBundleValidatorTest.java
index c68599f4595..19be886d3e5 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/PublicApiBundleValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/PublicApiBundleValidatorTest.java
@@ -1,6 +1,8 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation;
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.vespa.model.application.validation.AbstractBundleValidator.JarContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -13,6 +15,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasSize;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* @author gjoranv
@@ -29,7 +32,11 @@ public class PublicApiBundleValidatorTest {
var jarFile = BundleValidatorTest.createTemporaryJarFile(tempDir, "non-public-api");
var validator = new PublicApiBundleValidator();
- validator.validateJarFile(deployState, jarFile);
+ validator.validateJarFile(new JarContext() {
+ @Override public void illegal(String error) { fail(); }
+ @Override public void illegal(String error, Throwable cause) { fail(); }
+ @Override public DeployState deployState() { return deployState; }
+ }, jarFile);
String output = outputBuf.toString();
assertThat(output, containsString("uses non-public Vespa APIs: ["));
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/SecretStoreValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/SecretStoreValidatorTest.java
index ae23b3b722d..9d53c5af61c 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/SecretStoreValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/SecretStoreValidatorTest.java
@@ -48,7 +48,7 @@ public class SecretStoreValidatorTest {
DeployState deployState = deployState(servicesXml(), deploymentXml(true));
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new SecretStoreValidator().validate(model, deployState);
+ ValidationTester.validate(new SecretStoreValidator(), model, deployState);
}
@Test
@@ -58,7 +58,7 @@ public class SecretStoreValidatorTest {
DeployState deployState = deployState(servicesXml(), deploymentXml(false));
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new SecretStoreValidator().validate(model, deployState);
+ ValidationTester.validate(new SecretStoreValidator(), model, deployState);
});
assertTrue(exception.getMessage().contains("Container cluster 'default' uses a secret store, so an Athenz domain and" +
@@ -74,7 +74,7 @@ public class SecretStoreValidatorTest {
DeployState deployState = deployState(servicesXml, deploymentXml(false));
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new SecretStoreValidator().validate(model, deployState);
+ ValidationTester.validate(new SecretStoreValidator(), model, deployState);
}
private static DeployState deployState(String servicesXml, String deploymentXml) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java
index 9a2f9fadac6..92c2b5276cd 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java
@@ -107,7 +107,7 @@ public class UriBindingsValidatorTest {
.endpoints(Set.of(new ContainerEndpoint("default", ApplicationClusterEndpoint.Scope.zone, List.of("default.example.com"))))
.build();
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new UriBindingsValidator().validate(model, deployState);
+ ValidationTester.validate(new UriBindingsValidator(), model, deployState);
}
private static String createServicesXmlWithHandler(String handlerBinding) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java
index 837de946e36..d4a324901e2 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java
@@ -81,7 +81,7 @@ public class UrlConfigValidatorTest {
.build();
DeployState deployState = createDeployState(app, systemName);
VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
- new UrlConfigValidator().validate(model, deployState);
+ ValidationTester.validate(new UrlConfigValidator(), model, deployState);
}
private static DeployState createDeployState(ApplicationPackage app, SystemName systemName) {
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 8dc07d8857d..29279635918 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
@@ -16,12 +16,15 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.application.validation.Validation.Execution;
+import com.yahoo.vespa.model.application.validation.change.ChangeValidator;
import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -30,6 +33,8 @@ import java.util.stream.Stream;
import static com.yahoo.config.model.test.MockApplicationPackage.BOOK_SCHEMA;
import static com.yahoo.config.model.test.MockApplicationPackage.MUSIC_SCHEMA;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author bratseth
@@ -114,4 +119,27 @@ public class ValidationTester {
return s.replaceAll("\\d", "-");
}
+ public static void expect(Validator validator, VespaModel model, DeployState deployState, String... expectedMessages) {
+ Execution execution = new Execution(model, deployState);
+ validator.validate(execution);
+ assertTrue( execution.errors().stream().allMatch(error -> Arrays.stream(expectedMessages).anyMatch(error::contains))
+ && Arrays.stream(expectedMessages).allMatch(expected -> execution.errors().stream().anyMatch(error -> error.contains(expected))),
+ "Expected errors: " + Arrays.toString(expectedMessages) + "\nActual errors: " + execution.errors());
+ }
+
+ /** Runs validation, and throws on illegalities. */
+ public static void validate(Validator validator, VespaModel model, DeployState deployState) {
+ Execution execution = new Execution(model, deployState);
+ validator.validate(execution);
+ execution.throwIfFailed();
+ }
+
+ /** Runs validation and returns the resulting config chance actions, without checking whether they're currently allowed; or throws on illegalities. */
+ public static List<ConfigChangeAction> validateChanges(ChangeValidator validator, VespaModel model, DeployState deployState) {
+ Execution execution = new Execution(model, deployState);
+ validator.validate(execution);
+ if ( ! execution.errors().isEmpty()) execution.throwIfFailed();
+ return execution.actions();
+ }
+
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java
index bc36b800bfb..6b5db3b081f 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java
@@ -41,22 +41,22 @@ public class CertificateRemovalChangeValidatorTest {
CertificateRemovalChangeValidator validator = new CertificateRemovalChangeValidator();
// Adding certs -> ok
- validator.validateClients("clusterId", List.of(c1, c2), List.of(c1, c2, c3), new DeployState.Builder().now(now).build());
+ validator.validateClients("clusterId", List.of(c1, c2), List.of(c1, c2, c3), (id, msg) -> ValidationOverrides.empty.invalid(id, msg, now));
// Removing certs -> fails
assertThrows(ValidationOverrides.ValidationException.class,
() ->validator.validateClients("clusterId", List.of(c1, c2, c3), List.of(c1, c3),
- new DeployState.Builder().now(now).build()));
+ (id, msg) -> ValidationOverrides.empty.invalid(id, msg, now)));
// Removing certs with validationoverrides -> ok
validator.validateClients("clusterId", List.of(c1, c2, c3), List.of(c1, c3),
- new DeployState.Builder().now(now).validationOverrides(ValidationOverrides.fromXml(validationOverrides)).build());
+ (id, msg) -> ValidationOverrides.fromXml(validationOverrides).invalid(id, msg, now));
// Adding and removing internal certs are ok:
validator.validateClients("clusterId", List.of(c1, c2), List.of(c1, c2, internal),
- new DeployState.Builder().build());
+ (id, msg) -> ValidationOverrides.empty.invalid(id, msg, now));
validator.validateClients("clusterId", List.of(c1, c2, internal), List.of(c1, c2),
- new DeployState.Builder().now(now).build());
+ (id, msg) -> ValidationOverrides.empty.invalid(id, msg, now));
}
static X509Certificate certificate(String cn) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java
index 081e10ecea6..c9703fc34af 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java
@@ -7,9 +7,11 @@ import com.yahoo.config.model.api.ServiceInfo;
import com.yahoo.config.provision.ClusterSpec;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
+import static java.util.Comparator.comparing;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ConfigChangeTestUtils {
@@ -60,8 +62,8 @@ public class ConfigChangeTestUtils {
public static void assertEqualActions(List<ConfigChangeAction> exp, List<ConfigChangeAction> act) {
var mutableExp = new ArrayList<>(exp);
var mutableAct = new ArrayList<>(act);
- mutableExp.sort((lhs, rhs) -> lhs.getMessage().compareTo(rhs.getMessage()));
- mutableAct.sort((lhs, rhs) -> lhs.getMessage().compareTo(rhs.getMessage()));
+ mutableExp.sort(comparing(ConfigChangeAction::getMessage));
+ mutableAct.sort(comparing(ConfigChangeAction::getMessage));
assertEquals(mutableExp, mutableAct);
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidatorTest.java
index a41b538d3ca..f68a1da7dfb 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidatorTest.java
@@ -1,16 +1,15 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change;
-import com.yahoo.config.model.deploy.DeployState;
-import com.yahoo.test.AnotherrestartConfig;
import com.yahoo.config.ConfigInstance;
-import com.yahoo.test.RestartConfig;
-import com.yahoo.test.SimpletypesConfig;
import com.yahoo.config.model.api.ConfigChangeAction;
+import com.yahoo.config.model.producer.AbstractConfigProducerRoot;
import com.yahoo.config.model.producer.AnyConfigProducer;
import com.yahoo.config.model.producer.TreeConfigProducer;
-import com.yahoo.config.model.producer.AbstractConfigProducerRoot;
import com.yahoo.config.model.test.MockRoot;
+import com.yahoo.test.AnotherrestartConfig;
+import com.yahoo.test.RestartConfig;
+import com.yahoo.test.SimpletypesConfig;
import com.yahoo.vespa.model.AbstractService;
import com.yahoo.vespa.model.Host;
import com.yahoo.vespa.model.HostResource;
@@ -25,7 +24,9 @@ import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.stream.Collectors;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Testing the validator on both a stub model and a real-life Vespa model.
@@ -152,11 +153,6 @@ public class ConfigValueChangeValidatorTest {
assertEmptyLog();
}
- private List<ConfigChangeAction> getConfigChanges(VespaModel currentModel, VespaModel nextModel) {
- ConfigValueChangeValidator validator = new ConfigValueChangeValidator();
- return validator.validate(currentModel, nextModel, new DeployState.Builder().deployLogger(logger).build());
- }
-
private List<ConfigChangeAction> getConfigChanges(AbstractConfigProducerRoot currentModel,
AbstractConfigProducerRoot nextModel) {
ConfigValueChangeValidator validator = new ConfigValueChangeValidator();
@@ -245,8 +241,7 @@ public class ConfigValueChangeValidatorTest {
setHostResource(new HostResource(new Host(null, "localhost")));
}
- @Override
- public int getPortCount() {
+ @Override public int getPortCount() {
return 0;
}
@@ -262,8 +257,7 @@ public class ConfigValueChangeValidatorTest {
this.value = value;
}
- @Override
- public void getConfig(RestartConfig.Builder builder) {
+ @Override public void getConfig(RestartConfig.Builder builder) {
builder.value(value);
}
@@ -283,8 +277,7 @@ public class ConfigValueChangeValidatorTest {
this.anotherValue = anotherValue;
}
- @Override
- public void getConfig(AnotherrestartConfig.Builder builder) {
+ @Override public void getConfig(AnotherrestartConfig.Builder builder) {
builder.anothervalue(anotherValue);
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java
index ac59ca58cb5..a7485b177d3 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java
@@ -5,6 +5,7 @@ import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.vespa.defaults.Defaults;
import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.application.validation.ValidationTester;
import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg;
import org.junit.jupiter.api.Test;
@@ -67,7 +68,7 @@ public class ContainerRestartValidatorTest {
}
private static List<ConfigChangeAction> validateModel(VespaModel current, VespaModel next) {
- return new ContainerRestartValidator().validate(current, next, new DeployState.Builder().build());
+ return ValidationTester.validateChanges(new ContainerRestartValidator(), next, new DeployState.Builder().previousModel(current).build());
}
private static VespaModel createModel(boolean restartOnDeploy, boolean alwaysRestart) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java
index cdc80754194..f4123a72e1f 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.application.validation.ValidationTester;
@@ -14,7 +15,7 @@ import static org.junit.jupiter.api.Assertions.*;
public class GlobalDocumentChangeValidatorTest {
@Test
- void testChangGlobalAttribute() {
+ void testChangeGlobalAttribute() {
testChangeGlobalAttribute(true, false, false, null);
testChangeGlobalAttribute(true, true, true, null);
testChangeGlobalAttribute(false, false, true, null);
@@ -27,14 +28,16 @@ public class GlobalDocumentChangeValidatorTest {
ValidationTester tester = new ValidationTester();
VespaModel oldModel = tester.deploy(null, getServices(oldGlobal), Environment.prod, validationOverrides, "default.indexing").getFirst();
try {
- tester.deploy(oldModel, getServices(newGlobal), Environment.prod, validationOverrides, "default.indexing").getSecond();
+ var actions = tester.deploy(oldModel, getServices(newGlobal), Environment.prod, validationOverrides, "default.indexing").getSecond();
assertTrue(allowed);
- } catch (IllegalStateException e) {
+ assertEquals(validationOverrides == null ? 0 : 1, actions.size());
+ if (validationOverrides != null) assertEquals(ClusterSpec.Id.from("default"), actions.get(0).clusterId());
+ } catch (IllegalArgumentException e) {
assertFalse(allowed);
- assertEquals("Document type music in cluster default changed global from " + oldGlobal + " to " + newGlobal + ". " +
- "Add validation override 'global-document-change' to force this change through. " +
- "First, stop services on all content nodes. Then, deploy with validation override. Finally, start services on all content nodes.",
- e.getMessage());
+ assertEquals("global-document-change: Document type music in cluster default changed global from " + oldGlobal + " to " + newGlobal + ". " +
+ "To handle this change, first stop services on all content nodes. Then, deploy with validation override. Finally, start services on all content nodes. " +
+ "To allow this add <allow until='yyyy-mm-dd'>global-document-change</allow> to validation-overrides.xml, see https://docs.vespa.ai/en/reference/validation-overrides.html",
+ e.getMessage());
}
}
@@ -52,8 +55,10 @@ public class GlobalDocumentChangeValidatorTest {
}
private static final String globalDocumentValidationOverrides =
- "<validation-overrides>\n" +
- " <allow until='2000-01-14' comment='test override'>global-document-change</allow>\n" +
- "</validation-overrides>\n";
+ """
+ <validation-overrides>
+ <allow until='2000-01-14' comment='test override'>global-document-change</allow>
+ </validation-overrides>
+ """;
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSchemaClusterChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSchemaClusterChangeValidatorTest.java
index fb4e9f1a00b..3555fc21471 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSchemaClusterChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSchemaClusterChangeValidatorTest.java
@@ -7,6 +7,7 @@ import com.yahoo.config.model.api.ServiceInfo;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.application.validation.ValidationTester;
import com.yahoo.vespa.model.content.utils.ApplicationPackageBuilder;
import com.yahoo.vespa.model.content.utils.ContentClusterBuilder;
import com.yahoo.vespa.model.content.utils.SchemaBuilder;
@@ -70,8 +71,7 @@ public class IndexedSchemaClusterChangeValidatorTest {
}
private List<ConfigChangeAction> validate() {
- return normalizeServicesInActions(validator.validate(currentModel, nextModel,
- new DeployState.Builder().build()));
+ return normalizeServicesInActions(ValidationTester.validateChanges(validator, nextModel, new DeployState.Builder().previousModel(currentModel).build()));
}
public void assertValidation() {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java
index afa36ac271e..b2439651cf9 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java
@@ -13,6 +13,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.application.validation.ValidationTester;
import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg;
import org.junit.jupiter.api.Test;
@@ -58,7 +59,7 @@ public class NodeResourceChangeValidatorTest {
}
private List<ConfigChangeAction> validate(VespaModel current, VespaModel next) {
- return new NodeResourceChangeValidator().validate(current, next, new DeployState.Builder().build());
+ return ValidationTester.validateChanges(new NodeResourceChangeValidator(), next, new DeployState.Builder().previousModel(current).build());
}
private static VespaModel model(int mem1, int mem2, int mem3, int mem4) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java
index 13389689de5..67e8a4d512e 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RestartOnDeployForOnnxModelChangesValidatorTest.java
@@ -8,6 +8,7 @@ import com.yahoo.config.model.api.OnnxModelOptions;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.deploy.TestProperties;
import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.application.validation.ValidationTester;
import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg;
import org.junit.jupiter.api.Test;
@@ -71,7 +72,7 @@ public class RestartOnDeployForOnnxModelChangesValidatorTest {
}
private static List<ConfigChangeAction> validateModel(VespaModel current, VespaModel next) {
- return new RestartOnDeployForOnnxModelChangesValidator().validate(current, next, deployStateBuilder().build());
+ return ValidationTester.validateChanges(new RestartOnDeployForOnnxModelChangesValidator(), next, deployStateBuilder().previousModel(current).build());
}
private static OnnxModelCost onnxModelCost() {
@@ -79,7 +80,7 @@ public class RestartOnDeployForOnnxModelChangesValidatorTest {
}
private static OnnxModelCost onnxModelCost(long estimatedCost, long hash) {
- return (appPkg, applicationId) -> new OnnxModelCost.Calculator() {
+ return (appPkg, applicationId, clusterId) -> new OnnxModelCost.Calculator() {
private final Map<String, OnnxModelCost.ModelInfo> models = new HashMap<>();
private boolean restartOnDeploy = false;
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSchemaClusterChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSchemaClusterChangeValidatorTest.java
index 8db9d39534d..ee64ceb6969 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSchemaClusterChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSchemaClusterChangeValidatorTest.java
@@ -7,6 +7,7 @@ import com.yahoo.config.model.api.ServiceInfo;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.application.validation.ValidationTester;
import com.yahoo.vespa.model.content.utils.ApplicationPackageBuilder;
import com.yahoo.vespa.model.content.utils.ContentClusterBuilder;
import com.yahoo.vespa.model.content.utils.DocType;
@@ -69,8 +70,8 @@ public class StreamingSchemaClusterChangeValidatorTest {
}
public List<ConfigChangeAction> validate() {
- return normalizeServicesInActions(validator.validate(currentModel, nextModel,
- new DeployState.Builder().build()));
+ return normalizeServicesInActions(ValidationTester.validateChanges(validator, nextModel,
+ new DeployState.Builder().previousModel(currentModel).build()));
}
public void assertValidation() {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/EmbedderTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/EmbedderTestCase.java
index 138bef3ae73..2532a5be863 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/EmbedderTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/EmbedderTestCase.java
@@ -12,6 +12,7 @@ import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.deploy.TestProperties;
import com.yahoo.embedding.BertBaseEmbedderConfig;
import com.yahoo.embedding.ColBertEmbedderConfig;
+import com.yahoo.embedding.SpladeEmbedderConfig;
import com.yahoo.embedding.huggingface.HuggingFaceEmbedderConfig;
import com.yahoo.language.huggingface.config.HuggingFaceTokenizerConfig;
import com.yahoo.path.Path;
@@ -24,6 +25,7 @@ import com.yahoo.vespa.model.container.component.BertEmbedder;
import com.yahoo.vespa.model.container.component.ColBertEmbedder;
import com.yahoo.vespa.model.container.component.Component;
import com.yahoo.vespa.model.container.component.HuggingFaceEmbedder;
+import com.yahoo.vespa.model.container.component.SpladeEmbedder;
import com.yahoo.vespa.model.container.component.HuggingFaceTokenizer;
import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithFilePkg;
import com.yahoo.yolean.Exceptions;
@@ -101,6 +103,23 @@ public class EmbedderTestCase {
assertEquals(-1, tokenizerCfg.maxLength());
}
+ @Test
+ void spladeEmbedder_selfhosted() throws Exception {
+ var model = loadModel(Path.fromString("src/test/cfg/application/embed/"), false);
+ var cluster = model.getContainerClusters().get("container");
+ var embedderCfg = assertSpladeEmbedderComponentPresent(cluster);
+
+ assertEquals("my_input_ids", embedderCfg.transformerInputIds());
+ assertEquals("https://my/url/model.onnx", modelReference(embedderCfg, "transformerModel").url().orElseThrow().value());
+ assertEquals(0.2, embedderCfg.termScoreThreshold());
+ assertEquals(1024, embedderCfg.transformerMaxTokens());
+
+ var tokenizerCfg = assertHuggingfaceTokenizerComponentPresent(cluster);
+ assertEquals("https://my/url/tokenizer.json", modelReference(tokenizerCfg.model().get(0), "path").url().orElseThrow().value());
+ assertEquals(-1, tokenizerCfg.maxLength());
+ }
+
+ @Test
void colBertEmbedder_selfhosted() throws Exception {
var model = loadModel(Path.fromString("src/test/cfg/application/embed/"), false);
var cluster = model.getContainerClusters().get("container");
@@ -113,6 +132,7 @@ public class EmbedderTestCase {
assertEquals(-1, tokenizerCfg.maxLength());
}
+ @Test
void colBertEmbedder_hosted() throws Exception {
var model = loadModel(Path.fromString("src/test/cfg/application/embed/"), true);
var cluster = model.getContainerClusters().get("container");
@@ -266,13 +286,21 @@ public class EmbedderTestCase {
}
private static ColBertEmbedderConfig assertColBertEmbedderComponentPresent(ApplicationContainerCluster cluster) {
- var colbert = (ColBertEmbedder) cluster.getComponentsMap().get(new ComponentId("colbert-embedder"));
+ var colbert = (ColBertEmbedder) cluster.getComponentsMap().get(new ComponentId("colbert"));
assertEquals("ai.vespa.embedding.ColBertEmbedder", colbert.getClassId().getName());
var cfgBuilder = new ColBertEmbedderConfig.Builder();
colbert.getConfig(cfgBuilder);
return cfgBuilder.build();
}
+ private static SpladeEmbedderConfig assertSpladeEmbedderComponentPresent(ApplicationContainerCluster cluster) {
+ var splade = (SpladeEmbedder) cluster.getComponentsMap().get(new ComponentId("splade"));
+ assertEquals("ai.vespa.embedding.SpladeEmbedder", splade.getClassId().getName());
+ var cfgBuilder = new SpladeEmbedderConfig.Builder();
+ splade.getConfig(cfgBuilder);
+ return cfgBuilder.build();
+ }
+
private static BertBaseEmbedderConfig assertBertEmbedderComponentPresent(ApplicationContainerCluster cluster) {
var bertEmbedder = (BertEmbedder) cluster.getComponentsMap().get(new ComponentId("bert-embedder"));
assertEquals("ai.vespa.embedding.BertBaseEmbedder", bertEmbedder.getClassId().getName());
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ModelIdResolverTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ModelIdResolverTest.java
new file mode 100644
index 00000000000..409c3ac833a
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ModelIdResolverTest.java
@@ -0,0 +1,35 @@
+package com.yahoo.vespa.model.container.xml;
+
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.config.model.deploy.TestProperties;
+import org.junit.jupiter.api.Test;
+
+import java.util.Optional;
+import java.util.Set;
+
+import static com.yahoo.vespa.model.container.xml.ModelIdResolver.HF_TOKENIZER;
+import static com.yahoo.vespa.model.container.xml.ModelIdResolver.ONNX_MODEL;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+ * @author bjorncs
+ */
+class ModelIdResolverTest {
+
+ @Test
+ void throws_on_known_model_with_missing_tags() {
+ var state = new DeployState.Builder().properties(new TestProperties().setHostedVespa(true)).build();
+ var e = assertThrows(IllegalArgumentException.class, () ->
+ ModelIdResolver.resolveToModelReference(
+ "param", Optional.of("minilm-l6-v2"), Optional.empty(), Optional.empty(), Set.of(HF_TOKENIZER), state));
+ var expectedMsg = "Model 'minilm-l6-v2' on 'param' has tags [onnx-model] but are missing required tags [huggingface-tokenizer]";
+ assertEquals(expectedMsg, e.getMessage());
+
+ assertDoesNotThrow(
+ () -> ModelIdResolver.resolveToModelReference(
+ "param", Optional.of("minilm-l6-v2"), Optional.empty(), Optional.empty(), Set.of(ONNX_MODEL), state));
+ }
+
+} \ No newline at end of file
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/utils/SchemaBuilder.java b/config-model/src/test/java/com/yahoo/vespa/model/content/utils/SchemaBuilder.java
index 6defca17bcb..304f3dc426f 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/content/utils/SchemaBuilder.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/content/utils/SchemaBuilder.java
@@ -3,7 +3,6 @@ package com.yahoo.vespa.model.content.utils;
import java.util.Arrays;
import java.util.List;
-import java.util.stream.Collectors;
import static com.yahoo.config.model.test.TestUtil.joinLines;
diff --git a/config-model/src/test/resources/cloud-clients-validator/cert-with-empty-sequence-of-extensions.pem b/config-model/src/test/resources/cloud-clients-validator/cert-with-empty-sequence-of-extensions.pem
new file mode 100644
index 00000000000..1942c12b28e
--- /dev/null
+++ b/config-model/src/test/resources/cloud-clients-validator/cert-with-empty-sequence-of-extensions.pem
@@ -0,0 +1,9 @@
+-----BEGIN CERTIFICATE-----
+MIIBPDCB46ADAgECAhEAhdEB3eHnsQxTdcYcClVpkzAKBggqhkjOPQQDAjAeMRww
+GgYDVQQDExNjbG91ZC52ZXNwYS5leGFtcGxlMB4XDTIyMTIyMTE4NTg0MloXDTMy
+MTIxODE4NTg0MlowHjEcMBoGA1UEAxMTY2xvdWQudmVzcGEuZXhhbXBsZTBZMBMG
+ByqGSM49AgEGCCqGSM49AwEHA0IABOPzpGlb+4HvgsRT5Ic6gmzYqAE2GQrgfi5z
+txf8yzoi5YqgEG6utFhjleQ5bUusDhMtrfOJoBL5VZxrQccmwsCjAjAAMAoGCCqG
+SM49BAMCA0gAMEUCIQCuNXMk5lsb9lF2IloYZB2wAHme/xAOyQ2arWzZf6BH2wIg
+dEsmbGhel9MLlfPVQjeUwCJha/XD7xfWW6IaL+hI5TQ=
+-----END CERTIFICATE-----
diff --git a/config-model/src/test/resources/cloud-clients-validator/valid-cert.pem b/config-model/src/test/resources/cloud-clients-validator/valid-cert.pem
new file mode 100644
index 00000000000..aebec508772
--- /dev/null
+++ b/config-model/src/test/resources/cloud-clients-validator/valid-cert.pem
@@ -0,0 +1,9 @@
+-----BEGIN CERTIFICATE-----
+MIIBNzCB3qADAgECAhB00FXOPRoixiJghCsT2FVOMAoGCCqGSM49BAMCMB4xHDAa
+BgNVBAMTE2Nsb3VkLnZlc3BhLmV4YW1wbGUwHhcNMjQwMTA0MTM0MTMwWhcNMzQw
+MTAxMTM0MTMwWjAeMRwwGgYDVQQDExNjbG91ZC52ZXNwYS5leGFtcGxlMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAEts/fYf1H+aOW4xZHtcxX2YvMWojzU4HvHw1b
+9Zc+7OoUcoqv9dTZMVaYj3J8Z3A73wNn5rhjPrI4sKtI5KN6sjAKBggqhkjOPQQD
+AgNIADBFAiEAqgs4QouJOf6ny48o5c6EZSTB3+iNyZr+23JXKwnYuUkCIFRtE736
+BJ5KdCPpI4jS611HgeLLlJmgF2524Gz4EpjH
+-----END CERTIFICATE-----