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.parser.impl;
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;
18 import java.io.FileInputStream;
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.math.BigInteger;
24 import java.net.URISyntaxException;
25 import java.text.DateFormat;
26 import java.text.ParseException;
27 import java.text.SimpleDateFormat;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.Date;
32 import java.util.Iterator;
33 import java.util.LinkedHashSet;
34 import java.util.List;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.opendaylight.yangtools.yang.common.QName;
41 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
42 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
43 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
44 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
45 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
46 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
47 import org.opendaylight.yangtools.yang.model.api.Deviation;
48 import org.opendaylight.yangtools.yang.model.api.Deviation.Deviate;
49 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
50 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
51 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
52 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
53 import org.opendaylight.yangtools.yang.model.api.Module;
54 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
55 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
56 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
57 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
58 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
59 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
60 import org.opendaylight.yangtools.yang.model.api.Status;
61 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
62 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
63 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
64 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
65 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
66 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
67 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
68 import org.opendaylight.yangtools.yang.model.util.Decimal64;
69 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
70 import org.opendaylight.yangtools.yang.model.util.Int16;
71 import org.opendaylight.yangtools.yang.model.util.Int32;
72 import org.opendaylight.yangtools.yang.model.util.StringType;
73 import org.opendaylight.yangtools.yang.model.util.Uint32;
74 import org.opendaylight.yangtools.yang.model.util.UnionType;
75 import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
76 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
78 public class YangParserTest {
79 public static final String FS = File.separator;
81 private final URI fooNS = URI.create("urn:opendaylight.foo");
82 private final URI barNS = URI.create("urn:opendaylight.bar");
83 private final URI bazNS = URI.create("urn:opendaylight.baz");
88 private Set<Module> modules;
91 public void init() throws Exception {
92 DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
93 fooRev = simpleDateFormat.parse("2013-02-27");
94 barRev = simpleDateFormat.parse("2013-07-03");
95 bazRev = simpleDateFormat.parse("2013-02-27");
97 modules = TestUtils.loadModules(getClass().getResource("/model").toURI());
98 assertEquals(3, modules.size());
102 public void testHeaders() throws ParseException {
103 Module foo = TestUtils.findModule(modules, "foo");
105 assertEquals("foo", foo.getName());
106 assertEquals("1", foo.getYangVersion());
107 assertEquals(fooNS, foo.getNamespace());
108 assertEquals("foo", foo.getPrefix());
110 Set<ModuleImport> imports = foo.getImports();
111 assertEquals(2, imports.size());
113 ModuleImport import2 = TestUtils.findImport(imports, "br");
114 assertEquals("bar", import2.getModuleName());
115 assertEquals(barRev, import2.getRevision());
117 ModuleImport import3 = TestUtils.findImport(imports, "bz");
118 assertEquals("baz", import3.getModuleName());
119 assertEquals(bazRev, import3.getRevision());
121 assertEquals("opendaylight", foo.getOrganization());
122 assertEquals("http://www.opendaylight.org/", foo.getContact());
123 Date expectedRevision = TestUtils.createDate("2013-02-27");
124 assertEquals(expectedRevision, foo.getRevision());
125 assertEquals(" WILL BE DEFINED LATER", foo.getReference());
129 public void testParseList() {
130 Module bar = TestUtils.findModule(modules, "bar");
131 URI expectedNamespace = URI.create("urn:opendaylight.bar");
132 String expectedPrefix = "bar";
134 ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName("interfaces");
136 ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
137 // test SchemaNode args
138 QName expectedQName = QName.create(expectedNamespace, barRev, "ifEntry");
139 assertEquals(expectedQName, ifEntry.getQName());
140 SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, barRev, expectedPrefix, "interfaces",
142 assertEquals(expectedPath, ifEntry.getPath());
143 assertNull(ifEntry.getDescription());
144 assertNull(ifEntry.getReference());
145 assertEquals(Status.CURRENT, ifEntry.getStatus());
146 assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
147 // test DataSchemaNode args
148 assertFalse(ifEntry.isAugmenting());
149 assertTrue(ifEntry.isConfiguration());
150 ConstraintDefinition constraints = ifEntry.getConstraints();
151 assertNull(constraints.getWhenCondition());
152 assertEquals(0, constraints.getMustConstraints().size());
153 assertFalse(constraints.isMandatory());
154 assertEquals(1, (int) constraints.getMinElements());
155 assertEquals(11, (int) constraints.getMaxElements());
156 // test AugmentationTarget args
157 Set<AugmentationSchema> availableAugmentations = ifEntry.getAvailableAugmentations();
158 assertEquals(2, availableAugmentations.size());
159 // test ListSchemaNode args
160 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 LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName("ifIndex");
171 assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
172 assertTrue(ifIndex.getType() instanceof Uint32);
173 LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName("ifMtu");
174 assertTrue(ifMtu.getType() instanceof Int32);
178 public void testTypedefRangesResolving() throws ParseException {
179 Module foo = TestUtils.findModule(modules, "foo");
180 LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName("int32-leaf");
182 ExtendedType leafType = (ExtendedType) int32Leaf.getType();
183 QName leafTypeQName = leafType.getQName();
184 assertEquals("int32-ext2", leafTypeQName.getLocalName());
185 assertEquals(fooNS, leafTypeQName.getNamespace());
186 assertEquals(fooRev, leafTypeQName.getRevision());
187 assertNull(leafType.getUnits());
188 assertNull(leafType.getDefaultValue());
189 assertTrue(leafType.getLengthConstraints().isEmpty());
190 assertTrue(leafType.getPatternConstraints().isEmpty());
191 List<RangeConstraint> ranges = leafType.getRangeConstraints();
192 assertEquals(1, ranges.size());
193 RangeConstraint range = ranges.get(0);
194 assertEquals(BigInteger.valueOf(12), range.getMin());
195 assertEquals(BigInteger.valueOf(20), range.getMax());
197 ExtendedType baseType = (ExtendedType) leafType.getBaseType();
198 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());
204 assertTrue(leafType.getLengthConstraints().isEmpty());
205 assertTrue(leafType.getPatternConstraints().isEmpty());
206 List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
207 assertEquals(2, baseTypeRanges.size());
208 RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
209 assertEquals(BigInteger.valueOf(3), baseTypeRange1.getMin());
210 assertEquals(BigInteger.valueOf(9), baseTypeRange1.getMax());
211 RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
212 assertEquals(BigInteger.valueOf(11), baseTypeRange2.getMin());
213 assertEquals(BigInteger.valueOf(20), baseTypeRange2.getMax());
215 ExtendedType base = (ExtendedType) baseType.getBaseType();
216 QName baseQName = base.getQName();
217 assertEquals("int32-ext1", baseQName.getLocalName());
218 assertEquals(barNS, baseQName.getNamespace());
219 assertEquals(barRev, baseQName.getRevision());
220 assertNull(base.getUnits());
221 assertNull(base.getDefaultValue());
222 assertTrue(leafType.getLengthConstraints().isEmpty());
223 assertTrue(leafType.getPatternConstraints().isEmpty());
224 List<RangeConstraint> baseRanges = base.getRangeConstraints();
225 assertEquals(1, baseRanges.size());
226 RangeConstraint baseRange = baseRanges.get(0);
227 assertEquals(BigInteger.valueOf(2), baseRange.getMin());
228 assertEquals(BigInteger.valueOf(20), baseRange.getMax());
230 assertTrue(base.getBaseType() instanceof Int32);
234 public void testTypedefPatternsResolving() {
235 Module foo = TestUtils.findModule(modules, "foo");
236 LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName("string-leaf");
238 ExtendedType type = (ExtendedType) stringleaf.getType();
239 QName typeQName = type.getQName();
240 assertEquals("string-ext4", typeQName.getLocalName());
241 assertEquals(barNS, typeQName.getNamespace());
242 assertEquals(barRev, typeQName.getRevision());
243 assertNull(type.getUnits());
244 assertNull(type.getDefaultValue());
245 List<PatternConstraint> patterns = type.getPatternConstraints();
246 assertEquals(1, patterns.size());
247 PatternConstraint pattern = patterns.iterator().next();
248 assertEquals("^[e-z]*$", pattern.getRegularExpression());
249 assertTrue(type.getLengthConstraints().isEmpty());
250 assertTrue(type.getRangeConstraints().isEmpty());
252 ExtendedType baseType1 = (ExtendedType) type.getBaseType();
253 QName baseType1QName = baseType1.getQName();
254 assertEquals("string-ext3", baseType1QName.getLocalName());
255 assertEquals(barNS, baseType1QName.getNamespace());
256 assertEquals(barRev, baseType1QName.getRevision());
257 assertNull(baseType1.getUnits());
258 assertNull(baseType1.getDefaultValue());
259 patterns = baseType1.getPatternConstraints();
260 assertEquals(1, patterns.size());
261 pattern = patterns.iterator().next();
262 assertEquals("^[b-u]*$", pattern.getRegularExpression());
263 assertTrue(baseType1.getLengthConstraints().isEmpty());
264 assertTrue(baseType1.getRangeConstraints().isEmpty());
266 ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
267 QName baseType2QName = baseType2.getQName();
268 assertEquals("string-ext2", baseType2QName.getLocalName());
269 assertEquals(barNS, baseType2QName.getNamespace());
270 assertEquals(barRev, baseType2QName.getRevision());
271 assertNull(baseType2.getUnits());
272 assertNull(baseType2.getDefaultValue());
273 assertTrue(baseType2.getPatternConstraints().isEmpty());
274 List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
275 assertEquals(1, baseType2Lengths.size());
276 LengthConstraint length = baseType2Lengths.get(0);
277 assertEquals(BigInteger.valueOf(6), length.getMin());
278 assertEquals(BigInteger.TEN, length.getMax());
279 assertTrue(baseType2.getRangeConstraints().isEmpty());
281 ExtendedType baseType3 = (ExtendedType) baseType2.getBaseType();
282 QName baseType3QName = baseType3.getQName();
283 assertEquals("string-ext1", baseType3QName.getLocalName());
284 assertEquals(barNS, baseType3QName.getNamespace());
285 assertEquals(barRev, baseType3QName.getRevision());
286 assertNull(baseType3.getUnits());
287 assertNull(baseType3.getDefaultValue());
288 patterns = baseType3.getPatternConstraints();
289 assertEquals(1, patterns.size());
290 pattern = patterns.iterator().next();
291 assertEquals("^[a-k]*$", pattern.getRegularExpression());
292 List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
293 assertEquals(1, baseType3Lengths.size());
294 length = baseType3Lengths.get(0);
295 assertEquals(BigInteger.valueOf(5), length.getMin());
296 assertEquals(BigInteger.valueOf(11), length.getMax());
297 assertTrue(baseType3.getRangeConstraints().isEmpty());
299 assertTrue(baseType3.getBaseType() instanceof StringType);
303 public void testTypedefInvalidPatternsResolving() {
304 Module foo = TestUtils.findModule(modules, "foo");
305 final LeafSchemaNode invalidPatternStringLeaf = (LeafSchemaNode) foo.getDataChildByName("invalid-pattern-string-leaf");
306 ExtendedType type = (ExtendedType) invalidPatternStringLeaf.getType();
307 QName typeQName = type.getQName();
308 assertEquals("invalid-string-pattern", typeQName.getLocalName());
309 assertEquals(barNS, typeQName.getNamespace());
310 assertEquals(barRev, typeQName.getRevision());
311 assertNull(type.getUnits());
312 assertNull(type.getDefaultValue());
313 List<PatternConstraint> patterns = type.getPatternConstraints();
314 assertTrue(patterns.isEmpty());
316 final LeafSchemaNode invalidDirectStringPatternDefLeaf = (LeafSchemaNode) foo.getDataChildByName("invalid-direct-string-pattern-def-leaf");
317 type = (ExtendedType) invalidDirectStringPatternDefLeaf.getType();
318 typeQName = type.getQName();
319 assertEquals("string", typeQName.getLocalName());
320 assertEquals(fooNS, typeQName.getNamespace());
321 assertEquals(fooRev, typeQName.getRevision());
322 assertNull(type.getUnits());
323 assertNull(type.getDefaultValue());
324 patterns = type.getPatternConstraints();
325 assertTrue(patterns.isEmpty());
327 final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) foo.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.getDataChildByName("multiple-pattern-direct-string-def-leaf");
344 type = (ExtendedType) multiplePatternDirectStringDefLeaf.getType();
345 typeQName = type.getQName();
346 assertEquals("string", typeQName.getLocalName());
347 assertEquals(fooNS, typeQName.getNamespace());
348 assertEquals(fooRev, typeQName.getRevision());
349 assertNull(type.getUnits());
350 assertNull(type.getDefaultValue());
351 patterns = type.getPatternConstraints();
352 assertTrue(!patterns.isEmpty());
353 assertEquals(2, patterns.size());
355 boolean isEZPattern = false;
356 boolean isADPattern = false;
357 for (final PatternConstraint patternConstraint : patterns) {
358 if (patternConstraint.getRegularExpression().equals("^[e-z]*$")) {
360 } else if (patternConstraint.getRegularExpression().equals("^[a-d]*$")) {
364 assertTrue(isEZPattern);
365 assertTrue( isADPattern);
369 public void testTypedefLengthsResolving() {
370 Module foo = TestUtils.findModule(modules, "foo");
372 LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName("length-leaf");
373 ExtendedType type = (ExtendedType) lengthLeaf.getType();
375 QName typeQName = type.getQName();
376 assertEquals("string-ext2", typeQName.getLocalName());
377 assertEquals(fooNS, typeQName.getNamespace());
378 assertEquals(fooRev, typeQName.getRevision());
379 assertNull(type.getUnits());
380 assertNull(type.getDefaultValue());
381 assertTrue(type.getPatternConstraints().isEmpty());
382 List<LengthConstraint> typeLengths = type.getLengthConstraints();
383 assertEquals(1, typeLengths.size());
384 LengthConstraint length = typeLengths.get(0);
385 assertEquals(BigInteger.valueOf(7), length.getMin());
386 assertEquals(BigInteger.TEN, length.getMax());
387 assertTrue(type.getRangeConstraints().isEmpty());
389 ExtendedType baseType1 = (ExtendedType) type.getBaseType();
390 QName baseType1QName = baseType1.getQName();
391 assertEquals("string-ext2", baseType1QName.getLocalName());
392 assertEquals(barNS, baseType1QName.getNamespace());
393 assertEquals(barRev, baseType1QName.getRevision());
394 assertNull(baseType1.getUnits());
395 assertNull(baseType1.getDefaultValue());
396 assertTrue(baseType1.getPatternConstraints().isEmpty());
397 List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
398 assertEquals(1, baseType2Lengths.size());
399 length = baseType2Lengths.get(0);
400 assertEquals(BigInteger.valueOf(6), length.getMin());
401 assertEquals(BigInteger.TEN, length.getMax());
402 assertTrue(baseType1.getRangeConstraints().isEmpty());
404 ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
405 QName baseType2QName = baseType2.getQName();
406 assertEquals("string-ext1", baseType2QName.getLocalName());
407 assertEquals(barNS, baseType2QName.getNamespace());
408 assertEquals(barRev, baseType2QName.getRevision());
409 assertNull(baseType2.getUnits());
410 assertNull(baseType2.getDefaultValue());
411 List<PatternConstraint> patterns = baseType2.getPatternConstraints();
412 assertEquals(1, patterns.size());
413 PatternConstraint pattern = patterns.iterator().next();
414 assertEquals("^[a-k]*$", pattern.getRegularExpression());
415 List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
416 assertEquals(1, baseType3Lengths.size());
417 length = baseType3Lengths.get(0);
418 assertEquals(BigInteger.valueOf(5), length.getMin());
419 assertEquals(BigInteger.valueOf(11), length.getMax());
420 assertTrue(baseType2.getRangeConstraints().isEmpty());
422 assertTrue(baseType2.getBaseType() instanceof StringType);
426 public void testTypedefDecimal1() {
427 Module foo = TestUtils.findModule(modules, "foo");
428 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf");
430 ExtendedType type = (ExtendedType) testleaf.getType();
431 QName typeQName = type.getQName();
432 assertEquals("my-decimal-type", typeQName.getLocalName());
433 assertEquals(fooNS, typeQName.getNamespace());
434 assertEquals(fooRev, typeQName.getRevision());
435 assertNull(type.getUnits());
436 assertNull(type.getDefaultValue());
437 assertEquals(4, (int) type.getFractionDigits());
438 assertTrue(type.getLengthConstraints().isEmpty());
439 assertTrue(type.getPatternConstraints().isEmpty());
440 assertTrue(type.getRangeConstraints().isEmpty());
442 ExtendedType typeBase = (ExtendedType) type.getBaseType();
443 QName typeBaseQName = typeBase.getQName();
444 assertEquals("my-decimal-type", typeBaseQName.getLocalName());
445 assertEquals(barNS, typeBaseQName.getNamespace());
446 assertEquals(barRev, typeBaseQName.getRevision());
447 assertNull(typeBase.getUnits());
448 assertNull(typeBase.getDefaultValue());
449 assertNull(typeBase.getFractionDigits());
450 assertTrue(typeBase.getLengthConstraints().isEmpty());
451 assertTrue(typeBase.getPatternConstraints().isEmpty());
452 assertTrue(typeBase.getRangeConstraints().isEmpty());
454 Decimal64 decimal = (Decimal64) typeBase.getBaseType();
455 assertEquals(6, (int) decimal.getFractionDigits());
459 public void testTypedefDecimal2() {
460 Module foo = TestUtils.findModule(modules, "foo");
461 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf2");
463 ExtendedType type = (ExtendedType) testleaf.getType();
464 QName typeQName = type.getQName();
465 assertEquals("my-decimal-type", typeQName.getLocalName());
466 assertEquals(barNS, typeQName.getNamespace());
467 assertEquals(barRev, typeQName.getRevision());
468 assertNull(type.getUnits());
469 assertNull(type.getDefaultValue());
470 assertNull(type.getFractionDigits());
471 assertTrue(type.getLengthConstraints().isEmpty());
472 assertTrue(type.getPatternConstraints().isEmpty());
473 assertTrue(type.getRangeConstraints().isEmpty());
475 Decimal64 baseTypeDecimal = (Decimal64) type.getBaseType();
476 assertEquals(6, (int) baseTypeDecimal.getFractionDigits());
480 public void testTypedefUnion() {
481 Module foo = TestUtils.findModule(modules, "foo");
482 LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName("union-leaf");
484 ExtendedType type = (ExtendedType) unionleaf.getType();
485 QName typeQName = type.getQName();
486 assertEquals("my-union-ext", typeQName.getLocalName());
487 assertEquals(barNS, typeQName.getNamespace());
488 assertEquals(barRev, typeQName.getRevision());
489 assertNull(type.getUnits());
490 assertNull(type.getDefaultValue());
491 assertNull(type.getFractionDigits());
492 assertTrue(type.getLengthConstraints().isEmpty());
493 assertTrue(type.getPatternConstraints().isEmpty());
494 assertTrue(type.getRangeConstraints().isEmpty());
496 ExtendedType baseType = (ExtendedType) type.getBaseType();
497 QName baseTypeQName = baseType.getQName();
498 assertEquals("my-union", baseTypeQName.getLocalName());
499 assertEquals(barNS, baseTypeQName.getNamespace());
500 assertEquals(barRev, baseTypeQName.getRevision());
501 assertNull(baseType.getUnits());
502 assertNull(baseType.getDefaultValue());
503 assertNull(baseType.getFractionDigits());
504 assertTrue(baseType.getLengthConstraints().isEmpty());
505 assertTrue(baseType.getPatternConstraints().isEmpty());
506 assertTrue(baseType.getRangeConstraints().isEmpty());
508 UnionType unionType = (UnionType) baseType.getBaseType();
509 List<TypeDefinition<?>> unionTypes = unionType.getTypes();
510 assertEquals(2, unionTypes.size());
512 ExtendedType unionType1 = (ExtendedType) unionTypes.get(0);
513 QName unionType1QName = baseType.getQName();
514 assertEquals("my-union", unionType1QName.getLocalName());
515 assertEquals(barNS, unionType1QName.getNamespace());
516 assertEquals(barRev, unionType1QName.getRevision());
517 assertNull(unionType1.getUnits());
518 assertNull(unionType1.getDefaultValue());
519 assertNull(unionType1.getFractionDigits());
520 assertTrue(unionType1.getLengthConstraints().isEmpty());
521 assertTrue(unionType1.getPatternConstraints().isEmpty());
522 List<RangeConstraint> ranges = unionType1.getRangeConstraints();
523 assertEquals(1, ranges.size());
524 RangeConstraint range = ranges.get(0);
525 assertEquals(BigInteger.ONE, range.getMin());
526 assertEquals(BigInteger.valueOf(100), range.getMax());
527 assertTrue(unionType1.getBaseType() instanceof Int16);
529 assertTrue(unionTypes.get(1) instanceof Int32);
533 public void testNestedUnionResolving() {
534 Module foo = TestUtils.findModule(modules, "foo");
535 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("custom-union-leaf");
537 ExtendedType type = (ExtendedType) testleaf.getType();
538 QName testleafTypeQName = type.getQName();
539 assertEquals(bazNS, testleafTypeQName.getNamespace());
540 assertEquals(bazRev, testleafTypeQName.getRevision());
541 assertEquals("union1", testleafTypeQName.getLocalName());
542 assertNull(type.getUnits());
543 assertNull(type.getDefaultValue());
544 assertNull(type.getFractionDigits());
545 assertTrue(type.getLengthConstraints().isEmpty());
546 assertTrue(type.getPatternConstraints().isEmpty());
547 assertTrue(type.getRangeConstraints().isEmpty());
549 ExtendedType typeBase = (ExtendedType) type.getBaseType();
550 QName typeBaseQName = typeBase.getQName();
551 assertEquals(bazNS, typeBaseQName.getNamespace());
552 assertEquals(bazRev, typeBaseQName.getRevision());
553 assertEquals("union2", typeBaseQName.getLocalName());
554 assertNull(typeBase.getUnits());
555 assertNull(typeBase.getDefaultValue());
556 assertNull(typeBase.getFractionDigits());
557 assertTrue(typeBase.getLengthConstraints().isEmpty());
558 assertTrue(typeBase.getPatternConstraints().isEmpty());
559 assertTrue(typeBase.getRangeConstraints().isEmpty());
561 UnionType union = (UnionType) typeBase.getBaseType();
562 List<TypeDefinition<?>> unionTypes = union.getTypes();
563 assertEquals(2, unionTypes.size());
564 assertTrue(unionTypes.get(0) instanceof Int32);
565 assertTrue(unionTypes.get(1) instanceof ExtendedType);
567 ExtendedType unionType1 = (ExtendedType) unionTypes.get(1);
568 QName uniontType1QName = unionType1.getQName();
569 assertEquals(barNS, uniontType1QName.getNamespace());
570 assertEquals(barRev, uniontType1QName.getRevision());
571 assertEquals("nested-union2", uniontType1QName.getLocalName());
572 assertNull(unionType1.getUnits());
573 assertNull(unionType1.getDefaultValue());
574 assertNull(unionType1.getFractionDigits());
575 assertTrue(unionType1.getLengthConstraints().isEmpty());
576 assertTrue(unionType1.getPatternConstraints().isEmpty());
577 assertTrue(unionType1.getRangeConstraints().isEmpty());
579 UnionType nestedUnion = (UnionType) unionType1.getBaseType();
580 List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
581 assertEquals(2, nestedUnion2Types.size());
582 assertTrue(nestedUnion2Types.get(0) instanceof StringType);
583 assertTrue(nestedUnion2Types.get(1) instanceof ExtendedType);
585 ExtendedType myUnionExt = (ExtendedType) nestedUnion2Types.get(1);
586 QName myUnionExtQName = myUnionExt.getQName();
587 assertEquals(barNS, myUnionExtQName.getNamespace());
588 assertEquals(barRev, myUnionExtQName.getRevision());
589 assertEquals("my-union-ext", myUnionExtQName.getLocalName());
590 assertNull(myUnionExt.getUnits());
591 assertNull(myUnionExt.getDefaultValue());
592 assertNull(myUnionExt.getFractionDigits());
593 assertTrue(myUnionExt.getLengthConstraints().isEmpty());
594 assertTrue(myUnionExt.getPatternConstraints().isEmpty());
595 assertTrue(myUnionExt.getRangeConstraints().isEmpty());
597 ExtendedType myUnion = (ExtendedType) myUnionExt.getBaseType();
598 QName myUnionQName = myUnion.getQName();
599 assertEquals(barNS, myUnionQName.getNamespace());
600 assertEquals(barRev, myUnionQName.getRevision());
601 assertEquals("my-union", myUnionQName.getLocalName());
602 assertNull(myUnion.getUnits());
603 assertNull(myUnion.getDefaultValue());
604 assertNull(myUnion.getFractionDigits());
605 assertTrue(myUnion.getLengthConstraints().isEmpty());
606 assertTrue(myUnion.getPatternConstraints().isEmpty());
607 assertTrue(myUnion.getRangeConstraints().isEmpty());
609 UnionType myUnionBase = (UnionType) myUnion.getBaseType();
610 List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
611 assertEquals(2, myUnionBaseTypes.size());
612 assertTrue(myUnionBaseTypes.get(0) instanceof ExtendedType);
613 assertTrue(myUnionBaseTypes.get(1) instanceof Int32);
615 ExtendedType int16Ext = (ExtendedType) myUnionBaseTypes.get(0);
616 QName int16ExtQName = int16Ext.getQName();
617 assertEquals(barNS, int16ExtQName.getNamespace());
618 assertEquals(barRev, int16ExtQName.getRevision());
619 assertEquals("int16", int16ExtQName.getLocalName());
620 assertNull(int16Ext.getUnits());
621 assertNull(int16Ext.getDefaultValue());
622 assertNull(int16Ext.getFractionDigits());
623 assertTrue(int16Ext.getLengthConstraints().isEmpty());
624 assertTrue(int16Ext.getPatternConstraints().isEmpty());
625 List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
626 assertEquals(1, ranges.size());
627 RangeConstraint range = ranges.get(0);
628 assertEquals(BigInteger.ONE, range.getMin());
629 assertEquals(BigInteger.valueOf(100), range.getMax());
631 assertTrue(int16Ext.getBaseType() instanceof Int16);
635 public void testChoice() {
636 Module foo = TestUtils.findModule(modules, "foo");
637 ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName("transfer");
638 ChoiceNode how = (ChoiceNode) transfer.getDataChildByName("how");
639 Set<ChoiceCaseNode> cases = how.getCases();
640 assertEquals(5, cases.size());
641 ChoiceCaseNode input = null;
642 ChoiceCaseNode output = null;
643 for (ChoiceCaseNode caseNode : cases) {
644 if ("input".equals(caseNode.getQName().getLocalName())) {
646 } else if ("output".equals(caseNode.getQName().getLocalName())) {
650 assertNotNull(input);
651 assertNotNull(input.getPath());
652 assertNotNull(output);
653 assertNotNull(output.getPath());
657 public void testDeviation() {
658 Module foo = TestUtils.findModule(modules, "foo");
659 Set<Deviation> deviations = foo.getDeviations();
660 assertEquals(1, deviations.size());
661 Deviation dev = deviations.iterator().next();
662 assertEquals("system/user ref", dev.getReference());
664 List<QName> path = new ArrayList<>();
665 path.add(QName.create(barNS, barRev, "interfaces"));
666 path.add(QName.create(barNS, barRev, "ifEntry"));
667 SchemaPath expectedPath = SchemaPath.create(path, true);
669 assertEquals(expectedPath, dev.getTargetPath());
670 assertEquals(Deviate.ADD, dev.getDeviate());
674 public void testUnknownNode() {
675 Module baz = TestUtils.findModule(modules, "baz");
676 ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName("network");
677 List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
678 assertEquals(1, unknownNodes.size());
679 UnknownSchemaNode unknownNode = unknownNodes.get(0);
680 assertNotNull(unknownNode.getNodeType());
681 assertEquals("point", unknownNode.getNodeParameter());
685 public void testFeature() {
686 Module baz = TestUtils.findModule(modules, "baz");
687 Set<FeatureDefinition> features = baz.getFeatures();
688 assertEquals(1, features.size());
692 public void testExtension() {
693 Module baz = TestUtils.findModule(modules, "baz");
694 List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
695 assertEquals(1, extensions.size());
696 ExtensionDefinition extension = extensions.get(0);
697 assertEquals("name", extension.getArgument());
698 assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.",
699 extension.getDescription());
700 assertTrue(extension.isYinElement());
704 public void testNotification() {
705 Module baz = TestUtils.findModule(modules, "baz");
706 String expectedPrefix = "c";
708 Set<NotificationDefinition> notifications = baz.getNotifications();
709 assertEquals(1, notifications.size());
711 NotificationDefinition notification = notifications.iterator().next();
712 // test SchemaNode args
713 QName expectedQName = QName.create(bazNS, bazRev, "event");
714 assertEquals(expectedQName, notification.getQName());
715 SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event");
716 assertEquals(expectedPath, notification.getPath());
717 assertNull(notification.getDescription());
718 assertNull(notification.getReference());
719 assertEquals(Status.CURRENT, notification.getStatus());
720 assertEquals(0, notification.getUnknownSchemaNodes().size());
721 // test DataNodeContainer args
722 assertEquals(0, notification.getTypeDefinitions().size());
723 assertEquals(3, notification.getChildNodes().size());
724 assertEquals(0, notification.getGroupings().size());
725 assertEquals(0, notification.getUses().size());
727 LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName("event-class");
728 assertTrue(eventClass.getType() instanceof StringType);
729 LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName("severity");
730 assertTrue(severity.getType() instanceof StringType);
734 public void testRpc() {
735 Module baz = TestUtils.findModule(modules, "baz");
737 Set<RpcDefinition> rpcs = baz.getRpcs();
738 assertEquals(1, rpcs.size());
740 RpcDefinition rpc = rpcs.iterator().next();
741 assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
742 assertEquals("RFC 6241, Section 7.1", rpc.getReference());
746 public void testTypePath() throws ParseException {
747 Module bar = TestUtils.findModule(modules, "bar");
748 Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
751 ExtendedType int32ext1 = (ExtendedType) TestUtils.findTypedef(types, "int32-ext1");
752 QName int32TypedefQName = int32ext1.getQName();
754 assertEquals(barNS, int32TypedefQName.getNamespace());
755 assertEquals(barRev, int32TypedefQName.getRevision());
756 assertEquals("int32-ext1", int32TypedefQName.getLocalName());
758 SchemaPath typeSchemaPath = int32ext1.getPath();
759 Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
760 Iterator<QName> typePathIt = typePath.iterator();
761 assertEquals(int32TypedefQName, typePathIt.next());
762 assertFalse(typePathIt.hasNext());
765 Int32 int32 = (Int32) int32ext1.getBaseType();
766 assertEquals(Int32.getInstance(), int32);
770 public void testTypePath2() throws ParseException {
771 Module bar = TestUtils.findModule(modules, "bar");
772 Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
775 ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types, "my-decimal-type");
776 QName myDecTypeQName = myDecType.getQName();
778 assertEquals(barNS, myDecTypeQName.getNamespace());
779 assertEquals(barRev, myDecTypeQName.getRevision());
780 assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
782 SchemaPath typeSchemaPath = myDecType.getPath();
783 Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
784 Iterator<QName> typePathIt = typePath.iterator();
785 assertEquals(myDecTypeQName, typePathIt.next());
786 assertFalse(typePathIt.hasNext());
788 // my-base-int32-type/int32
789 Decimal64 dec64 = (Decimal64) myDecType.getBaseType();
790 QName dec64QName = dec64.getQName();
792 assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), dec64QName.getNamespace());
793 assertNull(dec64QName.getRevision());
794 assertEquals("decimal64", dec64QName.getLocalName());
796 SchemaPath dec64SchemaPath = dec64.getPath();
797 Iterable<QName> dec64Path = dec64SchemaPath.getPathFromRoot();
798 Iterator<QName> dec64PathIt = dec64Path.iterator();
799 assertEquals(myDecTypeQName, dec64PathIt.next());
800 assertEquals(dec64QName, dec64PathIt.next());
801 assertFalse(dec64PathIt.hasNext());
805 public void testParseMethod1() throws Exception {
806 File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI());
807 File dependenciesDir = new File(getClass().getResource("/parse-methods").toURI());
808 YangContextParser parser = new YangParserImpl();
809 modules = parser.parseFile(yangFile, dependenciesDir).getModules();
810 assertEquals(6, modules.size());
814 public void testParseMethod2() throws Exception {
815 File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI());
816 File dependenciesDir = new File(getClass().getResource("/parse-methods/dependencies").toURI());
817 YangContextParser parser = new YangParserImpl();
818 modules = parser.parseFile(yangFile, dependenciesDir).getModules();
819 assertEquals(6, modules.size());
823 public void testSorting() throws Exception {
824 // Correct order: m2, m4, m6, m8, m7, m6, m3, m1
825 File yangFile = new File(getClass().getResource("/sorting-test/m1.yang").toURI());
826 File dependenciesDir = new File(getClass().getResource("/sorting-test").toURI());
827 YangContextParser parser = new YangParserImpl();
828 modules = parser.parseFile(yangFile, dependenciesDir).getModules();
829 SchemaContext ctx = new SchemaContextImpl(modules, Collections.<ModuleIdentifier, String> emptyMap());
831 assertSetEquals(modules, ctx.getModules());
834 parser = new YangParserImpl();
835 final File testDir = dependenciesDir;
836 final String[] fileList = testDir.list();
837 final List<File> testFiles = new ArrayList<>();
838 if (fileList == null) {
839 throw new FileNotFoundException(dependenciesDir.getAbsolutePath());
841 for (String fileName : fileList) {
842 testFiles.add(new File(testDir, fileName));
844 Set<Module> newModules = parser.parseFiles(testFiles).getModules();
845 assertSetEquals(newModules, modules);
846 ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
847 assertSetEquals(newModules, ctx.getModules());
849 newModules = parser.parseFiles(testFiles, null).getModules();
850 assertSetEquals(newModules, modules);
851 ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
852 assertSetEquals(newModules, ctx.getModules());
854 List<InputStream> streams = new ArrayList<>();
855 for (File f : testFiles) {
856 streams.add(new FileInputStream(f));
858 newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles)).getModules();
859 assertSetEquals(newModules, modules);
860 ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
861 assertSetEquals(newModules, ctx.getModules());
864 for (File f : testFiles) {
865 streams.add(new FileInputStream(f));
867 newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles), null).getModules();
868 assertSetEquals(newModules, modules);
869 ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
870 assertSetEquals(newModules, ctx.getModules());
872 Map<File, Module> mapped = parser.parseYangModelsMapped(testFiles);
873 newModules = new LinkedHashSet<>(mapped.values());
874 assertSetEquals(newModules, modules);
875 ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
876 assertSetEquals(newModules, ctx.getModules());
879 for (File f : testFiles) {
880 streams.add(new FileInputStream(f));
882 Map<InputStream, Module> mappedStreams = parser.parseYangModelsFromStreamsMapped(streams);
883 newModules = new LinkedHashSet<>(mappedStreams.values());
884 assertSetEquals(newModules, modules);
885 ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
886 assertSetEquals(newModules, ctx.getModules());
889 private void checkOrder(final Collection<Module> modules) {
890 Iterator<Module> it = modules.iterator();
891 Module m = it.next();
892 assertEquals("m2", m.getName());
894 assertEquals("m4", m.getName());
896 assertEquals("m6", m.getName());
898 assertEquals("m8", m.getName());
900 assertEquals("m7", m.getName());
902 assertEquals("m5", m.getName());
904 assertEquals("m3", m.getName());
906 assertEquals("m1", m.getName());
909 private void assertSetEquals(final Set<Module> s1, final Set<Module> s2) {
910 assertEquals(s1, s2);
911 Iterator<Module> it = s1.iterator();
912 for (Module m : s2) {
913 assertEquals(m, it.next());
918 public void testSubmodules() throws Exception {
919 Module foo = TestUtils.findModule(modules, "foo");
921 DataSchemaNode id = foo.getDataChildByName("id");
923 DataSchemaNode subExt = foo.getDataChildByName("sub-ext");
924 assertNotNull(subExt);
925 DataSchemaNode subTransfer = foo.getDataChildByName("sub-transfer");
926 assertNotNull(subTransfer);
928 assertEquals(2, foo.getExtensionSchemaNodes().size());
929 assertEquals(2, foo.getAugmentations().size());
933 public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException {
935 File yang = new File(getClass().getResource("/yang-grammar-test/submodule-header-extension.yang").toURI());
938 YangParserImpl.getInstance().parseFile(yang, yang.getParentFile());
939 } catch (YangSyntaxErrorException | YangParseException e) {
941 fail("YangSyntaxErrorException or YangParseException should not be thrown");
947 public void unknownStatementBetweenRevisionsTest() throws IOException, URISyntaxException {
949 File yangModul = new File(getClass().getResource("/yang-grammar-test/revisions-extension.yang").toURI());
950 File yangSubmodul = new File(getClass().getResource("/yang-grammar-test/submodule-header-extension.yang")
953 List<File> yangs = new ArrayList<File>();
954 yangs.add(yangModul);
955 yangs.add(yangSubmodul);
958 YangParserImpl.getInstance().parseFiles(yangs);
959 } catch (YangParseException e) {
961 fail("YangParseException should not be thrown");