/*
* Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.yangtools.yang.stmt;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
import org.opendaylight.yangtools.yang.common.YangConstants;
import org.opendaylight.yangtools.yang.common.YangVersion;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DeviateKind;
import org.opendaylight.yangtools.yang.model.api.Deviation;
import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.ModuleImport;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.Status;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
import org.opendaylight.yangtools.yang.parser.util.YangParseException;
public class YangParserTest {
public static final String FS = File.separator;
private final URI fooNS = URI.create("urn:opendaylight.foo");
private final URI barNS = URI.create("urn:opendaylight.bar");
private final URI bazNS = URI.create("urn:opendaylight.baz");
private Date fooRev;
private Date barRev;
private Date bazRev;
private Set<Module> modules;
@Before
public void init() throws Exception {
final DateFormat simpleDateFormat = SimpleDateFormatUtil.getRevisionFormat();
fooRev = simpleDateFormat.parse("2013-02-27");
barRev = simpleDateFormat.parse("2013-07-03");
bazRev = simpleDateFormat.parse("2013-02-27");
modules = TestUtils.loadModules(getClass().getResource("/model").toURI());
assertEquals(3, modules.size());
}
@Test
public void testHeaders() throws ParseException {
final Module foo = TestUtils.findModule(modules, "foo");
assertEquals("foo", foo.getName());
assertEquals(YangVersion.VERSION_1.toString(), foo.getYangVersion());
assertEquals(fooNS, foo.getNamespace());
assertEquals("foo", foo.getPrefix());
final Set<ModuleImport> imports = foo.getImports();
assertEquals(2, imports.size());
final ModuleImport import2 = TestUtils.findImport(imports, "br");
assertEquals("bar", import2.getModuleName());
assertEquals(barRev, import2.getRevision());
final ModuleImport import3 = TestUtils.findImport(imports, "bz");
assertEquals("baz", import3.getModuleName());
assertEquals(bazRev, import3.getRevision());
assertEquals("opendaylight", foo.getOrganization());
assertEquals("http://www.opendaylight.org/", foo.getContact());
final Date expectedRevision = TestUtils.createDate("2013-02-27");
assertEquals(expectedRevision, foo.getRevision());
assertNull(foo.getReference());
}
@Test
public void testParseList() {
final Module bar = TestUtils.findModule(modules, "bar");
final URI expectedNamespace = URI.create("urn:opendaylight.bar");
final String expectedPrefix = "bar";
final ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName(QName.create(
bar.getQNameModule(), "interfaces"));
final ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName(QName.create(bar.getQNameModule(),
"ifEntry"));
// test SchemaNode args
final QName expectedQName = QName.create(expectedNamespace, barRev, "ifEntry");
assertEquals(expectedQName, ifEntry.getQName());
final SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, barRev, expectedPrefix,
"interfaces", "ifEntry");
assertEquals(expectedPath, ifEntry.getPath());
assertNull(ifEntry.getDescription());
assertNull(ifEntry.getReference());
assertEquals(Status.CURRENT, ifEntry.getStatus());
assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
// test DataSchemaNode args
assertFalse(ifEntry.isAugmenting());
assertTrue(ifEntry.isConfiguration());
final ConstraintDefinition constraints = ifEntry.getConstraints();
// :TODO augment to ifEntry have when condition and so in consequence
// ifEntry should be a context node ?
// assertNull(constraints.getWhenCondition());
assertEquals(0, constraints.getMustConstraints().size());
assertTrue(constraints.isMandatory());
assertEquals(1, (int) constraints.getMinElements());
assertEquals(11, (int) constraints.getMaxElements());
// test AugmentationTarget args
final Set<AugmentationSchema> availableAugmentations = ifEntry.getAvailableAugmentations();
assertEquals(2, availableAugmentations.size());
// test ListSchemaNode args
final List<QName> expectedKey = new ArrayList<>();
expectedKey.add(QName.create(expectedNamespace, barRev, "ifIndex"));
assertEquals(expectedKey, ifEntry.getKeyDefinition());
assertFalse(ifEntry.isUserOrdered());
// test DataNodeContainer args
assertEquals(0, ifEntry.getTypeDefinitions().size());
assertEquals(4, ifEntry.getChildNodes().size());
assertEquals(0, ifEntry.getGroupings().size());
assertEquals(0, ifEntry.getUses().size());
final LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName(QName.create(bar.getQNameModule(), "ifIndex"));
assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
assertTrue(ifIndex.getType() instanceof UnsignedIntegerTypeDefinition);
assertEquals("minutes", ifIndex.getUnits());
final LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName(QName.create(bar.getQNameModule(), "ifMtu"));
assertEquals(BaseTypes.int32Type(), ifMtu.getType());
}
@Test
public void testTypedefRangesResolving() throws ParseException {
final Module foo = TestUtils.findModule(modules, "foo");
final LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "int32-leaf"));
final IntegerTypeDefinition leafType = (IntegerTypeDefinition) int32Leaf.getType();
final QName leafTypeQName = leafType.getQName();
assertEquals("int32-ext2", leafTypeQName.getLocalName());
assertEquals(fooNS, leafTypeQName.getNamespace());
assertEquals(fooRev, leafTypeQName.getRevision());
assertEquals("mile", leafType.getUnits());
assertEquals("11", leafType.getDefaultValue());
final List<RangeConstraint> ranges = leafType.getRangeConstraints();
assertEquals(1, ranges.size());
final RangeConstraint range = ranges.get(0);
assertEquals(12, range.getMin().intValue());
assertEquals(20, range.getMax().intValue());
final IntegerTypeDefinition baseType = leafType.getBaseType();
final QName baseTypeQName = baseType.getQName();
assertEquals("int32-ext2", baseTypeQName.getLocalName());
assertEquals(barNS, baseTypeQName.getNamespace());
assertEquals(barRev, baseTypeQName.getRevision());
assertEquals("mile", baseType.getUnits());
assertEquals("11", baseType.getDefaultValue());
final List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
assertEquals(2, baseTypeRanges.size());
final RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
assertEquals(3, baseTypeRange1.getMin().intValue());
assertEquals(9, baseTypeRange1.getMax().intValue());
final RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
assertEquals(11, baseTypeRange2.getMin().intValue());
assertEquals(20, baseTypeRange2.getMax().intValue());
final IntegerTypeDefinition base = baseType.getBaseType();
final QName baseQName = base.getQName();
assertEquals("int32-ext1", baseQName.getLocalName());
assertEquals(barNS, baseQName.getNamespace());
assertEquals(barRev, baseQName.getRevision());
assertNull(base.getUnits());
assertNull(base.getDefaultValue());
final List<RangeConstraint> baseRanges = base.getRangeConstraints();
assertEquals(1, baseRanges.size());
final RangeConstraint baseRange = baseRanges.get(0);
assertEquals(2, baseRange.getMin().intValue());
assertEquals(20, baseRange.getMax().intValue());
assertEquals(BaseTypes.int32Type(), base.getBaseType());
}
@Test
public void testTypedefPatternsResolving() {
final Module foo = TestUtils.findModule(modules, "foo");
final LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "string-leaf"));
assertTrue(stringleaf.getType() instanceof StringTypeDefinition);
final StringTypeDefinition type = (StringTypeDefinition) stringleaf.getType();
final QName typeQName = type.getQName();
assertEquals("string-ext4", typeQName.getLocalName());
assertEquals(barNS, typeQName.getNamespace());
assertEquals(barRev, typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
List<PatternConstraint> patterns = type.getPatternConstraints();
assertEquals(1, patterns.size());
PatternConstraint pattern = patterns.iterator().next();
assertEquals("^[e-z]*$", pattern.getRegularExpression());
assertEquals(1, type.getLengthConstraints().size());
final StringTypeDefinition baseType1 = type.getBaseType();
final QName baseType1QName = baseType1.getQName();
assertEquals("string-ext3", baseType1QName.getLocalName());
assertEquals(barNS, baseType1QName.getNamespace());
assertEquals(barRev, baseType1QName.getRevision());
assertNull(baseType1.getUnits());
assertNull(baseType1.getDefaultValue());
patterns = baseType1.getPatternConstraints();
assertEquals(1, patterns.size());
pattern = patterns.iterator().next();
assertEquals("^[b-u]*$", pattern.getRegularExpression());
assertEquals(1, baseType1.getLengthConstraints().size());
final StringTypeDefinition baseType2 = baseType1.getBaseType();
final QName baseType2QName = baseType2.getQName();
assertEquals("string-ext2", baseType2QName.getLocalName());
assertEquals(barNS, baseType2QName.getNamespace());
assertEquals(barRev, baseType2QName.getRevision());
assertNull(baseType2.getUnits());
assertNull(baseType2.getDefaultValue());
assertTrue(baseType2.getPatternConstraints().isEmpty());
final List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
assertEquals(1, baseType2Lengths.size());
LengthConstraint length = baseType2Lengths.get(0);
assertEquals(6, length.getMin().intValue());
assertEquals(10, length.getMax().intValue());
final StringTypeDefinition baseType3 = baseType2.getBaseType();
final QName baseType3QName = baseType3.getQName();
assertEquals("string-ext1", baseType3QName.getLocalName());
assertEquals(barNS, baseType3QName.getNamespace());
assertEquals(barRev, baseType3QName.getRevision());
assertNull(baseType3.getUnits());
assertNull(baseType3.getDefaultValue());
patterns = baseType3.getPatternConstraints();
assertEquals(1, patterns.size());
pattern = patterns.iterator().next();
assertEquals("^[a-k]*$", pattern.getRegularExpression());
final List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
assertEquals(1, baseType3Lengths.size());
length = baseType3Lengths.get(0);
assertEquals(5, length.getMin().intValue());
assertEquals(11, length.getMax().intValue());
assertEquals(BaseTypes.stringType(), baseType3.getBaseType());
}
@Test
public void testTypedefInvalidPatternsResolving() {
final Module foo = TestUtils.findModule(modules, "foo");
final LeafSchemaNode invalidPatternStringLeaf = (LeafSchemaNode) foo
.getDataChildByName(QName.create(foo.getQNameModule(), "invalid-pattern-string-leaf"));
StringTypeDefinition type = (StringTypeDefinition) invalidPatternStringLeaf.getType();
QName typeQName = type.getQName();
assertEquals("invalid-string-pattern", typeQName.getLocalName());
assertEquals(barNS, typeQName.getNamespace());
assertEquals(barRev, typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
List<PatternConstraint> patterns = type.getPatternConstraints();
assertTrue(patterns.isEmpty());
final LeafSchemaNode invalidDirectStringPatternDefLeaf = (LeafSchemaNode) foo
.getDataChildByName(QName.create(foo.getQNameModule(), "invalid-direct-string-pattern-def-leaf"));
type = (StringTypeDefinition) invalidDirectStringPatternDefLeaf.getType();
typeQName = type.getQName();
assertEquals("string", typeQName.getLocalName());
assertEquals(YangConstants.RFC6020_YANG_NAMESPACE, typeQName.getNamespace());
assertNull(typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
patterns = type.getPatternConstraints();
assertTrue(patterns.isEmpty());
final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) foo
.getDataChildByName(QName.create(foo.getQNameModule(), "multiple-pattern-string-leaf"));
type = (StringTypeDefinition) multiplePatternStringLeaf.getType();
typeQName = type.getQName();
assertEquals("multiple-pattern-string", typeQName.getLocalName());
assertEquals(barNS, typeQName.getNamespace());
assertEquals(barRev, typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
patterns = type.getPatternConstraints();
assertTrue(!patterns.isEmpty());
assertEquals(1, patterns.size());
final PatternConstraint pattern = patterns.iterator().next();
assertEquals("^[e-z]*$", pattern.getRegularExpression());
assertEquals(1, type.getLengthConstraints().size());
final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) foo
.getDataChildByName(QName.create(foo.getQNameModule(), "multiple-pattern-direct-string-def-leaf"));
type = (StringTypeDefinition) multiplePatternDirectStringDefLeaf.getType();
typeQName = type.getQName();
assertEquals("string", typeQName.getLocalName());
assertEquals(fooNS, typeQName.getNamespace());
assertEquals(fooRev, typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
patterns = type.getPatternConstraints();
assertTrue(!patterns.isEmpty());
assertEquals(2, patterns.size());
boolean isEZPattern = false;
boolean isADPattern = false;
for (final PatternConstraint patternConstraint : patterns) {
if (patternConstraint.getRegularExpression().equals("^[e-z]*$")) {
isEZPattern = true;
} else if (patternConstraint.getRegularExpression().equals("^[a-d]*$")) {
isADPattern = true;
}
}
assertTrue(isEZPattern);
assertTrue(isADPattern);
}
@Test
public void testTypedefLengthsResolving() {
final Module foo = TestUtils.findModule(modules, "foo");
final LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "length-leaf"));
final StringTypeDefinition type = (StringTypeDefinition) lengthLeaf.getType();
final QName typeQName = type.getQName();
assertEquals("string-ext2", typeQName.getLocalName());
assertEquals(fooNS, typeQName.getNamespace());
assertEquals(fooRev, typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
assertTrue(type.getPatternConstraints().isEmpty());
final List<LengthConstraint> typeLengths = type.getLengthConstraints();
assertEquals(1, typeLengths.size());
LengthConstraint length = typeLengths.get(0);
assertEquals(7, length.getMin().intValue());
assertEquals(10, length.getMax().intValue());
final StringTypeDefinition baseType1 = type.getBaseType();
final QName baseType1QName = baseType1.getQName();
assertEquals("string-ext2", baseType1QName.getLocalName());
assertEquals(barNS, baseType1QName.getNamespace());
assertEquals(barRev, baseType1QName.getRevision());
assertNull(baseType1.getUnits());
assertNull(baseType1.getDefaultValue());
assertTrue(baseType1.getPatternConstraints().isEmpty());
final List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
assertEquals(1, baseType2Lengths.size());
length = baseType2Lengths.get(0);
assertEquals(6, length.getMin().intValue());
assertEquals(10, length.getMax().intValue());
final StringTypeDefinition baseType2 = baseType1.getBaseType();
final QName baseType2QName = baseType2.getQName();
assertEquals("string-ext1", baseType2QName.getLocalName());
assertEquals(barNS, baseType2QName.getNamespace());
assertEquals(barRev, baseType2QName.getRevision());
assertNull(baseType2.getUnits());
assertNull(baseType2.getDefaultValue());
final List<PatternConstraint> patterns = baseType2.getPatternConstraints();
assertEquals(1, patterns.size());
final PatternConstraint pattern = patterns.iterator().next();
assertEquals("^[a-k]*$", pattern.getRegularExpression());
final List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
assertEquals(1, baseType3Lengths.size());
length = baseType3Lengths.get(0);
assertEquals(5, length.getMin().intValue());
assertEquals(11, length.getMax().intValue());
assertEquals(BaseTypes.stringType(), baseType2.getBaseType());
}
@Test
public void testTypedefDecimal1() {
final Module foo = TestUtils.findModule(modules, "foo");
final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "decimal-leaf"));
assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
final DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
final QName typeQName = type.getQName();
assertEquals("my-decimal-type", typeQName.getLocalName());
assertEquals(barNS, typeQName.getNamespace());
assertEquals(barRev, typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
assertEquals(6, type.getFractionDigits().intValue());
assertEquals(1, type.getRangeConstraints().size());
final DecimalTypeDefinition typeBase = type.getBaseType();
final QName typeBaseQName = typeBase.getQName();
assertEquals("decimal64", typeBaseQName.getLocalName());
assertEquals(barNS, typeBaseQName.getNamespace());
assertEquals(barRev, typeBaseQName.getRevision());
assertNull(typeBase.getUnits());
assertNull(typeBase.getDefaultValue());
assertEquals(6, typeBase.getFractionDigits().intValue());
assertEquals(1, typeBase.getRangeConstraints().size());
assertNull(typeBase.getBaseType());
}
@Test
public void testTypedefDecimal2() {
final Module foo = TestUtils.findModule(modules, "foo");
final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "decimal-leaf2"));
assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
final DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
final QName typeQName = type.getQName();
assertEquals("my-decimal-type", typeQName.getLocalName());
assertEquals(barNS, typeQName.getNamespace());
assertEquals(barRev, typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
assertEquals(6, type.getFractionDigits().intValue());
assertEquals(1, type.getRangeConstraints().size());
final DecimalTypeDefinition baseTypeDecimal = type.getBaseType();
assertEquals(6, baseTypeDecimal.getFractionDigits().intValue());
}
@Test
public void testTypedefUnion() {
final Module foo = TestUtils.findModule(modules, "foo");
final LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "union-leaf"));
assertTrue(unionleaf.getType() instanceof UnionTypeDefinition);
final UnionTypeDefinition type = (UnionTypeDefinition) unionleaf.getType();
final QName typeQName = type.getQName();
assertEquals("my-union-ext", typeQName.getLocalName());
assertEquals(barNS, typeQName.getNamespace());
assertEquals(barRev, typeQName.getRevision());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
final UnionTypeDefinition baseType = type.getBaseType();
final QName baseTypeQName = baseType.getQName();
assertEquals("my-union", baseTypeQName.getLocalName());
assertEquals(barNS, baseTypeQName.getNamespace());
assertEquals(barRev, baseTypeQName.getRevision());
assertNull(baseType.getUnits());
assertNull(baseType.getDefaultValue());
final UnionTypeDefinition unionType = baseType.getBaseType();
final List<TypeDefinition<?>> unionTypes = unionType.getTypes();
assertEquals(2, unionTypes.size());
final IntegerTypeDefinition unionType1 = (IntegerTypeDefinition) unionTypes.get(0);
final QName unionType1QName = baseType.getQName();
assertEquals("my-union", unionType1QName.getLocalName());
assertEquals(barNS, unionType1QName.getNamespace());
assertEquals(barRev, unionType1QName.getRevision());
assertNull(unionType1.getUnits());
assertNull(unionType1.getDefaultValue());
final List<RangeConstraint> ranges = unionType1.getRangeConstraints();
assertEquals(1, ranges.size());
final RangeConstraint range = ranges.get(0);
assertEquals(1, range.getMin().intValue());
assertEquals(100, range.getMax().intValue());
assertEquals(BaseTypes.int16Type(), unionType1.getBaseType());
assertEquals(BaseTypes.int32Type(), unionTypes.get(1));
}
@Test
public void testNestedUnionResolving() {
final Module foo = TestUtils.findModule(modules, "foo");
final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "custom-union-leaf"));
assertTrue(testleaf.getType() instanceof UnionTypeDefinition);
final UnionTypeDefinition type = (UnionTypeDefinition) testleaf.getType();
final QName testleafTypeQName = type.getQName();
assertEquals(bazNS, testleafTypeQName.getNamespace());
assertEquals(bazRev, testleafTypeQName.getRevision());
assertEquals("union1", testleafTypeQName.getLocalName());
assertNull(type.getUnits());
assertNull(type.getDefaultValue());
final UnionTypeDefinition typeBase = type.getBaseType();
final QName typeBaseQName = typeBase.getQName();
assertEquals(bazNS, typeBaseQName.getNamespace());
assertEquals(bazRev, typeBaseQName.getRevision());
assertEquals("union2", typeBaseQName.getLocalName());
assertNull(typeBase.getUnits());
assertNull(typeBase.getDefaultValue());
final UnionTypeDefinition union = typeBase.getBaseType();
final List<TypeDefinition<?>> unionTypes = union.getTypes();
assertEquals(2, unionTypes.size());
assertEquals(BaseTypes.int32Type(), unionTypes.get(0));
assertTrue(unionTypes.get(1) instanceof UnionTypeDefinition);
final UnionTypeDefinition unionType1 = (UnionTypeDefinition) unionTypes.get(1);
final QName uniontType1QName = unionType1.getQName();
assertEquals(barNS, uniontType1QName.getNamespace());
assertEquals(barRev, uniontType1QName.getRevision());
assertEquals("nested-union2", uniontType1QName.getLocalName());
assertNull(unionType1.getUnits());
assertNull(unionType1.getDefaultValue());
final UnionTypeDefinition nestedUnion = unionType1.getBaseType();
final List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
assertEquals(2, nestedUnion2Types.size());
assertTrue(nestedUnion2Types.get(1) instanceof StringTypeDefinition);
assertTrue(nestedUnion2Types.get(0) instanceof UnionTypeDefinition);
final UnionTypeDefinition myUnionExt = (UnionTypeDefinition) nestedUnion2Types.get(0);
final QName myUnionExtQName = myUnionExt.getQName();
assertEquals(barNS, myUnionExtQName.getNamespace());
assertEquals(barRev, myUnionExtQName.getRevision());
assertEquals("my-union-ext", myUnionExtQName.getLocalName());
assertNull(myUnionExt.getUnits());
assertNull(myUnionExt.getDefaultValue());
final UnionTypeDefinition myUnion = myUnionExt.getBaseType();
final QName myUnionQName = myUnion.getQName();
assertEquals(barNS, myUnionQName.getNamespace());
assertEquals(barRev, myUnionQName.getRevision());
assertEquals("my-union", myUnionQName.getLocalName());
assertNull(myUnion.getUnits());
assertNull(myUnion.getDefaultValue());
final UnionTypeDefinition myUnionBase = myUnion.getBaseType();
final List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
assertEquals(2, myUnionBaseTypes.size());
assertTrue(myUnionBaseTypes.get(0) instanceof IntegerTypeDefinition);
assertEquals(BaseTypes.int32Type(), myUnionBaseTypes.get(1));
final IntegerTypeDefinition int16Ext = (IntegerTypeDefinition) myUnionBaseTypes.get(0);
final QName int16ExtQName = int16Ext.getQName();
assertEquals(barNS, int16ExtQName.getNamespace());
assertEquals(barRev, int16ExtQName.getRevision());
assertEquals("int16", int16ExtQName.getLocalName());
assertNull(int16Ext.getUnits());
assertNull(int16Ext.getDefaultValue());
final List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
assertEquals(1, ranges.size());
final RangeConstraint range = ranges.get(0);
assertEquals(1, range.getMin().intValue());
assertEquals(100, range.getMax().intValue());
assertEquals(BaseTypes.int16Type(), int16Ext.getBaseType());
}
@Test
public void testChoice() {
final Module foo = TestUtils.findModule(modules, "foo");
final ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "transfer"));
final ChoiceSchemaNode how = (ChoiceSchemaNode) transfer.getDataChildByName(QName.create(foo.getQNameModule(), "how"));
final Set<ChoiceCaseNode> cases = how.getCases();
assertEquals(5, cases.size());
ChoiceCaseNode input = null;
ChoiceCaseNode output = null;
for (final ChoiceCaseNode caseNode : cases) {
if ("input".equals(caseNode.getQName().getLocalName())) {
input = caseNode;
} else if ("output".equals(caseNode.getQName().getLocalName())) {
output = caseNode;
}
}
assertNotNull(input);
assertNotNull(input.getPath());
assertNotNull(output);
assertNotNull(output.getPath());
}
@Test
public void testDeviation() {
final Module foo = TestUtils.findModule(modules, "foo");
final Set<Deviation> deviations = foo.getDeviations();
assertEquals(1, deviations.size());
final Deviation dev = deviations.iterator().next();
assertEquals("system/user ref", dev.getReference());
final List<QName> path = new ArrayList<>();
path.add(QName.create(barNS, barRev, "interfaces"));
path.add(QName.create(barNS, barRev, "ifEntry"));
final SchemaPath expectedPath = SchemaPath.create(path, true);
assertEquals(expectedPath, dev.getTargetPath());
assertEquals(DeviateKind.ADD, dev.getDeviates().iterator().next().getDeviateType());
}
@Test
public void testUnknownNode() {
final Module baz = TestUtils.findModule(modules, "baz");
final ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName(QName.create(baz.getQNameModule(), "network"));
final List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
assertEquals(1, unknownNodes.size());
final UnknownSchemaNode unknownNode = unknownNodes.get(0);
assertNotNull(unknownNode.getNodeType());
assertEquals("point", unknownNode.getNodeParameter());
}
@Test
public void testFeature() {
final Module baz = TestUtils.findModule(modules, "baz");
final Set<FeatureDefinition> features = baz.getFeatures();
assertEquals(1, features.size());
}
@Test
public void testExtension() {
final Module baz = TestUtils.findModule(modules, "baz");
final List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
assertEquals(1, extensions.size());
final ExtensionDefinition extension = extensions.get(0);
assertEquals("name", extension.getArgument());
assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.",
extension.getDescription());
assertTrue(extension.isYinElement());
}
@Test
public void testNotification() {
final Module baz = TestUtils.findModule(modules, "baz");
final String expectedPrefix = "c";
final Set<NotificationDefinition> notifications = baz.getNotifications();
assertEquals(1, notifications.size());
final NotificationDefinition notification = notifications.iterator().next();
// test SchemaNode args
final QName expectedQName = QName.create(bazNS, bazRev, "event");
assertEquals(expectedQName, notification.getQName());
final SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event");
assertEquals(expectedPath, notification.getPath());
assertNull(notification.getDescription());
assertNull(notification.getReference());
assertEquals(Status.CURRENT, notification.getStatus());
assertEquals(0, notification.getUnknownSchemaNodes().size());
// test DataNodeContainer args
assertEquals(0, notification.getTypeDefinitions().size());
assertEquals(3, notification.getChildNodes().size());
assertEquals(0, notification.getGroupings().size());
assertEquals(0, notification.getUses().size());
final LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName(QName.create(baz.getQNameModule(), "event-class"));
assertTrue(eventClass.getType() instanceof StringTypeDefinition);
final LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName(QName.create(baz.getQNameModule(), "severity"));
assertTrue(severity.getType() instanceof StringTypeDefinition);
}
@Test
public void testRpc() {
final Module baz = TestUtils.findModule(modules, "baz");
final Set<RpcDefinition> rpcs = baz.getRpcs();
assertEquals(1, rpcs.size());
final RpcDefinition rpc = rpcs.iterator().next();
assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
assertEquals("RFC 6241, Section 7.1", rpc.getReference());
}
@Test
public void testTypePath() throws ParseException {
final Module bar = TestUtils.findModule(modules, "bar");
final Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
// int32-ext1
final IntegerTypeDefinition int32ext1 = (IntegerTypeDefinition) TestUtils.findTypedef(types, "int32-ext1");
final QName int32TypedefQName = int32ext1.getQName();
assertEquals(barNS, int32TypedefQName.getNamespace());
assertEquals(barRev, int32TypedefQName.getRevision());
assertEquals("int32-ext1", int32TypedefQName.getLocalName());
final SchemaPath typeSchemaPath = int32ext1.getPath();
final Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
final Iterator<QName> typePathIt = typePath.iterator();
assertEquals(int32TypedefQName, typePathIt.next());
assertFalse(typePathIt.hasNext());
// int32-ext1/int32
final IntegerTypeDefinition int32 = int32ext1.getBaseType();
assertEquals(BaseTypes.int32Type(), int32);
}
@Test
public void testTypePath2() throws ParseException {
final Module bar = TestUtils.findModule(modules, "bar");
final Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
// my-decimal-type
final DecimalTypeDefinition myDecType = (DecimalTypeDefinition) TestUtils.findTypedef(types, "my-decimal-type");
final QName myDecTypeQName = myDecType.getQName();
assertEquals(barNS, myDecTypeQName.getNamespace());
assertEquals(barRev, myDecTypeQName.getRevision());
assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
final SchemaPath typeSchemaPath = myDecType.getPath();
final Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
final Iterator<QName> typePathIt = typePath.iterator();
assertEquals(myDecTypeQName, typePathIt.next());
assertFalse(typePathIt.hasNext());
// my-base-int32-type/int32
final DecimalTypeDefinition dec64 = myDecType.getBaseType();
final QName dec64QName = dec64.getQName();
assertEquals(barNS, dec64QName.getNamespace());
assertEquals(barRev, dec64QName.getRevision());
assertEquals("decimal64", dec64QName.getLocalName());
final SchemaPath dec64SchemaPath = dec64.getPath();
final Iterable<QName> dec64Path = dec64SchemaPath.getPathFromRoot();
final Iterator<QName> dec64PathIt = dec64Path.iterator();
assertEquals(myDecTypeQName, dec64PathIt.next());
assertEquals(dec64QName, dec64PathIt.next());
assertFalse(dec64PathIt.hasNext());
}
private static void checkOrder(final Collection<Module> modules) {
final Iterator<Module> it = modules.iterator();
Module m = it.next();
assertEquals("m2", m.getName());
m = it.next();
assertEquals("m4", m.getName());
m = it.next();
assertEquals("m6", m.getName());
m = it.next();
assertEquals("m8", m.getName());
m = it.next();
assertEquals("m7", m.getName());
m = it.next();
assertEquals("m5", m.getName());
m = it.next();
assertEquals("m3", m.getName());
m = it.next();
assertEquals("m1", m.getName());
}
private static void assertSetEquals(final Set<Module> s1, final Set<Module> s2) {
assertEquals(s1, s2);
final Iterator<Module> it = s1.iterator();
for (final Module m : s2) {
assertEquals(m, it.next());
}
}
@Test
public void testSubmodules() {
final Module foo = TestUtils.findModule(modules, "foo");
final DataSchemaNode id = foo.getDataChildByName(QName.create(foo.getQNameModule(), "id"));
assertNotNull(id);
final DataSchemaNode subExt = foo.getDataChildByName(QName.create(foo.getQNameModule(), "sub-ext"));
assertNotNull(subExt);
final DataSchemaNode subTransfer = foo.getDataChildByName(QName.create(foo.getQNameModule(), "sub-transfer"));
assertNotNull(subTransfer);
assertEquals(2, foo.getExtensionSchemaNodes().size());
assertEquals(2, foo.getAugmentations().size());
}
@Test
public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException, ReactorException {
final StatementStreamSource yang1 = sourceForResource("/yang-grammar-test/revisions-extension.yang");
final StatementStreamSource yang2 = sourceForResource("/yang-grammar-test/submodule-header-extension.yang");
try {
TestUtils.parseYangSources(yang1, yang2);
} catch (final YangParseException e) {
e.printStackTrace();
fail("YangParseException should not be thrown");
}
}
@Test
public void unknownStatementBetweenRevisionsTest() throws ReactorException {
final StatementStreamSource yangModule = sourceForResource("/yang-grammar-test/revisions-extension.yang");
final StatementStreamSource yangSubmodule = sourceForResource(
"/yang-grammar-test/submodule-header-extension.yang");
final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
reactor.addSources(yangModule, yangSubmodule);
final EffectiveSchemaContext result = reactor.buildEffective();
assertNotNull(result);
}
@Test
public void unknownStatementsInStatementsTest() throws ReactorException {
final StatementStreamSource yangFile1 = sourceForResource(
"/yang-grammar-test/stmtsep-in-statements.yang");
final StatementStreamSource yangFile2 = sourceForResource(
"/yang-grammar-test/stmtsep-in-statements2.yang");
final StatementStreamSource yangFile3 = sourceForResource(
"/yang-grammar-test/stmtsep-in-statements-sub.yang");
final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
reactor.addSources(yangFile1, yangFile2, yangFile3);
// TODO: change test or create new module in order to respect new statement parser validations
try {
final EffectiveSchemaContext result = reactor.buildEffective();
} catch (final Exception e) {
assertEquals(SomeModifiersUnresolvedException.class, e.getClass());
assertTrue(e.getCause() instanceof SourceException);
assertTrue(e.getCause().getMessage().startsWith("aaa is not a YANG statement or use of extension"));
}
}
}