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.junit.Assert.fail;
16 import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
19 import java.io.IOException;
21 import java.net.URISyntaxException;
22 import java.text.DateFormat;
23 import java.text.ParseException;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Date;
27 import java.util.Iterator;
28 import java.util.List;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.opendaylight.yangtools.yang.common.QName;
33 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
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.SchemaPath;
53 import org.opendaylight.yangtools.yang.model.api.Status;
54 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
55 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
56 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
57 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
58 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
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;
71 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
72 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
74 public class YangParserTest {
75 public static final String FS = File.separator;
77 private final URI fooNS = URI.create("urn:opendaylight.foo");
78 private final URI barNS = URI.create("urn:opendaylight.bar");
79 private final URI bazNS = URI.create("urn:opendaylight.baz");
84 private Set<Module> modules;
87 public void init() throws Exception {
88 final DateFormat simpleDateFormat = SimpleDateFormatUtil.getRevisionFormat();
89 fooRev = simpleDateFormat.parse("2013-02-27");
90 barRev = simpleDateFormat.parse("2013-07-03");
91 bazRev = simpleDateFormat.parse("2013-02-27");
93 modules = TestUtils.loadModules(getClass().getResource("/model").toURI());
94 assertEquals(3, modules.size());
98 public void testHeaders() throws ParseException {
99 final Module foo = TestUtils.findModule(modules, "foo");
101 assertEquals("foo", foo.getName());
102 assertEquals(YangVersion.VERSION_1.toString(), foo.getYangVersion());
103 assertEquals(fooNS, foo.getNamespace());
104 assertEquals("foo", foo.getPrefix());
106 final Set<ModuleImport> imports = foo.getImports();
107 assertEquals(2, imports.size());
109 final ModuleImport import2 = TestUtils.findImport(imports, "br");
110 assertEquals("bar", import2.getModuleName());
111 assertEquals(barRev, import2.getRevision());
113 final ModuleImport import3 = TestUtils.findImport(imports, "bz");
114 assertEquals("baz", import3.getModuleName());
115 assertEquals(bazRev, import3.getRevision());
117 assertEquals("opendaylight", foo.getOrganization());
118 assertEquals("http://www.opendaylight.org/", foo.getContact());
119 final Date expectedRevision = TestUtils.createDate("2013-02-27");
120 assertEquals(expectedRevision, foo.getRevision());
121 assertNull(foo.getReference());
125 public void testParseList() {
126 final Module bar = TestUtils.findModule(modules, "bar");
127 final URI expectedNamespace = URI.create("urn:opendaylight.bar");
128 final String expectedPrefix = "bar";
130 final ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName(QName.create(
131 bar.getQNameModule(), "interfaces"));
133 final ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName(QName.create(bar.getQNameModule(),
135 // test SchemaNode args
136 final QName expectedQName = QName.create(expectedNamespace, barRev, "ifEntry");
137 assertEquals(expectedQName, ifEntry.getQName());
138 final SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, barRev, expectedPrefix,
139 "interfaces", "ifEntry");
140 assertEquals(expectedPath, ifEntry.getPath());
141 assertNull(ifEntry.getDescription());
142 assertNull(ifEntry.getReference());
143 assertEquals(Status.CURRENT, ifEntry.getStatus());
144 assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
145 // test DataSchemaNode args
146 assertFalse(ifEntry.isAugmenting());
147 assertTrue(ifEntry.isConfiguration());
148 final ConstraintDefinition constraints = ifEntry.getConstraints();
149 // :TODO augment to ifEntry have when condition and so in consequence
150 // ifEntry should be a context node ?
151 // assertNull(constraints.getWhenCondition());
152 assertEquals(0, constraints.getMustConstraints().size());
153 assertTrue(constraints.isMandatory());
154 assertEquals(1, (int) constraints.getMinElements());
155 assertEquals(11, (int) constraints.getMaxElements());
156 // test AugmentationTarget args
157 final Set<AugmentationSchema> availableAugmentations = ifEntry.getAvailableAugmentations();
158 assertEquals(2, availableAugmentations.size());
159 // test ListSchemaNode args
160 final List<QName> expectedKey = new ArrayList<>();
161 expectedKey.add(QName.create(expectedNamespace, barRev, "ifIndex"));
162 assertEquals(expectedKey, ifEntry.getKeyDefinition());
163 assertFalse(ifEntry.isUserOrdered());
164 // test DataNodeContainer args
165 assertEquals(0, ifEntry.getTypeDefinitions().size());
166 assertEquals(4, ifEntry.getChildNodes().size());
167 assertEquals(0, ifEntry.getGroupings().size());
168 assertEquals(0, ifEntry.getUses().size());
170 final LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName(QName.create(bar.getQNameModule(), "ifIndex"));
171 assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
172 assertTrue(ifIndex.getType() instanceof UnsignedIntegerTypeDefinition);
173 assertEquals("minutes", ifIndex.getUnits());
174 final LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName(QName.create(bar.getQNameModule(), "ifMtu"));
175 assertEquals(BaseTypes.int32Type(), ifMtu.getType());
179 public void testTypedefRangesResolving() throws ParseException {
180 final Module foo = TestUtils.findModule(modules, "foo");
181 final LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "int32-leaf"));
183 final IntegerTypeDefinition leafType = (IntegerTypeDefinition) int32Leaf.getType();
184 final QName leafTypeQName = leafType.getQName();
185 assertEquals("int32-ext2", leafTypeQName.getLocalName());
186 assertEquals(fooNS, leafTypeQName.getNamespace());
187 assertEquals(fooRev, leafTypeQName.getRevision());
188 assertEquals("mile", leafType.getUnits());
189 assertEquals("11", leafType.getDefaultValue());
191 final List<RangeConstraint> ranges = leafType.getRangeConstraints();
192 assertEquals(1, ranges.size());
193 final RangeConstraint range = ranges.get(0);
194 assertEquals(12, range.getMin().intValue());
195 assertEquals(20, range.getMax().intValue());
197 final IntegerTypeDefinition baseType = leafType.getBaseType();
198 final QName baseTypeQName = baseType.getQName();
199 assertEquals("int32-ext2", baseTypeQName.getLocalName());
200 assertEquals(barNS, baseTypeQName.getNamespace());
201 assertEquals(barRev, baseTypeQName.getRevision());
202 assertEquals("mile", baseType.getUnits());
203 assertEquals("11", baseType.getDefaultValue());
205 final List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
206 assertEquals(2, baseTypeRanges.size());
207 final RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
208 assertEquals(3, baseTypeRange1.getMin().intValue());
209 assertEquals(9, baseTypeRange1.getMax().intValue());
210 final RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
211 assertEquals(11, baseTypeRange2.getMin().intValue());
212 assertEquals(20, baseTypeRange2.getMax().intValue());
214 final IntegerTypeDefinition base = baseType.getBaseType();
215 final QName baseQName = base.getQName();
216 assertEquals("int32-ext1", baseQName.getLocalName());
217 assertEquals(barNS, baseQName.getNamespace());
218 assertEquals(barRev, baseQName.getRevision());
219 assertNull(base.getUnits());
220 assertNull(base.getDefaultValue());
222 final List<RangeConstraint> baseRanges = base.getRangeConstraints();
223 assertEquals(1, baseRanges.size());
224 final RangeConstraint baseRange = baseRanges.get(0);
225 assertEquals(2, baseRange.getMin().intValue());
226 assertEquals(20, baseRange.getMax().intValue());
228 assertEquals(BaseTypes.int32Type(), base.getBaseType());
232 public void testTypedefPatternsResolving() {
233 final Module foo = TestUtils.findModule(modules, "foo");
234 final LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "string-leaf"));
236 assertTrue(stringleaf.getType() instanceof StringTypeDefinition);
237 final StringTypeDefinition type = (StringTypeDefinition) stringleaf.getType();
238 final QName typeQName = type.getQName();
239 assertEquals("string-ext4", typeQName.getLocalName());
240 assertEquals(barNS, typeQName.getNamespace());
241 assertEquals(barRev, typeQName.getRevision());
242 assertNull(type.getUnits());
243 assertNull(type.getDefaultValue());
244 List<PatternConstraint> patterns = type.getPatternConstraints();
245 assertEquals(1, patterns.size());
246 PatternConstraint pattern = patterns.iterator().next();
247 assertEquals("^(?:[e-z]*)$", pattern.getRegularExpression());
248 assertEquals(1, type.getLengthConstraints().size());
250 final StringTypeDefinition baseType1 = type.getBaseType();
251 final QName baseType1QName = baseType1.getQName();
252 assertEquals("string-ext3", baseType1QName.getLocalName());
253 assertEquals(barNS, baseType1QName.getNamespace());
254 assertEquals(barRev, baseType1QName.getRevision());
255 assertNull(baseType1.getUnits());
256 assertNull(baseType1.getDefaultValue());
257 patterns = baseType1.getPatternConstraints();
258 assertEquals(1, patterns.size());
259 pattern = patterns.iterator().next();
260 assertEquals("^(?:[b-u]*)$", pattern.getRegularExpression());
261 assertEquals(1, baseType1.getLengthConstraints().size());
263 final StringTypeDefinition baseType2 = baseType1.getBaseType();
264 final QName baseType2QName = baseType2.getQName();
265 assertEquals("string-ext2", baseType2QName.getLocalName());
266 assertEquals(barNS, baseType2QName.getNamespace());
267 assertEquals(barRev, baseType2QName.getRevision());
268 assertNull(baseType2.getUnits());
269 assertNull(baseType2.getDefaultValue());
270 assertTrue(baseType2.getPatternConstraints().isEmpty());
271 final List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
272 assertEquals(1, baseType2Lengths.size());
273 LengthConstraint length = baseType2Lengths.get(0);
274 assertEquals(6, length.getMin().intValue());
275 assertEquals(10, length.getMax().intValue());
277 final StringTypeDefinition baseType3 = baseType2.getBaseType();
278 final QName baseType3QName = baseType3.getQName();
279 assertEquals("string-ext1", baseType3QName.getLocalName());
280 assertEquals(barNS, baseType3QName.getNamespace());
281 assertEquals(barRev, baseType3QName.getRevision());
282 assertNull(baseType3.getUnits());
283 assertNull(baseType3.getDefaultValue());
284 patterns = baseType3.getPatternConstraints();
285 assertEquals(1, patterns.size());
286 pattern = patterns.iterator().next();
287 assertEquals("^(?:[a-k]*)$", pattern.getRegularExpression());
288 final List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
289 assertEquals(1, baseType3Lengths.size());
290 length = baseType3Lengths.get(0);
291 assertEquals(5, length.getMin().intValue());
292 assertEquals(11, length.getMax().intValue());
294 assertEquals(BaseTypes.stringType(), baseType3.getBaseType());
298 public void testTypedefInvalidPatternsResolving() {
299 final Module foo = TestUtils.findModule(modules, "foo");
300 final LeafSchemaNode invalidPatternStringLeaf = (LeafSchemaNode) foo
301 .getDataChildByName(QName.create(foo.getQNameModule(), "invalid-pattern-string-leaf"));
302 StringTypeDefinition type = (StringTypeDefinition) invalidPatternStringLeaf.getType();
303 QName typeQName = type.getQName();
304 assertEquals("invalid-string-pattern", typeQName.getLocalName());
305 assertEquals(barNS, typeQName.getNamespace());
306 assertEquals(barRev, typeQName.getRevision());
307 assertNull(type.getUnits());
308 assertNull(type.getDefaultValue());
309 List<PatternConstraint> patterns = type.getPatternConstraints();
310 assertTrue(patterns.isEmpty());
312 final LeafSchemaNode invalidDirectStringPatternDefLeaf = (LeafSchemaNode) foo
313 .getDataChildByName(QName.create(foo.getQNameModule(), "invalid-direct-string-pattern-def-leaf"));
314 type = (StringTypeDefinition) invalidDirectStringPatternDefLeaf.getType();
315 typeQName = type.getQName();
316 assertEquals("string", typeQName.getLocalName());
317 assertEquals(YangConstants.RFC6020_YANG_NAMESPACE, typeQName.getNamespace());
318 assertNull(typeQName.getRevision());
319 assertNull(type.getUnits());
320 assertNull(type.getDefaultValue());
321 patterns = type.getPatternConstraints();
322 assertTrue(patterns.isEmpty());
324 final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) foo
325 .getDataChildByName(QName.create(foo.getQNameModule(), "multiple-pattern-string-leaf"));
326 type = (StringTypeDefinition) multiplePatternStringLeaf.getType();
327 typeQName = type.getQName();
328 assertEquals("multiple-pattern-string", typeQName.getLocalName());
329 assertEquals(barNS, typeQName.getNamespace());
330 assertEquals(barRev, typeQName.getRevision());
331 assertNull(type.getUnits());
332 assertNull(type.getDefaultValue());
333 patterns = type.getPatternConstraints();
334 assertTrue(!patterns.isEmpty());
335 assertEquals(1, patterns.size());
336 final PatternConstraint pattern = patterns.iterator().next();
337 assertEquals("^(?:[e-z]*)$", pattern.getRegularExpression());
338 assertEquals(1, type.getLengthConstraints().size());
340 final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) foo
341 .getDataChildByName(QName.create(foo.getQNameModule(), "multiple-pattern-direct-string-def-leaf"));
342 type = (StringTypeDefinition) multiplePatternDirectStringDefLeaf.getType();
343 typeQName = type.getQName();
344 assertEquals("string", typeQName.getLocalName());
345 assertEquals(fooNS, typeQName.getNamespace());
346 assertEquals(fooRev, typeQName.getRevision());
347 assertNull(type.getUnits());
348 assertNull(type.getDefaultValue());
349 patterns = type.getPatternConstraints();
350 assertTrue(!patterns.isEmpty());
351 assertEquals(2, patterns.size());
353 boolean isEZPattern = false;
354 boolean isADPattern = false;
355 for (final PatternConstraint patternConstraint : patterns) {
356 if (patternConstraint.getRegularExpression().equals("^(?:[e-z]*)$")) {
358 } else if (patternConstraint.getRegularExpression().equals("^(?:[a-d]*)$")) {
362 assertTrue(isEZPattern);
363 assertTrue(isADPattern);
367 public void testTypedefLengthsResolving() {
368 final Module foo = TestUtils.findModule(modules, "foo");
370 final LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "length-leaf"));
371 final StringTypeDefinition type = (StringTypeDefinition) lengthLeaf.getType();
373 final QName typeQName = type.getQName();
374 assertEquals("string-ext2", typeQName.getLocalName());
375 assertEquals(fooNS, typeQName.getNamespace());
376 assertEquals(fooRev, typeQName.getRevision());
377 assertNull(type.getUnits());
378 assertNull(type.getDefaultValue());
379 assertTrue(type.getPatternConstraints().isEmpty());
380 final List<LengthConstraint> typeLengths = type.getLengthConstraints();
381 assertEquals(1, typeLengths.size());
382 LengthConstraint length = typeLengths.get(0);
383 assertEquals(7, length.getMin().intValue());
384 assertEquals(10, length.getMax().intValue());
386 final StringTypeDefinition baseType1 = type.getBaseType();
387 final QName baseType1QName = baseType1.getQName();
388 assertEquals("string-ext2", baseType1QName.getLocalName());
389 assertEquals(barNS, baseType1QName.getNamespace());
390 assertEquals(barRev, baseType1QName.getRevision());
391 assertNull(baseType1.getUnits());
392 assertNull(baseType1.getDefaultValue());
393 assertTrue(baseType1.getPatternConstraints().isEmpty());
394 final List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
395 assertEquals(1, baseType2Lengths.size());
396 length = baseType2Lengths.get(0);
397 assertEquals(6, length.getMin().intValue());
398 assertEquals(10, length.getMax().intValue());
400 final StringTypeDefinition baseType2 = baseType1.getBaseType();
401 final QName baseType2QName = baseType2.getQName();
402 assertEquals("string-ext1", baseType2QName.getLocalName());
403 assertEquals(barNS, baseType2QName.getNamespace());
404 assertEquals(barRev, baseType2QName.getRevision());
405 assertNull(baseType2.getUnits());
406 assertNull(baseType2.getDefaultValue());
407 final List<PatternConstraint> patterns = baseType2.getPatternConstraints();
408 assertEquals(1, patterns.size());
409 final PatternConstraint pattern = patterns.iterator().next();
410 assertEquals("^(?:[a-k]*)$", pattern.getRegularExpression());
411 final List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
412 assertEquals(1, baseType3Lengths.size());
413 length = baseType3Lengths.get(0);
414 assertEquals(5, length.getMin().intValue());
415 assertEquals(11, length.getMax().intValue());
417 assertEquals(BaseTypes.stringType(), baseType2.getBaseType());
421 public void testTypedefDecimal1() {
422 final Module foo = TestUtils.findModule(modules, "foo");
423 final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "decimal-leaf"));
425 assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
426 final DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
427 final QName typeQName = type.getQName();
428 assertEquals("my-decimal-type", typeQName.getLocalName());
429 assertEquals(barNS, typeQName.getNamespace());
430 assertEquals(barRev, typeQName.getRevision());
431 assertNull(type.getUnits());
432 assertNull(type.getDefaultValue());
433 assertEquals(6, type.getFractionDigits().intValue());
434 assertEquals(1, type.getRangeConstraints().size());
436 final DecimalTypeDefinition typeBase = type.getBaseType();
437 final QName typeBaseQName = typeBase.getQName();
438 assertEquals("decimal64", typeBaseQName.getLocalName());
439 assertEquals(barNS, typeBaseQName.getNamespace());
440 assertEquals(barRev, typeBaseQName.getRevision());
441 assertNull(typeBase.getUnits());
442 assertNull(typeBase.getDefaultValue());
443 assertEquals(6, typeBase.getFractionDigits().intValue());
444 assertEquals(1, typeBase.getRangeConstraints().size());
446 assertNull(typeBase.getBaseType());
450 public void testTypedefDecimal2() {
451 final Module foo = TestUtils.findModule(modules, "foo");
452 final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "decimal-leaf2"));
454 assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
455 final DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
456 final QName typeQName = type.getQName();
457 assertEquals("my-decimal-type", typeQName.getLocalName());
458 assertEquals(barNS, typeQName.getNamespace());
459 assertEquals(barRev, typeQName.getRevision());
460 assertNull(type.getUnits());
461 assertNull(type.getDefaultValue());
462 assertEquals(6, type.getFractionDigits().intValue());
463 assertEquals(1, type.getRangeConstraints().size());
465 final DecimalTypeDefinition baseTypeDecimal = type.getBaseType();
466 assertEquals(6, baseTypeDecimal.getFractionDigits().intValue());
470 public void testTypedefUnion() {
471 final Module foo = TestUtils.findModule(modules, "foo");
472 final LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "union-leaf"));
474 assertTrue(unionleaf.getType() instanceof UnionTypeDefinition);
475 final UnionTypeDefinition type = (UnionTypeDefinition) unionleaf.getType();
476 final QName typeQName = type.getQName();
477 assertEquals("my-union-ext", typeQName.getLocalName());
478 assertEquals(barNS, typeQName.getNamespace());
479 assertEquals(barRev, typeQName.getRevision());
480 assertNull(type.getUnits());
481 assertNull(type.getDefaultValue());
483 final UnionTypeDefinition baseType = type.getBaseType();
484 final QName baseTypeQName = baseType.getQName();
485 assertEquals("my-union", baseTypeQName.getLocalName());
486 assertEquals(barNS, baseTypeQName.getNamespace());
487 assertEquals(barRev, baseTypeQName.getRevision());
488 assertNull(baseType.getUnits());
489 assertNull(baseType.getDefaultValue());
491 final UnionTypeDefinition unionType = baseType.getBaseType();
492 final List<TypeDefinition<?>> unionTypes = unionType.getTypes();
493 assertEquals(2, unionTypes.size());
495 final IntegerTypeDefinition unionType1 = (IntegerTypeDefinition) unionTypes.get(0);
496 final QName unionType1QName = baseType.getQName();
497 assertEquals("my-union", unionType1QName.getLocalName());
498 assertEquals(barNS, unionType1QName.getNamespace());
499 assertEquals(barRev, unionType1QName.getRevision());
500 assertNull(unionType1.getUnits());
501 assertNull(unionType1.getDefaultValue());
503 final List<RangeConstraint> ranges = unionType1.getRangeConstraints();
504 assertEquals(1, ranges.size());
505 final RangeConstraint range = ranges.get(0);
506 assertEquals(1, range.getMin().intValue());
507 assertEquals(100, range.getMax().intValue());
508 assertEquals(BaseTypes.int16Type(), unionType1.getBaseType());
510 assertEquals(BaseTypes.int32Type(), unionTypes.get(1));
514 public void testNestedUnionResolving() {
515 final Module foo = TestUtils.findModule(modules, "foo");
516 final LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "custom-union-leaf"));
518 assertTrue(testleaf.getType() instanceof UnionTypeDefinition);
519 final UnionTypeDefinition type = (UnionTypeDefinition) testleaf.getType();
520 final QName testleafTypeQName = type.getQName();
521 assertEquals(bazNS, testleafTypeQName.getNamespace());
522 assertEquals(bazRev, testleafTypeQName.getRevision());
523 assertEquals("union1", testleafTypeQName.getLocalName());
524 assertNull(type.getUnits());
525 assertNull(type.getDefaultValue());
527 final UnionTypeDefinition typeBase = type.getBaseType();
528 final QName typeBaseQName = typeBase.getQName();
529 assertEquals(bazNS, typeBaseQName.getNamespace());
530 assertEquals(bazRev, typeBaseQName.getRevision());
531 assertEquals("union2", typeBaseQName.getLocalName());
532 assertNull(typeBase.getUnits());
533 assertNull(typeBase.getDefaultValue());
535 final UnionTypeDefinition union = typeBase.getBaseType();
536 final List<TypeDefinition<?>> unionTypes = union.getTypes();
537 assertEquals(2, unionTypes.size());
538 assertEquals(BaseTypes.int32Type(), unionTypes.get(0));
539 assertTrue(unionTypes.get(1) instanceof UnionTypeDefinition);
541 final UnionTypeDefinition unionType1 = (UnionTypeDefinition) unionTypes.get(1);
542 final QName uniontType1QName = unionType1.getQName();
543 assertEquals(barNS, uniontType1QName.getNamespace());
544 assertEquals(barRev, uniontType1QName.getRevision());
545 assertEquals("nested-union2", uniontType1QName.getLocalName());
546 assertNull(unionType1.getUnits());
547 assertNull(unionType1.getDefaultValue());
549 final UnionTypeDefinition nestedUnion = unionType1.getBaseType();
550 final List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
551 assertEquals(2, nestedUnion2Types.size());
552 assertTrue(nestedUnion2Types.get(1) instanceof StringTypeDefinition);
553 assertTrue(nestedUnion2Types.get(0) instanceof UnionTypeDefinition);
555 final UnionTypeDefinition myUnionExt = (UnionTypeDefinition) nestedUnion2Types.get(0);
556 final QName myUnionExtQName = myUnionExt.getQName();
557 assertEquals(barNS, myUnionExtQName.getNamespace());
558 assertEquals(barRev, myUnionExtQName.getRevision());
559 assertEquals("my-union-ext", myUnionExtQName.getLocalName());
560 assertNull(myUnionExt.getUnits());
561 assertNull(myUnionExt.getDefaultValue());
564 final UnionTypeDefinition myUnion = myUnionExt.getBaseType();
565 final QName myUnionQName = myUnion.getQName();
566 assertEquals(barNS, myUnionQName.getNamespace());
567 assertEquals(barRev, myUnionQName.getRevision());
568 assertEquals("my-union", myUnionQName.getLocalName());
569 assertNull(myUnion.getUnits());
570 assertNull(myUnion.getDefaultValue());
572 final UnionTypeDefinition myUnionBase = myUnion.getBaseType();
573 final List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
574 assertEquals(2, myUnionBaseTypes.size());
575 assertTrue(myUnionBaseTypes.get(0) instanceof IntegerTypeDefinition);
576 assertEquals(BaseTypes.int32Type(), myUnionBaseTypes.get(1));
578 final IntegerTypeDefinition int16Ext = (IntegerTypeDefinition) myUnionBaseTypes.get(0);
579 final QName int16ExtQName = int16Ext.getQName();
580 assertEquals(barNS, int16ExtQName.getNamespace());
581 assertEquals(barRev, int16ExtQName.getRevision());
582 assertEquals("int16", int16ExtQName.getLocalName());
583 assertNull(int16Ext.getUnits());
584 assertNull(int16Ext.getDefaultValue());
585 final List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
586 assertEquals(1, ranges.size());
587 final RangeConstraint range = ranges.get(0);
588 assertEquals(1, range.getMin().intValue());
589 assertEquals(100, range.getMax().intValue());
591 assertEquals(BaseTypes.int16Type(), int16Ext.getBaseType());
595 public void testChoice() {
596 final Module foo = TestUtils.findModule(modules, "foo");
597 final ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "transfer"));
598 final ChoiceSchemaNode how = (ChoiceSchemaNode) transfer.getDataChildByName(QName.create(foo.getQNameModule(), "how"));
599 final Set<ChoiceCaseNode> cases = how.getCases();
600 assertEquals(5, cases.size());
601 ChoiceCaseNode input = null;
602 ChoiceCaseNode output = null;
603 for (final ChoiceCaseNode caseNode : cases) {
604 if ("input".equals(caseNode.getQName().getLocalName())) {
606 } else if ("output".equals(caseNode.getQName().getLocalName())) {
610 assertNotNull(input);
611 assertNotNull(input.getPath());
612 assertNotNull(output);
613 assertNotNull(output.getPath());
617 public void testDeviation() {
618 final Module foo = TestUtils.findModule(modules, "foo");
619 final Set<Deviation> deviations = foo.getDeviations();
620 assertEquals(1, deviations.size());
621 final Deviation dev = deviations.iterator().next();
622 assertEquals("system/user ref", dev.getReference());
624 final List<QName> path = new ArrayList<>();
625 path.add(QName.create(barNS, barRev, "interfaces"));
626 path.add(QName.create(barNS, barRev, "ifEntry"));
627 final SchemaPath expectedPath = SchemaPath.create(path, true);
629 assertEquals(expectedPath, dev.getTargetPath());
630 assertEquals(DeviateKind.ADD, dev.getDeviates().iterator().next().getDeviateType());
634 public void testUnknownNode() {
635 final Module baz = TestUtils.findModule(modules, "baz");
636 final ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName(QName.create(baz.getQNameModule(), "network"));
637 final List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
638 assertEquals(1, unknownNodes.size());
639 final UnknownSchemaNode unknownNode = unknownNodes.get(0);
640 assertNotNull(unknownNode.getNodeType());
641 assertEquals("point", unknownNode.getNodeParameter());
645 public void testFeature() {
646 final Module baz = TestUtils.findModule(modules, "baz");
647 final Set<FeatureDefinition> features = baz.getFeatures();
648 assertEquals(1, features.size());
652 public void testExtension() {
653 final Module baz = TestUtils.findModule(modules, "baz");
654 final List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
655 assertEquals(1, extensions.size());
656 final ExtensionDefinition extension = extensions.get(0);
657 assertEquals("name", extension.getArgument());
658 assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.",
659 extension.getDescription());
660 assertTrue(extension.isYinElement());
664 public void testNotification() {
665 final Module baz = TestUtils.findModule(modules, "baz");
666 final String expectedPrefix = "c";
668 final Set<NotificationDefinition> notifications = baz.getNotifications();
669 assertEquals(1, notifications.size());
671 final NotificationDefinition notification = notifications.iterator().next();
672 // test SchemaNode args
673 final QName expectedQName = QName.create(bazNS, bazRev, "event");
674 assertEquals(expectedQName, notification.getQName());
675 final SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event");
676 assertEquals(expectedPath, notification.getPath());
677 assertNull(notification.getDescription());
678 assertNull(notification.getReference());
679 assertEquals(Status.CURRENT, notification.getStatus());
680 assertEquals(0, notification.getUnknownSchemaNodes().size());
681 // test DataNodeContainer args
682 assertEquals(0, notification.getTypeDefinitions().size());
683 assertEquals(3, notification.getChildNodes().size());
684 assertEquals(0, notification.getGroupings().size());
685 assertEquals(0, notification.getUses().size());
687 final LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName(QName.create(baz.getQNameModule(), "event-class"));
688 assertTrue(eventClass.getType() instanceof StringTypeDefinition);
689 final LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName(QName.create(baz.getQNameModule(), "severity"));
690 assertTrue(severity.getType() instanceof StringTypeDefinition);
694 public void testRpc() {
695 final Module baz = TestUtils.findModule(modules, "baz");
697 final Set<RpcDefinition> rpcs = baz.getRpcs();
698 assertEquals(1, rpcs.size());
700 final RpcDefinition rpc = rpcs.iterator().next();
701 assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
702 assertEquals("RFC 6241, Section 7.1", rpc.getReference());
706 public void testTypePath() throws ParseException {
707 final Module bar = TestUtils.findModule(modules, "bar");
708 final Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
711 final IntegerTypeDefinition int32ext1 = (IntegerTypeDefinition) TestUtils.findTypedef(types, "int32-ext1");
712 final QName int32TypedefQName = int32ext1.getQName();
714 assertEquals(barNS, int32TypedefQName.getNamespace());
715 assertEquals(barRev, int32TypedefQName.getRevision());
716 assertEquals("int32-ext1", int32TypedefQName.getLocalName());
718 final SchemaPath typeSchemaPath = int32ext1.getPath();
719 final Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
720 final Iterator<QName> typePathIt = typePath.iterator();
721 assertEquals(int32TypedefQName, typePathIt.next());
722 assertFalse(typePathIt.hasNext());
725 final IntegerTypeDefinition int32 = int32ext1.getBaseType();
726 assertEquals(BaseTypes.int32Type(), int32);
730 public void testTypePath2() throws ParseException {
731 final Module bar = TestUtils.findModule(modules, "bar");
732 final Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
735 final DecimalTypeDefinition myDecType = (DecimalTypeDefinition) TestUtils.findTypedef(types, "my-decimal-type");
736 final QName myDecTypeQName = myDecType.getQName();
738 assertEquals(barNS, myDecTypeQName.getNamespace());
739 assertEquals(barRev, myDecTypeQName.getRevision());
740 assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
742 final SchemaPath typeSchemaPath = myDecType.getPath();
743 final Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
744 final Iterator<QName> typePathIt = typePath.iterator();
745 assertEquals(myDecTypeQName, typePathIt.next());
746 assertFalse(typePathIt.hasNext());
748 // my-base-int32-type/int32
749 final DecimalTypeDefinition dec64 = myDecType.getBaseType();
750 final QName dec64QName = dec64.getQName();
752 assertEquals(barNS, dec64QName.getNamespace());
753 assertEquals(barRev, dec64QName.getRevision());
754 assertEquals("decimal64", dec64QName.getLocalName());
756 final SchemaPath dec64SchemaPath = dec64.getPath();
757 final Iterable<QName> dec64Path = dec64SchemaPath.getPathFromRoot();
758 final Iterator<QName> dec64PathIt = dec64Path.iterator();
759 assertEquals(myDecTypeQName, dec64PathIt.next());
760 assertEquals(dec64QName, dec64PathIt.next());
761 assertFalse(dec64PathIt.hasNext());
764 private static void checkOrder(final Collection<Module> modules) {
765 final Iterator<Module> it = modules.iterator();
766 Module m = it.next();
767 assertEquals("m2", m.getName());
769 assertEquals("m4", m.getName());
771 assertEquals("m6", m.getName());
773 assertEquals("m8", m.getName());
775 assertEquals("m7", m.getName());
777 assertEquals("m5", m.getName());
779 assertEquals("m3", m.getName());
781 assertEquals("m1", m.getName());
784 private static void assertSetEquals(final Set<Module> s1, final Set<Module> s2) {
785 assertEquals(s1, s2);
786 final Iterator<Module> it = s1.iterator();
787 for (final Module m : s2) {
788 assertEquals(m, it.next());
793 public void testSubmodules() {
794 final Module foo = TestUtils.findModule(modules, "foo");
796 final DataSchemaNode id = foo.getDataChildByName(QName.create(foo.getQNameModule(), "id"));
798 final DataSchemaNode subExt = foo.getDataChildByName(QName.create(foo.getQNameModule(), "sub-ext"));
799 assertNotNull(subExt);
800 final DataSchemaNode subTransfer = foo.getDataChildByName(QName.create(foo.getQNameModule(), "sub-transfer"));
801 assertNotNull(subTransfer);
803 assertEquals(2, foo.getExtensionSchemaNodes().size());
804 assertEquals(2, foo.getAugmentations().size());
808 public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException, ReactorException {
809 final StatementStreamSource yang1 = sourceForResource("/yang-grammar-test/revisions-extension.yang");
810 final StatementStreamSource yang2 = sourceForResource("/yang-grammar-test/submodule-header-extension.yang");
813 TestUtils.parseYangSources(yang1, yang2);
814 } catch (final YangParseException e) {
816 fail("YangParseException should not be thrown");
822 public void unknownStatementBetweenRevisionsTest() throws ReactorException {
824 final StatementStreamSource yangModule = sourceForResource("/yang-grammar-test/revisions-extension.yang");
825 final StatementStreamSource yangSubmodule = sourceForResource(
826 "/yang-grammar-test/submodule-header-extension.yang");
828 final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
829 reactor.addSources(yangModule, yangSubmodule);
831 final EffectiveSchemaContext result = reactor.buildEffective();
832 assertNotNull(result);
836 public void unknownStatementsInStatementsTest() throws ReactorException {
838 final StatementStreamSource yangFile1 = sourceForResource(
839 "/yang-grammar-test/stmtsep-in-statements.yang");
840 final StatementStreamSource yangFile2 = sourceForResource(
841 "/yang-grammar-test/stmtsep-in-statements2.yang");
842 final StatementStreamSource yangFile3 = sourceForResource(
843 "/yang-grammar-test/stmtsep-in-statements-sub.yang");
845 final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
846 reactor.addSources(yangFile1, yangFile2, yangFile3);
847 // TODO: change test or create new module in order to respect new statement parser validations
849 final EffectiveSchemaContext result = reactor.buildEffective();
850 } catch (final Exception e) {
851 assertEquals(SomeModifiersUnresolvedException.class, e.getClass());
852 assertTrue(e.getCause() instanceof SourceException);
853 assertTrue(e.getCause().getMessage().startsWith("aaa is not a YANG statement or use of extension"));