Mahesh Poojary S
Committed by Patrick Liu

[ONOS-4910, ONOS-4921] Framework: utils validation and defect fix

Change-Id: I821920fa8c88e64406b702c2b8736bdeaf231474
Showing 39 changed files with 1188 additions and 159 deletions
......@@ -16,7 +16,6 @@
package org.onosproject.yangutils.datamodel;
import java.io.Serializable;
import java.math.BigDecimal;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.DataTypeException;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangBuiltInDataTypeInfo;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
......@@ -80,7 +79,7 @@ public final class BuiltInTypeObjectFactory implements Serializable {
return (T) new YangUint64(valueInStr);
}
case DECIMAL64: {
return (T) new YangDecimal64(new BigDecimal(valueInStr));
return (T) new YangDecimal64(valueInStr);
}
default: {
throw new DataTypeException("YANG file error : Unsupported data type");
......
......@@ -67,17 +67,6 @@ public class YangBits implements Parsable, Serializable {
}
/**
* Creates an instance of YANG bits.
*
* @param bits set of bit names
* @throws DataModelException due to violation in data model rules
*/
public YangBits(String bits) throws DataModelException {
String[] bitNames = bits.trim().split(Pattern.quote(SPACE));
setBitDataSet(bitNames);
}
/**
* Returns the bits name.
*
* @return the bits name
......@@ -229,9 +218,11 @@ public class YangBits implements Parsable, Serializable {
* @param bits set of bit names
* @return Object of YANG bits
*/
public static YangBits fromString(String bits) {
public YangBits fromString(String bits) {
try {
return new YangBits(bits);
String[] bitNames = bits.trim().split(Pattern.quote(SPACE));
setBitDataSet(bitNames);
return this;
} catch (Exception e) {
}
return null;
......
......@@ -84,32 +84,6 @@ public class YangChoice extends YangNode
private boolean isConfig;
/**
* Reference RFC 6020.
*
* The "default" statement indicates if a case should be considered as the
* default if no child nodes from any of the choice's cases exist. The
* argument is the identifier of the "case" statement. If the "default"
* statement is missing, there is no default case.
*
* The "default" statement MUST NOT be present on choices where "mandatory"
* is true.
*
* The default case is only important when considering the default values of
* nodes under the cases. The default values for nodes under the default
* case are used if none of the nodes under any of the cases are present.
*
* There MUST NOT be any mandatory nodes directly under the default case.
*
* Default values for child nodes under a case are only used if one of the
* nodes under that case is present, or if that case is the default case. If
* none of the nodes under a case are present and the case is not the
* default case, the default values of the cases' child nodes are ignored.
*
* the default case to be used if no case members is present.
*/
private String defaultCase;
/**
* Description of choice.
*/
private String description;
......@@ -146,8 +120,28 @@ public class YangChoice extends YangNode
private YangStatusType status;
/**
* Default value in string, needs to be converted to the target object,
* based on the type.
* Reference RFC 6020.
* <p>
* The "default" statement indicates if a case should be considered as the
* default if no child nodes from any of the choice's cases exist. The
* argument is the identifier of the "case" statement. If the "default"
* statement is missing, there is no default case.
* <p>
* The "default" statement MUST NOT be present on choices where "mandatory"
* is true.
* <p>
* The default case is only important when considering the default values of
* nodes under the cases. The default values for nodes under the default
* case are used if none of the nodes under any of the cases are present.
* <p>
* There MUST NOT be any mandatory nodes directly under the default case.
* <p>
* Default values for child nodes under a case are only used if one of the
* nodes under that case is present, or if that case is the default case. If
* none of the nodes under a case are present and the case is not the
* default case, the default values of the cases' child nodes are ignored.
* <p>
* the default case to be used if no case members is present.
*/
private String defaultValueInString;
......@@ -238,24 +232,6 @@ public class YangChoice extends YangNode
}
/**
* Returns the default case.
*
* @return the default case
*/
public String getDefaultCase() {
return defaultCase;
}
/**
* Sets the default case.
*
* @param defaultCase the default case to set
*/
public void setDefaultCase(String defaultCase) {
this.defaultCase = defaultCase;
}
/**
* Returns the mandatory status.
*
* @return the mandatory status
......@@ -378,7 +354,25 @@ public class YangChoice extends YangNode
*/
@Override
public void validateDataOnExit() throws DataModelException {
// TODO auto-generated method stub, to be implemented by parser
if (defaultValueInString != null && !defaultValueInString.isEmpty()) {
YangNode node = getChild();
boolean matched = false;
// Check whether default string matches the case
while (node != null) {
if (node instanceof YangCase) {
if (defaultValueInString.equals(((YangCase) node).getName())) {
matched = true;
break;
}
}
node = node.getNextSibling();
}
if (!matched) {
throw new DataModelException("YANG file error: default string \"" + defaultValueInString
+ "\" not matching choice \"" + getName() + "\" case.");
}
}
}
@Override
......
......@@ -20,6 +20,7 @@ import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.FractionDigits;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.DataTypeException;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangBuiltInDataTypeInfo;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
......@@ -55,6 +56,16 @@ public class YangDecimal64<T>
*/
public static final int MAX_FRACTION_DIGITS_VALUE = 18;
/**
* Valid minimum value of YANG's decimal64.
*/
public static final BigDecimal MIN_VALUE = BigDecimal.valueOf(-922337203685477580.8);
/**
* Valid maximum value of YANG's decimal64.
*/
public static final BigDecimal MAX_VALUE = BigDecimal.valueOf(922337203685477580.7);
// Decimal64 value
private BigDecimal value;
......@@ -84,11 +95,29 @@ public class YangDecimal64<T>
/**
* Creates an instance of YANG decimal64.
*
* @param value of decimal64 in string
* @throws DataModelException a violation of data model rules
* @param valueInString of decimal64 in string
*/
public YangDecimal64(String value) throws DataModelException {
fromString(value);
public YangDecimal64(String valueInString) {
if (valueInString.matches(MIN_KEYWORD)) {
value = MIN_VALUE;
} else if (valueInString.matches(MAX_KEYWORD)) {
value = MAX_VALUE;
} else {
try {
value = new BigDecimal(valueInString);
} catch (Exception e) {
throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
"decimal64.");
}
}
if (value.doubleValue() < MIN_VALUE.doubleValue()) {
throw new DataTypeException("YANG file error : " + valueInString + " is lesser than minimum value "
+ MIN_VALUE + ".");
} else if (value.doubleValue() > MAX_VALUE.doubleValue()) {
throw new DataTypeException("YANG file error : " + valueInString + " is greater than maximum value "
+ MAX_VALUE + ".");
}
}
/**
......@@ -178,20 +207,53 @@ public class YangDecimal64<T>
* @throws DataModelException a violation of data model rules
*/
public static YangDecimal64 fromString(String valInString) throws DataModelException {
YangDecimal64 decimal64;
decimal64 = of(new BigDecimal(valInString));
decimal64.validateValue();
return decimal64;
return new YangDecimal64(valInString);
}
/**
* Checks whether specific fraction-digit in its range.
*
* @return true if fraction-digit is in its range otherwise false
*/
public boolean isValidFractionDigit() {
if ((fractionDigit >= 1) && (fractionDigit <= 18)) {
return true;
}
return false;
}
/**
* Validate decimal64 value.
* Checks whether value is in correct decimal64 value range.
*
* @throws DataModelException a violation of data model rules
*/
public void validateValue() throws DataModelException {
if (!(FractionDigits.isValidDecimal64(this.value, this.fractionDigit))) {
throw new DataModelException("YANG file error : decimal64 validation failed.");
public void validateDecimal64() throws DataModelException {
YangRangeRestriction rangeRestriction = (YangRangeRestriction) getRangeRestrictedExtendedInfo();
if (rangeRestriction != null) {
// Check whether value is within provided range value
ListIterator<YangRangeInterval> rangeListIterator = rangeRestriction.getAscendingRangeIntervals()
.listIterator();
boolean isMatched = false;
while (rangeListIterator.hasNext()) {
YangRangeInterval rangeInterval = rangeListIterator.next();
BigDecimal startValue = ((YangDecimal64) rangeInterval.getStartValue()).getValue();
BigDecimal endValue = ((YangDecimal64) rangeInterval.getEndValue()).getValue();
if ((this.value.doubleValue() >= startValue.doubleValue()) &&
(this.value.doubleValue() <= endValue.doubleValue())) {
isMatched = true;
break;
}
}
// If range is not matched then throw error
if (!isMatched) {
throw new DataModelException("YANG file error : decimal64 validation failed.");
}
} else {
// Check value is in fraction-digits decimal64 value range
if (!FractionDigits.isValueInDecimal64Range(this.value, getFractionDigit())) {
throw new DataModelException("YANG file error : decimal64 validation failed.");
}
}
}
......@@ -203,6 +265,7 @@ public class YangDecimal64<T>
public void validateRange() throws DataModelException {
YangRangeRestriction rangeRestriction = (YangRangeRestriction) getRangeRestrictedExtendedInfo();
if (rangeRestriction == null) {
// No need to validate. Range is optional.
return;
}
......@@ -210,14 +273,14 @@ public class YangDecimal64<T>
.listIterator();
while (rangeListIterator.hasNext()) {
YangRangeInterval rangeInterval = rangeListIterator.next();
if (!(FractionDigits.isValidDecimal64(((YangDecimal64) rangeInterval.getStartValue()).getValue(),
getFractionDigit()))) {
throw new DataModelException("YANG file error : decimal64 validation failed.");
if (!(FractionDigits.isValueInDecimal64Range(((YangDecimal64) rangeInterval.getStartValue()).getValue(),
getFractionDigit()))) {
throw new DataModelException("YANG file error : range validation failed.");
}
if (!(FractionDigits.isValidDecimal64(((YangDecimal64) rangeInterval.getEndValue()).getValue(),
getFractionDigit()))) {
throw new DataModelException("YANG file error : decimal64 validation failed.");
if (!(FractionDigits.isValueInDecimal64Range(((YangDecimal64) rangeInterval.getEndValue()).getValue(),
getFractionDigit()))) {
throw new DataModelException("YANG file error : range validation failed.");
}
}
}
......
......@@ -380,8 +380,9 @@ public class YangLeaf
@Override
public void validateDataOnExit()
throws DataModelException {
// TODO auto-generated method stub, to be implemented by parser
if (defaultValueInString != null && !defaultValueInString.isEmpty() && dataType != null) {
dataType.isValidValue(defaultValueInString);
}
}
@Override
......
......@@ -17,6 +17,8 @@
package org.onosproject.yangutils.datamodel;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.ListIterator;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
......@@ -193,6 +195,61 @@ public class YangStringRestriction implements YangDesc, YangReference, Parsable,
return YangConstructType.PATTERN_DATA;
}
/**
* Validates if the given value is correct as per the length restriction.
*
* @param valueInString value
* @return true, if the value is confirming to length restriction, false otherwise
*/
public boolean isValidStringOnLengthRestriction(String valueInString) {
if (lengthRestriction == null || lengthRestriction.getAscendingRangeIntervals() == null
|| lengthRestriction.getAscendingRangeIntervals().isEmpty()) {
// Length restriction is optional
return true;
}
ListIterator<YangRangeInterval<YangUint64>> rangeListIterator = lengthRestriction.getAscendingRangeIntervals()
.listIterator();
boolean isMatched = false;
while (rangeListIterator.hasNext()) {
YangRangeInterval rangeInterval = rangeListIterator.next();
BigInteger startValue = ((YangUint64) rangeInterval.getStartValue()).getValue();
BigInteger endValue = ((YangUint64) rangeInterval.getEndValue()).getValue();
if ((valueInString.length() >= startValue.intValue()) &&
(valueInString.length() <= endValue.intValue())) {
isMatched = true;
break;
}
}
return isMatched;
}
/**
* Validates if the given value is correct as per the pattern restriction.
*
* @param valueInString value
* @return true, if the value is confirming to pattern restriction, false otherwise
*/
public boolean isValidStringOnPatternRestriction(String valueInString) {
if (patternRestriction == null
|| patternRestriction.getPatternList().isEmpty()) {
// Pattern restriction is optional
return true;
}
ListIterator<String> patternListIterator = patternRestriction.getPatternList().listIterator();
boolean isMatched = false;
while (patternListIterator.hasNext()) {
if (valueInString.matches(patternListIterator.next())) {
isMatched = true;
break;
}
}
return isMatched;
}
@Override
public void validateDataOnEntry() throws DataModelException {
// TODO: implement the method.
......
......@@ -17,12 +17,18 @@
package org.onosproject.yangutils.datamodel;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.ListIterator;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.DataModelUtils;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.DataTypeException;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangUint64;
import static org.onosproject.yangutils.datamodel.BuiltInTypeObjectFactory.getDataObjectFromString;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypeUtils.isOfRangeRestrictedType;
......@@ -268,9 +274,9 @@ public class YangType<T>
* type as per the YANG file.
*
* @param value input data value
* @return status of validation
* @throws DataModelException a violation of data model rules
*/
public boolean isValidValue(String value) {
public void isValidValue(String value) throws DataModelException {
switch (getDataType()) {
case INT8:
case INT16:
......@@ -280,83 +286,210 @@ public class YangType<T>
case UINT16:
case UINT32:
case UINT64: {
isValidValueForRangeRestrictedType(value);
if (getDataTypeExtendedInfo() == null) {
getDataObjectFromString(value, getDataType());
} else {
((YangRangeRestriction) getDataTypeExtendedInfo()).isValidValueString(value);
}
break;
}
case DECIMAL64: {
// TODO
// Fraction-Digits and range needs to get it from yang
YangDecimal64<YangRangeRestriction> decimal64 =
(YangDecimal64<YangRangeRestriction>) getDataTypeExtendedInfo();
validateDecimal64(value, decimal64.getFractionDigit(),
decimal64.getRangeRestrictedExtendedInfo());
break;
}
case STRING: {
// TODO implement in string restriction similar to range restriction
if (!(((YangStringRestriction) getDataTypeExtendedInfo()).isValidStringOnLengthRestriction(value) &&
((YangStringRestriction) getDataTypeExtendedInfo()).isValidStringOnPatternRestriction(value))) {
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
"string");
}
break;
}
case BOOLEAN:
if (!(value.equals(DataModelUtils.TRUE) || value.equals(DataModelUtils.FALSE))) {
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
"boolean");
}
break;
case ENUMERATION: {
// TODO validate using list of YANG enum of enumeration class in extended info.
}
case BINARY: {
// TODO validate based on extended info
Iterator<YangEnum> iterator = ((YangEnumeration) getDataTypeExtendedInfo()).getEnumSet().iterator();
boolean isValidated = false;
while (iterator.hasNext()) {
YangEnum enumTemp = (YangEnum) iterator.next();
if (enumTemp.getNamedValue().equals(value)) {
isValidated = true;
break;
}
}
if (!isValidated) {
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
"union");
}
break;
}
case BITS: {
// TODO validate based on extended info
YangBits bits = (YangBits) getDataTypeExtendedInfo();
if (bits.fromString(value) == null) {
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
"bits");
}
break;
}
case BOOLEAN: {
// TODO true or false
case BINARY: {
if (!isValidBinary(value, (YangRangeRestriction) getDataTypeExtendedInfo())) {
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
"binary");
}
break;
}
case LEAFREF: {
// TODO validate based on extended info
YangLeafRef<?> leafRef = (YangLeafRef<?>) getDataTypeExtendedInfo();
leafRef.validateDataOnExit();
break;
}
case IDENTITYREF: {
// TODO TBD
break;
}
case EMPTY: {
// TODO true or false
throw new DataTypeException("YANG file error : Input value \"" + value
+ "\" is not a allowed for a data type " + "empty");
}
case UNION: {
// TODO validate based on extended info
ListIterator<YangType<?>> listIterator = ((YangUnion) getDataTypeExtendedInfo()).getTypeList()
.listIterator();
boolean isValidated = false;
while (listIterator.hasNext()) {
YangType<?> type = (YangType<?>) listIterator.next();
try {
type.isValidValue(value);
// If it is not thrown exception then validation is success
isValidated = true;
break;
} catch (Exception e) {
}
}
if (!isValidated) {
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
"union");
}
break;
}
case INSTANCE_IDENTIFIER: {
// TODO TBD
break;
}
case DERIVED: {
if (isOfRangeRestrictedType(((YangDerivedInfo) getDataTypeExtendedInfo()).getEffectiveBuiltInType())) {
try {
if (((YangDerivedInfo) getDataTypeExtendedInfo()).getResolvedExtendedInfo() == null) {
getDataObjectFromString(value,
((YangDerivedInfo) getDataTypeExtendedInfo()).getEffectiveBuiltInType());
return true;
} else {
return ((YangRangeRestriction) ((YangDerivedInfo) getDataTypeExtendedInfo())
.getResolvedExtendedInfo()).isValidValueString(value);
YangDataTypes dataType = ((YangDerivedInfo) getDataTypeExtendedInfo()).getEffectiveBuiltInType();
if (isOfRangeRestrictedType(dataType)) {
if (((YangDerivedInfo) getDataTypeExtendedInfo()).getResolvedExtendedInfo() == null) {
getDataObjectFromString(value,
((YangDerivedInfo) getDataTypeExtendedInfo())
.getEffectiveBuiltInType());
} else {
if (!((YangRangeRestriction) ((YangDerivedInfo) getDataTypeExtendedInfo())
.getResolvedExtendedInfo()).isValidValueString(value)) {
throw new DataTypeException("YANG file error : Input value \"" + value
+ "\" is not a valid " + dataType.toString());
}
} catch (Exception e) {
return false;
}
} else {
// TODO
} else if (dataType == YangDataTypes.STRING) {
if (((YangDerivedInfo) getDataTypeExtendedInfo()).getResolvedExtendedInfo() != null) {
YangStringRestriction stringRestriction =
((YangStringRestriction) ((YangDerivedInfo) getDataTypeExtendedInfo())
.getResolvedExtendedInfo());
if (!(stringRestriction.isValidStringOnLengthRestriction(value) &&
stringRestriction.isValidStringOnPatternRestriction(value))) {
throw new DataTypeException("YANG file error : Input value \"" + value
+ "\" is not a valid " + dataType.toString());
}
}
} else if (dataType == YangDataTypes.BITS) {
YangBits bits = (YangBits) getDataTypeExtendedInfo();
if (bits.fromString(value) == null) {
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
"bits");
}
} else if (dataType == YangDataTypes.BINARY) {
if (!isValidBinary(value, (YangRangeRestriction) ((YangDerivedInfo)
getDataTypeExtendedInfo()).getResolvedExtendedInfo())) {
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
dataType.toString());
}
} else if (dataType == YangDataTypes.DECIMAL64) {
YangDerivedInfo derivedInfo = (YangDerivedInfo) getDataTypeExtendedInfo();
YangTypeDef typedef = (YangTypeDef) derivedInfo.getReferredTypeDef();
YangType<YangDecimal64> decimal64Type =
(YangType<YangDecimal64>) typedef.getTypeList().iterator().next();
YangDecimal64<YangRangeRestriction> decimal64 = decimal64Type.getDataTypeExtendedInfo();
// Fraction-Digits and range needs to get it from yang
validateDecimal64(value, decimal64.getFractionDigit(),
decimal64.getRangeRestrictedExtendedInfo());
}
break;
}
default: {
// TODO
throw new DataTypeException("YANG file error : Input value \"" + value + "\" is for unsupported " +
"data type.");
}
}
return true;
}
/**
* Validates the input data value for range restricted types against the
* permissible value for the type as per the YANG file.
* Checks whether specific string is valid decimal64 value.
*
* @param value input data value
* @return status of validation
* @param value decimal64 value
*/
private boolean isValidValueForRangeRestrictedType(String value) {
try {
if (getDataTypeExtendedInfo() == null) {
getDataObjectFromString(value, getDataType());
return true;
} else {
return ((YangRangeRestriction) getDataTypeExtendedInfo()).isValidValueString(value);
}
} catch (Exception e) {
private void validateDecimal64(String value, int fractionDigit, YangRangeRestriction rangeRestriction)
throws DataModelException {
YangDecimal64<YangRangeRestriction> decimal64 = YangDecimal64.fromString(value);
decimal64.setFractionDigit(fractionDigit);
decimal64.setRangeRestrictedExtendedInfo(rangeRestriction);
decimal64.validateDecimal64();
}
/**
* Checks whether specific string is valid binary.
*
* @param value binary value
* @return true if validation success otherwise false
*/
private boolean isValidBinary(String value, YangRangeRestriction lengthRestriction) {
YangBinary binary = new YangBinary(value);
// After decoding binary, its length should not be zero
if (binary.getBinaryData().length == 0) {
return false;
}
if (lengthRestriction == null || lengthRestriction.getAscendingRangeIntervals() == null
|| lengthRestriction.getAscendingRangeIntervals().isEmpty()) {
// Length restriction is optional
return true;
}
ListIterator<YangRangeInterval<YangUint64>> rangeListIterator = lengthRestriction.getAscendingRangeIntervals()
.listIterator();
boolean isMatched = false;
while (rangeListIterator.hasNext()) {
YangRangeInterval rangeInterval = rangeListIterator.next();
BigInteger startValue = ((YangUint64) rangeInterval.getStartValue()).getValue();
BigInteger endValue = ((YangUint64) rangeInterval.getEndValue()).getValue();
// convert (encode) back and check length
if ((binary.toString().length() >= startValue.intValue()) &&
(binary.toString().length() <= endValue.intValue())) {
isMatched = true;
break;
}
}
return isMatched;
}
}
......
......@@ -251,7 +251,9 @@ public class YangTypeDef extends YangNode implements YangCommonInfo, Parsable, Y
*/
@Override
public void validateDataOnExit() throws DataModelException {
// TODO auto-generated method stub, to be implemented by parser
if (defaultValueInString != null && !defaultValueInString.isEmpty() && getTypeDefBaseType() != null) {
getTypeDefBaseType().isValidValue(defaultValueInString);
}
}
/**
......
......@@ -55,6 +55,8 @@ import java.util.Set;
* Represents utilities for data model tree.
*/
public final class DataModelUtils {
public static final String TRUE = "true";
public static final String FALSE = "false";
/**
* Creates a new data model tree utility.
......
......@@ -105,7 +105,7 @@ public final class FractionDigits {
*
* @return decimal64 value range by fraction-digits as index
*/
private static ArrayList<Range> getDecimal64ValueRange() {
public static ArrayList<Range> getDecimal64ValueRange() {
if (decimal64ValueRange == null) {
decimal64ValueRange = new ArrayList<>();
decimal64ValueRange.add(new Range(-922337203685477580.8, 922337203685477580.7)); // fraction-digit: 1
......@@ -131,37 +131,38 @@ public final class FractionDigits {
}
/**
* Checks given decimal64 value is in the specific range based on given fraction-digit.
* Retrieve range based on fraction-digits.
*
* @param value decimal64 value
* @param fractionDigit fraction-digits
* @return success when it is in specific range otherwise false
* @return range
* @throws DataModelException a violation of data model rules
*/
public static boolean isValidDecimal64(BigDecimal value, int fractionDigit) {
public static Range getRange(int fractionDigit) throws DataModelException {
if (!((fractionDigit >= 1) && (fractionDigit <= 18))) {
return false;
throw new DataModelException("YANG file error : given fraction-digit is not in its range (1..18).");
}
// ArrayList index starts from 0.
Range range = getDecimal64ValueRange().get(fractionDigit - 1);
if ((value.doubleValue() >= range.min) && (value.doubleValue() <= range.max)) {
return true;
}
return false;
return getDecimal64ValueRange().get(fractionDigit - 1);
}
/**
* Retrieve range based on fraction-digits.
* Checks whether specific decimal64 value is in correct range based fraction-digit.
*
* @param value decimal64 value
* @param fractionDigit fraction-digits
* @return range
* @throws DataModelException a violation of data model rules
* @return true when it is in correct range otherwise false
*/
public static Range getRange(int fractionDigit) throws DataModelException {
public static boolean isValueInDecimal64Range(BigDecimal value, int fractionDigit) {
// Fraction-digits should be in correct its own range.
if (!((fractionDigit >= 1) && (fractionDigit <= 18))) {
throw new DataModelException("YANG file error : given fraction-digit is not in its range (1..18).");
return false;
}
return getDecimal64ValueRange().get(fractionDigit - 1);
// ArrayList index starts from 0.
FractionDigits.Range range = FractionDigits.getDecimal64ValueRange().get(fractionDigit - 1);
if ((value.doubleValue() >= range.getMin()) && (value.doubleValue() <= range.getMax())) {
return true;
}
return false;
}
}
......
......@@ -49,6 +49,7 @@ import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLoc
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_CONTENT;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
......@@ -156,6 +157,13 @@ public final class ChoiceListener {
checkStackIsNotEmpty(listener, MISSING_HOLDER, CHOICE_DATA, ctx.identifier().getText(), EXIT);
if (listener.getParsedDataStack().peek() instanceof YangChoice) {
YangChoice choiceNode = (YangChoice) listener.getParsedDataStack().peek();
try {
choiceNode.validateDataOnExit();
} catch (DataModelException e) {
throw new ParserException(constructListenerErrorMessage(INVALID_CONTENT, CHOICE_DATA,
ctx.identifier().getText(), EXIT));
}
listener.getParsedDataStack().pop();
} else {
throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, CHOICE_DATA,
......
......@@ -46,6 +46,7 @@ import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil;
import static org.onosproject.yangutils.datamodel.utils.YangConstructType.DEFAULT_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
......@@ -82,17 +83,17 @@ public final class DefaultListener {
switch (tmpNode.getYangConstructType()) {
case TYPEDEF_DATA: {
YangTypeDef typeDef = (YangTypeDef) tmpNode;
typeDef.setDefaultValueInString(ctx.string().getText());
typeDef.setDefaultValueInString(ListenerUtil.removeQuotesAndHandleConcat(ctx.string().getText()));
break;
}
case LEAF_DATA: {
YangLeaf leaf = (YangLeaf) tmpNode;
leaf.setDefaultValueInString(ctx.string().getText());
leaf.setDefaultValueInString(ListenerUtil.removeQuotesAndHandleConcat(ctx.string().getText()));
break;
}
case CHOICE_DATA: {
YangChoice choice = (YangChoice) tmpNode;
choice.setDefaultValueInString(ctx.string().getText());
choice.setDefaultValueInString(ListenerUtil.removeQuotesAndHandleConcat(ctx.string().getText()));
break;
}
default:
......
......@@ -22,6 +22,7 @@ package org.onosproject.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
......@@ -42,6 +43,7 @@ import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLoc
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_CONTENT;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
......@@ -143,6 +145,13 @@ public final class LeafListener {
checkStackIsNotEmpty(listener, MISSING_HOLDER, LEAF_DATA, ctx.identifier().getText(), EXIT);
if (listener.getParsedDataStack().peek() instanceof YangLeaf) {
YangLeaf leafNode = (YangLeaf) listener.getParsedDataStack().peek();
try {
leafNode.validateDataOnExit();
} catch (DataModelException e) {
throw new ParserException(constructListenerErrorMessage(INVALID_CONTENT, LEAF_DATA,
ctx.identifier().getText(), EXIT));
}
listener.getParsedDataStack().pop();
} else {
throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, LEAF_DATA,
......
......@@ -1143,7 +1143,7 @@ public final class MethodsGenerator {
JavaAttributeInfo fromStringAttributeInfo) {
return EIGHT_SPACE_INDENTATION + getTrySubString() + NEW_LINE + TWELVE_SPACE_INDENTATION
+ getParsedSubString(attr, fromStringAttributeInfo) + SEMI_COLAN + NEW_LINE + TWELVE_SPACE_INDENTATION
+ getParsedSubString(attr, fromStringAttributeInfo) + NEW_LINE + TWELVE_SPACE_INDENTATION
+ getReturnOfSubString() + NEW_LINE + EIGHT_SPACE_INDENTATION + getCatchSubString()
+ NEW_LINE + EIGHT_SPACE_INDENTATION + CLOSE_CURLY_BRACKET;
}
......
......@@ -145,9 +145,9 @@ public class Decimal64ListenerTest {
assertThat(decimal64.getFractionDigit(), is(18));
decimal64.setValue(new BigDecimal(-9.223372036854775808));
decimal64.validateValue();
decimal64.validateDecimal64();
decimal64.setValue(new BigDecimal(9.223372036854775807));
decimal64.validateValue();
decimal64.validateDecimal64();
}
/**
......@@ -181,7 +181,7 @@ public class Decimal64ListenerTest {
decimal64.setValue(new BigDecimal(-92233720368547758.08));
// validation should fail
decimal64.validateValue();
decimal64.validateDecimal64();
}
/**
......@@ -271,7 +271,7 @@ public class Decimal64ListenerTest {
@Test
public void processDecimal64InvalidRange() throws IOException, ParserException, DataModelException {
thrown.expect(ParserException.class);
thrown.expectMessage("YANG file error : decimal64 validation failed.");
thrown.expectMessage("YANG file error : range validation failed.");
manager.getDataModel("src/test/resources/decimal64/Decimal64TypeInvalidRangeStmnt.yang");
}
......
......@@ -19,13 +19,21 @@ package org.onosproject.yangutils.parser.impl.listeners;
import java.io.IOException;
import java.util.ListIterator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.datamodel.YangDerivedInfo;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangChoice;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.DataTypeException;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangInt64;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
......@@ -36,6 +44,8 @@ import static org.junit.Assert.assertThat;
* Test cases for testing default listener functionality.
*/
public class DefaultListenerTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
private final YangUtilsParserManager manager = new YangUtilsParserManager();
......@@ -43,9 +53,9 @@ public class DefaultListenerTest {
* Checks if default value is set correctly.
*/
@Test
public void processLeafSubStatementDefault() throws IOException, ParserException {
public void processDefaultValueInLeafSubStatement() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/LeafSubStatementDefault.yang");
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueInLeafSubStatement.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
......@@ -60,16 +70,28 @@ public class DefaultListenerTest {
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("invalid-interval"));
assertThat(leafInfo.getDefaultValueInString(), is("\"1\""));
assertThat(leafInfo.getDefaultValueInString(), is("1"));
}
/**
* Checks if default value is set correctly.
* Validates default invalid value in leaf.
*/
@Test
public void processDefaultInalueInLeafSubStatement() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"x\" is not a valid uint16.");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueInLeafSubStatement.yang");
}
/**
* Validates default case value in choice statement.
*/
@Test
public void processChoiceSubStatementDefault() throws IOException, ParserException {
public void processDefaultCaseInChoiceSubStatement() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ChoiceSubStatementDefault.yang");
YangNode node = manager.getDataModel("src/test/resources/default/DefaultCaseInChoiceSubStatement.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
......@@ -85,6 +107,408 @@ public class DefaultListenerTest {
YangChoice yangChoice = (YangChoice) yangContainer.getChild();
assertThat(yangChoice.getName(), is("snack"));
assertThat(yangChoice.getDefaultValueInString(), is("\"hello\""));
assertThat(yangChoice.getDefaultValueInString(), is("sports-arena"));
}
/**
* Validates default invalide case in choice statement.
*/
@Test
public void processDefaultInvalidCaseInChoiceSubStatement() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("Internal parser error detected: Invalid content in choice \"snack\" after processing.");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueInChoiceSubStmt.yang");
}
/**
* Validates default value in typedef.
*/
@Test
public void processDefaultInTypedef() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueInTypeDef.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check typedef
YangTypeDef typedef = (YangTypeDef) yangNode.getChild();
assertThat(typedef.getName(), is("topInt"));
assertThat(typedef.getDefaultValueInString(), is("10"));
YangType type = typedef.getTypeList().iterator().next();
assertThat(type.getDataType(), is(YangDataTypes.INT64));
assertThat(type.getDataTypeName(), is("int64"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("myValue"));
// Check leaf reffered typedef
assertThat(leafInfo.getDataType().getDataTypeName(), is("topInt"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.DERIVED));
YangType<YangDerivedInfo> typeDerived = (YangType<YangDerivedInfo>) leafInfo.getDataType();
YangDerivedInfo derivedInfo = (YangDerivedInfo) typeDerived.getDataTypeExtendedInfo();
YangTypeDef prevTypedef = (YangTypeDef) derivedInfo.getReferredTypeDef();
assertThat(prevTypedef.getName(), is("topInt"));
assertThat(prevTypedef.getDefaultValueInString(), is("10"));
YangType topType = prevTypedef.getTypeList().iterator().next();
assertThat(topType.getDataType(), is(YangDataTypes.INT64));
assertThat(topType.getDataTypeName(), is("int64"));
YangType<YangInt64> typeInt64 = (YangType<YangInt64>) topType;
YangInt64 int64Obj = typeInt64.getDataTypeExtendedInfo();
}
/**
* Validates invalid default value in typedef.
*/
@Test
public void processInvalidDefaultValueInTypdeDef() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"x\" is not a valid int64.");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueInTypeDef.yang");
}
/**
* Validates default value decimal64 in leaf.
*/
@Test
public void processDefaultValueDecimal64InLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueDecimal64InLeaf.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// check the default value
// This default value is verified by YangType.isValidValue() called from LeafListener.processLeafExit()
assertThat(leafInfo.getName(), is("mydecimal"));
assertThat(leafInfo.getDefaultValueInString(), is("5"));
}
/**
* Validates default invalid value decimal64 in leaf.
*/
@Test
public void processDefaultInvalidValueDecimal64InLeaf() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"x\" is not a valid decimal64.");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueDecimal64InLeaf.yang");
}
/**
* Validates default value string in leaf.
*/
@Test
public void processDefaultValueStringInLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueStringInLeaf.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// check the default value
// This default value is verified by YangType.isValidValue() called from LeafListener.processLeafExit()
assertThat(leafInfo.getName(), is("MyString"));
assertThat(leafInfo.getDefaultValueInString(), is("2bB"));
}
/**
* Validates default invalid value string in leaf.
*/
@Test
public void processDefaultInvalidValueStringInLeaf() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"2bB2bB\" is not a valid string");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueStringInLeaf.yang");
}
/**
* Validates default value boolean in leaf.
*/
@Test
public void processDefaultValueBooleanInLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueBooleanInLeaf.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// check the default value
// This default value is verified by YangType.isValidValue() called from LeafListener.processLeafExit()
assertThat(leafInfo.getName(), is("myboolean"));
assertThat(leafInfo.getDefaultValueInString(), is("true"));
}
/**
* Validates default invalid value boolean in leaf.
*/
@Test
public void processDefaultInvalidValueBooleanInLeaf() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"yes\" is not a valid boolean");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueBooleanInLeaf.yang");
}
/**
* Validates default value enumeration in leaf.
*/
@Test
public void processDefaultValueEnumberationInLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueEnumerationInLeaf.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// check the default value
// This default value is verified by YangType.isValidValue() called from LeafListener.processLeafExit()
assertThat(leafInfo.getName(), is("myenum"));
assertThat(leafInfo.getDefaultValueInString(), is("one"));
}
/**
* Validates default invalid value enumeration in leaf.
*/
@Test
public void processDefaultInvalidValueEnumberationInLeaf() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"xyz\" is not a valid union");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueEnumerationInLeaf.yang");
}
/**
* Validates default value bits in leaf.
*/
@Test
public void processDefaultValueBitsInLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueBitsInLeaf.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// check the default value
// This default value is verified by YangType.isValidValue() called from LeafListener.processLeafExit()
assertThat(leafInfo.getName(), is("mybits"));
assertThat(leafInfo.getDefaultValueInString(), is("auto-sense-speed"));
}
/**
* Validates default invalid value bits in leaf.
*/
@Test
public void processDefaultInvalidValueBitsInLeaf() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"xyz\" is not a valid bits");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueBitsInLeaf.yang");
}
/**
* Validates default value binary in leaf.
*/
@Test
public void processDefaultValueBinaryInLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueBinaryInLeaf.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// check the default value
// This default value is verified by YangType.isValidValue() called from LeafListener.processLeafExit()
assertThat(leafInfo.getName(), is("message"));
assertThat(leafInfo.getDefaultValueInString(), is("10010010"));
}
/**
* Validates default invalid value binary in leaf.
*/
@Test
public void processDefaultInvlaidValueBinaryInLeaf() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"000\" is not a valid binary");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueBinaryInLeaf.yang");
}
/**
* Validates default value empty in leaf.
*/
@Test
public void processDefaultValueEmptyInLeaf() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"something\" is not a allowed for a data type empty");
manager.getDataModel("src/test/resources/default/DefaultValueEmptyInLeaf.yang");
}
/**
* Validates default value union in leaf.
*/
@Test
public void processDefaultValueUnionInLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueUnionInLeaf.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
// check the default value
// This default value is verified by YangType.isValidValue() called from LeafListener.processLeafExit()
assertThat(leafInfo.getName(), is("message"));
assertThat(leafInfo.getDefaultValueInString(), is("unbounded"));
}
/**
* Validates default invalid value union in leaf.
*/
@Test
public void processDefaultInvalidValueUnionInLeaf() throws IOException, ParserException {
thrown.expect(DataTypeException.class);
thrown.expectMessage("YANG file error : Input value \"xyz\" is not a valid union");
manager.getDataModel("src/test/resources/default/DefaultInvalidValueUnionInLeaf.yang");
}
/**
* Validates default value in multiple typedef.
*/
@Test
public void processDefaultInMultiTypedef() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/default/DefaultValueInMultiTypeDef.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// check typedef
YangTypeDef typedef = (YangTypeDef) yangNode.getChild();
assertThat(typedef.getName(), is("topInt"));
assertThat(typedef.getDefaultValueInString(), is("10"));
YangType type = typedef.getTypeList().iterator().next();
assertThat(type.getDataType(), is(YangDataTypes.INT64));
assertThat(type.getDataTypeName(), is("int64"));
// check leaf
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("lowInt"));
// check leaf type
assertThat(leafInfo.getName(), is("lowInt"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("midInt"));
YangType<YangDerivedInfo> derivedInfoType = (YangType<YangDerivedInfo>) leafInfo.getDataType();
assertThat(derivedInfoType.getDataType(), is(YangDataTypes.DERIVED));
YangDerivedInfo derivedInfo = (YangDerivedInfo) derivedInfoType.getDataTypeExtendedInfo();
// check previous typedef
YangTypeDef prevTypedef = (YangTypeDef) derivedInfo.getReferredTypeDef();
assertThat(prevTypedef.getName(), is("midInt"));
type = prevTypedef.getTypeList().iterator().next();
assertThat(type.getDataType(), is(YangDataTypes.DERIVED));
derivedInfo = (YangDerivedInfo) type.getDataTypeExtendedInfo();
// check top typedef
YangTypeDef topTypedef = (YangTypeDef) derivedInfo.getReferredTypeDef();
assertThat(topTypedef.getName(), is("topInt"));
assertThat(topTypedef.getDefaultValueInString(), is("10"));
YangType topType = topTypedef.getTypeList().iterator().next();
assertThat(topType.getDataType(), is(YangDataTypes.INT64));
assertThat(topType.getDataTypeName(), is("int64"));
YangType<YangInt64> typeInt64 = (YangType<YangInt64>) topType;
YangInt64 int64Obj = typeInt64.getDataTypeExtendedInfo();
}
}
......
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container food {
choice snack {
case sports-arena {
leaf pretzel {
type string;
}
leaf beer {
type string;
}
}
case late-night {
leaf chocolate {
type string;
}
}
default "sports-arena";
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf message {
type binary {
length "8";
}
default "000";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf mybits {
type bits {
bit disable-nagle {
position 0;
}
bit auto-sense-speed {
position 1;
}
bit Mb-only {
position 2;
}
}
default "xyz";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf myboolean {
type boolean;
default "yes";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf mydecimal {
type decimal64 {
fraction-digits 4;
range 4..6;
}
default "x";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf myenum {
type enumeration {
enum zero;
enum one;
enum seven {
value 7;
}
}
default "xyz";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container food {
choice snack {
case sports-arena {
leaf pretzel {
type string;
}
leaf beer {
type string;
}
}
case late-night {
leaf chocolate {
type string;
}
}
default "hello";
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf invalid-interval {
type "uint16";
units "seconds";
default "x";
description "Interval before a route is declared invalid";
config true;
mandatory true;
status current;
reference "RFC 6020";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
typedef topInt {
type int64;
default "x";
}
leaf myValue {
type topInt;
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf MyString {
type string {
length "0..4";
pattern "[0-9a-fA-F]*";
}
default "2bB2bB";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf message {
type union {
type int32;
type enumeration {
enum "unbounded";
}
}
default "xyz";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf message {
type binary {
length "8";
}
default "10010010";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf mybits {
type bits {
bit disable-nagle {
position 0;
}
bit auto-sense-speed {
position 1;
}
bit Mb-only {
position 2;
}
}
default "auto-sense-speed";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf myboolean {
type boolean;
default "true";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf mydecimal {
type decimal64 {
fraction-digits 4;
range 4..6;
}
default "5";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
typedef topInt {
type int64;
default "10";
}
leaf myValue {
type topInt;
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf enable-qos {
type empty;
default "something";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf myenum {
type enumeration {
enum zero;
enum one;
enum seven {
value 7;
}
}
default "one";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf invalid-interval {
type "uint16";
units "seconds";
default "1";
description "Interval before a route is declared invalid";
config true;
mandatory true;
status current;
reference "RFC 6020";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
typedef topInt {
type int64;
default "10";
}
typedef midInt {
type topInt;
}
leaf lowInt {
type midInt;
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
typedef topInt {
type int64;
default "10";
}
leaf myValue {
type topInt;
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf MyString {
type string {
length "0..4";
pattern "[0-9a-fA-F]*";
}
default "2bB";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf message {
type union {
type int32;
type enumeration {
enum "unbounded";
}
}
default "unbounded";
}
}