2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.stmt;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
17 import com.google.common.collect.Range;
18 import com.google.common.collect.RangeSet;
19 import java.io.IOException;
21 import java.net.URISyntaxException;
22 import java.text.ParseException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Optional;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.common.QNameModule;
33 import org.opendaylight.yangtools.yang.common.Revision;
34 import org.opendaylight.yangtools.yang.common.YangConstants;
35 import org.opendaylight.yangtools.yang.common.YangVersion;
36 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
37 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
38 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
40 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.DeviateKind;
43 import org.opendaylight.yangtools.yang.model.api.Deviation;
44 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
45 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
46 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
47 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
48 import org.opendaylight.yangtools.yang.model.api.Module;
49 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
50 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
51 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
52 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
53 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
54 import org.opendaylight.yangtools.yang.model.api.Status;
55 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
56 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
57 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
58 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
59 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
60 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
61 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
62 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
63 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
64 import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
65 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
66 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
67 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
68 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
69 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
70 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
72 public class YangParserTest {
73 private static final QNameModule FOO = QNameModule.create(
74 URI.create("urn:opendaylight.foo"), Revision.valueOf("2013-02-27"));
75 private static final QNameModule BAR = QNameModule.create(
76 URI.create("urn:opendaylight.bar"), Revision.valueOf("2013-07-03"));
77 private static final QNameModule BAZ = QNameModule.create(
78 URI.create("urn:opendaylight.baz"), Revision.valueOf("2013-02-27"));
80 private SchemaContext context;
86 public void init() throws Exception {
87 context = TestUtils.loadModules(getClass().getResource("/model").toURI());
88 foo = TestUtils.findModule(context, "foo").get();
89 bar = TestUtils.findModule(context, "bar").get();
90 baz = TestUtils.findModule(context, "baz").get();
94 public void testHeaders() throws ParseException {
95 assertEquals("foo", foo.getName());
96 assertEquals(YangVersion.VERSION_1, foo.getYangVersion());
97 assertEquals(FOO.getNamespace(), foo.getNamespace());
98 assertEquals("foo", foo.getPrefix());
100 final Set<ModuleImport> imports = foo.getImports();
101 assertEquals(2, imports.size());
103 final ModuleImport import2 = TestUtils.findImport(imports, "br");
104 assertEquals("bar", import2.getModuleName());
105 assertEquals(BAR.getRevision(), import2.getRevision());
107 final ModuleImport import3 = TestUtils.findImport(imports, "bz");
108 assertEquals("baz", import3.getModuleName());
109 assertEquals(BAZ.getRevision(), import3.getRevision());
111 assertEquals("opendaylight", foo.getOrganization());
112 assertEquals("http://www.opendaylight.org/", foo.getContact());
113 assertEquals(Optional.of(Revision.valueOf("2013-02-27")), foo.getRevision());
114 assertNull(foo.getReference());
118 public void testParseList() {
119 final ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName(QName.create(
120 bar.getQNameModule(), "interfaces"));
122 final ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName(QName.create(bar.getQNameModule(),
124 // test SchemaNode args
125 assertEquals(QName.create(BAR, "ifEntry"), ifEntry.getQName());
127 final SchemaPath expectedPath = TestUtils.createPath(true, BAR, "interfaces", "ifEntry");
128 assertEquals(expectedPath, ifEntry.getPath());
129 assertNull(ifEntry.getDescription());
130 assertNull(ifEntry.getReference());
131 assertEquals(Status.CURRENT, ifEntry.getStatus());
132 assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
133 // test DataSchemaNode args
134 assertFalse(ifEntry.isAugmenting());
135 assertTrue(ifEntry.isConfiguration());
136 final ConstraintDefinition constraints = ifEntry.getConstraints();
137 // :TODO augment to ifEntry have when condition and so in consequence
138 // ifEntry should be a context node ?
139 // assertNull(constraints.getWhenCondition());
140 assertEquals(0, constraints.getMustConstraints().size());
141 assertTrue(constraints.isMandatory());
142 assertEquals(1, (int) constraints.getMinElements());
143 assertEquals(11, (int) constraints.getMaxElements());
144 // test AugmentationTarget args
145 final Set<AugmentationSchema> availableAugmentations = ifEntry.getAvailableAugmentations();
146 assertEquals(2, availableAugmentations.size());
147 // test ListSchemaNode args
148 final List<QName> expectedKey = new ArrayList<>();
149 expectedKey.add(QName.create(BAR, "ifIndex"));
150 assertEquals(expectedKey, ifEntry.getKeyDefinition());
151 assertFalse(ifEntry.isUserOrdered());
152 // test DataNodeContainer args
153 assertEquals(0, ifEntry.getTypeDefinitions().size());
154 assertEquals(4, ifEntry.getChildNodes().size());
155 assertEquals(0, ifEntry.getGroupings().size());
156 assertEquals(0, ifEntry.getUses().size());
158 final LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName(QName.create(bar.getQNameModule(), "ifIndex"));
159 assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
160 assertTrue(ifIndex.getType() instanceof UnsignedIntegerTypeDefinition);
161 assertEquals("minutes", ifIndex.getUnits());
162 final LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName(QName.create(bar.getQNameModule(), "ifMtu"));
163 assertEquals(BaseTypes.int32Type(), ifMtu.getType());
167 public void testTypedefRangesResolving() throws ParseException {
168 final LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "int32-leaf"));
170 final IntegerTypeDefinition leafType = (IntegerTypeDefinition) int32Leaf.getType();
171 assertEquals(QName.create(FOO, "int32-ext2"), leafType.getQName());
172 assertEquals("mile", leafType.getUnits());
173 assertEquals("11", leafType.getDefaultValue());
175 final List<RangeConstraint> ranges = leafType.getRangeConstraints();
176 assertEquals(1, ranges.size());
177 final RangeConstraint range = ranges.get(0);
178 assertEquals(12, range.getMin().intValue());
179 assertEquals(20, range.getMax().intValue());
181 final IntegerTypeDefinition baseType = leafType.getBaseType();
182 assertEquals(QName.create(BAR, "int32-ext2"), baseType.getQName());
183 assertEquals("mile", baseType.getUnits());
184 assertEquals("11", baseType.getDefaultValue());
186 final List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
187 assertEquals(2, baseTypeRanges.size());
188 final RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
189 assertEquals(3, baseTypeRange1.getMin().intValue());
190 assertEquals(9, baseTypeRange1.getMax().intValue());
191 final RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
192 assertEquals(11, baseTypeRange2.getMin().intValue());
193 assertEquals(20, baseTypeRange2.getMax().intValue());
195 final IntegerTypeDefinition base = baseType.getBaseType();
196 final QName baseQName = base.getQName();
197 assertEquals("int32-ext1", baseQName.getLocalName());
198 assertEquals(BAR, baseQName.getModule());
199 assertNull(base.getUnits());
200 assertNull(base.getDefaultValue());
202 final List<RangeConstraint> baseRanges = base.getRangeConstraints();
203 assertEquals(1, baseRanges.size());
204 final RangeConstraint baseRange = baseRanges.get(0);
205 assertEquals(2, baseRange.getMin().intValue());
206 assertEquals(20, baseRange.getMax().intValue());
208 assertEquals(BaseTypes.int32Type(), base.getBaseType());
212 public void testTypedefPatternsResolving() {
213 final LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "string-leaf"));
215 assertTrue(stringleaf.getType() instanceof StringTypeDefinition);
216 final StringTypeDefinition type = (StringTypeDefinition) stringleaf.getType();
217 final QName typeQName = type.getQName();
218 assertEquals("string-ext4", typeQName.getLocalName());
219 assertEquals(BAR, typeQName.getModule());
220 assertNull(type.getUnits());
221 assertNull(type.getDefaultValue());
222 List<PatternConstraint> patterns = type.getPatternConstraints();
223 assertEquals(1, patterns.size());
224 PatternConstraint pattern = patterns.iterator().next();
225 assertEquals("^[e-z]*$", pattern.getRegularExpression());
226 assertEquals(1, type.getLengthConstraint().get().getAllowedRanges().asRanges().size());
228 final StringTypeDefinition baseType1 = type.getBaseType();
229 final QName baseType1QName = baseType1.getQName();
230 assertEquals("string-ext3", baseType1QName.getLocalName());
231 assertEquals(BAR, baseType1QName.getModule());
232 assertNull(baseType1.getUnits());
233 assertNull(baseType1.getDefaultValue());
234 patterns = baseType1.getPatternConstraints();
235 assertEquals(1, patterns.size());
236 pattern = patterns.iterator().next();
237 assertEquals("^[b-u]*$", pattern.getRegularExpression());
238 assertEquals(1, baseType1.getLengthConstraint().get().getAllowedRanges().asRanges().size());
240 final StringTypeDefinition baseType2 = baseType1.getBaseType();
241 final QName baseType2QName = baseType2.getQName();
242 assertEquals("string-ext2", baseType2QName.getLocalName());
243 assertEquals(BAR, baseType2QName.getModule());
244 assertNull(baseType2.getUnits());
245 assertNull(baseType2.getDefaultValue());
246 assertTrue(baseType2.getPatternConstraints().isEmpty());
247 final RangeSet<Integer> baseType2Lengths = baseType2.getLengthConstraint().get().getAllowedRanges();
248 assertEquals(1, baseType2Lengths.asRanges().size());
249 Range<Integer> length = baseType2Lengths.span();
250 assertEquals(6, length.lowerEndpoint().intValue());
251 assertEquals(10, length.upperEndpoint().intValue());
253 final StringTypeDefinition baseType3 = baseType2.getBaseType();
254 assertEquals(QName.create(BAR, "string-ext1"), baseType3.getQName());
255 assertNull(baseType3.getUnits());
256 assertNull(baseType3.getDefaultValue());
257 patterns = baseType3.getPatternConstraints();
258 assertEquals(1, patterns.size());
259 pattern = patterns.iterator().next();
260 assertEquals("^[a-k]*$", pattern.getRegularExpression());
261 final RangeSet<Integer> baseType3Lengths = baseType3.getLengthConstraint().get().getAllowedRanges();
262 assertEquals(1, baseType3Lengths.asRanges().size());
263 length = baseType3Lengths.span();
264 assertEquals(5, length.lowerEndpoint().intValue());
265 assertEquals(11, length.upperEndpoint().intValue());
267 assertEquals(BaseTypes.stringType(), baseType3.getBaseType());
271 public void testTypedefInvalidPatternsResolving() {
272 final LeafSchemaNode invalidPatternStringLeaf = (LeafSchemaNode) foo
273 .getDataChildByName(QName.create(foo.getQNameModule(), "invalid-pattern-string-leaf"));
274 StringTypeDefinition type = (StringTypeDefinition) invalidPatternStringLeaf.getType();
275 assertEquals(QName.create(BAR, "invalid-string-pattern"), type.getQName());
276 assertNull(type.getUnits());
277 assertNull(type.getDefaultValue());
278 List<PatternConstraint> patterns = type.getPatternConstraints();
279 assertTrue(patterns.isEmpty());
281 final LeafSchemaNode invalidDirectStringPatternDefLeaf = (LeafSchemaNode) foo
282 .getDataChildByName(QName.create(foo.getQNameModule(), "invalid-direct-string-pattern-def-leaf"));
283 type = (StringTypeDefinition) invalidDirectStringPatternDefLeaf.getType();
285 assertEquals(QName.create(YangConstants.RFC6020_YANG_MODULE, "string"), type.getQName());
286 assertNull(type.getUnits());
287 assertNull(type.getDefaultValue());
288 patterns = type.getPatternConstraints();
289 assertTrue(patterns.isEmpty());
291 final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) foo
292 .getDataChildByName(QName.create(foo.getQNameModule(), "multiple-pattern-string-leaf"));
293 type = (StringTypeDefinition) multiplePatternStringLeaf.getType();
294 assertEquals(QName.create(BAR, "multiple-pattern-string"), type.getQName());
295 assertNull(type.getUnits());
296 assertNull(type.getDefaultValue());
297 patterns = type.getPatternConstraints();
298 assertTrue(!patterns.isEmpty());
299 assertEquals(1, patterns.size());
300 final PatternConstraint pattern = patterns.iterator().next();
301 assertEquals("^[e-z]*$", pattern.getRegularExpression());
302 assertEquals(1, type.getLengthConstraint().get().getAllowedRanges().asRanges().size());
304 final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) foo
305 .getDataChildByName(QName.create(foo.getQNameModule(), "multiple-pattern-direct-string-def-leaf"));
306 type = (StringTypeDefinition) multiplePatternDirectStringDefLeaf.getType();
307 assertEquals(QName.create(FOO, "string"), type.getQName());
308 assertNull(type.getUnits());
309 assertNull(type.getDefaultValue());
310 patterns = type.getPatternConstraints();
311 assertTrue(!patterns.isEmpty());
312 assertEquals(2, patterns.size());
314 boolean isEZPattern = false;
315 boolean isADPattern = false;
316 for (final PatternConstraint patternConstraint : patterns) {
317 if (patternConstraint.getRegularExpression().equals("^[e-z]*$")) {
319 } else if (patternConstraint.getRegularExpression().equals("^[a-d]*$")) {
323 assertTrue(isEZPattern);
324 assertTrue(isADPattern);
328 public void testTypedefLengthsResolving() {
329 final LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(),
331 final StringTypeDefinition type = (StringTypeDefinition) lengthLeaf.getType();
333 assertEquals(QName.create(FOO, "string-ext2"), type.getQName());
334 assertNull(type.getUnits());
335 assertNull(type.getDefaultValue());
336 assertTrue(type.getPatternConstraints().isEmpty());
337 final RangeSet<Integer> typeLengths = type.getLengthConstraint().get().getAllowedRanges();
338 assertEquals(1, typeLengths.asRanges().size());
339 Range<Integer> length = typeLengths.span();
340 assertEquals(7, length.lowerEndpoint().intValue());
341 assertEquals(10, length.upperEndpoint().intValue());
343 final StringTypeDefinition baseType1 = type.getBaseType();
344 assertEquals(QName.create(BAR, "string-ext2"), baseType1.getQName());
345 assertNull(baseType1.getUnits());
346 assertNull(baseType1.getDefaultValue());
347 assertTrue(baseType1.getPatternConstraints().isEmpty());
348 final RangeSet<Integer> baseType2Lengths = baseType1.getLengthConstraint().get().getAllowedRanges();
349 assertEquals(1, baseType2Lengths.asRanges().size());
350 length = baseType2Lengths.span();
351 assertEquals(6, length.lowerEndpoint().intValue());
352 assertEquals(10, length.upperEndpoint().intValue());
354 final StringTypeDefinition baseType2 = baseType1.getBaseType();
355 assertEquals(QName.create(BAR, "string-ext1"), baseType2.getQName());
356 assertNull(baseType2.getUnits());
357 assertNull(baseType2.getDefaultValue());
358 final List<PatternConstraint> patterns = baseType2.getPatternConstraints();
359 assertEquals(1, patterns.size());
360 final PatternConstraint pattern = patterns.iterator().next();
361 assertEquals("^[a-k]*$", pattern.getRegularExpression());
362 final RangeSet<Integer> baseType3Lengths = baseType2.getLengthConstraint().get().getAllowedRanges();
363 assertEquals(1, baseType3Lengths.asRanges().size());
364 length = baseType3Lengths.span();
365 assertEquals(5, length.lowerEndpoint().intValue());
366 assertEquals(11, length.upperEndpoint().intValue());
368 assertEquals(BaseTypes.stringType(), baseType2.getBaseType());
372 public void testTypedefDecimal1() {
373 final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "decimal-leaf"));
375 assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
376 final DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
377 assertEquals(QName.create(BAR, "my-decimal-type"), type.getQName());
378 assertNull(type.getUnits());
379 assertNull(type.getDefaultValue());
380 assertEquals(6, type.getFractionDigits().intValue());
381 assertEquals(1, type.getRangeConstraints().size());
383 final DecimalTypeDefinition typeBase = type.getBaseType();
384 assertEquals(QName.create(BAR, "decimal64"), typeBase.getQName());
385 assertNull(typeBase.getUnits());
386 assertNull(typeBase.getDefaultValue());
387 assertEquals(6, typeBase.getFractionDigits().intValue());
388 assertEquals(1, typeBase.getRangeConstraints().size());
390 assertNull(typeBase.getBaseType());
394 public void testTypedefDecimal2() {
395 final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "decimal-leaf2"));
397 assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
398 final DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
399 assertEquals(QName.create(BAR, "my-decimal-type"), type.getQName());
400 assertNull(type.getUnits());
401 assertNull(type.getDefaultValue());
402 assertEquals(6, type.getFractionDigits().intValue());
403 assertEquals(1, type.getRangeConstraints().size());
405 final DecimalTypeDefinition baseTypeDecimal = type.getBaseType();
406 assertEquals(6, baseTypeDecimal.getFractionDigits().intValue());
410 public void testTypedefUnion() {
411 final LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "union-leaf"));
413 assertTrue(unionleaf.getType() instanceof UnionTypeDefinition);
414 final UnionTypeDefinition type = (UnionTypeDefinition) unionleaf.getType();
415 assertEquals(QName.create(BAR, "my-union-ext"), type.getQName());
416 assertNull(type.getUnits());
417 assertNull(type.getDefaultValue());
419 final UnionTypeDefinition baseType = type.getBaseType();
420 assertEquals(QName.create(BAR, "my-union"), baseType.getQName());
421 assertNull(baseType.getUnits());
422 assertNull(baseType.getDefaultValue());
424 final UnionTypeDefinition unionType = baseType.getBaseType();
425 final List<TypeDefinition<?>> unionTypes = unionType.getTypes();
426 assertEquals(2, unionTypes.size());
428 final IntegerTypeDefinition unionType1 = (IntegerTypeDefinition) unionTypes.get(0);
429 assertEquals(QName.create(BAR, "my-union"), baseType.getQName());
430 assertNull(unionType1.getUnits());
431 assertNull(unionType1.getDefaultValue());
433 final List<RangeConstraint> ranges = unionType1.getRangeConstraints();
434 assertEquals(1, ranges.size());
435 final RangeConstraint range = ranges.get(0);
436 assertEquals(1, range.getMin().intValue());
437 assertEquals(100, range.getMax().intValue());
438 assertEquals(BaseTypes.int16Type(), unionType1.getBaseType());
440 assertEquals(BaseTypes.int32Type(), unionTypes.get(1));
444 public void testNestedUnionResolving() {
445 final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "custom-union-leaf"));
447 assertTrue(testleaf.getType() instanceof UnionTypeDefinition);
448 final UnionTypeDefinition type = (UnionTypeDefinition) testleaf.getType();
449 assertEquals(QName.create(BAZ, "union1"), type.getQName());
450 assertNull(type.getUnits());
451 assertNull(type.getDefaultValue());
453 final UnionTypeDefinition typeBase = type.getBaseType();
454 assertEquals(QName.create(BAZ, "union2"), typeBase.getQName());
455 assertNull(typeBase.getUnits());
456 assertNull(typeBase.getDefaultValue());
458 final UnionTypeDefinition union = typeBase.getBaseType();
459 final List<TypeDefinition<?>> unionTypes = union.getTypes();
460 assertEquals(2, unionTypes.size());
461 assertEquals(BaseTypes.int32Type(), unionTypes.get(0));
462 assertTrue(unionTypes.get(1) instanceof UnionTypeDefinition);
464 final UnionTypeDefinition unionType1 = (UnionTypeDefinition) unionTypes.get(1);
465 assertEquals(QName.create(BAR, "nested-union2"), unionType1.getQName());
466 assertNull(unionType1.getUnits());
467 assertNull(unionType1.getDefaultValue());
469 final UnionTypeDefinition nestedUnion = unionType1.getBaseType();
470 final List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
471 assertEquals(2, nestedUnion2Types.size());
472 assertTrue(nestedUnion2Types.get(1) instanceof StringTypeDefinition);
473 assertTrue(nestedUnion2Types.get(0) instanceof UnionTypeDefinition);
475 final UnionTypeDefinition myUnionExt = (UnionTypeDefinition) nestedUnion2Types.get(0);
476 assertEquals(QName.create(BAR, "my-union-ext"), myUnionExt.getQName());
477 assertNull(myUnionExt.getUnits());
478 assertNull(myUnionExt.getDefaultValue());
481 final UnionTypeDefinition myUnion = myUnionExt.getBaseType();
482 assertEquals(QName.create(BAR, "my-union"), myUnion.getQName());
483 assertNull(myUnion.getUnits());
484 assertNull(myUnion.getDefaultValue());
486 final UnionTypeDefinition myUnionBase = myUnion.getBaseType();
487 final List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
488 assertEquals(2, myUnionBaseTypes.size());
489 assertTrue(myUnionBaseTypes.get(0) instanceof IntegerTypeDefinition);
490 assertEquals(BaseTypes.int32Type(), myUnionBaseTypes.get(1));
492 final IntegerTypeDefinition int16Ext = (IntegerTypeDefinition) myUnionBaseTypes.get(0);
493 assertEquals(QName.create(BAR, "int16"), int16Ext.getQName());
494 assertNull(int16Ext.getUnits());
495 assertNull(int16Ext.getDefaultValue());
496 final List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
497 assertEquals(1, ranges.size());
498 final RangeConstraint range = ranges.get(0);
499 assertEquals(1, range.getMin().intValue());
500 assertEquals(100, range.getMax().intValue());
502 assertEquals(BaseTypes.int16Type(), int16Ext.getBaseType());
506 public void testChoice() {
507 final ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "transfer"));
508 final ChoiceSchemaNode how = (ChoiceSchemaNode) transfer.getDataChildByName(QName.create(foo.getQNameModule(), "how"));
509 final Set<ChoiceCaseNode> cases = how.getCases();
510 assertEquals(5, cases.size());
511 ChoiceCaseNode input = null;
512 ChoiceCaseNode output = null;
513 for (final ChoiceCaseNode caseNode : cases) {
514 if ("input".equals(caseNode.getQName().getLocalName())) {
516 } else if ("output".equals(caseNode.getQName().getLocalName())) {
520 assertNotNull(input);
521 assertNotNull(input.getPath());
522 assertNotNull(output);
523 assertNotNull(output.getPath());
527 public void testDeviation() {
528 final Set<Deviation> deviations = foo.getDeviations();
529 assertEquals(1, deviations.size());
530 final Deviation dev = deviations.iterator().next();
531 assertEquals("system/user ref", dev.getReference());
533 final SchemaPath expectedPath = SchemaPath.create(true,
534 QName.create(BAR, "interfaces"),
535 QName.create(BAR, "ifEntry"));
537 assertEquals(expectedPath, dev.getTargetPath());
538 assertEquals(DeviateKind.ADD, dev.getDeviates().iterator().next().getDeviateType());
542 public void testUnknownNode() {
543 final ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName(QName.create(baz.getQNameModule(), "network"));
544 final List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
545 assertEquals(1, unknownNodes.size());
546 final UnknownSchemaNode unknownNode = unknownNodes.get(0);
547 assertNotNull(unknownNode.getNodeType());
548 assertEquals("point", unknownNode.getNodeParameter());
552 public void testFeature() {
553 final Set<FeatureDefinition> features = baz.getFeatures();
554 assertEquals(1, features.size());
558 public void testExtension() {
559 final List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
560 assertEquals(1, extensions.size());
561 final ExtensionDefinition extension = extensions.get(0);
562 assertEquals("name", extension.getArgument());
563 assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.",
564 extension.getDescription());
565 assertTrue(extension.isYinElement());
569 public void testNotification() {
570 final Set<NotificationDefinition> notifications = baz.getNotifications();
571 assertEquals(1, notifications.size());
573 final NotificationDefinition notification = notifications.iterator().next();
574 // test SchemaNode args
575 assertEquals(QName.create(BAZ, "event"), notification.getQName());
576 final SchemaPath expectedPath = SchemaPath.create(true, QName.create(BAZ, "event"));
577 assertEquals(expectedPath, notification.getPath());
578 assertNull(notification.getDescription());
579 assertNull(notification.getReference());
580 assertEquals(Status.CURRENT, notification.getStatus());
581 assertEquals(0, notification.getUnknownSchemaNodes().size());
582 // test DataNodeContainer args
583 assertEquals(0, notification.getTypeDefinitions().size());
584 assertEquals(3, notification.getChildNodes().size());
585 assertEquals(0, notification.getGroupings().size());
586 assertEquals(0, notification.getUses().size());
588 final LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName(QName.create(baz.getQNameModule(), "event-class"));
589 assertTrue(eventClass.getType() instanceof StringTypeDefinition);
590 final LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName(QName.create(baz.getQNameModule(), "severity"));
591 assertTrue(severity.getType() instanceof StringTypeDefinition);
595 public void testRpc() {
596 final Set<RpcDefinition> rpcs = baz.getRpcs();
597 assertEquals(1, rpcs.size());
599 final RpcDefinition rpc = rpcs.iterator().next();
600 assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
601 assertEquals("RFC 6241, Section 7.1", rpc.getReference());
605 public void testTypePath() throws ParseException {
606 final Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
609 final IntegerTypeDefinition int32ext1 = (IntegerTypeDefinition) TestUtils.findTypedef(types, "int32-ext1");
610 final QName int32TypedefQName = QName.create(BAR, "int32-ext1");
611 assertEquals(int32TypedefQName, int32ext1.getQName());
613 final SchemaPath typeSchemaPath = int32ext1.getPath();
614 final Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
615 final Iterator<QName> typePathIt = typePath.iterator();
616 assertEquals(int32TypedefQName, typePathIt.next());
617 assertFalse(typePathIt.hasNext());
620 final IntegerTypeDefinition int32 = int32ext1.getBaseType();
621 assertEquals(BaseTypes.int32Type(), int32);
625 public void testTypePath2() throws ParseException {
626 final Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
629 final DecimalTypeDefinition myDecType = (DecimalTypeDefinition) TestUtils.findTypedef(types, "my-decimal-type");
630 final QName myDecTypeQName = myDecType.getQName();
632 assertEquals(BAR, myDecTypeQName.getModule());
633 assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
635 final SchemaPath typeSchemaPath = myDecType.getPath();
636 final Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
637 final Iterator<QName> typePathIt = typePath.iterator();
638 assertEquals(myDecTypeQName, typePathIt.next());
639 assertFalse(typePathIt.hasNext());
641 // my-base-int32-type/int32
642 final DecimalTypeDefinition dec64 = myDecType.getBaseType();
643 final QName dec64QName = dec64.getQName();
645 assertEquals(BAR, dec64QName.getModule());
646 assertEquals("decimal64", dec64QName.getLocalName());
648 final SchemaPath dec64SchemaPath = dec64.getPath();
649 final Iterable<QName> dec64Path = dec64SchemaPath.getPathFromRoot();
650 final Iterator<QName> dec64PathIt = dec64Path.iterator();
651 assertEquals(myDecTypeQName, dec64PathIt.next());
652 assertEquals(dec64QName, dec64PathIt.next());
653 assertFalse(dec64PathIt.hasNext());
656 private static void checkOrder(final Collection<Module> modules) {
657 final Iterator<Module> it = modules.iterator();
658 Module m = it.next();
659 assertEquals("m2", m.getName());
661 assertEquals("m4", m.getName());
663 assertEquals("m6", m.getName());
665 assertEquals("m8", m.getName());
667 assertEquals("m7", m.getName());
669 assertEquals("m5", m.getName());
671 assertEquals("m3", m.getName());
673 assertEquals("m1", m.getName());
676 private static void assertSetEquals(final Set<Module> s1, final Set<Module> s2) {
677 assertEquals(s1, s2);
678 final Iterator<Module> it = s1.iterator();
679 for (final Module m : s2) {
680 assertEquals(m, it.next());
685 public void testSubmodules() {
686 final DataSchemaNode id = foo.getDataChildByName(QName.create(foo.getQNameModule(), "id"));
688 final DataSchemaNode subExt = foo.getDataChildByName(QName.create(foo.getQNameModule(), "sub-ext"));
689 assertNotNull(subExt);
690 final DataSchemaNode subTransfer = foo.getDataChildByName(QName.create(foo.getQNameModule(), "sub-transfer"));
691 assertNotNull(subTransfer);
693 assertEquals(2, foo.getExtensionSchemaNodes().size());
694 assertEquals(2, foo.getAugmentations().size());
698 public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException, ReactorException {
699 final StatementStreamSource yang1 = sourceForResource("/yang-grammar-test/revisions-extension.yang");
700 final StatementStreamSource yang2 = sourceForResource("/yang-grammar-test/submodule-header-extension.yang");
701 TestUtils.parseYangSources(yang1, yang2);
705 public void unknownStatementBetweenRevisionsTest() throws ReactorException {
707 final StatementStreamSource yangModule = sourceForResource("/yang-grammar-test/revisions-extension.yang");
708 final StatementStreamSource yangSubmodule = sourceForResource(
709 "/yang-grammar-test/submodule-header-extension.yang");
711 final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
712 reactor.addSources(yangModule, yangSubmodule);
714 final SchemaContext result = reactor.buildEffective();
715 assertNotNull(result);
719 public void unknownStatementsInStatementsTest() throws ReactorException {
721 final StatementStreamSource yangFile1 = sourceForResource(
722 "/yang-grammar-test/stmtsep-in-statements.yang");
723 final StatementStreamSource yangFile2 = sourceForResource(
724 "/yang-grammar-test/stmtsep-in-statements2.yang");
725 final StatementStreamSource yangFile3 = sourceForResource(
726 "/yang-grammar-test/stmtsep-in-statements-sub.yang");
728 final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
729 reactor.addSources(yangFile1, yangFile2, yangFile3);
730 // TODO: change test or create new module in order to respect new statement parser validations
732 final SchemaContext result = reactor.buildEffective();
733 } catch (final Exception e) {
734 assertEquals(SomeModifiersUnresolvedException.class, e.getClass());
735 assertTrue(e.getCause() instanceof SourceException);
736 assertTrue(e.getCause().getMessage().startsWith("aaa is not a YANG statement or use of extension"));