Merge "Fixed YANG model registry to remove the model during unregistration and to protect against NPE."
diff --git a/compiler/base/datamodel/src/test/java/org/onosproject/yang/compiler/datamodel/CheckValidationTest.java b/compiler/base/datamodel/src/test/java/org/onosproject/yang/compiler/datamodel/CheckValidationTest.java
new file mode 100644
index 0000000..1827aba
--- /dev/null
+++ b/compiler/base/datamodel/src/test/java/org/onosproject/yang/compiler/datamodel/CheckValidationTest.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.onosproject.yang.compiler.datamodel;
+
+import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
+import org.onosproject.yang.compiler.datamodel.utils.builtindatatype.DataTypeException;
+import org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes;
+import org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangUint16;
+import org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangUint32;
+import org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangUint64;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangInt8.MAX_VALUE;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangInt8.MIN_VALUE;
+
+/**
+ * Utility class to check error messages.
+ */
+final class CheckValidationTest {
+ private static final String E_MESS = "Exception has not occurred for " +
+ "invalid value with type ";
+ private static boolean expOccurred;
+
+ private CheckValidationTest() {
+ }
+
+ /**
+ * Tests the value against the respective YANG node data type.
+ *
+ * @param node associated with YANG node data type
+ * @param value associated with value of YANG node
+ */
+ static void dataValidation(YangType node, String value)
+ throws DataModelException {
+ YangDataTypes type = node.getDataType();
+ try {
+ node.isValidValue(value);
+ } catch (DataTypeException e) {
+ expOccurred = true;
+ assertEquals(e.getMessage(), getErrorString(value, type));
+ }
+ assertEquals(E_MESS + type, expOccurred, true);
+ }
+
+ /**
+ * Tests the range of the value against the respective YANG node data type.
+ *
+ * @param node associated with YANG node data type
+ * @param value associated with value of YANG node
+ */
+ static void rangeCheck(YangType node, String value)
+ throws DataModelException {
+ YangDataTypes type = node.getDataType();
+ try {
+ node.isValidValue(value);
+ } catch (DataTypeException e) {
+ expOccurred = true;
+ assertEquals(e.getMessage(), getRangeError(value, type));
+ }
+ assertEquals(E_MESS + type, expOccurred, true);
+ }
+
+ /**
+ * Returns the error message for the corresponding range of value of the
+ * respective data type.
+ *
+ * @param value associated with value of YANG node
+ * @param type of the YANG node
+ * @return the error message associated with the validation
+ */
+ private static String getRangeError(String value, YangDataTypes type) {
+ StringBuilder msg = new StringBuilder();
+ switch (type) {
+ case UINT8:
+ if (Integer.valueOf(value) < MIN_VALUE) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is lesser than minimum value ")
+ .append(MIN_VALUE).append(".");
+ } else if (Integer.valueOf(value) > MAX_VALUE) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is greater than maximum value ")
+ .append(MAX_VALUE).append(".");
+ }
+ break;
+ case UINT16:
+ if (Integer.valueOf(value) < YangUint16.MIN_VALUE) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is lesser than minimum value ")
+ .append(YangUint16.MIN_VALUE).append(".");
+ } else if (Integer.valueOf(value) > YangUint16.MAX_VALUE) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is greater than maximum value ")
+ .append(YangUint16.MAX_VALUE).append(".");
+ }
+ break;
+ case UINT32:
+ if (Long.parseLong(value) < YangUint32.MIN_VALUE) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is lesser than minimum value ")
+ .append(YangUint32.MIN_VALUE).append(".");
+ } else if (Long.parseLong(value) > YangUint32.MAX_VALUE) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is greater than maximum value ")
+ .append(YangUint32.MAX_VALUE).append(".");
+ }
+ break;
+ case UINT64:
+ BigInteger val = new BigInteger(value);
+ if (val.compareTo(YangUint64.MIN_VALUE) == -1) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is lesser than minimum value ")
+ .append(YangUint64.MIN_VALUE).append(".");
+ } else if (val.compareTo(YangUint64.MAX_VALUE) == 1) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is greater than maximum value ")
+ .append(YangUint64.MAX_VALUE).append(".");
+ }
+ break;
+ case DECIMAL64:
+ BigDecimal decVal = new BigDecimal(value);
+ BigDecimal min = new BigDecimal("-9.2233720368547763E+17");
+ BigDecimal max = new BigDecimal("9.2233720368547763E+17");
+
+ if (decVal.compareTo(min) == -1) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is less than minimum value ")
+ .append(min).append(".");
+ } else if (decVal.compareTo(max) == 1) {
+ msg.append("YANG file error : ")
+ .append(value)
+ .append(" is greater than maximum value ")
+ .append(max).append(".");
+ }
+ break;
+ default:
+ return null;
+ }
+ return msg.toString();
+ }
+
+ /**
+ * Utility function to get the error string of the respective data type.
+ *
+ * @param value is associated with value of the YANG node value
+ * @param dataType is associated with YANG data type
+ * @return the error string
+ */
+
+ private static String getErrorString(String value, YangDataTypes dataType) {
+ StringBuilder msg = new StringBuilder();
+ switch (dataType) {
+ case UINT8:
+ case UINT16:
+ case UINT32:
+ case UINT64:
+ case INT8:
+ case INT16:
+ case INT32:
+ case INT64:
+ case DECIMAL64:
+ msg.append("YANG file error : Input value ").append("\"")
+ .append(value).append("\"")
+ .append(" is not a valid ")
+ .append(dataType.toString().toLowerCase())
+ .append(".");
+ break;
+ case BITS:
+ case ENUMERATION:
+ case BINARY:
+ case STRING:
+ case BOOLEAN:
+ msg.append("YANG file error : Input value ").append("\"")
+ .append(value).append("\"")
+ .append(" is not a valid ").append(dataType);
+ break;
+ case EMPTY:
+ msg.append("YANG file error : Input value ").append("\"")
+ .append(value).append("\"")
+ .append(" is not allowed for a data type ")
+ .append(dataType);
+ break;
+ default:
+ return null;
+ }
+ return msg.toString();
+ }
+}
\ No newline at end of file
diff --git a/compiler/base/datamodel/src/test/java/org/onosproject/yang/compiler/datamodel/DataValidator.java b/compiler/base/datamodel/src/test/java/org/onosproject/yang/compiler/datamodel/DataValidator.java
new file mode 100644
index 0000000..5d6ac49
--- /dev/null
+++ b/compiler/base/datamodel/src/test/java/org/onosproject/yang/compiler/datamodel/DataValidator.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.onosproject.yang.compiler.datamodel;
+
+import org.junit.Test;
+import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
+
+import static org.onosproject.yang.compiler.datamodel.CheckValidationTest.dataValidation;
+import static org.onosproject.yang.compiler.datamodel.CheckValidationTest.rangeCheck;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.BINARY;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.BITS;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.BOOLEAN;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.DECIMAL64;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.EMPTY;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.INT16;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.INT32;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.INT64;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.INT8;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.UINT16;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.UINT32;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.UINT64;
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.UINT8;
+
+/**
+ * Unit tests for data type validations.Creates and validates different data
+ * types against their data types covering different scenarios.
+ */
+public class DataValidator {
+
+ /*
+ * Creating nodes of type INT8 and testing the data validation.
+ */
+ @Test
+ public void negativeIntTest1() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(INT8);
+ dataValidation(newNode, "-129");
+ dataValidation(newNode, "128");
+ dataValidation(newNode, " ");
+ }
+
+ /*
+ * Creating nodes of type INT16 and testing the data validation.
+ */
+ @Test
+ public void negativeIntTest2() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(INT16);
+ dataValidation(newNode, "-32769");
+ dataValidation(newNode, "32768");
+ dataValidation(newNode, " ");
+ }
+
+ /*
+ * Creating nodes of type INT32 and testing the data validation.
+ */
+ @Test
+ public void negativeIntTest3() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(INT32);
+ dataValidation(newNode, "-2147483649");
+ dataValidation(newNode, "2147483648");
+ dataValidation(newNode, " ");
+ }
+
+ /**
+ * Creating nodes of type INT64 and testing the data validation.
+ */
+ @Test
+ public void negativeIntTest4() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(INT64);
+ dataValidation(newNode, "-9223372036854775809");
+ dataValidation(newNode, "9223372036854775808");
+ dataValidation(newNode, " ");
+ }
+
+ /**
+ * Creating nodes of type UINT8 and testing the data validation.
+ */
+ @Test
+ public void negativeUintTest1() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(UINT8);
+ rangeCheck(newNode, "-1");
+ rangeCheck(newNode, "256");
+ dataValidation(newNode, " ");
+ }
+
+ /**
+ * Creating nodes of type UINT16 and testing the data validation.
+ */
+ @Test
+ public void negativeUintTest2() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(UINT16);
+ rangeCheck(newNode, "-2");
+ rangeCheck(newNode, "65536");
+ dataValidation(newNode, " ");
+ }
+
+ /**
+ * Creating nodes of type UINT32 and testing the data validation.
+ */
+ @Test
+ public void negativeUintTest3() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(UINT32);
+ rangeCheck(newNode, "-3");
+ rangeCheck(newNode, "4294967298");
+ dataValidation(newNode, " ");
+ }
+
+ /**
+ * Creating nodes of type UINT64 and testing the data validation.
+ */
+ @Test
+ public void negativeUintTest4() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(UINT64);
+ rangeCheck(newNode, "-9223372036854775809");
+ rangeCheck(newNode, "18446744073709551616");
+ dataValidation(newNode, " ");
+ }
+
+ /**
+ * Creating nodes of type BOOLEAN and testing the data validation.
+ */
+ @Test
+ public void negativeBool() throws DataModelException {
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(BOOLEAN);
+ dataValidation(newNode, " ");
+ dataValidation(newNode, "10");
+ dataValidation(newNode, "ABCD");
+ }
+
+ /**
+ * Creating nodes of type DECIMAL64 and testing the data validation.
+ */
+ @Test
+ public void negativeDec64() throws DataModelException {
+
+ YangType<YangDecimal64> newNode = new YangType<>();
+ newNode.setDataType(DECIMAL64);
+ YangDecimal64 decimal64Node = new YangDecimal64();
+ newNode.setDataTypeExtendedInfo(decimal64Node);
+ rangeCheck(newNode, "-932337203685477580.9");
+ rangeCheck(newNode, "932337203685477580.8");
+ dataValidation(newNode, " ");
+ }
+
+ /**
+ * Creating nodes of type BIT and testing the data validation.
+ */
+ @Test
+ public void negativeBits() throws DataModelException {
+
+ YangType<YangBits> newNode = new YangType<>();
+ newNode.setDataType(BITS);
+ YangBits bitNode = new YangBits();
+ newNode.setDataTypeExtendedInfo(bitNode);
+ dataValidation(newNode, " ");
+ dataValidation(newNode, "0");
+ dataValidation(newNode, "default");
+ dataValidation(newNode, "1");
+ }
+
+ /**
+ * Creating nodes of type EMPTY and testing the data validation.
+ */
+ @Test
+ public void negativeEmpty() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(EMPTY);
+ dataValidation(newNode, "0");
+ dataValidation(newNode, "ABCD");
+ }
+
+ /**
+ * Creating nodes of type BINARY and testing the data validation.
+ */
+ @Test
+ public void negativeBin() throws DataModelException {
+
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(BINARY);
+ dataValidation(newNode, " ");
+ }
+
+ /* TODO: need to verify .
+ @Test
+ public void negativeEnum() throws DataModelException {
+
+ YangType<YangEnumeration> newNode = new YangType<>();
+ newNode.setDataType(YangDataTypes.ENUMERATION);
+ YangEnum enum1 = new YangEnum();
+ enum1.setNamedValue("sample1");
+
+ YangEnum enum2 = new YangEnum();
+ enum2.setNamedValue("sample2");
+ enum2.setValue(20);
+
+ YangEnumeration YEnumeration = new YangEnumeration() {
+ @Override
+ public String getJavaPackage() {
+ return null;
+ }
+
+ @Override
+ public String getJavaClassNameOrBuiltInType() {
+ return null;
+ }
+
+ @Override
+ public String getJavaAttributeName() {
+ return null;
+ }
+ };
+ YEnumeration.addEnumInfo(enum1);
+ YEnumeration.addEnumInfo(enum2);
+ newNode.setDataTypeExtendedInfo(YEnumeration);
+ dataValidation(newNode," ");
+ dataValidation(newNode,"123");
+ dataValidation(newNode,"sample1");
+ }
+
+ @Test
+ public void negativeUnion() throws DataModelException {
+ YangType<?> newNode = new YangType<>();
+ newNode.setDataType(YangDataTypes.UNION);
+ List<YangType<?>> list = new LinkedList<>();
+ YangUnion union = new YangUnion() {
+ @Override
+ public String getJavaPackage() {
+ return null;
+ }
+
+ @Override
+ public String getJavaClassNameOrBuiltInType() {
+ return null;
+ }
+
+ @Override
+ public String getJavaAttributeName() {
+ return null;
+ }
+ };
+ YangUnion YUnion = union;
+ YangType<YangInt8> typeInt1 = new YangType<>();
+ YangType<YangDecimal64> typeInt2 = new YangType<>();
+ YUnion.addType(typeInt1);
+ YUnion.addType(typeInt2);
+ // newNode.setDataTypeExtendedInfo(YUnion);
+ dataValidation(newNode,"INT8");
+ }
+ */
+}