2 * Copyright (c) 2013 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.retest;
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;
17 import java.io.IOException;
18 import java.math.BigInteger;
20 import java.net.URISyntaxException;
21 import java.text.DateFormat;
22 import java.text.ParseException;
23 import java.text.SimpleDateFormat;
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.model.api.AugmentationSchema;
34 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
35 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
37 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.Deviation;
40 import org.opendaylight.yangtools.yang.model.api.Deviation.Deviate;
41 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
42 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
43 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
44 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
45 import org.opendaylight.yangtools.yang.model.api.Module;
46 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
47 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
48 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
49 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
50 import org.opendaylight.yangtools.yang.model.api.Status;
51 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
52 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
53 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
54 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
55 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
56 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
57 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
58 import org.opendaylight.yangtools.yang.model.util.Decimal64;
59 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
60 import org.opendaylight.yangtools.yang.model.util.Int16;
61 import org.opendaylight.yangtools.yang.model.util.Int32;
62 import org.opendaylight.yangtools.yang.model.util.StringType;
63 import org.opendaylight.yangtools.yang.model.util.Uint32;
64 import org.opendaylight.yangtools.yang.model.util.UnionType;
65 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
66 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
67 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
68 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
69 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
70 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
71 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
73 public class YangParserTest {
74 public static final String FS = File.separator;
76 private final URI fooNS = URI.create("urn:opendaylight.foo");
77 private final URI barNS = URI.create("urn:opendaylight.bar");
78 private final URI bazNS = URI.create("urn:opendaylight.baz");
83 private Set<Module> modules;
86 public void init() throws Exception {
87 DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
88 fooRev = simpleDateFormat.parse("2013-02-27");
89 barRev = simpleDateFormat.parse("2013-07-03");
90 bazRev = simpleDateFormat.parse("2013-02-27");
92 modules = TestUtils.loadModules(getClass().getResource("/model").toURI());
93 assertEquals(3, modules.size());
97 public void testHeaders() throws ParseException {
98 Module foo = TestUtils.findModule(modules, "foo");
100 assertEquals("foo", foo.getName());
101 assertEquals("1", foo.getYangVersion());
102 assertEquals(fooNS, foo.getNamespace());
103 assertEquals("foo", foo.getPrefix());
105 Set<ModuleImport> imports = foo.getImports();
106 assertEquals(2, imports.size());
108 ModuleImport import2 = TestUtils.findImport(imports, "br");
109 assertEquals("bar", import2.getModuleName());
110 assertEquals(barRev, import2.getRevision());
112 ModuleImport import3 = TestUtils.findImport(imports, "bz");
113 assertEquals("baz", import3.getModuleName());
114 assertEquals(bazRev, import3.getRevision());
116 assertEquals("opendaylight", foo.getOrganization());
117 assertEquals("http://www.opendaylight.org/", foo.getContact());
118 Date expectedRevision = TestUtils.createDate("2013-02-27");
119 assertEquals(expectedRevision, foo.getRevision());
120 assertEquals(" WILL BE DEFINED LATER", foo.getReference());
124 public void testParseList() {
125 Module bar = TestUtils.findModule(modules, "bar");
126 URI expectedNamespace = URI.create("urn:opendaylight.bar");
127 String expectedPrefix = "bar";
129 ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName("interfaces");
131 ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
132 // test SchemaNode args
133 QName expectedQName = QName.create(expectedNamespace, barRev, "ifEntry");
134 assertEquals(expectedQName, ifEntry.getQName());
135 SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, barRev, expectedPrefix, "interfaces",
137 assertEquals(expectedPath, ifEntry.getPath());
138 assertNull(ifEntry.getDescription());
139 assertNull(ifEntry.getReference());
140 assertEquals(Status.CURRENT, ifEntry.getStatus());
141 assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
142 // test DataSchemaNode args
143 assertFalse(ifEntry.isAugmenting());
144 assertTrue(ifEntry.isConfiguration());
145 ConstraintDefinition constraints = ifEntry.getConstraints();
146 // :TODO augment to ifEntry have when condition and so in consequence
147 // ifEntry should be a context node ?
148 // assertNull(constraints.getWhenCondition());
149 assertEquals(0, constraints.getMustConstraints().size());
150 assertFalse(constraints.isMandatory());
151 assertEquals(1, (int) constraints.getMinElements());
152 assertEquals(11, (int) constraints.getMaxElements());
153 // test AugmentationTarget args
154 Set<AugmentationSchema> availableAugmentations = ifEntry.getAvailableAugmentations();
155 assertEquals(2, availableAugmentations.size());
156 // test ListSchemaNode args
157 List<QName> expectedKey = new ArrayList<>();
158 expectedKey.add(QName.create(expectedNamespace, barRev, "ifIndex"));
159 assertEquals(expectedKey, ifEntry.getKeyDefinition());
160 assertFalse(ifEntry.isUserOrdered());
161 // test DataNodeContainer args
162 assertEquals(0, ifEntry.getTypeDefinitions().size());
163 assertEquals(4, ifEntry.getChildNodes().size());
164 assertEquals(0, ifEntry.getGroupings().size());
165 assertEquals(0, ifEntry.getUses().size());
167 LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName("ifIndex");
168 assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
169 assertTrue(ifIndex.getType() instanceof Uint32);
170 LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName("ifMtu");
171 assertTrue(ifMtu.getType() instanceof Int32);
175 public void testTypedefRangesResolving() throws ParseException {
176 Module foo = TestUtils.findModule(modules, "foo");
177 LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName("int32-leaf");
179 ExtendedType leafType = (ExtendedType) int32Leaf.getType();
180 QName leafTypeQName = leafType.getQName();
181 assertEquals("int32-ext2", leafTypeQName.getLocalName());
182 assertEquals(fooNS, leafTypeQName.getNamespace());
183 assertEquals(fooRev, leafTypeQName.getRevision());
184 assertNull(leafType.getUnits());
185 assertNull(leafType.getDefaultValue());
186 assertTrue(leafType.getLengthConstraints().isEmpty());
187 assertTrue(leafType.getPatternConstraints().isEmpty());
188 List<RangeConstraint> ranges = leafType.getRangeConstraints();
189 assertEquals(1, ranges.size());
190 RangeConstraint range = ranges.get(0);
191 assertEquals(BigInteger.valueOf(12), range.getMin());
192 assertEquals(BigInteger.valueOf(20), range.getMax());
194 ExtendedType baseType = (ExtendedType) leafType.getBaseType();
195 QName baseTypeQName = baseType.getQName();
196 assertEquals("int32-ext2", baseTypeQName.getLocalName());
197 assertEquals(barNS, baseTypeQName.getNamespace());
198 assertEquals(barRev, baseTypeQName.getRevision());
199 assertEquals("mile", baseType.getUnits());
200 assertEquals("11", baseType.getDefaultValue());
201 assertTrue(leafType.getLengthConstraints().isEmpty());
202 assertTrue(leafType.getPatternConstraints().isEmpty());
203 List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
204 assertEquals(2, baseTypeRanges.size());
205 RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
206 assertEquals(BigInteger.valueOf(3), baseTypeRange1.getMin());
207 assertEquals(BigInteger.valueOf(9), baseTypeRange1.getMax());
208 RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
209 assertEquals(BigInteger.valueOf(11), baseTypeRange2.getMin());
210 assertEquals(BigInteger.valueOf(20), baseTypeRange2.getMax());
212 ExtendedType base = (ExtendedType) baseType.getBaseType();
213 QName baseQName = base.getQName();
214 assertEquals("int32-ext1", baseQName.getLocalName());
215 assertEquals(barNS, baseQName.getNamespace());
216 assertEquals(barRev, baseQName.getRevision());
217 assertNull(base.getUnits());
218 assertNull(base.getDefaultValue());
219 assertTrue(leafType.getLengthConstraints().isEmpty());
220 assertTrue(leafType.getPatternConstraints().isEmpty());
221 List<RangeConstraint> baseRanges = base.getRangeConstraints();
222 assertEquals(1, baseRanges.size());
223 RangeConstraint baseRange = baseRanges.get(0);
224 assertEquals(BigInteger.valueOf(2), baseRange.getMin());
225 assertEquals(BigInteger.valueOf(20), baseRange.getMax());
227 assertTrue(base.getBaseType() instanceof Int32);
231 public void testTypedefPatternsResolving() {
232 Module foo = TestUtils.findModule(modules, "foo");
233 LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName("string-leaf");
235 ExtendedType type = (ExtendedType) stringleaf.getType();
236 QName typeQName = type.getQName();
237 assertEquals("string-ext4", typeQName.getLocalName());
238 assertEquals(barNS, typeQName.getNamespace());
239 assertEquals(barRev, typeQName.getRevision());
240 assertNull(type.getUnits());
241 assertNull(type.getDefaultValue());
242 List<PatternConstraint> patterns = type.getPatternConstraints();
243 assertEquals(1, patterns.size());
244 PatternConstraint pattern = patterns.iterator().next();
245 assertEquals("^[e-z]*$", pattern.getRegularExpression());
246 assertTrue(type.getLengthConstraints().isEmpty());
247 assertTrue(type.getRangeConstraints().isEmpty());
249 ExtendedType baseType1 = (ExtendedType) type.getBaseType();
250 QName baseType1QName = baseType1.getQName();
251 assertEquals("string-ext3", baseType1QName.getLocalName());
252 assertEquals(barNS, baseType1QName.getNamespace());
253 assertEquals(barRev, baseType1QName.getRevision());
254 assertNull(baseType1.getUnits());
255 assertNull(baseType1.getDefaultValue());
256 patterns = baseType1.getPatternConstraints();
257 assertEquals(1, patterns.size());
258 pattern = patterns.iterator().next();
259 assertEquals("^[b-u]*$", pattern.getRegularExpression());
260 assertTrue(baseType1.getLengthConstraints().isEmpty());
261 assertTrue(baseType1.getRangeConstraints().isEmpty());
263 ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
264 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 List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
272 assertEquals(1, baseType2Lengths.size());
273 LengthConstraint length = baseType2Lengths.get(0);
274 assertEquals(BigInteger.valueOf(6), length.getMin());
275 assertEquals(BigInteger.TEN, length.getMax());
276 assertTrue(baseType2.getRangeConstraints().isEmpty());
278 ExtendedType baseType3 = (ExtendedType) baseType2.getBaseType();
279 QName baseType3QName = baseType3.getQName();
280 assertEquals("string-ext1", baseType3QName.getLocalName());
281 assertEquals(barNS, baseType3QName.getNamespace());
282 assertEquals(barRev, baseType3QName.getRevision());
283 assertNull(baseType3.getUnits());
284 assertNull(baseType3.getDefaultValue());
285 patterns = baseType3.getPatternConstraints();
286 assertEquals(1, patterns.size());
287 pattern = patterns.iterator().next();
288 assertEquals("^[a-k]*$", pattern.getRegularExpression());
289 List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
290 assertEquals(1, baseType3Lengths.size());
291 length = baseType3Lengths.get(0);
292 assertEquals(BigInteger.valueOf(5), length.getMin());
293 assertEquals(BigInteger.valueOf(11), length.getMax());
294 assertTrue(baseType3.getRangeConstraints().isEmpty());
296 assertTrue(baseType3.getBaseType() instanceof StringType);
300 public void testTypedefInvalidPatternsResolving() {
301 Module foo = TestUtils.findModule(modules, "foo");
302 final LeafSchemaNode invalidPatternStringLeaf = (LeafSchemaNode) foo
303 .getDataChildByName("invalid-pattern-string-leaf");
304 ExtendedType type = (ExtendedType) invalidPatternStringLeaf.getType();
305 QName typeQName = type.getQName();
306 assertEquals("invalid-string-pattern", typeQName.getLocalName());
307 assertEquals(barNS, typeQName.getNamespace());
308 assertEquals(barRev, typeQName.getRevision());
309 assertNull(type.getUnits());
310 assertNull(type.getDefaultValue());
311 List<PatternConstraint> patterns = type.getPatternConstraints();
312 assertTrue(patterns.isEmpty());
314 final LeafSchemaNode invalidDirectStringPatternDefLeaf = (LeafSchemaNode) foo
315 .getDataChildByName("invalid-direct-string-pattern-def-leaf");
316 type = (ExtendedType) invalidDirectStringPatternDefLeaf.getType();
317 typeQName = type.getQName();
318 assertEquals("string", typeQName.getLocalName());
319 assertEquals(fooNS, typeQName.getNamespace());
320 assertEquals(fooRev, typeQName.getRevision());
321 assertNull(type.getUnits());
322 assertNull(type.getDefaultValue());
323 patterns = type.getPatternConstraints();
324 assertTrue(patterns.isEmpty());
326 final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) foo
327 .getDataChildByName("multiple-pattern-string-leaf");
328 type = (ExtendedType) multiplePatternStringLeaf.getType();
329 typeQName = type.getQName();
330 assertEquals("multiple-pattern-string", typeQName.getLocalName());
331 assertEquals(barNS, typeQName.getNamespace());
332 assertEquals(barRev, typeQName.getRevision());
333 assertNull(type.getUnits());
334 assertNull(type.getDefaultValue());
335 patterns = type.getPatternConstraints();
336 assertTrue(!patterns.isEmpty());
337 assertEquals(1, patterns.size());
338 PatternConstraint pattern = patterns.iterator().next();
339 assertEquals("^[e-z]*$", pattern.getRegularExpression());
340 assertTrue(type.getLengthConstraints().isEmpty());
341 assertTrue(type.getRangeConstraints().isEmpty());
343 final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) foo
344 .getDataChildByName("multiple-pattern-direct-string-def-leaf");
345 type = (ExtendedType) multiplePatternDirectStringDefLeaf.getType();
346 typeQName = type.getQName();
347 assertEquals("string", typeQName.getLocalName());
348 assertEquals(fooNS, typeQName.getNamespace());
349 assertEquals(fooRev, typeQName.getRevision());
350 assertNull(type.getUnits());
351 assertNull(type.getDefaultValue());
352 patterns = type.getPatternConstraints();
353 assertTrue(!patterns.isEmpty());
354 assertEquals(2, patterns.size());
356 boolean isEZPattern = false;
357 boolean isADPattern = false;
358 for (final PatternConstraint patternConstraint : patterns) {
359 if (patternConstraint.getRegularExpression().equals("^[e-z]*$")) {
361 } else if (patternConstraint.getRegularExpression().equals("^[a-d]*$")) {
365 assertTrue(isEZPattern);
366 assertTrue(isADPattern);
370 public void testTypedefLengthsResolving() {
371 Module foo = TestUtils.findModule(modules, "foo");
373 LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName("length-leaf");
374 ExtendedType type = (ExtendedType) lengthLeaf.getType();
376 QName typeQName = type.getQName();
377 assertEquals("string-ext2", typeQName.getLocalName());
378 assertEquals(fooNS, typeQName.getNamespace());
379 assertEquals(fooRev, typeQName.getRevision());
380 assertNull(type.getUnits());
381 assertNull(type.getDefaultValue());
382 assertTrue(type.getPatternConstraints().isEmpty());
383 List<LengthConstraint> typeLengths = type.getLengthConstraints();
384 assertEquals(1, typeLengths.size());
385 LengthConstraint length = typeLengths.get(0);
386 assertEquals(BigInteger.valueOf(7), length.getMin());
387 assertEquals(BigInteger.TEN, length.getMax());
388 assertTrue(type.getRangeConstraints().isEmpty());
390 ExtendedType baseType1 = (ExtendedType) type.getBaseType();
391 QName baseType1QName = baseType1.getQName();
392 assertEquals("string-ext2", baseType1QName.getLocalName());
393 assertEquals(barNS, baseType1QName.getNamespace());
394 assertEquals(barRev, baseType1QName.getRevision());
395 assertNull(baseType1.getUnits());
396 assertNull(baseType1.getDefaultValue());
397 assertTrue(baseType1.getPatternConstraints().isEmpty());
398 List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
399 assertEquals(1, baseType2Lengths.size());
400 length = baseType2Lengths.get(0);
401 assertEquals(BigInteger.valueOf(6), length.getMin());
402 assertEquals(BigInteger.TEN, length.getMax());
403 assertTrue(baseType1.getRangeConstraints().isEmpty());
405 ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
406 QName baseType2QName = baseType2.getQName();
407 assertEquals("string-ext1", baseType2QName.getLocalName());
408 assertEquals(barNS, baseType2QName.getNamespace());
409 assertEquals(barRev, baseType2QName.getRevision());
410 assertNull(baseType2.getUnits());
411 assertNull(baseType2.getDefaultValue());
412 List<PatternConstraint> patterns = baseType2.getPatternConstraints();
413 assertEquals(1, patterns.size());
414 PatternConstraint pattern = patterns.iterator().next();
415 assertEquals("^[a-k]*$", pattern.getRegularExpression());
416 List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
417 assertEquals(1, baseType3Lengths.size());
418 length = baseType3Lengths.get(0);
419 assertEquals(BigInteger.valueOf(5), length.getMin());
420 assertEquals(BigInteger.valueOf(11), length.getMax());
421 assertTrue(baseType2.getRangeConstraints().isEmpty());
423 assertTrue(baseType2.getBaseType() instanceof StringType);
427 public void testTypedefDecimal1() {
428 Module foo = TestUtils.findModule(modules, "foo");
429 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf");
431 ExtendedType type = (ExtendedType) testleaf.getType();
432 QName typeQName = type.getQName();
433 assertEquals("my-decimal-type", typeQName.getLocalName());
434 assertEquals(fooNS, typeQName.getNamespace());
435 assertEquals(fooRev, typeQName.getRevision());
436 assertNull(type.getUnits());
437 assertNull(type.getDefaultValue());
438 assertEquals(4, (int) type.getFractionDigits());
439 assertTrue(type.getLengthConstraints().isEmpty());
440 assertTrue(type.getPatternConstraints().isEmpty());
441 assertTrue(type.getRangeConstraints().isEmpty());
443 ExtendedType typeBase = (ExtendedType) type.getBaseType();
444 QName typeBaseQName = typeBase.getQName();
445 assertEquals("my-decimal-type", typeBaseQName.getLocalName());
446 assertEquals(barNS, typeBaseQName.getNamespace());
447 assertEquals(barRev, typeBaseQName.getRevision());
448 assertNull(typeBase.getUnits());
449 assertNull(typeBase.getDefaultValue());
450 assertNull(typeBase.getFractionDigits());
451 assertTrue(typeBase.getLengthConstraints().isEmpty());
452 assertTrue(typeBase.getPatternConstraints().isEmpty());
453 assertTrue(typeBase.getRangeConstraints().isEmpty());
455 Decimal64 decimal = (Decimal64) typeBase.getBaseType();
456 assertEquals(6, (int) decimal.getFractionDigits());
460 public void testTypedefDecimal2() {
461 Module foo = TestUtils.findModule(modules, "foo");
462 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf2");
464 ExtendedType type = (ExtendedType) testleaf.getType();
465 QName typeQName = type.getQName();
466 assertEquals("my-decimal-type", typeQName.getLocalName());
467 assertEquals(barNS, typeQName.getNamespace());
468 assertEquals(barRev, typeQName.getRevision());
469 assertNull(type.getUnits());
470 assertNull(type.getDefaultValue());
471 assertNull(type.getFractionDigits());
472 assertTrue(type.getLengthConstraints().isEmpty());
473 assertTrue(type.getPatternConstraints().isEmpty());
474 assertTrue(type.getRangeConstraints().isEmpty());
476 Decimal64 baseTypeDecimal = (Decimal64) type.getBaseType();
477 assertEquals(6, (int) baseTypeDecimal.getFractionDigits());
481 public void testTypedefUnion() {
482 Module foo = TestUtils.findModule(modules, "foo");
483 LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName("union-leaf");
485 ExtendedType type = (ExtendedType) unionleaf.getType();
486 QName typeQName = type.getQName();
487 assertEquals("my-union-ext", typeQName.getLocalName());
488 assertEquals(barNS, typeQName.getNamespace());
489 assertEquals(barRev, typeQName.getRevision());
490 assertNull(type.getUnits());
491 assertNull(type.getDefaultValue());
492 assertNull(type.getFractionDigits());
493 assertTrue(type.getLengthConstraints().isEmpty());
494 assertTrue(type.getPatternConstraints().isEmpty());
495 assertTrue(type.getRangeConstraints().isEmpty());
497 ExtendedType baseType = (ExtendedType) type.getBaseType();
498 QName baseTypeQName = baseType.getQName();
499 assertEquals("my-union", baseTypeQName.getLocalName());
500 assertEquals(barNS, baseTypeQName.getNamespace());
501 assertEquals(barRev, baseTypeQName.getRevision());
502 assertNull(baseType.getUnits());
503 assertNull(baseType.getDefaultValue());
504 assertNull(baseType.getFractionDigits());
505 assertTrue(baseType.getLengthConstraints().isEmpty());
506 assertTrue(baseType.getPatternConstraints().isEmpty());
507 assertTrue(baseType.getRangeConstraints().isEmpty());
509 UnionType unionType = (UnionType) baseType.getBaseType();
510 List<TypeDefinition<?>> unionTypes = unionType.getTypes();
511 assertEquals(2, unionTypes.size());
513 ExtendedType unionType1 = (ExtendedType) unionTypes.get(0);
514 QName unionType1QName = baseType.getQName();
515 assertEquals("my-union", unionType1QName.getLocalName());
516 assertEquals(barNS, unionType1QName.getNamespace());
517 assertEquals(barRev, unionType1QName.getRevision());
518 assertNull(unionType1.getUnits());
519 assertNull(unionType1.getDefaultValue());
520 assertNull(unionType1.getFractionDigits());
521 assertTrue(unionType1.getLengthConstraints().isEmpty());
522 assertTrue(unionType1.getPatternConstraints().isEmpty());
523 List<RangeConstraint> ranges = unionType1.getRangeConstraints();
524 assertEquals(1, ranges.size());
525 RangeConstraint range = ranges.get(0);
526 assertEquals(BigInteger.ONE, range.getMin());
527 assertEquals(BigInteger.valueOf(100), range.getMax());
528 assertTrue(unionType1.getBaseType() instanceof Int16);
530 assertTrue(unionTypes.get(1) instanceof Int32);
534 public void testNestedUnionResolving() {
535 Module foo = TestUtils.findModule(modules, "foo");
536 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("custom-union-leaf");
538 ExtendedType type = (ExtendedType) testleaf.getType();
539 QName testleafTypeQName = type.getQName();
540 assertEquals(bazNS, testleafTypeQName.getNamespace());
541 assertEquals(bazRev, testleafTypeQName.getRevision());
542 assertEquals("union1", testleafTypeQName.getLocalName());
543 assertNull(type.getUnits());
544 assertNull(type.getDefaultValue());
545 assertNull(type.getFractionDigits());
546 assertTrue(type.getLengthConstraints().isEmpty());
547 assertTrue(type.getPatternConstraints().isEmpty());
548 assertTrue(type.getRangeConstraints().isEmpty());
550 ExtendedType typeBase = (ExtendedType) type.getBaseType();
551 QName typeBaseQName = typeBase.getQName();
552 assertEquals(bazNS, typeBaseQName.getNamespace());
553 assertEquals(bazRev, typeBaseQName.getRevision());
554 assertEquals("union2", typeBaseQName.getLocalName());
555 assertNull(typeBase.getUnits());
556 assertNull(typeBase.getDefaultValue());
557 assertNull(typeBase.getFractionDigits());
558 assertTrue(typeBase.getLengthConstraints().isEmpty());
559 assertTrue(typeBase.getPatternConstraints().isEmpty());
560 assertTrue(typeBase.getRangeConstraints().isEmpty());
562 UnionType union = (UnionType) typeBase.getBaseType();
563 List<TypeDefinition<?>> unionTypes = union.getTypes();
564 assertEquals(2, unionTypes.size());
565 assertTrue(unionTypes.get(0) instanceof Int32);
566 assertTrue(unionTypes.get(1) instanceof ExtendedType);
568 ExtendedType unionType1 = (ExtendedType) unionTypes.get(1);
569 QName uniontType1QName = unionType1.getQName();
570 assertEquals(barNS, uniontType1QName.getNamespace());
571 assertEquals(barRev, uniontType1QName.getRevision());
572 assertEquals("nested-union2", uniontType1QName.getLocalName());
573 assertNull(unionType1.getUnits());
574 assertNull(unionType1.getDefaultValue());
575 assertNull(unionType1.getFractionDigits());
576 assertTrue(unionType1.getLengthConstraints().isEmpty());
577 assertTrue(unionType1.getPatternConstraints().isEmpty());
578 assertTrue(unionType1.getRangeConstraints().isEmpty());
580 UnionType nestedUnion = (UnionType) unionType1.getBaseType();
581 List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
582 assertEquals(2, nestedUnion2Types.size());
583 assertTrue(nestedUnion2Types.get(0) instanceof StringType);
584 assertTrue(nestedUnion2Types.get(1) instanceof ExtendedType);
586 ExtendedType myUnionExt = (ExtendedType) nestedUnion2Types.get(1);
587 QName myUnionExtQName = myUnionExt.getQName();
588 assertEquals(barNS, myUnionExtQName.getNamespace());
589 assertEquals(barRev, myUnionExtQName.getRevision());
590 assertEquals("my-union-ext", myUnionExtQName.getLocalName());
591 assertNull(myUnionExt.getUnits());
592 assertNull(myUnionExt.getDefaultValue());
593 assertNull(myUnionExt.getFractionDigits());
594 assertTrue(myUnionExt.getLengthConstraints().isEmpty());
595 assertTrue(myUnionExt.getPatternConstraints().isEmpty());
596 assertTrue(myUnionExt.getRangeConstraints().isEmpty());
598 ExtendedType myUnion = (ExtendedType) myUnionExt.getBaseType();
599 QName myUnionQName = myUnion.getQName();
600 assertEquals(barNS, myUnionQName.getNamespace());
601 assertEquals(barRev, myUnionQName.getRevision());
602 assertEquals("my-union", myUnionQName.getLocalName());
603 assertNull(myUnion.getUnits());
604 assertNull(myUnion.getDefaultValue());
605 assertNull(myUnion.getFractionDigits());
606 assertTrue(myUnion.getLengthConstraints().isEmpty());
607 assertTrue(myUnion.getPatternConstraints().isEmpty());
608 assertTrue(myUnion.getRangeConstraints().isEmpty());
610 UnionType myUnionBase = (UnionType) myUnion.getBaseType();
611 List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
612 assertEquals(2, myUnionBaseTypes.size());
613 assertTrue(myUnionBaseTypes.get(0) instanceof ExtendedType);
614 assertTrue(myUnionBaseTypes.get(1) instanceof Int32);
616 ExtendedType int16Ext = (ExtendedType) myUnionBaseTypes.get(0);
617 QName int16ExtQName = int16Ext.getQName();
618 assertEquals(barNS, int16ExtQName.getNamespace());
619 assertEquals(barRev, int16ExtQName.getRevision());
620 assertEquals("int16", int16ExtQName.getLocalName());
621 assertNull(int16Ext.getUnits());
622 assertNull(int16Ext.getDefaultValue());
623 assertNull(int16Ext.getFractionDigits());
624 assertTrue(int16Ext.getLengthConstraints().isEmpty());
625 assertTrue(int16Ext.getPatternConstraints().isEmpty());
626 List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
627 assertEquals(1, ranges.size());
628 RangeConstraint range = ranges.get(0);
629 assertEquals(BigInteger.ONE, range.getMin());
630 assertEquals(BigInteger.valueOf(100), range.getMax());
632 assertTrue(int16Ext.getBaseType() instanceof Int16);
636 public void testChoice() {
637 Module foo = TestUtils.findModule(modules, "foo");
638 ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName("transfer");
639 ChoiceSchemaNode how = (ChoiceSchemaNode) transfer.getDataChildByName("how");
640 Set<ChoiceCaseNode> cases = how.getCases();
641 assertEquals(5, cases.size());
642 ChoiceCaseNode input = null;
643 ChoiceCaseNode output = null;
644 for (ChoiceCaseNode caseNode : cases) {
645 if ("input".equals(caseNode.getQName().getLocalName())) {
647 } else if ("output".equals(caseNode.getQName().getLocalName())) {
651 assertNotNull(input);
652 assertNotNull(input.getPath());
653 assertNotNull(output);
654 assertNotNull(output.getPath());
658 public void testDeviation() {
659 Module foo = TestUtils.findModule(modules, "foo");
660 Set<Deviation> deviations = foo.getDeviations();
661 assertEquals(1, deviations.size());
662 Deviation dev = deviations.iterator().next();
663 assertEquals("system/user ref", dev.getReference());
665 List<QName> path = new ArrayList<>();
666 path.add(QName.create(barNS, barRev, "interfaces"));
667 path.add(QName.create(barNS, barRev, "ifEntry"));
668 SchemaPath expectedPath = SchemaPath.create(path, true);
670 assertEquals(expectedPath, dev.getTargetPath());
671 assertEquals(Deviate.ADD, dev.getDeviate());
675 public void testUnknownNode() {
676 Module baz = TestUtils.findModule(modules, "baz");
677 ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName("network");
678 List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
679 assertEquals(1, unknownNodes.size());
680 UnknownSchemaNode unknownNode = unknownNodes.get(0);
681 assertNotNull(unknownNode.getNodeType());
682 assertEquals("point", unknownNode.getNodeParameter());
686 public void testFeature() {
687 Module baz = TestUtils.findModule(modules, "baz");
688 Set<FeatureDefinition> features = baz.getFeatures();
689 assertEquals(1, features.size());
693 public void testExtension() {
694 Module baz = TestUtils.findModule(modules, "baz");
695 List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
696 assertEquals(1, extensions.size());
697 ExtensionDefinition extension = extensions.get(0);
698 assertEquals("name", extension.getArgument());
699 assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.",
700 extension.getDescription());
701 assertTrue(extension.isYinElement());
705 public void testNotification() {
706 Module baz = TestUtils.findModule(modules, "baz");
707 String expectedPrefix = "c";
709 Set<NotificationDefinition> notifications = baz.getNotifications();
710 assertEquals(1, notifications.size());
712 NotificationDefinition notification = notifications.iterator().next();
713 // test SchemaNode args
714 QName expectedQName = QName.create(bazNS, bazRev, "event");
715 assertEquals(expectedQName, notification.getQName());
716 SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event");
717 assertEquals(expectedPath, notification.getPath());
718 assertNull(notification.getDescription());
719 assertNull(notification.getReference());
720 assertEquals(Status.CURRENT, notification.getStatus());
721 assertEquals(0, notification.getUnknownSchemaNodes().size());
722 // test DataNodeContainer args
723 assertEquals(0, notification.getTypeDefinitions().size());
724 assertEquals(3, notification.getChildNodes().size());
725 assertEquals(0, notification.getGroupings().size());
726 assertEquals(0, notification.getUses().size());
728 LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName("event-class");
729 assertTrue(eventClass.getType() instanceof StringType);
730 LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName("severity");
731 assertTrue(severity.getType() instanceof StringType);
735 public void testRpc() {
736 Module baz = TestUtils.findModule(modules, "baz");
738 Set<RpcDefinition> rpcs = baz.getRpcs();
739 assertEquals(1, rpcs.size());
741 RpcDefinition rpc = rpcs.iterator().next();
742 assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
743 assertEquals("RFC 6241, Section 7.1", rpc.getReference());
747 public void testTypePath() throws ParseException {
748 Module bar = TestUtils.findModule(modules, "bar");
749 Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
752 ExtendedType int32ext1 = (ExtendedType) TestUtils.findTypedef(types, "int32-ext1");
753 QName int32TypedefQName = int32ext1.getQName();
755 assertEquals(barNS, int32TypedefQName.getNamespace());
756 assertEquals(barRev, int32TypedefQName.getRevision());
757 assertEquals("int32-ext1", int32TypedefQName.getLocalName());
759 SchemaPath typeSchemaPath = int32ext1.getPath();
760 Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
761 Iterator<QName> typePathIt = typePath.iterator();
762 assertEquals(int32TypedefQName, typePathIt.next());
763 assertFalse(typePathIt.hasNext());
766 Int32 int32 = (Int32) int32ext1.getBaseType();
767 assertEquals(Int32.getInstance(), int32);
771 public void testTypePath2() throws ParseException {
772 Module bar = TestUtils.findModule(modules, "bar");
773 Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
776 ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types, "my-decimal-type");
777 QName myDecTypeQName = myDecType.getQName();
779 assertEquals(barNS, myDecTypeQName.getNamespace());
780 assertEquals(barRev, myDecTypeQName.getRevision());
781 assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
783 SchemaPath typeSchemaPath = myDecType.getPath();
784 Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
785 Iterator<QName> typePathIt = typePath.iterator();
786 assertEquals(myDecTypeQName, typePathIt.next());
787 assertFalse(typePathIt.hasNext());
789 // my-base-int32-type/int32
790 Decimal64 dec64 = (Decimal64) myDecType.getBaseType();
791 QName dec64QName = dec64.getQName();
793 assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), dec64QName.getNamespace());
794 assertNull(dec64QName.getRevision());
795 assertEquals("decimal64", dec64QName.getLocalName());
797 SchemaPath dec64SchemaPath = dec64.getPath();
798 Iterable<QName> dec64Path = dec64SchemaPath.getPathFromRoot();
799 Iterator<QName> dec64PathIt = dec64Path.iterator();
800 assertEquals(myDecTypeQName, dec64PathIt.next());
801 assertEquals(dec64QName, dec64PathIt.next());
802 assertFalse(dec64PathIt.hasNext());
806 public void testParseMethod1() throws Exception {
807 File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI());
808 File dependenciesDir = new File(getClass().getResource("/parse-methods").toURI());
809 YangContextParser parser = new YangParserImpl();
810 modules = parser.parseFile(yangFile, dependenciesDir).getModules();
811 assertEquals(6, modules.size());
815 public void testParseMethod2() throws Exception {
816 File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI());
817 File dependenciesDir = new File(getClass().getResource("/parse-methods/dependencies").toURI());
818 YangContextParser parser = new YangParserImpl();
819 modules = parser.parseFile(yangFile, dependenciesDir).getModules();
820 assertEquals(6, modules.size());
824 // public void testSorting() throws Exception {
825 // // Correct order: m2, m4, m6, m8, m7, m6, m3, m1
826 // File yangFile = new File(getClass().getResource("/sorting-test/m1.yang").toURI());
827 // File dependenciesDir = new File(getClass().getResource("/sorting-test").toURI());
828 // YangContextParser parser = new YangParserImpl();
829 // modules = parser.parseFile(yangFile, dependenciesDir).getModules();
830 // SchemaContext ctx = new SchemaContextImpl(modules, Collections.<ModuleIdentifier, String> emptyMap());
831 // checkOrder(modules);
832 // assertSetEquals(modules, ctx.getModules());
835 // parser = new YangParserImpl();
836 // final File testDir = dependenciesDir;
837 // final String[] fileList = testDir.list();
838 // final List<File> testFiles = new ArrayList<>();
839 // if (fileList == null) {
840 // throw new FileNotFoundException(dependenciesDir.getAbsolutePath());
842 // for (String fileName : fileList) {
843 // testFiles.add(new File(testDir, fileName));
845 // Set<Module> newModules = parser.parseFiles(testFiles).getModules();
846 // assertSetEquals(newModules, modules);
847 // ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
848 // assertSetEquals(newModules, ctx.getModules());
850 // newModules = parser.parseFiles(testFiles, null).getModules();
851 // assertSetEquals(newModules, modules);
852 // ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
853 // assertSetEquals(newModules, ctx.getModules());
855 // List<InputStream> streams = new ArrayList<>();
856 // for (File f : testFiles) {
857 // streams.add(new FileInputStream(f));
859 // newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles)).getModules();
860 // assertSetEquals(newModules, modules);
861 // ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
862 // assertSetEquals(newModules, ctx.getModules());
865 // for (File f : testFiles) {
866 // streams.add(new FileInputStream(f));
868 // newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles), null).getModules();
869 // assertSetEquals(newModules, modules);
870 // ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
871 // assertSetEquals(newModules, ctx.getModules());
873 // Map<File, Module> mapped = parser.parseYangModelsMapped(testFiles);
874 // newModules = new LinkedHashSet<>(mapped.values());
875 // assertSetEquals(newModules, modules);
876 // ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
877 // assertSetEquals(newModules, ctx.getModules());
880 // for (File f : testFiles) {
881 // streams.add(new FileInputStream(f));
883 // Map<InputStream, Module> mappedStreams = parser.parseYangModelsFromStreamsMapped(streams);
884 // newModules = new LinkedHashSet<>(mappedStreams.values());
885 // assertSetEquals(newModules, modules);
886 // ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
887 // assertSetEquals(newModules, ctx.getModules());
890 private static void checkOrder(final Collection<Module> modules) {
891 Iterator<Module> it = modules.iterator();
892 Module m = it.next();
893 assertEquals("m2", m.getName());
895 assertEquals("m4", m.getName());
897 assertEquals("m6", m.getName());
899 assertEquals("m8", m.getName());
901 assertEquals("m7", m.getName());
903 assertEquals("m5", m.getName());
905 assertEquals("m3", m.getName());
907 assertEquals("m1", m.getName());
910 private static void assertSetEquals(final Set<Module> s1, final Set<Module> s2) {
911 assertEquals(s1, s2);
912 Iterator<Module> it = s1.iterator();
913 for (Module m : s2) {
914 assertEquals(m, it.next());
919 public void testSubmodules() {
920 Module foo = TestUtils.findModule(modules, "foo");
922 DataSchemaNode id = foo.getDataChildByName("id");
924 DataSchemaNode subExt = foo.getDataChildByName("sub-ext");
925 assertNotNull(subExt);
926 DataSchemaNode subTransfer = foo.getDataChildByName("sub-transfer");
927 assertNotNull(subTransfer);
929 assertEquals(2, foo.getExtensionSchemaNodes().size());
930 assertEquals(2, foo.getAugmentations().size());
934 public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException {
936 File yang = new File(getClass().getResource("/yang-grammar-test/submodule-header-extension.yang").toURI());
939 YangParserImpl.getInstance().parseFile(yang, yang.getParentFile());
940 } catch (YangSyntaxErrorException | YangParseException e) {
942 fail("YangSyntaxErrorException or YangParseException should not be thrown");
948 public void unknownStatementBetweenRevisionsTest() throws ReactorException {
950 final YangStatementSourceImpl yangModule = new YangStatementSourceImpl(
951 "/yang-grammar-test/revisions-extension.yang", false);
952 final YangStatementSourceImpl yangSubmodule = new YangStatementSourceImpl(
953 "/yang-grammar-test/submodule-header-extension.yang", false);
955 CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
956 addSources(reactor, yangModule, yangSubmodule);
958 final EffectiveSchemaContext result = reactor.buildEffective();
959 assertNotNull(result);
963 public void unknownStatementsInStatementsTest() throws ReactorException {
965 final YangStatementSourceImpl yangFile1 = new YangStatementSourceImpl(
966 "/yang-grammar-test/stmtsep-in-statements.yang", false);
967 final YangStatementSourceImpl yangFile2 = new YangStatementSourceImpl(
968 "/yang-grammar-test/stmtsep-in-statements2.yang", false);
969 final YangStatementSourceImpl yangFile3 = new YangStatementSourceImpl(
970 "/yang-grammar-test/stmtsep-in-statements-sub.yang", false);
972 CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
973 addSources(reactor, yangFile1, yangFile2, yangFile3);
974 // TODO: change test or create new module in order to respect new statement parser validations
976 final EffectiveSchemaContext result = reactor.buildEffective();
977 } catch (Exception e) {
978 assertEquals(IllegalArgumentException.class, e.getClass());
979 assertTrue(e.getMessage().startsWith("aaa is not a YANG statement or use of extension"));
983 private static void addSources(final CrossSourceStatementReactor.BuildAction reactor, final YangStatementSourceImpl... sources) {
984 for (YangStatementSourceImpl source : sources) {
985 reactor.addSource(source);