summaryrefslogtreecommitdiffstats
path: root/pmdictionaryvalidation/src/test
diff options
context:
space:
mode:
authorPawel <pawel.kasperkiewicz@nokia.com>2020-11-12 12:15:55 +0100
committerPawel <pawel.kasperkiewicz@nokia.com>2020-11-24 09:08:06 +0100
commitb6ff67fa1d21765f2f52f3643946c96b2f13aa07 (patch)
treea3c03d814bccabd9de7d16c2da87a0e3a0f7ea08 /pmdictionaryvalidation/src/test
parente1be6d1ea065340aaabce761705755970348c6c4 (diff)
Extract pm-dicrionary validation
Issue-ID: VNFSDK-713 Signed-off-by: Pawel <pawel.kasperkiewicz@nokia.com> Change-Id: Iee5a23a3a6c9215927aa2c453faab62d30453444
Diffstat (limited to 'pmdictionaryvalidation/src/test')
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlFileValidatorTest.java110
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlLoaderTest.java96
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlLoadingUtils.java94
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlValidatorTest.java118
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/model/YamlDocumentFactoryTest.java134
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/model/YamlParameterListFactoryTest.java83
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/process/YamlValidationProcessTest.java97
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/schema/YamlSchemaFactoryTest.java118
-rw-r--r--pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/schema/node/YamlSchemaNodeFactoryTest.java146
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/Multi_Document_Invalid.yaml86
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/PM_Dictionary.yaml228
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/PM_Dictionary_JSON_Style.yaml239
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Mapping_Value.yaml149
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Schema_Construction.yaml39
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Schema_LazyLoading.yaml39
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Unknown_Escape_Character.yaml149
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Valid_Schema.yaml39
-rw-r--r--pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Valid_Schema_Multi_Root.yaml23
18 files changed, 1987 insertions, 0 deletions
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlFileValidatorTest.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlFileValidatorTest.java
new file mode 100644
index 0000000..089348d
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlFileValidatorTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml;
+
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.Test;
+import org.onap.validation.yaml.error.YamlDocumentValidationError;
+import org.onap.validation.yaml.exception.YamlProcessingException;
+import org.yaml.snakeyaml.parser.ParserException;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class YamlFileValidatorTest {
+
+ @Test
+ void shouldReturnCorrectErrorsWhenGivenPathToValidPmDictionaryFile() throws YamlProcessingException {
+ // given
+ String path = getFullPathForGivenResources(YamlLoadingUtils.PATH_TO_VALID_YAML);
+
+ // when
+ List<YamlDocumentValidationError> validationErrors = new YamlFileValidator().validateYamlFileWithSchema(path);
+
+ // then
+ assertValidationReturnedExpectedErrors(validationErrors);
+
+ }
+
+ @Test
+ void shouldReturnCorrecErrorsWhenGivenPathToValidJsonStylePmDictionaryFile() throws YamlProcessingException {
+ // given
+ String path = getFullPathForGivenResources(YamlLoadingUtils.PATH_TO_VALID_JSON_STYLE_YAML);
+
+ // when
+ List<YamlDocumentValidationError> validationErrors = new YamlFileValidator().validateYamlFileWithSchema(path);
+
+ // then
+ assertValidationReturnedExpectedErrors(validationErrors);
+ }
+
+
+ private void assertValidationReturnedExpectedErrors(List<YamlDocumentValidationError> validationErrors) {
+ assertThat(validationErrors)
+ .isNotNull()
+ .hasSize(4)
+ .usingRecursiveFieldByFieldElementComparator()
+ .containsAll(
+ Lists.list(
+ new YamlDocumentValidationError(1,
+ "/pmMetaData/pmFields/measResultType",
+ "Value(s) is/are not in array of accepted values.\n" +
+ " value(s): integer\n" +
+ " accepted value(s): [float, uint32, uint64]"),
+ new YamlDocumentValidationError(1,
+ "/pmMetaData/pmFields/",
+ "Key not found: measChangeType"),
+ new YamlDocumentValidationError(2,
+ "/pmMetaData/pmFields/",
+ "Key not found: measChangeType"),
+ new YamlDocumentValidationError(3,
+ "/pmMetaData/pmFields/measAdditionalFields/vendorField1",
+ "Value(s) is/are not in array of accepted values.\n" +
+ " value(s): [Z, A]\n" +
+ " accepted value(s): [X, Y, Z]")
+ )
+ );
+ }
+
+ @Test
+ void shouldThrowErrorWhenGivenPathToInvalidPmDictionaryFile() {
+ // given
+ String path = getFullPathForGivenResources(YamlLoadingUtils.PATH_TO_MULTI_DOCUMENT_INVALID_YAML);
+ // when then
+ assertThatThrownBy(() -> new YamlFileValidator().validateYamlFileWithSchema(path))
+ .isInstanceOf(ParserException.class)
+ .hasMessageContaining("expected the node content, but found '<document end>'");
+ }
+
+ @Test
+ void shouldThrowErrorWhenGivenInvalidPath() {
+ // given
+ String path = "invalid/path/to/pm_dictionary";
+
+ // when then
+ assertThatThrownBy(() -> new YamlFileValidator().validateYamlFileWithSchema(path))
+ .isInstanceOf(YamlProcessingException.class)
+ .hasMessageContaining("PM_Dictionary YAML file is empty");
+ }
+
+ private String getFullPathForGivenResources(String pathToValidYaml) {
+ return this.getClass().getClassLoader().getResource(pathToValidYaml).getPath();
+ }
+}
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlLoaderTest.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlLoaderTest.java
new file mode 100644
index 0000000..36297ca
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlLoaderTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml;
+
+import org.junit.jupiter.api.Test;
+import org.onap.validation.yaml.exception.YamlProcessingException;
+import org.onap.validation.yaml.model.YamlDocument;
+import org.onap.validation.yaml.model.YamlDocumentFactory;
+import org.yaml.snakeyaml.parser.ParserException;
+import org.yaml.snakeyaml.scanner.ScannerException;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+
+class YamlLoaderTest {
+
+ private static final int EXPECTED_NUMBER_OF_DOCUMENTS = 5;
+ private static final String LETTER_S_WITH_ASCII_CODE = "s(115)";
+
+ @Test
+ void shouldLoadAllDocumentsFromYamlFile() throws YamlDocumentFactory.YamlDocumentParsingException {
+ // when
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidMultiDocumentYamlFile();
+
+ // then
+ assertThat(documents).hasSize(EXPECTED_NUMBER_OF_DOCUMENTS);
+ }
+
+ @Test
+ void shouldLoadAllDocumentsFromJsonStyleYamlFile() throws YamlDocumentFactory.YamlDocumentParsingException {
+ // when
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidJsonStyleMultiDocumentYamlFile();
+
+ // then
+ assertThat(documents).hasSize(EXPECTED_NUMBER_OF_DOCUMENTS);
+ }
+
+ @Test
+ void shouldLoadAllDocumentsFromYamlFileUsingPathInString() throws YamlProcessingException {
+ // when
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidMultiDocumentYamlFileUsingStringPath();
+
+ // then
+ assertThat(documents).hasSize(EXPECTED_NUMBER_OF_DOCUMENTS);
+ }
+
+ @Test
+ void shouldThrowExceptionWhenLoadingDocumentsFromInvalidYamlFile() {
+ // when then
+ assertThatThrownBy(YamlLoadingUtils::tryToLoadMultiDocumentInvalidYamlFile)
+ .isInstanceOf(ParserException.class)
+ .hasMessageContaining("expected the node content, but found '<document end>'");
+ }
+
+ @Test
+ void shouldThrowExceptionWhenLoadingDocumentsFromInvalidYamlFileUsingPathInString() {
+ // when then
+ assertThatThrownBy(YamlLoadingUtils::tryToLoadMultiDocumentInvalidYamlFileUsingStringPath)
+ .isInstanceOf(ParserException.class)
+ .hasMessageContaining("expected the node content, but found '<document end>'");
+ }
+
+ @Test
+ void shouldThrowExceptionWhenLoadingInvalidYamlFileWithIncorrectKeyMapping() {
+ // when then
+ assertThatThrownBy(YamlLoadingUtils::tryToLoadInvalidYamlFileWithIncorrectKeyMapping)
+ .isInstanceOf(ScannerException.class)
+ .hasMessageContaining("mapping values are not allowed here");
+ }
+
+ @Test
+ void shouldThrowExceptionWhenLoadingInvalidYamlFileWithUnknownEscapeCharacter() {
+ // when then
+ assertThatThrownBy(YamlLoadingUtils::tryToLoadInvalidYamlFileWithUnknownEscapeCharacter)
+ .isInstanceOf(ScannerException.class)
+ .hasMessageContaining("found unknown escape character " + LETTER_S_WITH_ASCII_CODE);
+ }
+}
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlLoadingUtils.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlLoadingUtils.java
new file mode 100644
index 0000000..b65029f
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlLoadingUtils.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml;
+
+import org.onap.validation.yaml.exception.YamlProcessingException;
+import org.onap.validation.yaml.model.YamlDocument;
+
+import java.net.URL;
+import java.util.List;
+
+import static org.onap.validation.yaml.model.YamlDocumentFactory.YamlDocumentParsingException;
+
+public final class YamlLoadingUtils {
+
+ private YamlLoadingUtils() { }
+
+ public static final int VALID_YAML_DOCUMENT_INDEX = 4;
+ public static final int YAML_DOCUMENT_WITH_WRONG_VALUE_IN_ARRAY_INDEX = 3;
+ public static final int YAML_DOCUMENT_WITH_MISSING_FIELD_INDEX = 2;
+ public static final int YAML_DOCUMENT_WITH_MISSING_FIELD_AND_WRONG_VALUE_INDEX = 1;
+
+ static final String PATH_TO_VALID_YAML = "yaml_schema/PM_Dictionary.yaml";
+ static final String PATH_TO_VALID_JSON_STYLE_YAML = "yaml_schema/PM_Dictionary_JSON_Style.yaml";
+ private static final String PATH_TO_SIMPLE_VALID_SCHEMA = "yaml_schema/Simple_Valid_Schema.yaml";
+ private static final String PATH_TO_SIMPLE_VALID_SCHEMA_MULTI_ROOT = "yaml_schema/Simple_Valid_Schema_Multi_Root.yaml";
+ private static final String PATH_TO_SIMPLE_INVALID_SCHEMA = "yaml_schema/Simple_Invalid_Schema_Construction.yaml";
+ private static final String PATH_TO_SIMPLE_INVALID_SCHEMA_FOR_LAZY_LOADING = "yaml_schema/Simple_Invalid_Schema_LazyLoading.yaml";
+ static final String PATH_TO_MULTI_DOCUMENT_INVALID_YAML = "yaml_schema/Multi_Document_Invalid.yaml";
+ private static final String PATH_TO_INVALID_YAML_WITH_INCORRECT_KEY_MAPPING = "yaml_schema/Simple_Invalid_Mapping_Value.yaml";
+ private static final String PATH_TO_INVALID_YAML_WITH_UNKNOWN_ESCAPE_CHARACTER = "yaml_schema/Simple_Unknown_Escape_Character.yaml";
+
+ public static List<YamlDocument> loadValidMultiDocumentYamlFile() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_VALID_YAML));
+ }
+
+ public static List<YamlDocument> loadValidJsonStyleMultiDocumentYamlFile() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_VALID_JSON_STYLE_YAML));
+ }
+
+ public static List<YamlDocument> loadValidMultiDocumentYamlFileUsingStringPath() throws YamlProcessingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_VALID_YAML).getPath());
+ }
+
+ public static YamlDocument loadSimpleValidYamlSchemaFile() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_SIMPLE_VALID_SCHEMA)).get(0);
+ }
+
+ public static YamlDocument loadSimpleInvalidYamlSchemaFile() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_SIMPLE_INVALID_SCHEMA)).get(0);
+ }
+
+ public static YamlDocument loadSimpleInvalidYamlSchemaForLazyLoadingFile() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_SIMPLE_INVALID_SCHEMA_FOR_LAZY_LOADING)).get(0);
+ }
+
+ public static YamlDocument loadSimpleValidYamlSchemaWithMultiRootFile() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_SIMPLE_VALID_SCHEMA_MULTI_ROOT)).get(0);
+ }
+
+ public static List<YamlDocument> tryToLoadMultiDocumentInvalidYamlFile() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_MULTI_DOCUMENT_INVALID_YAML));
+ }
+
+ public static List<YamlDocument> tryToLoadMultiDocumentInvalidYamlFileUsingStringPath() throws YamlProcessingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_MULTI_DOCUMENT_INVALID_YAML).getPath());
+ }
+
+ public static List<YamlDocument> tryToLoadInvalidYamlFileWithIncorrectKeyMapping() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_INVALID_YAML_WITH_INCORRECT_KEY_MAPPING));
+ }
+
+ public static List<YamlDocument> tryToLoadInvalidYamlFileWithUnknownEscapeCharacter() throws YamlDocumentParsingException {
+ return new YamlLoader().loadMultiDocumentYamlFile(getUrlForGivenPath(PATH_TO_INVALID_YAML_WITH_UNKNOWN_ESCAPE_CHARACTER));
+ }
+
+ private static URL getUrlForGivenPath(String path) {
+ return YamlLoadingUtils.class.getClassLoader().getResource(path);
+ }
+}
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlValidatorTest.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlValidatorTest.java
new file mode 100644
index 0000000..3f64540
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/YamlValidatorTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml;
+
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.Test;
+import org.onap.validation.yaml.error.SchemaValidationError;
+import org.onap.validation.yaml.exception.YamlProcessingException;
+import org.onap.validation.yaml.model.YamlDocument;
+import org.onap.validation.yaml.schema.YamlSchemaFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.onap.validation.yaml.YamlLoadingUtils.VALID_YAML_DOCUMENT_INDEX;
+import static org.onap.validation.yaml.YamlLoadingUtils.YAML_DOCUMENT_WITH_MISSING_FIELD_AND_WRONG_VALUE_INDEX;
+import static org.onap.validation.yaml.YamlLoadingUtils.YAML_DOCUMENT_WITH_MISSING_FIELD_INDEX;
+import static org.onap.validation.yaml.YamlLoadingUtils.YAML_DOCUMENT_WITH_WRONG_VALUE_IN_ARRAY_INDEX;
+
+class YamlValidatorTest {
+
+ @Test
+ void shouldCreateValidatorUsingSchemaLoadedFromYamlFileAndValidatedJsonStyleDocumentsFromThatFile()
+ throws YamlProcessingException {
+
+ // given
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidJsonStyleMultiDocumentYamlFile();
+ YamlValidator validator = new YamlValidator(new YamlSchemaFactory().createTreeStructuredYamlSchema(documents.get(0)));
+ Map<Integer, List<SchemaValidationError>> validationErrors = new HashMap<>();
+
+ // when
+ for (int documentIndex = 1; documentIndex < documents.size(); documentIndex++) {
+ validationErrors.put(documentIndex, validator.validate(documents.get(documentIndex)));
+ }
+
+ // then
+ assertValidatorReturnedCorrectErrors(validationErrors);
+ }
+
+ @Test
+ void shouldCreateValidatorUsingSchemaLoadedFromYamlFileAndValidatedDocumentsFromThatFile()
+ throws YamlProcessingException {
+
+ // given
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidMultiDocumentYamlFile();
+ YamlValidator validator = new YamlValidator(new YamlSchemaFactory().createTreeStructuredYamlSchema(documents.get(0)));
+ Map<Integer, List<SchemaValidationError>> validationErrors = new HashMap<>();
+
+ // when
+ for (int documentIndex = 1; documentIndex < documents.size(); documentIndex++) {
+ validationErrors.put(documentIndex, validator.validate(documents.get(documentIndex)));
+ }
+
+ // then
+ assertValidatorReturnedCorrectErrors(validationErrors);
+ }
+
+ private void assertValidatorReturnedCorrectErrors(Map<Integer, List<SchemaValidationError>> validationErrors) {
+
+ SchemaValidationError expectedValidationValueError =
+ new SchemaValidationError(
+ "/pmMetaData/pmFields/measResultType",
+ "Value(s) is/are not in array of accepted values.\n"
+ + " value(s): integer\n"
+ + " accepted value(s): [float, uint32, uint64]"
+ );
+ SchemaValidationError expectedValidationKeyError =
+ new SchemaValidationError(
+ "/pmMetaData/pmFields/",
+ "Key not found: measChangeType"
+ );
+ SchemaValidationError expectedValidationValuesInArrayError =
+ new SchemaValidationError(
+ "/pmMetaData/pmFields/measAdditionalFields/vendorField1",
+ "Value(s) is/are not in array of accepted values.\n"
+ + " value(s): [Z, A]\n"
+ + " accepted value(s): [X, Y, Z]"
+ );
+
+ assertThat(validationErrors)
+ .hasSize(4)
+ .containsKeys(1, 2, 3);
+ assertThat(validationErrors.get(YAML_DOCUMENT_WITH_MISSING_FIELD_AND_WRONG_VALUE_INDEX))
+ .hasSize(2)
+ .usingFieldByFieldElementComparator()
+ .containsAll(Lists.list(
+ expectedValidationValueError,
+ expectedValidationKeyError
+ ));
+ assertThat(validationErrors.get(YAML_DOCUMENT_WITH_MISSING_FIELD_INDEX))
+ .hasSize(1)
+ .usingFieldByFieldElementComparator()
+ .contains(expectedValidationKeyError);
+ assertThat(validationErrors.get(YAML_DOCUMENT_WITH_WRONG_VALUE_IN_ARRAY_INDEX))
+ .hasSize(1)
+ .usingFieldByFieldElementComparator()
+ .contains(expectedValidationValuesInArrayError);
+ assertThat(validationErrors.get(VALID_YAML_DOCUMENT_INDEX)).hasSize(0);
+ }
+
+}
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/model/YamlDocumentFactoryTest.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/model/YamlDocumentFactoryTest.java
new file mode 100644
index 0000000..0bd0579
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/model/YamlDocumentFactoryTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml.model;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.onap.validation.yaml.model.YamlDocumentFactory.YamlDocumentParsingException;
+
+class YamlDocumentFactoryTest {
+
+ @Test
+ void shouldTurnMapOfUnknownKeyTypeToMapWithStringKeysAndBeAbleToReturnStringifyValues()
+ throws YamlDocumentParsingException {
+ // given
+ List<String> testList = List.of("element1", "element11");
+ Map<Object, Object> testEmptyMap = Collections.emptyMap();
+ Map<Object, Object> inputMap = Map.of(
+ "test", testList,
+ 345, "element2",
+ "test2", "element3",
+ 2.67, testEmptyMap);
+
+ // when
+ YamlDocument document = new YamlDocumentFactory().createYamlDocument(inputMap);
+
+ // then
+ assertThat(document).isNotNull();
+ assertThat(document.getYaml()).containsKeys("test", "345", "test2", "2.67");
+
+ assertThat(document.getYaml()).containsEntry("test", testList);
+ assertThat(document.getValue("test")).isEqualTo("[element1, element11]");
+
+ assertThat(document.getValue("345")).isEqualTo("element2");
+ assertThat(document.getValue("test2")).isEqualTo("element3");
+
+ assertThat(document.getYaml()).containsEntry("2.67", testEmptyMap);
+ assertThat(document.getValue("2.67")).isEqualTo("{}");
+ }
+
+ @Test
+ void shouldTurnMapOfUnknownKeyTypeToMapWithStringKeysAndBeAbleToExtractSubStructure()
+ throws YamlDocumentParsingException {
+ // given
+ Map<Object, Object> subStructureMap = Map.of(
+ "subTest1", "subElement1",
+ "subTest2", "subElement2");
+ Map<Object, Object> inputMap = Map.of(
+ "test", "element1",
+ "structure", subStructureMap);
+
+ // when
+ YamlDocument document = new YamlDocumentFactory().createYamlDocument(inputMap);
+
+ // then
+ assertThat(document).isNotNull();
+ assertThat(document.getYaml()).containsKeys("test", "structure");
+ assertThat(document.getValue("test")).isEqualTo("element1");
+
+ assertThat(document.getSubStructure("structure")).isNotNull();
+ assertThat(document.getSubStructure("structure").getValue("subTest1")).isEqualTo("subElement1");
+ assertThat(document.getSubStructure("structure").getValue("subTest2")).isEqualTo("subElement2");
+ }
+
+ @Test
+ void shouldTurnMapOfUnknownKeyTypeToMapWithStringKeysAndBeAbleToExtractParametersList()
+ throws YamlDocumentParsingException {
+ // given
+ List<String> parametersList = List.of("parameter1", "parameter2");
+ Map<Object, Object> inputMap = Map.of(
+ "test", "element1",
+ "parameters", parametersList);
+
+ // when
+ YamlDocument document = new YamlDocumentFactory().createYamlDocument(inputMap);
+
+ // then
+ assertThat(document).isNotNull();
+ assertThat(document.getYaml()).containsKeys("test", "parameters");
+ assertThat(document.getValue("test")).isEqualTo("element1");
+
+ assertThat(document.getListOfValues("parameters")).isNotNull();
+ assertThat(document.getListOfValues("parameters").getParameters()).contains("parameter1", "parameter2");
+ }
+
+ @Test
+ void shouldThrowExceptionIfGetSubStructureIsCalledOnList()
+ throws YamlDocumentParsingException {
+ // given
+ List<String> testList = List.of("element1", "element2");
+ Map<Object, Object> inputMap = Collections.singletonMap("test", testList);
+
+ YamlDocument document = new YamlDocumentFactory().createYamlDocument(inputMap);
+
+ // when then
+ assertThatThrownBy(() -> document.getSubStructure("test"))
+ .isInstanceOf(YamlDocumentParsingException.class)
+ .hasMessageContaining(String.format("Fail to parse given objects: %s as yaml document", testList));
+ }
+
+ @Test
+ void shouldThrowExceptionIfGetSubStructureIsCalledOnString()
+ throws YamlDocumentParsingException {
+ // given
+ Map<Object, Object> inputMap = Collections.singletonMap("test", "testElement");
+
+ YamlDocument document = new YamlDocumentFactory().createYamlDocument(inputMap);
+
+ // when then
+ assertThatThrownBy(() -> document.getSubStructure("test"))
+ .isInstanceOf(YamlDocumentParsingException.class)
+ .hasMessageContaining(String.format("Fail to parse given objects: %s as yaml document.", "testElement"));
+ }
+}
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/model/YamlParameterListFactoryTest.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/model/YamlParameterListFactoryTest.java
new file mode 100644
index 0000000..ed15532
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/model/YamlParameterListFactoryTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml.model;
+
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class YamlParameterListFactoryTest {
+
+ @Test
+ void shouldCreateEmptyParametersList() {
+ // when
+ YamlParametersList parametersList = new YamlParameterListFactory().createEmptyYamlParameterList();
+
+ // then
+ assertThat(parametersList).isNotNull();
+ assertThat(parametersList.getParameters()).isEmpty();
+ }
+
+ @Test
+ void shouldCreateParametersListContainingStringsFromListContainingSimpleTypes() {
+ // given
+ List<Object> elements = List.of("test1", 3, 23.45, 'a', "test2");
+
+ // when
+ YamlParametersList parametersList = new YamlParameterListFactory().createYamlParameterList( elements);
+
+ // then
+ assertThat(parametersList).isNotNull();
+ assertThat(parametersList.getParameters())
+ .hasSize(5)
+ .contains("test1", "test2", "3", "23.45", "a");
+ }
+
+ @Test
+ void shouldCreateParametersListContainingStringsFromListContainingVariousTypes() {
+ // given
+ List<Object> testList = List.of("test1", 3, Lists.list(2, 3, 4), "test2");
+
+ // when
+ YamlParametersList parametersList = new YamlParameterListFactory().createYamlParameterList(testList);
+
+ // then
+ assertThat(parametersList).isNotNull();
+ assertThat(parametersList.getParameters())
+ .hasSize(4)
+ .contains("test1", "test2", "3", "[2, 3, 4]");
+ }
+
+ @Test
+ void shouldCreateListWithOneStringWhenGivenObjectIsNotList() {
+ // given
+ Object testObject = "test";
+
+ // when
+ YamlParametersList parametersList = new YamlParameterListFactory().createYamlParameterList(testObject);
+
+ // then
+ assertThat(parametersList).isNotNull();
+ assertThat(parametersList.getParameters())
+ .hasSize(1)
+ .contains("test");
+ }
+}
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/process/YamlValidationProcessTest.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/process/YamlValidationProcessTest.java
new file mode 100644
index 0000000..4c602e0
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/process/YamlValidationProcessTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml.process;
+
+import org.junit.jupiter.api.Test;
+import org.onap.validation.yaml.YamlLoadingUtils;
+import org.onap.validation.yaml.error.SchemaValidationError;
+import org.onap.validation.yaml.exception.YamlProcessingException;
+import org.onap.validation.yaml.model.YamlDocument;
+import org.onap.validation.yaml.schema.YamlSchema;
+import org.onap.validation.yaml.schema.YamlSchemaFactory;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.onap.validation.yaml.YamlLoadingUtils.VALID_YAML_DOCUMENT_INDEX;
+import static org.onap.validation.yaml.YamlLoadingUtils.YAML_DOCUMENT_WITH_MISSING_FIELD_AND_WRONG_VALUE_INDEX;
+import static org.onap.validation.yaml.YamlLoadingUtils.YAML_DOCUMENT_WITH_MISSING_FIELD_INDEX;
+
+class YamlValidationProcessTest {
+
+ @Test
+ void shouldReturnNoErrorWhenProcessingValidPmDictionaryYaml()
+ throws YamlProcessingException {
+ // given
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidMultiDocumentYamlFile();
+ YamlSchema schema = new YamlSchemaFactory().createTreeStructuredYamlSchema(documents.get(0));
+ YamlDocument document = documents.get(VALID_YAML_DOCUMENT_INDEX);
+
+ // when
+ List<SchemaValidationError> errors = new YamlValidationProcess(schema, document).validate();
+
+ // then
+ assertThat(errors).isEmpty();
+ }
+
+ @Test
+ void shouldReturnOneErrorWhenProcessingPmDictionaryYamlWithMissingField()
+ throws YamlProcessingException {
+ // given
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidMultiDocumentYamlFile();
+ YamlSchema schema = new YamlSchemaFactory().createTreeStructuredYamlSchema(documents.get(0));
+ YamlDocument document = documents.get(YAML_DOCUMENT_WITH_MISSING_FIELD_INDEX);
+
+ // when
+ List<SchemaValidationError> errors = new YamlValidationProcess(schema, document).validate();
+
+ // then
+ assertThat(errors).hasSize(1);
+ }
+
+ @Test
+ void shouldReturnTwoErrorsWhenProcessingPmDictionaryYamlWithMissingFieldAndIncorrectValue()
+ throws YamlProcessingException {
+ // given
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidMultiDocumentYamlFile();
+ YamlSchema schema = new YamlSchemaFactory().createTreeStructuredYamlSchema(documents.get(0));
+ YamlDocument document = documents.get(YAML_DOCUMENT_WITH_MISSING_FIELD_AND_WRONG_VALUE_INDEX);
+
+ // when
+ List<SchemaValidationError> errors = new YamlValidationProcess(schema, document).validate();
+
+ // then
+ assertThat(errors).hasSize(2);
+ }
+
+ @Test
+ void shouldThrowExceptionWhenProcessingPmDictionaryIsNotValidYaml()
+ throws YamlProcessingException {
+ // given
+ List<YamlDocument> documents = YamlLoadingUtils.loadValidMultiDocumentYamlFile();
+ YamlDocument schemaInYaml = YamlLoadingUtils.loadSimpleInvalidYamlSchemaForLazyLoadingFile();
+ YamlSchema schema = new YamlSchemaFactory().createTreeStructuredYamlSchema(schemaInYaml);
+ YamlDocument document = documents.get(VALID_YAML_DOCUMENT_INDEX);
+
+ // when then
+ assertThatThrownBy(() -> new YamlValidationProcess(schema, document).validate())
+ .isInstanceOf(YamlProcessingException.class)
+ .hasMessageContaining(String.format("Lazy loading failed, due to yaml parsing exception."));
+ }
+}
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/schema/YamlSchemaFactoryTest.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/schema/YamlSchemaFactoryTest.java
new file mode 100644
index 0000000..5768851
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/schema/YamlSchemaFactoryTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml.schema;
+
+import org.junit.jupiter.api.Test;
+import org.onap.validation.yaml.YamlLoadingUtils;
+import org.onap.validation.yaml.exception.YamlProcessingException;
+import org.onap.validation.yaml.model.YamlDocument;
+import org.onap.validation.yaml.schema.node.YamlSchemaNode;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.onap.validation.yaml.model.YamlDocumentFactory.YamlDocumentParsingException;
+import static org.onap.validation.yaml.schema.node.YamlSchemaNodeFactory.EMPTY_COMMENT;
+import static org.onap.validation.yaml.schema.node.YamlSchemaNodeFactoryTest.assertThatBranchNodeIsValid;
+import static org.onap.validation.yaml.schema.node.YamlSchemaNodeFactoryTest.assertThatLeafNodeIsValid;
+
+
+class YamlSchemaFactoryTest {
+
+ @Test
+ void shouldCreateYamlSchemaFromYamlDocumentWithMultipleRoots()
+ throws YamlProcessingException {
+
+ // given
+ YamlDocument documents = YamlLoadingUtils.loadSimpleValidYamlSchemaWithMultiRootFile();
+
+ // when
+ YamlSchema schema = new YamlSchemaFactory().createTreeStructuredYamlSchema(documents);
+
+ // then
+ assertThat(schema).isNotNull();
+ assertThat(schema.getRootNodes()).hasSize(3);
+ assertThat(schema.getRootNodes().get(0).getName()).isEqualTo("root1");
+ assertThat(schema.getRootNodes().get(1).getName()).isEqualTo("root2");
+ assertThat(schema.getRootNodes().get(2).getName()).isEqualTo("root3");
+ }
+
+
+ @Test
+ void shouldCreateYamlSchemaFromYamlDocument()
+ throws YamlProcessingException {
+
+ // given
+ YamlDocument documents = YamlLoadingUtils.loadSimpleValidYamlSchemaFile();
+
+ // when
+ YamlSchema schema = new YamlSchemaFactory().createTreeStructuredYamlSchema(documents);
+
+ // then
+ assertThat(schema).isNotNull();
+ assertThat(schema.getRootNodes()).hasSize(1);
+ YamlSchemaNode pmMetaData = schema.getRootNodes().get(0);
+ assertThatBranchNodeIsValid(pmMetaData, "pmMetaData", "/", true, EMPTY_COMMENT,
+ 2);
+
+ YamlSchemaNode pmHeader = pmMetaData.getNextNodes().get(1);
+ assertThatBranchNodeIsValid(pmHeader, "pmHeader", "/pmMetaData/", true, EMPTY_COMMENT,
+ 1);
+
+ YamlSchemaNode nfType = pmHeader.getNextNodes().get(0);
+ assertThatLeafNodeIsValid(nfType, "nfType", "/pmMetaData/pmHeader/", true, "nfType comment");
+
+ YamlSchemaNode pmFields = pmMetaData.getNextNodes().get(0);
+ assertThatBranchNodeIsValid(pmFields, "pmFields", "/pmMetaData/", true, EMPTY_COMMENT,
+ 2);
+
+ YamlSchemaNode measChangeType = pmFields.getNextNodes().get(1);
+ assertThatLeafNodeIsValid(measChangeType, "measChangeType", "/pmMetaData/pmFields/",
+ true, "measChangeType comment",
+ "added", "modified", "deleted");
+
+ YamlSchemaNode measAdditionalFields = pmFields.getNextNodes().get(0);
+ assertThatBranchNodeIsValid(measAdditionalFields, "measAdditionalFields", "/pmMetaData/pmFields/",
+ true, "measAdditionalFields comment",
+ 2);
+
+ YamlSchemaNode vendorField1 = measAdditionalFields.getNextNodes().get(0);
+ assertThatLeafNodeIsValid(vendorField1, "vendorField1", "/pmMetaData/pmFields/measAdditionalFields/",
+ true, "vendorField1 comment",
+ "X", "Y", "Z");
+ YamlSchemaNode vendorField2 = measAdditionalFields.getNextNodes().get(1);
+ assertThatLeafNodeIsValid(vendorField2, "vendorField2", "/pmMetaData/pmFields/measAdditionalFields/",
+ false, "vendorField2 comment",
+ "A", "B");
+ }
+
+ @Test
+ void shouldThrowYamlParsingExceptionWhenLoadedSchemaIsInvalid()
+ throws YamlDocumentParsingException {
+
+ // given
+ YamlDocument documents = YamlLoadingUtils.loadSimpleInvalidYamlSchemaFile();
+
+ // when/then
+ assertThatThrownBy(() -> new YamlSchemaFactory().createTreeStructuredYamlSchema(documents))
+ .isInstanceOf(YamlDocumentParsingException.class)
+ .hasMessageContaining(String.format(
+ "Fail to parse given objects: %s as yaml document",
+ documents.getSubStructure("pmMetaData").getYaml().get("structure"))
+ );
+ }
+}
diff --git a/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/schema/node/YamlSchemaNodeFactoryTest.java b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/schema/node/YamlSchemaNodeFactoryTest.java
new file mode 100644
index 0000000..ed43a1d
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/java/org/onap/validation/yaml/schema/node/YamlSchemaNodeFactoryTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2020 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onap.validation.yaml.schema.node;
+
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.Test;
+import org.onap.validation.yaml.YamlLoadingUtils;
+import org.onap.validation.yaml.exception.YamlProcessingException;
+import org.onap.validation.yaml.model.YamlDocument;
+import org.onap.validation.yaml.model.YamlDocumentFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.onap.validation.yaml.schema.node.YamlSchemaNodeFactory.EMPTY_COMMENT;
+
+public class YamlSchemaNodeFactoryTest {
+
+ private static final String ROOT_PATH = "/";
+
+ @Test
+ void shouldThrowExceptionDuringLazyLoadingWhenLoadedSchemaHaveInvalidSubStructure()
+ throws YamlProcessingException {
+ // given
+ String nodeName = "pmMetaData";
+
+ YamlDocument document = YamlLoadingUtils.loadSimpleInvalidYamlSchemaForLazyLoadingFile();
+ YamlSchemaNode node = new YamlSchemaNodeFactory()
+ .createNode(nodeName, ROOT_PATH, document.getSubStructure(nodeName));
+
+ // when/then
+ assertThatThrownBy(node::getNextNodes)
+ .isInstanceOf(YamlSchemaNode.YamlSchemaProcessingException.class)
+ .hasMessageContaining("Lazy loading failed, due to yaml parsing exception.");
+ }
+
+ @Test
+ void shouldCreateLeafNodeIfGivenYamlDocumentHaveNoSubStructure()
+ throws YamlProcessingException {
+ // given
+ String nodeName = "leaf_test";
+ String comment = "test leaf node";
+ List<String> acceptedValues = Lists.list("val1", "val2");
+ Map<Object, Object> nodeInYamlFormat = new HashMap<>();
+ nodeInYamlFormat.put(YamlSchemaNodeFactory.PRESENCE_KEY, YamlSchemaNodeFactory.PRESENCE_REQUIRED_KEY);
+ nodeInYamlFormat.put(YamlSchemaNodeFactory.COMMENT_KEY, comment);
+ nodeInYamlFormat.put(YamlSchemaNodeFactory.VALUE_KET, acceptedValues);
+ YamlDocument document = new YamlDocumentFactory().createYamlDocument(nodeInYamlFormat);
+
+ // when
+ YamlSchemaNode yamlSchemaNode = new YamlSchemaNodeFactory().createNode(nodeName, ROOT_PATH, document);
+
+ // then
+ assertThatLeafNodeIsValid(
+ yamlSchemaNode, nodeName, ROOT_PATH, true, comment,
+ acceptedValues.toArray(new String[acceptedValues.size()])
+ );
+ }
+
+ @Test
+ void shouldCreateBranchNodeIfGivenYamlDocumentHaveSubStructure()
+ throws YamlProcessingException {
+ // given
+ String nodeName = "branch_test";
+ String comment = "test branch node";
+
+ Map<Object, Object> subStructure = new HashMap<>();
+ String subNode1Name = "branch_test_node1";
+ String subNode2Name = "branch_test_node2";
+ subStructure.put(subNode1Name, new HashMap<>());
+ subStructure.put(subNode2Name, new HashMap<>());
+
+ Map<Object, Object> nodeInYamlFormat = new HashMap<>();
+ nodeInYamlFormat.put(YamlSchemaNodeFactory.PRESENCE_KEY, YamlSchemaNodeFactory.PRESENCE_REQUIRED_KEY);
+ nodeInYamlFormat.put(YamlSchemaNodeFactory.COMMENT_KEY, comment);
+ nodeInYamlFormat.put(YamlSchemaNodeFactory.STRUCTURE_KEY, subStructure);
+ YamlDocument document = new YamlDocumentFactory().createYamlDocument(nodeInYamlFormat);
+
+ // when
+ YamlSchemaNode yamlSchemaNode = new YamlSchemaNodeFactory().createNode(nodeName, ROOT_PATH, document);
+
+ // then
+ assertThatBranchNodeIsValid(yamlSchemaNode, nodeName, ROOT_PATH, true, comment, 2);
+
+ List<YamlSchemaNode> subNodes = yamlSchemaNode.getNextNodes();
+ assertThat(subNodes).hasSize(2);
+ assertThatLeafNodeIsValid(
+ subNodes.get(1), subNode1Name, ROOT_PATH + nodeName + "/", false, EMPTY_COMMENT);
+ assertThatLeafNodeIsValid(
+ subNodes.get(0), subNode2Name, ROOT_PATH + nodeName + "/", false, EMPTY_COMMENT);
+ }
+
+ public static void assertThatBranchNodeIsValid(
+ YamlSchemaNode yamlSchemaNode, String name, String path, boolean isRequired, String comment,
+ int numberOfSubNodes
+ ) throws YamlSchemaNode.YamlSchemaProcessingException {
+ assertThatNodeIsValid(yamlSchemaNode, name, path, isRequired, comment);
+
+ assertThat(yamlSchemaNode.getClass()).isEqualTo(YamlSchemaBranchNode.class);
+ assertThat(yamlSchemaNode.isContainingSubStructure()).isTrue();
+ assertThat(yamlSchemaNode.getNextNodes()).hasSize(numberOfSubNodes);
+ assertThat(yamlSchemaNode.getAcceptedValues()).isEmpty();
+ }
+
+ public static void assertThatLeafNodeIsValid(
+ YamlSchemaNode yamlSchemaNode, String name, String path, boolean isRequired, String comment,
+ String... acceptedValues
+ ) throws YamlSchemaNode.YamlSchemaProcessingException {
+ assertThatNodeIsValid(yamlSchemaNode, name, path, isRequired, comment);
+
+ assertThat(yamlSchemaNode.getClass()).isEqualTo(YamlSchemaLeafNode.class);
+ assertThat(yamlSchemaNode.isContainingSubStructure()).isFalse();
+ assertThat(yamlSchemaNode.getAcceptedValues()).containsExactly(acceptedValues);
+ assertThat(yamlSchemaNode.getNextNodes()).isEmpty();
+ }
+
+ private static void assertThatNodeIsValid(YamlSchemaNode yamlSchemaNode, String name, String path, boolean isRequired, String comment) {
+ assertThat(yamlSchemaNode).isNotNull();
+ assertThat(yamlSchemaNode.getName()).isEqualTo(name);
+ assertThat(yamlSchemaNode.getPath()).isEqualTo(path);
+ if (comment.isEmpty()) {
+ assertThat(yamlSchemaNode.getComment()).isNotEmpty();
+ } else {
+ assertThat(yamlSchemaNode.getComment()).isEqualTo(comment);
+ }
+ assertThat(yamlSchemaNode.isRequired()).isEqualTo(isRequired);
+ }
+}
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/Multi_Document_Invalid.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/Multi_Document_Invalid.yaml
new file mode 100644
index 0000000..aab34fa
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/Multi_Document_Invalid.yaml
@@ -0,0 +1,86 @@
+...
+# PM Dictionary perf3gpp measurements for the gnb-Nokia NF (bracket style yaml)
+---
+pmMetaData: {
+ pmHeader: {
+ nfType: gnb-Nokia,
+ pmDefSchemaVsn: 2.0,
+ pmDefVsn: 5G19_1906_002
+ },
+ pmFields: {
+ iMeasInfoId: 2204,
+ iMeasType: 1,
+
+ measCollectionMethod: CC,
+ measCondition: "This measurement is updated when X2AP: SgNB Modification Required message is sent to MeNB
+ with the SCG Change Indication set as PSCellChange.",
+ measDescription: "This counter indicates the number of intra gNB intra frequency PSCell change attempts.",
+ measFamily: NINFC,
+ measInfoId: "NR Intra Frequency PSCell Change",
+ measLastChange: 5G18A_1807_003,
+ measObjClass: NGCELL,
+ measResultRange: 0-4096,
+ measResultType: integer,
+ measResultUnits: number,
+ measType: VS.NINFC.IntraFrPscelChAttempt,
+ measAdditionalFields: {
+ vendorField1: X,
+ vendorField2: B
+ }
+ }
+}
+---
+pmMetaData: {
+ pmHeader: {
+ nfType: gnb-Nokia,
+ pmDefSchemaVsn: 2.0,
+ pmDefVsn: 5G19_1906_002
+ },
+ pmFields: {
+ iMeasInfoId: 2204,
+ iMeasType: 2,
+ measCollectionMethod: CC,
+ measCondition: "This measurement is updated when the TDCoverall timer has elapsed before gNB receives the X2AP: SgNB Modification Confirm message.",
+ measDescription: "This measurement the number of intra gNB intra frequency PSCell change failures due to TDCoverall timer expiry.",
+ measFamily: NINFC,
+ measInfoId: "NR Intra Frequency PSCell Change",
+ measLastChange: 5G18A_1807_003,
+ measObjClass: NGCELL,
+ measResultRange: 0-4096,
+ measResultType: float,
+ measResultUnits: number,
+ measType: VS.NINFC.IntraFrPscelChFailTdcExp,
+ measAdditionalFields: {
+ vendorField1: Y
+ }
+ }
+}
+...
+---
+pmMetaData: {
+ pmHeader: {
+ nfType: gnb-Nokia,
+ pmDefSchemaVsn: 2.0,
+ pmDefVsn: 5G19_1906_002
+ },
+ pmFields: {
+ iMeasInfoId: 2206,
+ iMeasType: 1,
+ measCondition: "This measurement is updated when MeNB replies to X2AP: SgNB Modification Required message with the X2AP: SgNB Modification Refuse message.",
+ measCollectionMethod: CC,
+ measDescription: "This counter indicates the number of intra gNB intra frequency PSCell change failures due to MeNB refusal.",
+ measFamily: NINFC,
+ measInfoId: "NR Intra Frequency PSCell Change",
+ measLastChange: 5G19_1906_002,
+ measObjClass: NGCELL,
+ measResultRange: 0-4096,
+ measResultType: float,
+ measChangeType: added,
+ measResultUnits: number,
+ measType: VS.NINFC.IntraFrPscelChFailMenbRef,
+ measAdditionalFields: {
+ vendorField1: Z,
+ vendorField2: A
+ }
+ }
+...
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/PM_Dictionary.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/PM_Dictionary.yaml
new file mode 100644
index 0000000..12a4af9
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/PM_Dictionary.yaml
@@ -0,0 +1,228 @@
+---
+# PM Dictionary schema specifying and describing the meta information
+# used to define perf3gpp measurements in the PM Dictionary
+pmMetaData: { presence: required, structure: {
+ pmHeader: {
+ presence: required,
+ structure: {
+ nfType: {
+ presence: required,
+ comment: "NF type; should match the nfName-vendor string used in
+ the fileReady or perf3gpp eventName"
+ },
+ pmDefSchemaVsn: {
+ presence: required,
+ value: 2.0,
+ comment: "PM Dictionary Schema Version from the VES Event
+ Registration specification"
+ },
+ pmDefVsn: {
+ presence: required,
+ comment: "vendor-defined PM Dictionary version"
+ }
+ }
+ },
+ pmFields: {
+ presence: required,
+ structure: {
+ iMeasInfoId: {
+ presence: required,
+ comment: "vendor-defined integer measurement group identifier"
+ },
+ iMeasType: {
+ presence: required,
+ comment: "vendor-defined integer identifier for the measType;
+ must be combined with measInfoId to identify a
+ specific measurement."
+ },
+ measChangeType: {
+ presence: required,
+ value: [added, modified, deleted],
+ comment: "indicates the type of change that occurred during
+ measLastChange"
+ },
+ measCollectionMethod: {
+ presence: required,
+ value: [CC, SI, DER, Gauge, Average],
+ comment: "the measurement collection method; CC, SI, DER and
+ Gauge are as defined in 3GPP; average contains the
+ average value of the measurement during the
+ granularity period"
+ },
+ measCondition: {
+ presence: required,
+ comment: "description of the condition causing the measurement"
+ },
+ measDescription: {
+ presence: required,
+ comment: "description of the measurement information
+ and purpose"
+ },
+ measFamily: {
+ presence: required,
+ comment: "abbreviation for a family of measurements, in
+ 3GPP format, or vendor defined"
+ },
+ measInfoId: {
+ presence: required,
+ comment: "name for a group of related measurements in
+ 3GPP format or vendor defined"
+ },
+ measLastChange: {
+ presence: required,
+ comment: "version of the PM Dictionary the last time this
+ measurement was added, modified or deleted"
+ },
+ measObjClass: {
+ presence: required,
+ value: [NGBTS, NGCELL, IPNO, IPSEC, ETHIF],
+ comment: "measurement object class"
+ },
+ measResultRange: {
+ presence: optional,
+ comment: "range of the measurement result; only necessary when
+ the range is smaller than the full range of the
+ data type"
+ },
+ measResultType: {
+ presence: required,
+ value: [float, uint32, uint64],
+ comment: "data type of the measurement result"
+ },
+ measResultUnits: {
+ presence: required,
+ value: [seconds, minutes, nanoseconds, microseconds, dB,
+ number, kilobytes, bytes, ethernetFrames,
+ packets, users],
+ comment: "units of measure for the measurement result"
+ },
+ measType: {
+ presence: required,
+ comment: "measurement name in 3GPP or vendor-specific format;
+ vendor specific names are preceded with VS"
+ },
+ measAdditionalFields: {
+ presence: required,
+ comment: "vendor-specific PM Dictionary fields",
+ structure: {
+ vendorField1: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "vendor field 1 description"
+ },
+ vendorField2: {
+ presence: optional,
+ value: [A, B],
+ comment: "vendor field 2 description."
+ }
+ }
+ }
+ }
+ }
+}}
+...
+# PM Dictionary perf3gpp measurements for the gnb-Nokia NF (bracket style yaml)
+---
+pmMetaData:
+ pmHeader:
+ nfType: gnb-Nokia
+ pmDefSchemaVsn: 2.0
+ pmDefVsn: 5G19_1906_002
+ pmFields:
+ iMeasInfoId: 2204
+ iMeasType: 1
+ measCollectionMethod: CC
+ measCondition: "This measurement is updated when X2AP: SgNB Modification Required message is sent to MeNB
+ with the SCG Change Indication set as PSCellChange."
+ measDescription: "This counter indicates the number of intra gNB intra frequency PSCell change attempts."
+ measFamily: NINFC
+ measInfoId: "NR Intra Frequency PSCell Change"
+ measLastChange: 5G18A_1807_003
+ measObjClass: NGCELL
+ measResultRange: 0-4096
+ measResultType: integer
+ measResultUnits: number
+ measType: VS.NINFC.IntraFrPscelChAttempt
+ measAdditionalFields:
+ vendorField1: X
+ vendorField2: B
+...
+---
+pmMetaData:
+ pmHeader:
+ nfType: gnb-Nokia
+ pmDefSchemaVsn: 2.0
+ pmDefVsn: 5G19_1906_002
+ pmFields:
+ iMeasInfoId: 2204
+ iMeasType: 2
+ measCollectionMethod: CC
+ measCondition: "This measurement is updated when the TDCoverall timer has elapsed before gNB receives the X2AP: SgNB Modification Confirm message."
+ measDescription: "This measurement the number of intra gNB intra frequency PSCell change failures due to TDCoverall timer expiry."
+ measFamily: NINFC
+ measInfoId: "NR Intra Frequency PSCell Change"
+ measLastChange: 5G18A_1807_003
+ measObjClass: NGCELL
+ measResultRange: 0-4096
+ measResultType: float
+ measResultUnits: number
+ measType: VS.NINFC.IntraFrPscelChFailTdcExp
+ measAdditionalFields:
+ vendorField1:
+ - Y
+ - X
+...
+---
+pmMetaData:
+ pmHeader:
+ nfType: gnb-Nokia
+ pmDefSchemaVsn: 2.0
+ pmDefVsn: 5G19_1906_002
+ pmFields:
+ iMeasInfoId: 2206
+ iMeasType: 1
+ measCondition: "This measurement is updated when MeNB replies to X2AP: SgNB Modification Required message with the X2AP: SgNB Modification Refuse message."
+ measCollectionMethod: CC
+ measDescription: "This counter indicates the number of intra gNB intra frequency PSCell change failures due to MeNB refusal."
+ measFamily: NINFC
+ measInfoId: "NR Intra Frequency PSCell Change"
+ measLastChange: 5G19_1906_002
+ measObjClass: NGCELL
+ measResultRange: 0-4096
+ measResultType: float
+ measChangeType: added
+ measResultUnits: number
+ measType: VS.NINFC.IntraFrPscelChFailMenbRef
+ measAdditionalFields:
+ vendorField1:
+ - Z
+ - A
+ vendorField2: A
+...
+---
+pmMetaData:
+ pmHeader:
+ nfType: gnb-Nokia
+ pmDefSchemaVsn: 2.0
+ pmDefVsn: 5G19_1906_002
+ pmFields:
+ iMeasInfoId: 2206
+ iMeasType: 1
+ measCondition: "This measurement is updated when MeNB replies to X2AP: SgNB Modification Required message with the X2AP: SgNB Modification Refuse message."
+ measCollectionMethod: CC
+ measDescription: "This counter indicates the number of intra gNB intra frequency PSCell change failures due to MeNB refusal."
+ measFamily: NINFC
+ measInfoId: "NR Intra Frequency PSCell Change"
+ measLastChange: 5G19_1906_002
+ measObjClass: NGCELL
+ measResultRange: 0-4096
+ measResultType: float
+ measChangeType: added
+ measResultUnits: number
+ measType: VS.NINFC.IntraFrPscelChFailMenbRef
+ measAdditionalFields:
+ vendorField1:
+ - X
+ - Y
+ vendorField2: A
+...
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/PM_Dictionary_JSON_Style.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/PM_Dictionary_JSON_Style.yaml
new file mode 100644
index 0000000..f4cbddf
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/PM_Dictionary_JSON_Style.yaml
@@ -0,0 +1,239 @@
+---
+# PM Dictionary schema specifying and describing the meta information
+# used to define perf3gpp measurements in the PM Dictionary
+pmMetaData: { presence: required, structure: {
+ pmHeader: {
+ presence: required,
+ structure: {
+ nfType: {
+ presence: required,
+ comment: "NF type; should match the nfName-vendor string used in
+ the fileReady or perf3gpp eventName"
+ },
+ pmDefSchemaVsn: {
+ presence: required,
+ value: 2.0,
+ comment: "PM Dictionary Schema Version from the VES Event
+ Registration specification"
+ },
+ pmDefVsn: {
+ presence: required,
+ comment: "vendor-defined PM Dictionary version"
+ }
+ }
+ },
+ pmFields: {
+ presence: required,
+ structure: {
+ iMeasInfoId: {
+ presence: required,
+ comment: "vendor-defined integer measurement group identifier"
+ },
+ iMeasType: {
+ presence: required,
+ comment: "vendor-defined integer identifier for the measType;
+ must be combined with measInfoId to identify a
+ specific measurement."
+ },
+ measChangeType: {
+ presence: required,
+ value: [added, modified, deleted],
+ comment: "indicates the type of change that occurred during
+ measLastChange"
+ },
+ measCollectionMethod: {
+ presence: required,
+ value: [CC, SI, DER, Gauge, Average],
+ comment: "the measurement collection method; CC, SI, DER and
+ Gauge are as defined in 3GPP; average contains the
+ average value of the measurement during the
+ granularity period"
+ },
+ measCondition: {
+ presence: required,
+ comment: "description of the condition causing the measurement"
+ },
+ measDescription: {
+ presence: required,
+ comment: "description of the measurement information
+ and purpose"
+ },
+ measFamily: {
+ presence: required,
+ comment: "abbreviation for a family of measurements, in
+ 3GPP format, or vendor defined"
+ },
+ measInfoId: {
+ presence: required,
+ comment: "name for a group of related measurements in
+ 3GPP format or vendor defined"
+ },
+ measLastChange: {
+ presence: required,
+ comment: "version of the PM Dictionary the last time this
+ measurement was added, modified or deleted"
+ },
+ measObjClass: {
+ presence: required,
+ value: [NGBTS, NGCELL, IPNO, IPSEC, ETHIF],
+ comment: "measurement object class"
+ },
+ measResultRange: {
+ presence: optional,
+ comment: "range of the measurement result; only necessary when
+ the range is smaller than the full range of the
+ data type"
+ },
+ measResultType: {
+ presence: required,
+ value: [float, uint32, uint64],
+ comment: "data type of the measurement result"
+ },
+ measResultUnits: {
+ presence: required,
+ value: [seconds, minutes, nanoseconds, microseconds, dB,
+ number, kilobytes, bytes, ethernetFrames,
+ packets, users],
+ comment: "units of measure for the measurement result"
+ },
+ measType: {
+ presence: required,
+ comment: "measurement name in 3GPP or vendor-specific format;
+ vendor specific names are preceded with VS"
+ },
+ measAdditionalFields: {
+ presence: required,
+ comment: "vendor-specific PM Dictionary fields",
+ structure: {
+ vendorField1: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "vendor field 1 description"
+ },
+ vendorField2: {
+ presence: optional,
+ value: [A, B],
+ comment: "vendor field 2 description."
+ }
+ }
+ }
+ }
+ }
+}}
+...
+# PM Dictionary perf3gpp measurements for the gnb-Nokia NF (bracket style yaml)
+---
+pmMetaData: {
+ pmHeader: {
+ nfType: gnb-Nokia,
+ pmDefSchemaVsn: 2.0,
+ pmDefVsn: 5G19_1906_002
+ },
+ pmFields: {
+ iMeasInfoId: 2204,
+ iMeasType: 1,
+
+ measCollectionMethod: CC,
+ measCondition: "This measurement is updated when X2AP: SgNB Modification Required message is sent to MeNB
+ with the SCG Change Indication set as PSCellChange.",
+ measDescription: "This counter indicates the number of intra gNB intra frequency PSCell change attempts.",
+ measFamily: NINFC,
+ measInfoId: "NR Intra Frequency PSCell Change",
+ measLastChange: 5G18A_1807_003,
+ measObjClass: NGCELL,
+ measResultRange: 0-4096,
+ measResultType: integer,
+ measResultUnits: number,
+ measType: VS.NINFC.IntraFrPscelChAttempt,
+ measAdditionalFields: {
+ vendorField1: X,
+ vendorField2: B
+ }
+ }
+}
+...
+---
+pmMetaData: {
+ pmHeader: {
+ nfType: gnb-Nokia,
+ pmDefSchemaVsn: 2.0,
+ pmDefVsn: 5G19_1906_002
+ },
+ pmFields: {
+ iMeasInfoId: 2204,
+ iMeasType: 2,
+ measCollectionMethod: CC,
+ measCondition: "This measurement is updated when the TDCoverall timer has elapsed before gNB receives the X2AP: SgNB Modification Confirm message.",
+ measDescription: "This measurement the number of intra gNB intra frequency PSCell change failures due to TDCoverall timer expiry.",
+ measFamily: NINFC,
+ measInfoId: "NR Intra Frequency PSCell Change",
+ measLastChange: 5G18A_1807_003,
+ measObjClass: NGCELL,
+ measResultRange: 0-4096,
+ measResultType: float,
+ measResultUnits: number,
+ measType: VS.NINFC.IntraFrPscelChFailTdcExp,
+ measAdditionalFields: {
+ vendorField1: [Y,Z]
+ }
+ }
+}
+...
+---
+pmMetaData: {
+ pmHeader: {
+ nfType: gnb-Nokia,
+ pmDefSchemaVsn: 2.0,
+ pmDefVsn: 5G19_1906_002
+ },
+ pmFields: {
+ iMeasInfoId: 2206,
+ iMeasType: 1,
+ measCondition: "This measurement is updated when MeNB replies to X2AP: SgNB Modification Required message with the X2AP: SgNB Modification Refuse message.",
+ measCollectionMethod: CC,
+ measDescription: "This counter indicates the number of intra gNB intra frequency PSCell change failures due to MeNB refusal.",
+ measFamily: NINFC,
+ measInfoId: "NR Intra Frequency PSCell Change",
+ measLastChange: 5G19_1906_002,
+ measObjClass: NGCELL,
+ measResultRange: 0-4096,
+ measResultType: float,
+ measChangeType: added,
+ measResultUnits: number,
+ measType: VS.NINFC.IntraFrPscelChFailMenbRef,
+ measAdditionalFields: {
+ vendorField1: [Z,A],
+ vendorField2: A
+ }
+ }
+}
+...
+---
+pmMetaData: {
+ pmHeader: {
+ nfType: gnb-Nokia,
+ pmDefSchemaVsn: 2.0,
+ pmDefVsn: 5G19_1906_002
+ },
+ pmFields: {
+ iMeasInfoId: 2206,
+ iMeasType: 1,
+ measCondition: "This measurement is updated when MeNB replies to X2AP: SgNB Modification Required message with the X2AP: SgNB Modification Refuse message.",
+ measCollectionMethod: CC,
+ measDescription: "This counter indicates the number of intra gNB intra frequency PSCell change failures due to MeNB refusal.",
+ measFamily: NINFC,
+ measInfoId: "NR Intra Frequency PSCell Change",
+ measLastChange: 5G19_1906_002,
+ measObjClass: NGCELL,
+ measResultRange: 0-4096,
+ measResultType: float,
+ measChangeType: added,
+ measResultUnits: number,
+ measType: VS.NINFC.IntraFrPscelChFailMenbRef,
+ measAdditionalFields: {
+ vendorField1: [X,Y],
+ vendorField2: A
+ }
+ }
+}
+...
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Mapping_Value.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Mapping_Value.yaml
new file mode 100644
index 0000000..25c72cd
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Mapping_Value.yaml
@@ -0,0 +1,149 @@
+---
+# PM Dictionary schema specifying and describing the meta information
+# used to define perf3gpp measurements in the PM Dictionary
+pmMetaData: { presence: required, structure: {
+ pmHeader: {
+ presence: required,
+ structure: {
+ nfType: {
+ presence: required,
+ comment: "NF type; should match the nfName-vendor string used in
+ the fileReady or perf3gpp eventName"
+ },
+ pmDefSchemaVsn: {
+ presence: required,
+ value: 2.0,
+ comment: "PM Dictionary Schema Version from the VES Event
+ Registration specification"
+ },
+ pmDefVsn: {
+ presence: required,
+ comment: "vendor-defined PM Dictionary version"
+ }
+ }
+ },
+ pmFields: {
+ presence: required,
+ structure: {
+ iMeasInfoId: {
+ presence: required,
+ comment: "vendor-defined integer measurement group identifier"
+ },
+ iMeasType: {
+ presence: required,
+ comment: "vendor-defined integer identifier for the measType;
+ must be combined with measInfoId to identify a
+ specific measurement."
+ },
+ measChangeType: {
+ presence: required,
+ value: [added, modified, deleted],
+ comment: "indicates the type of change that occurred during
+ measLastChange"
+ },
+ measCollectionMethod: {
+ presence: required,
+ value: [CC, SI, DER, Gauge, Average],
+ comment: "the measurement collection method; CC, SI, DER and
+ Gauge are as defined in 3GPP; average contains the
+ average value of the measurement during the
+ granularity period"
+ },
+ measCondition: {
+ presence: required,
+ comment: "description of the condition causing the measurement"
+ },
+ measDescription: {
+ presence: required,
+ comment: "description of the measurement information
+ and purpose"
+ },
+ measFamily: {
+ presence: required,
+ comment: "abbreviation for a family of measurements, in
+ 3GPP format, or vendor defined"
+ },
+ measInfoId: {
+ presence: required,
+ comment: "name for a group of related measurements in
+ 3GPP format or vendor defined"
+ },
+ measLastChange: {
+ presence: required,
+ comment: "version of the PM Dictionary the last time this
+ measurement was added, modified or deleted"
+ },
+ measObjClass: {
+ presence: required,
+ value: [NGBTS, NGCELL, IPNO, IPSEC, ETHIF],
+ comment: "measurement object class"
+ },
+ measResultRange: {
+ presence: optional,
+ comment: "range of the measurement result; only necessary when
+ the range is smaller than the full range of the
+ data type"
+ },
+ measResultType: {
+ presence: required,
+ value: [float, uint32, uint64],
+ comment: "data type of the measurement result"
+ },
+ measResultUnits: {
+ presence: required,
+ value: [seconds, minutes, nanoseconds, microseconds, dB,
+ number, kilobytes, bytes, ethernetFrames,
+ packets, users],
+ comment: "units of measure for the measurement result"
+ },
+ measType: {
+ presence: required,
+ comment: "measurement name in 3GPP or vendor-specific format;
+ vendor specific names are preceded with VS"
+ },
+ measAdditionalFields: {
+ presence: required,
+ comment: "vendor-specific PM Dictionary fields",
+ structure: {
+ vendorField1: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "vendor field 1 description"
+ },
+ vendorField2: {
+ presence: optional,
+ value: [A, B],
+ comment: "vendor field 2 description."
+ }
+ }
+ }
+ }
+ }
+}}
+...
+# PM Dictionary perf3gpp measurements for the gnb-Nokia NF (bracket style yaml)
+---
+pmMetaData:
+ pmHeader:
+ nfType: gnb-Nokia
+ pmDefSchemaVsn: 2.0
+ pmDefVsn: 5G19_1906_002
+ pmFields:
+ iMeasInfoId: 2204
+ iMeasType: 1
+ measCollectionMethod: CC
+ measCondition: This measurement is updated when X2AP: SgNB Modification Required message is sent to MeNB
+ with the SCG Change Indication set as PSCellChange.
+ measDescription: This counter indicates the number of intra gNB intra frequency PSCell change attempts.
+ measFamily: NINFC
+ measInfoId: "NR Intra Frequency PSCell Change"
+ measLastChange: 5G18A_1807_003
+ measObjClass: NGCELL
+ measResultRange: 0-4096
+ measResultType: integer
+ measResultUnits: number
+ measType: VS.NINFC.IntraFrPscelChAttempt
+ measAdditionalFields:
+ vendorField1: X
+ vendorField2: B
+...
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Schema_Construction.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Schema_Construction.yaml
new file mode 100644
index 0000000..c5e7b7c
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Schema_Construction.yaml
@@ -0,0 +1,39 @@
+---
+pmMetaData: { presence: required, structure: [
+ -pmHeader: {
+ presence: required,
+ structure: {
+ nfType: {
+ presence: required,
+ comment: "nfType comment"
+ }
+ }
+ },
+ -pmFields: {
+ presence: required,
+ structure: {
+ measChangeType: {
+ presence: required,
+ value: [added, modified, deleted],
+ comment: "measChangeType comment"
+ },
+ measAdditionalFields: {
+ presence: required,
+ comment: "measAdditionalFields comment",
+ structure: {
+ vendorField1: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "vendorField1 comment"
+ },
+ vendorField2: {
+ presence: optional,
+ value: [A, B],
+ comment: "vendorField2 comment"
+ }
+ }
+ }
+ }
+ }
+]}
+...
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Schema_LazyLoading.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Schema_LazyLoading.yaml
new file mode 100644
index 0000000..7f9f946
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Invalid_Schema_LazyLoading.yaml
@@ -0,0 +1,39 @@
+---
+pmMetaData: { presence: required, structure: {
+ pmHeader: {
+ presence: required,
+ structure: {
+ nfType: {
+ presence: required,
+ comment: "nfType comment"
+ }
+ }
+ },
+ pmFields: {
+ presence: required,
+ structure: [
+ -measChangeType: {
+ presence: required,
+ value: [added, modified, deleted],
+ comment: "measChangeType comment"
+ },
+ -measAdditionalFields: {
+ presence: required,
+ comment: "measAdditionalFields comment",
+ structure: {
+ vendorField1: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "vendorField1 comment"
+ },
+ vendorField2: {
+ presence: optional,
+ value: [A, B],
+ comment: "vendorField2 comment"
+ }
+ }
+ }
+ ]
+ }
+}}
+...
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Unknown_Escape_Character.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Unknown_Escape_Character.yaml
new file mode 100644
index 0000000..2cac9e6
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Unknown_Escape_Character.yaml
@@ -0,0 +1,149 @@
+---
+# PM Dictionary schema specifying and describing the meta information
+# used to define perf3gpp measurements in the PM Dictionary
+pmMetaData: { presence: required, structure: {
+ pmHeader: {
+ presence: required,
+ structure: {
+ nfType: {
+ presence: required,
+ comment: "NF type; should match the nfName-vendor string used in
+ the fileReady or perf3gpp eventName"
+ },
+ pmDefSchemaVsn: {
+ presence: required,
+ value: 2.0,
+ comment: "PM Dictionary Schema Version from the VES Event
+ Registration specification"
+ },
+ pmDefVsn: {
+ presence: required,
+ comment: "vendor-defined PM Dictionary version"
+ }
+ }
+ },
+ pmFields: {
+ presence: required,
+ structure: {
+ iMeasInfoId: {
+ presence: required,
+ comment: "vendor-defined integer measurement group identifier"
+ },
+ iMeasType: {
+ presence: required,
+ comment: "vendor-defined integer identifier for the measType;
+ must be combined with measInfoId to identify a
+ specific measurement."
+ },
+ measChangeType: {
+ presence: required,
+ value: [added, modified, deleted],
+ comment: "indicates the type of change that occurred during
+ measLastChange"
+ },
+ measCollectionMethod: {
+ presence: required,
+ value: [CC, SI, DER, Gauge, Average],
+ comment: "the measurement collection method; CC, SI, DER and
+ Gauge are as defined in 3GPP; average contains the
+ average value of the measurement during the
+ granularity period"
+ },
+ measCondition: {
+ presence: required,
+ comment: "description of the condition causing the measurement"
+ },
+ measDescription: {
+ presence: required,
+ comment: "description of the measurement information
+ and purpose"
+ },
+ measFamily: {
+ presence: required,
+ comment: "abbreviation for a family of measurements, in
+ 3GPP format, or vendor defined"
+ },
+ measInfoId: {
+ presence: required,
+ comment: "name for a group of related measurements in
+ 3GPP format or vendor defined"
+ },
+ measLastChange: {
+ presence: required,
+ comment: "version of the PM Dictionary the last time this
+ measurement was added, modified or deleted"
+ },
+ measObjClass: {
+ presence: required,
+ value: [NGBTS, NGCELL, IPNO, IPSEC, ETHIF],
+ comment: "measurement object class"
+ },
+ measResultRange: {
+ presence: optional,
+ comment: "range of the measurement result; only necessary when
+ the range is smaller than the full range of the
+ data type"
+ },
+ measResultType: {
+ presence: required,
+ value: [float, uint32, uint64],
+ comment: "data type of the measurement result"
+ },
+ measResultUnits: {
+ presence: required,
+ value: [seconds, minutes, nanoseconds, microseconds, dB,
+ number, kilobytes, bytes, ethernetFrames,
+ packets, users],
+ comment: "units of measure for the measurement result"
+ },
+ measType: {
+ presence: required,
+ comment: "measurement name in 3GPP or vendor-specific format;
+ vendor specific names are preceded with VS"
+ },
+ measAdditionalFields: {
+ presence: required,
+ comment: "vendor-specific PM Dictionary fields",
+ structure: {
+ vendorField1: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "vendor field 1 description"
+ },
+ vendorField2: {
+ presence: optional,
+ value: [A, B],
+ comment: "vendor field 2 description."
+ }
+ }
+ }
+ }
+ }
+}}
+...
+# PM Dictionary perf3gpp measurements for the gnb-Nokia NF (bracket style yaml)
+---
+pmMetaData:
+ pmHeader:
+ nfType: gnb-Nokia
+ pmDefSchemaVsn: 2.0
+ pmDefVsn: 5G19_1906_002
+ pmFields:
+ iMeasInfoId: 2204
+ iMeasType: 1
+ measCollectionMethod: CC
+ measCondition: "This measurement is updated when X2AP: SgNB Modification Required message is \sent\ to MeNB
+ with the SCG Change Indication set as PSCellChange."
+ measDescription: This counter indicates the number of intra gNB intra frequency PSCell change attempts.
+ measFamily: NINFC
+ measInfoId: "NR Intra Frequency PSCell Change"
+ measLastChange: 5G18A_1807_003
+ measObjClass: NGCELL
+ measResultRange: 0-4096
+ measResultType: integer
+ measResultUnits: number
+ measType: VS.NINFC.IntraFrPscelChAttempt
+ measAdditionalFields:
+ vendorField1: X
+ vendorField2: B
+...
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Valid_Schema.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Valid_Schema.yaml
new file mode 100644
index 0000000..a125b13
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Valid_Schema.yaml
@@ -0,0 +1,39 @@
+---
+pmMetaData: { presence: required, structure: {
+ pmHeader: {
+ presence: required,
+ structure: {
+ nfType: {
+ presence: required,
+ comment: "nfType comment"
+ }
+ }
+ },
+ pmFields: {
+ presence: required,
+ structure: {
+ measChangeType: {
+ presence: required,
+ value: [added, modified, deleted],
+ comment: "measChangeType comment"
+ },
+ measAdditionalFields: {
+ presence: required,
+ comment: "measAdditionalFields comment",
+ structure: {
+ vendorField1: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "vendorField1 comment"
+ },
+ vendorField2: {
+ presence: optional,
+ value: [A, B],
+ comment: "vendorField2 comment"
+ }
+ }
+ }
+ }
+ }
+}}
+...
diff --git a/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Valid_Schema_Multi_Root.yaml b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Valid_Schema_Multi_Root.yaml
new file mode 100644
index 0000000..d73ca4f
--- /dev/null
+++ b/pmdictionaryvalidation/src/test/resources/yaml_schema/Simple_Valid_Schema_Multi_Root.yaml
@@ -0,0 +1,23 @@
+---
+root1: { presence: required, structure: {
+ field1: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "field 1 description"
+ }
+}}
+root2: { presence: required, structure: {
+ field2: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "field 1 description"
+ }
+}}
+root3: { presence: required, structure: {
+ field3: {
+ presence: required,
+ value: [X, Y, Z],
+ comment: "field 1 description"
+ }
+}}
+...