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;
17 import java.io.FileInputStream;
18 import java.io.FileNotFoundException;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.math.BigInteger;
23 import java.net.URISyntaxException;
24 import java.text.DateFormat;
25 import java.text.ParseException;
26 import java.text.SimpleDateFormat;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Date;
31 import java.util.Iterator;
32 import java.util.List;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.opendaylight.yangtools.yang.common.QName;
37 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
38 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
39 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
40 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
41 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
43 import org.opendaylight.yangtools.yang.model.api.Deviation;
44 import org.opendaylight.yangtools.yang.model.api.Deviation.Deviate;
45 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
46 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
47 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
48 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
49 import org.opendaylight.yangtools.yang.model.api.Module;
50 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
51 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
52 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
53 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
54 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
55 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
56 import org.opendaylight.yangtools.yang.model.api.Status;
57 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
58 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
59 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
60 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
61 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
62 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
63 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
64 import org.opendaylight.yangtools.yang.model.util.Decimal64;
65 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
66 import org.opendaylight.yangtools.yang.model.util.Int16;
67 import org.opendaylight.yangtools.yang.model.util.Int32;
68 import org.opendaylight.yangtools.yang.model.util.StringType;
69 import org.opendaylight.yangtools.yang.model.util.Uint32;
70 import org.opendaylight.yangtools.yang.model.util.UnionType;
71 import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
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 DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
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 Module foo = TestUtils.findModule(modules, "foo");
101 assertEquals("foo", foo.getName());
102 assertEquals("1", foo.getYangVersion());
103 assertEquals(fooNS, foo.getNamespace());
104 assertEquals("foo", foo.getPrefix());
106 Set<ModuleImport> imports = foo.getImports();
107 assertEquals(2, imports.size());
109 ModuleImport import2 = TestUtils.findImport(imports, "br");
110 assertEquals("bar", import2.getModuleName());
111 assertEquals(barRev, import2.getRevision());
113 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 Date expectedRevision = TestUtils.createDate("2013-02-27");
120 assertEquals(expectedRevision, foo.getRevision());
121 assertEquals(" WILL BE DEFINED LATER", foo.getReference());
125 public void testParseList() {
126 Module bar = TestUtils.findModule(modules, "bar");
127 URI expectedNamespace = URI.create("urn:opendaylight.bar");
128 String expectedPrefix = "bar";
130 ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName("interfaces");
132 ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
133 // test SchemaNode args
134 QName expectedQName = QName.create(expectedNamespace, barRev, "ifEntry");
135 assertEquals(expectedQName, ifEntry.getQName());
136 SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, barRev, expectedPrefix, "interfaces",
138 assertEquals(expectedPath, ifEntry.getPath());
139 assertNull(ifEntry.getDescription());
140 assertNull(ifEntry.getReference());
141 assertEquals(Status.CURRENT, ifEntry.getStatus());
142 assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
143 // test DataSchemaNode args
144 assertFalse(ifEntry.isAugmenting());
145 assertTrue(ifEntry.isConfiguration());
146 ConstraintDefinition constraints = ifEntry.getConstraints();
147 assertNull(constraints.getWhenCondition());
148 assertEquals(0, constraints.getMustConstraints().size());
149 assertTrue(constraints.isMandatory());
150 assertEquals(1, (int) constraints.getMinElements());
151 assertEquals(11, (int) constraints.getMaxElements());
152 // test AugmentationTarget args
153 Set<AugmentationSchema> availableAugmentations = ifEntry.getAvailableAugmentations();
154 assertEquals(2, availableAugmentations.size());
155 // test ListSchemaNode args
156 List<QName> expectedKey = new ArrayList<>();
157 expectedKey.add(QName.create(expectedNamespace, barRev, "ifIndex"));
158 assertEquals(expectedKey, ifEntry.getKeyDefinition());
159 assertFalse(ifEntry.isUserOrdered());
160 // test DataNodeContainer args
161 assertEquals(0, ifEntry.getTypeDefinitions().size());
162 assertEquals(4, ifEntry.getChildNodes().size());
163 assertEquals(0, ifEntry.getGroupings().size());
164 assertEquals(0, ifEntry.getUses().size());
166 LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName("ifIndex");
167 assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
168 assertTrue(ifIndex.getType() instanceof Uint32);
169 LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName("ifMtu");
170 assertTrue(ifMtu.getType() instanceof Int32);
174 public void testTypedefRangesResolving() throws ParseException {
175 Module foo = TestUtils.findModule(modules, "foo");
176 LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName("int32-leaf");
178 ExtendedType leafType = (ExtendedType) int32Leaf.getType();
179 QName leafTypeQName = leafType.getQName();
180 assertEquals("int32-ext2", leafTypeQName.getLocalName());
181 assertEquals(fooNS, leafTypeQName.getNamespace());
182 assertEquals(fooRev, leafTypeQName.getRevision());
183 assertNull(leafType.getUnits());
184 assertNull(leafType.getDefaultValue());
185 assertTrue(leafType.getLengthConstraints().isEmpty());
186 assertTrue(leafType.getPatternConstraints().isEmpty());
187 List<RangeConstraint> ranges = leafType.getRangeConstraints();
188 assertEquals(1, ranges.size());
189 RangeConstraint range = ranges.get(0);
190 assertEquals(BigInteger.valueOf(12), range.getMin());
191 assertEquals(BigInteger.valueOf(20), range.getMax());
193 ExtendedType baseType = (ExtendedType) leafType.getBaseType();
194 QName baseTypeQName = baseType.getQName();
195 assertEquals("int32-ext2", baseTypeQName.getLocalName());
196 assertEquals(barNS, baseTypeQName.getNamespace());
197 assertEquals(barRev, baseTypeQName.getRevision());
198 assertEquals("mile", baseType.getUnits());
199 assertEquals("11", baseType.getDefaultValue());
200 assertTrue(leafType.getLengthConstraints().isEmpty());
201 assertTrue(leafType.getPatternConstraints().isEmpty());
202 List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
203 assertEquals(2, baseTypeRanges.size());
204 RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
205 assertEquals(BigInteger.valueOf(3), baseTypeRange1.getMin());
206 assertEquals(BigInteger.valueOf(9), baseTypeRange1.getMax());
207 RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
208 assertEquals(BigInteger.valueOf(11), baseTypeRange2.getMin());
209 assertEquals(BigInteger.valueOf(20), baseTypeRange2.getMax());
211 ExtendedType base = (ExtendedType) baseType.getBaseType();
212 QName baseQName = base.getQName();
213 assertEquals("int32-ext1", baseQName.getLocalName());
214 assertEquals(barNS, baseQName.getNamespace());
215 assertEquals(barRev, baseQName.getRevision());
216 assertNull(base.getUnits());
217 assertNull(base.getDefaultValue());
218 assertTrue(leafType.getLengthConstraints().isEmpty());
219 assertTrue(leafType.getPatternConstraints().isEmpty());
220 List<RangeConstraint> baseRanges = base.getRangeConstraints();
221 assertEquals(1, baseRanges.size());
222 RangeConstraint baseRange = baseRanges.get(0);
223 assertEquals(BigInteger.valueOf(2), baseRange.getMin());
224 assertEquals(BigInteger.valueOf(20), baseRange.getMax());
226 assertTrue(base.getBaseType() instanceof Int32);
230 public void testTypedefPatternsResolving() {
231 Module foo = TestUtils.findModule(modules, "foo");
232 LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName("string-leaf");
234 ExtendedType type = (ExtendedType) stringleaf.getType();
235 QName typeQName = type.getQName();
236 assertEquals("string-ext4", typeQName.getLocalName());
237 assertEquals(barNS, typeQName.getNamespace());
238 assertEquals(barRev, typeQName.getRevision());
239 assertNull(type.getUnits());
240 assertNull(type.getDefaultValue());
241 List<PatternConstraint> patterns = type.getPatternConstraints();
242 assertEquals(1, patterns.size());
243 PatternConstraint pattern = patterns.iterator().next();
244 assertEquals("^[e-z]*$", pattern.getRegularExpression());
245 assertTrue(type.getLengthConstraints().isEmpty());
246 assertTrue(type.getRangeConstraints().isEmpty());
248 ExtendedType baseType1 = (ExtendedType) type.getBaseType();
249 QName baseType1QName = baseType1.getQName();
250 assertEquals("string-ext3", baseType1QName.getLocalName());
251 assertEquals(barNS, baseType1QName.getNamespace());
252 assertEquals(barRev, baseType1QName.getRevision());
253 assertNull(baseType1.getUnits());
254 assertNull(baseType1.getDefaultValue());
255 patterns = baseType1.getPatternConstraints();
256 assertEquals(1, patterns.size());
257 pattern = patterns.iterator().next();
258 assertEquals("^[b-u]*$", pattern.getRegularExpression());
259 assertTrue(baseType1.getLengthConstraints().isEmpty());
260 assertTrue(baseType1.getRangeConstraints().isEmpty());
262 ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
263 QName baseType2QName = baseType2.getQName();
264 assertEquals("string-ext2", baseType2QName.getLocalName());
265 assertEquals(barNS, baseType2QName.getNamespace());
266 assertEquals(barRev, baseType2QName.getRevision());
267 assertNull(baseType2.getUnits());
268 assertNull(baseType2.getDefaultValue());
269 assertTrue(baseType2.getPatternConstraints().isEmpty());
270 List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
271 assertEquals(1, baseType2Lengths.size());
272 LengthConstraint length = baseType2Lengths.get(0);
273 assertEquals(BigInteger.valueOf(6), length.getMin());
274 assertEquals(BigInteger.TEN, length.getMax());
275 assertTrue(baseType2.getRangeConstraints().isEmpty());
277 ExtendedType baseType3 = (ExtendedType) baseType2.getBaseType();
278 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 List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
289 assertEquals(1, baseType3Lengths.size());
290 length = baseType3Lengths.get(0);
291 assertEquals(BigInteger.valueOf(5), length.getMin());
292 assertEquals(BigInteger.valueOf(11), length.getMax());
293 assertTrue(baseType3.getRangeConstraints().isEmpty());
295 assertTrue(baseType3.getBaseType() instanceof StringType);
299 public void testTypedefInvalidPatternsResolving() {
300 Module foo = TestUtils.findModule(modules, "foo");
301 final LeafSchemaNode invalidPatternStringLeaf = (LeafSchemaNode) foo.getDataChildByName("invalid-pattern-string-leaf");
302 ExtendedType type = (ExtendedType) 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.getDataChildByName("invalid-direct-string-pattern-def-leaf");
313 type = (ExtendedType) invalidDirectStringPatternDefLeaf.getType();
314 typeQName = type.getQName();
315 assertEquals("string", typeQName.getLocalName());
316 assertEquals(fooNS, typeQName.getNamespace());
317 assertEquals(fooRev, typeQName.getRevision());
318 assertNull(type.getUnits());
319 assertNull(type.getDefaultValue());
320 patterns = type.getPatternConstraints();
321 assertTrue(patterns.isEmpty());
323 final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) foo.getDataChildByName("multiple-pattern-string-leaf");
324 type = (ExtendedType) multiplePatternStringLeaf.getType();
325 typeQName = type.getQName();
326 assertEquals("multiple-pattern-string", typeQName.getLocalName());
327 assertEquals(barNS, typeQName.getNamespace());
328 assertEquals(barRev, typeQName.getRevision());
329 assertNull(type.getUnits());
330 assertNull(type.getDefaultValue());
331 patterns = type.getPatternConstraints();
332 assertTrue(!patterns.isEmpty());
333 assertEquals(1, patterns.size());
334 PatternConstraint pattern = patterns.iterator().next();
335 assertEquals("^[e-z]*$", pattern.getRegularExpression());
336 assertTrue(type.getLengthConstraints().isEmpty());
337 assertTrue(type.getRangeConstraints().isEmpty());
339 final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) foo.getDataChildByName("multiple-pattern-direct-string-def-leaf");
340 type = (ExtendedType) multiplePatternDirectStringDefLeaf.getType();
341 typeQName = type.getQName();
342 assertEquals("string", typeQName.getLocalName());
343 assertEquals(fooNS, typeQName.getNamespace());
344 assertEquals(fooRev, typeQName.getRevision());
345 assertNull(type.getUnits());
346 assertNull(type.getDefaultValue());
347 patterns = type.getPatternConstraints();
348 assertTrue(!patterns.isEmpty());
349 assertEquals(2, patterns.size());
351 boolean isEZPattern = false;
352 boolean isADPattern = false;
353 for (final PatternConstraint patternConstraint : patterns) {
354 if (patternConstraint.getRegularExpression().equals("^[e-z]*$")) {
356 } else if (patternConstraint.getRegularExpression().equals("^[a-d]*$")) {
360 assertTrue(isEZPattern);
361 assertTrue( isADPattern);
365 public void testTypedefLengthsResolving() {
366 Module foo = TestUtils.findModule(modules, "foo");
368 LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName("length-leaf");
369 ExtendedType type = (ExtendedType) lengthLeaf.getType();
371 QName typeQName = type.getQName();
372 assertEquals("string-ext2", typeQName.getLocalName());
373 assertEquals(fooNS, typeQName.getNamespace());
374 assertEquals(fooRev, typeQName.getRevision());
375 assertNull(type.getUnits());
376 assertNull(type.getDefaultValue());
377 assertTrue(type.getPatternConstraints().isEmpty());
378 List<LengthConstraint> typeLengths = type.getLengthConstraints();
379 assertEquals(1, typeLengths.size());
380 LengthConstraint length = typeLengths.get(0);
381 assertEquals(BigInteger.valueOf(7), length.getMin());
382 assertEquals(BigInteger.TEN, length.getMax());
383 assertTrue(type.getRangeConstraints().isEmpty());
385 ExtendedType baseType1 = (ExtendedType) type.getBaseType();
386 QName baseType1QName = baseType1.getQName();
387 assertEquals("string-ext2", baseType1QName.getLocalName());
388 assertEquals(barNS, baseType1QName.getNamespace());
389 assertEquals(barRev, baseType1QName.getRevision());
390 assertNull(baseType1.getUnits());
391 assertNull(baseType1.getDefaultValue());
392 assertTrue(baseType1.getPatternConstraints().isEmpty());
393 List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
394 assertEquals(1, baseType2Lengths.size());
395 length = baseType2Lengths.get(0);
396 assertEquals(BigInteger.valueOf(6), length.getMin());
397 assertEquals(BigInteger.TEN, length.getMax());
398 assertTrue(baseType1.getRangeConstraints().isEmpty());
400 ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
401 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 List<PatternConstraint> patterns = baseType2.getPatternConstraints();
408 assertEquals(1, patterns.size());
409 PatternConstraint pattern = patterns.iterator().next();
410 assertEquals("^[a-k]*$", pattern.getRegularExpression());
411 List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
412 assertEquals(1, baseType3Lengths.size());
413 length = baseType3Lengths.get(0);
414 assertEquals(BigInteger.valueOf(5), length.getMin());
415 assertEquals(BigInteger.valueOf(11), length.getMax());
416 assertTrue(baseType2.getRangeConstraints().isEmpty());
418 assertTrue(baseType2.getBaseType() instanceof StringType);
422 public void testTypedefDecimal1() {
423 Module foo = TestUtils.findModule(modules, "foo");
424 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf");
426 ExtendedType type = (ExtendedType) testleaf.getType();
427 QName typeQName = type.getQName();
428 assertEquals("my-decimal-type", typeQName.getLocalName());
429 assertEquals(fooNS, typeQName.getNamespace());
430 assertEquals(fooRev, typeQName.getRevision());
431 assertNull(type.getUnits());
432 assertNull(type.getDefaultValue());
433 assertEquals(4, (int) type.getFractionDigits());
434 assertTrue(type.getLengthConstraints().isEmpty());
435 assertTrue(type.getPatternConstraints().isEmpty());
436 assertTrue(type.getRangeConstraints().isEmpty());
438 ExtendedType typeBase = (ExtendedType) type.getBaseType();
439 QName typeBaseQName = typeBase.getQName();
440 assertEquals("my-decimal-type", typeBaseQName.getLocalName());
441 assertEquals(barNS, typeBaseQName.getNamespace());
442 assertEquals(barRev, typeBaseQName.getRevision());
443 assertNull(typeBase.getUnits());
444 assertNull(typeBase.getDefaultValue());
445 assertNull(typeBase.getFractionDigits());
446 assertTrue(typeBase.getLengthConstraints().isEmpty());
447 assertTrue(typeBase.getPatternConstraints().isEmpty());
448 assertTrue(typeBase.getRangeConstraints().isEmpty());
450 Decimal64 decimal = (Decimal64) typeBase.getBaseType();
451 assertEquals(6, (int) decimal.getFractionDigits());
455 public void testTypedefDecimal2() {
456 Module foo = TestUtils.findModule(modules, "foo");
457 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf2");
459 ExtendedType type = (ExtendedType) testleaf.getType();
460 QName typeQName = type.getQName();
461 assertEquals("my-decimal-type", typeQName.getLocalName());
462 assertEquals(barNS, typeQName.getNamespace());
463 assertEquals(barRev, typeQName.getRevision());
464 assertNull(type.getUnits());
465 assertNull(type.getDefaultValue());
466 assertNull(type.getFractionDigits());
467 assertTrue(type.getLengthConstraints().isEmpty());
468 assertTrue(type.getPatternConstraints().isEmpty());
469 assertTrue(type.getRangeConstraints().isEmpty());
471 Decimal64 baseTypeDecimal = (Decimal64) type.getBaseType();
472 assertEquals(6, (int) baseTypeDecimal.getFractionDigits());
476 public void testTypedefUnion() {
477 Module foo = TestUtils.findModule(modules, "foo");
478 LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName("union-leaf");
480 ExtendedType type = (ExtendedType) unionleaf.getType();
481 QName typeQName = type.getQName();
482 assertEquals("my-union-ext", typeQName.getLocalName());
483 assertEquals(barNS, typeQName.getNamespace());
484 assertEquals(barRev, typeQName.getRevision());
485 assertNull(type.getUnits());
486 assertNull(type.getDefaultValue());
487 assertNull(type.getFractionDigits());
488 assertTrue(type.getLengthConstraints().isEmpty());
489 assertTrue(type.getPatternConstraints().isEmpty());
490 assertTrue(type.getRangeConstraints().isEmpty());
492 ExtendedType baseType = (ExtendedType) type.getBaseType();
493 QName baseTypeQName = baseType.getQName();
494 assertEquals("my-union", baseTypeQName.getLocalName());
495 assertEquals(barNS, baseTypeQName.getNamespace());
496 assertEquals(barRev, baseTypeQName.getRevision());
497 assertNull(baseType.getUnits());
498 assertNull(baseType.getDefaultValue());
499 assertNull(baseType.getFractionDigits());
500 assertTrue(baseType.getLengthConstraints().isEmpty());
501 assertTrue(baseType.getPatternConstraints().isEmpty());
502 assertTrue(baseType.getRangeConstraints().isEmpty());
504 UnionType unionType = (UnionType) baseType.getBaseType();
505 List<TypeDefinition<?>> unionTypes = unionType.getTypes();
506 assertEquals(2, unionTypes.size());
508 ExtendedType unionType1 = (ExtendedType) unionTypes.get(0);
509 QName unionType1QName = baseType.getQName();
510 assertEquals("my-union", unionType1QName.getLocalName());
511 assertEquals(barNS, unionType1QName.getNamespace());
512 assertEquals(barRev, unionType1QName.getRevision());
513 assertNull(unionType1.getUnits());
514 assertNull(unionType1.getDefaultValue());
515 assertNull(unionType1.getFractionDigits());
516 assertTrue(unionType1.getLengthConstraints().isEmpty());
517 assertTrue(unionType1.getPatternConstraints().isEmpty());
518 List<RangeConstraint> ranges = unionType1.getRangeConstraints();
519 assertEquals(1, ranges.size());
520 RangeConstraint range = ranges.get(0);
521 assertEquals(BigInteger.ONE, range.getMin());
522 assertEquals(BigInteger.valueOf(100), range.getMax());
523 assertTrue(unionType1.getBaseType() instanceof Int16);
525 assertTrue(unionTypes.get(1) instanceof Int32);
529 public void testNestedUnionResolving() {
530 Module foo = TestUtils.findModule(modules, "foo");
531 LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("custom-union-leaf");
533 ExtendedType type = (ExtendedType) testleaf.getType();
534 QName testleafTypeQName = type.getQName();
535 assertEquals(bazNS, testleafTypeQName.getNamespace());
536 assertEquals(bazRev, testleafTypeQName.getRevision());
537 assertEquals("union1", testleafTypeQName.getLocalName());
538 assertNull(type.getUnits());
539 assertNull(type.getDefaultValue());
540 assertNull(type.getFractionDigits());
541 assertTrue(type.getLengthConstraints().isEmpty());
542 assertTrue(type.getPatternConstraints().isEmpty());
543 assertTrue(type.getRangeConstraints().isEmpty());
545 ExtendedType typeBase = (ExtendedType) type.getBaseType();
546 QName typeBaseQName = typeBase.getQName();
547 assertEquals(bazNS, typeBaseQName.getNamespace());
548 assertEquals(bazRev, typeBaseQName.getRevision());
549 assertEquals("union2", typeBaseQName.getLocalName());
550 assertNull(typeBase.getUnits());
551 assertNull(typeBase.getDefaultValue());
552 assertNull(typeBase.getFractionDigits());
553 assertTrue(typeBase.getLengthConstraints().isEmpty());
554 assertTrue(typeBase.getPatternConstraints().isEmpty());
555 assertTrue(typeBase.getRangeConstraints().isEmpty());
557 UnionType union = (UnionType) typeBase.getBaseType();
558 List<TypeDefinition<?>> unionTypes = union.getTypes();
559 assertEquals(2, unionTypes.size());
560 assertTrue(unionTypes.get(0) instanceof Int32);
561 assertTrue(unionTypes.get(1) instanceof ExtendedType);
563 ExtendedType unionType1 = (ExtendedType) unionTypes.get(1);
564 QName uniontType1QName = unionType1.getQName();
565 assertEquals(barNS, uniontType1QName.getNamespace());
566 assertEquals(barRev, uniontType1QName.getRevision());
567 assertEquals("nested-union2", uniontType1QName.getLocalName());
568 assertNull(unionType1.getUnits());
569 assertNull(unionType1.getDefaultValue());
570 assertNull(unionType1.getFractionDigits());
571 assertTrue(unionType1.getLengthConstraints().isEmpty());
572 assertTrue(unionType1.getPatternConstraints().isEmpty());
573 assertTrue(unionType1.getRangeConstraints().isEmpty());
575 UnionType nestedUnion = (UnionType) unionType1.getBaseType();
576 List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
577 assertEquals(2, nestedUnion2Types.size());
578 assertTrue(nestedUnion2Types.get(0) instanceof StringType);
579 assertTrue(nestedUnion2Types.get(1) instanceof ExtendedType);
581 ExtendedType myUnionExt = (ExtendedType) nestedUnion2Types.get(1);
582 QName myUnionExtQName = myUnionExt.getQName();
583 assertEquals(barNS, myUnionExtQName.getNamespace());
584 assertEquals(barRev, myUnionExtQName.getRevision());
585 assertEquals("my-union-ext", myUnionExtQName.getLocalName());
586 assertNull(myUnionExt.getUnits());
587 assertNull(myUnionExt.getDefaultValue());
588 assertNull(myUnionExt.getFractionDigits());
589 assertTrue(myUnionExt.getLengthConstraints().isEmpty());
590 assertTrue(myUnionExt.getPatternConstraints().isEmpty());
591 assertTrue(myUnionExt.getRangeConstraints().isEmpty());
593 ExtendedType myUnion = (ExtendedType) myUnionExt.getBaseType();
594 QName myUnionQName = myUnion.getQName();
595 assertEquals(barNS, myUnionQName.getNamespace());
596 assertEquals(barRev, myUnionQName.getRevision());
597 assertEquals("my-union", myUnionQName.getLocalName());
598 assertNull(myUnion.getUnits());
599 assertNull(myUnion.getDefaultValue());
600 assertNull(myUnion.getFractionDigits());
601 assertTrue(myUnion.getLengthConstraints().isEmpty());
602 assertTrue(myUnion.getPatternConstraints().isEmpty());
603 assertTrue(myUnion.getRangeConstraints().isEmpty());
605 UnionType myUnionBase = (UnionType) myUnion.getBaseType();
606 List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
607 assertEquals(2, myUnionBaseTypes.size());
608 assertTrue(myUnionBaseTypes.get(0) instanceof ExtendedType);
609 assertTrue(myUnionBaseTypes.get(1) instanceof Int32);
611 ExtendedType int16Ext = (ExtendedType) myUnionBaseTypes.get(0);
612 QName int16ExtQName = int16Ext.getQName();
613 assertEquals(barNS, int16ExtQName.getNamespace());
614 assertEquals(barRev, int16ExtQName.getRevision());
615 assertEquals("int16", int16ExtQName.getLocalName());
616 assertNull(int16Ext.getUnits());
617 assertNull(int16Ext.getDefaultValue());
618 assertNull(int16Ext.getFractionDigits());
619 assertTrue(int16Ext.getLengthConstraints().isEmpty());
620 assertTrue(int16Ext.getPatternConstraints().isEmpty());
621 List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
622 assertEquals(1, ranges.size());
623 RangeConstraint range = ranges.get(0);
624 assertEquals(BigInteger.ONE, range.getMin());
625 assertEquals(BigInteger.valueOf(100), range.getMax());
627 assertTrue(int16Ext.getBaseType() instanceof Int16);
631 public void testChoice() {
632 Module foo = TestUtils.findModule(modules, "foo");
633 ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName("transfer");
634 ChoiceSchemaNode how = (ChoiceSchemaNode) transfer.getDataChildByName("how");
635 Set<ChoiceCaseNode> cases = how.getCases();
636 assertEquals(5, cases.size());
637 ChoiceCaseNode input = null;
638 ChoiceCaseNode output = null;
639 for (ChoiceCaseNode caseNode : cases) {
640 if ("input".equals(caseNode.getQName().getLocalName())) {
642 } else if ("output".equals(caseNode.getQName().getLocalName())) {
646 assertNotNull(input);
647 assertNotNull(input.getPath());
648 assertNotNull(output);
649 assertNotNull(output.getPath());
653 public void testDeviation() {
654 Module foo = TestUtils.findModule(modules, "foo");
655 Set<Deviation> deviations = foo.getDeviations();
656 assertEquals(1, deviations.size());
657 Deviation dev = deviations.iterator().next();
658 assertEquals("system/user ref", dev.getReference());
660 List<QName> path = new ArrayList<>();
661 path.add(QName.create(barNS, barRev, "interfaces"));
662 path.add(QName.create(barNS, barRev, "ifEntry"));
663 SchemaPath expectedPath = SchemaPath.create(path, true);
665 assertEquals(expectedPath, dev.getTargetPath());
666 assertEquals(Deviate.ADD, dev.getDeviate());
670 public void testUnknownNode() {
671 Module baz = TestUtils.findModule(modules, "baz");
672 ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName("network");
673 List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
674 assertEquals(1, unknownNodes.size());
675 UnknownSchemaNode unknownNode = unknownNodes.get(0);
676 assertNotNull(unknownNode.getNodeType());
677 assertEquals("point", unknownNode.getNodeParameter());
681 public void testFeature() {
682 Module baz = TestUtils.findModule(modules, "baz");
683 Set<FeatureDefinition> features = baz.getFeatures();
684 assertEquals(1, features.size());
688 public void testExtension() {
689 Module baz = TestUtils.findModule(modules, "baz");
690 List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
691 assertEquals(1, extensions.size());
692 ExtensionDefinition extension = extensions.get(0);
693 assertEquals("name", extension.getArgument());
694 assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.",
695 extension.getDescription());
696 assertTrue(extension.isYinElement());
700 public void testNotification() {
701 Module baz = TestUtils.findModule(modules, "baz");
702 String expectedPrefix = "c";
704 Set<NotificationDefinition> notifications = baz.getNotifications();
705 assertEquals(1, notifications.size());
707 NotificationDefinition notification = notifications.iterator().next();
708 // test SchemaNode args
709 QName expectedQName = QName.create(bazNS, bazRev, "event");
710 assertEquals(expectedQName, notification.getQName());
711 SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event");
712 assertEquals(expectedPath, notification.getPath());
713 assertNull(notification.getDescription());
714 assertNull(notification.getReference());
715 assertEquals(Status.CURRENT, notification.getStatus());
716 assertEquals(0, notification.getUnknownSchemaNodes().size());
717 // test DataNodeContainer args
718 assertEquals(0, notification.getTypeDefinitions().size());
719 assertEquals(3, notification.getChildNodes().size());
720 assertEquals(0, notification.getGroupings().size());
721 assertEquals(0, notification.getUses().size());
723 LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName("event-class");
724 assertTrue(eventClass.getType() instanceof StringType);
725 LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName("severity");
726 assertTrue(severity.getType() instanceof StringType);
730 public void testRpc() {
731 Module baz = TestUtils.findModule(modules, "baz");
733 Set<RpcDefinition> rpcs = baz.getRpcs();
734 assertEquals(1, rpcs.size());
736 RpcDefinition rpc = rpcs.iterator().next();
737 assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
738 assertEquals("RFC 6241, Section 7.1", rpc.getReference());
742 public void testTypePath() throws ParseException {
743 Module bar = TestUtils.findModule(modules, "bar");
744 Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
747 ExtendedType int32ext1 = (ExtendedType) TestUtils.findTypedef(types, "int32-ext1");
748 QName int32TypedefQName = int32ext1.getQName();
750 assertEquals(barNS, int32TypedefQName.getNamespace());
751 assertEquals(barRev, int32TypedefQName.getRevision());
752 assertEquals("int32-ext1", int32TypedefQName.getLocalName());
754 SchemaPath typeSchemaPath = int32ext1.getPath();
755 Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
756 Iterator<QName> typePathIt = typePath.iterator();
757 assertEquals(int32TypedefQName, typePathIt.next());
758 assertFalse(typePathIt.hasNext());
761 Int32 int32 = (Int32) int32ext1.getBaseType();
762 assertEquals(Int32.getInstance(), int32);
766 public void testTypePath2() throws ParseException {
767 Module bar = TestUtils.findModule(modules, "bar");
768 Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
771 ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types, "my-decimal-type");
772 QName myDecTypeQName = myDecType.getQName();
774 assertEquals(barNS, myDecTypeQName.getNamespace());
775 assertEquals(barRev, myDecTypeQName.getRevision());
776 assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
778 SchemaPath typeSchemaPath = myDecType.getPath();
779 Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
780 Iterator<QName> typePathIt = typePath.iterator();
781 assertEquals(myDecTypeQName, typePathIt.next());
782 assertFalse(typePathIt.hasNext());
784 // my-base-int32-type/int32
785 Decimal64 dec64 = (Decimal64) myDecType.getBaseType();
786 QName dec64QName = dec64.getQName();
788 assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), dec64QName.getNamespace());
789 assertNull(dec64QName.getRevision());
790 assertEquals("decimal64", dec64QName.getLocalName());
792 SchemaPath dec64SchemaPath = dec64.getPath();
793 Iterable<QName> dec64Path = dec64SchemaPath.getPathFromRoot();
794 Iterator<QName> dec64PathIt = dec64Path.iterator();
795 assertEquals(myDecTypeQName, dec64PathIt.next());
796 assertEquals(dec64QName, dec64PathIt.next());
797 assertFalse(dec64PathIt.hasNext());
801 public void testParseMethod1() throws Exception {
802 File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI());
803 File dependenciesDir = new File(getClass().getResource("/parse-methods").toURI());
804 YangContextParser parser = new YangParserImpl();
805 modules = parser.parseFile(yangFile, dependenciesDir).getModules();
806 assertEquals(6, modules.size());
810 public void testParseMethod2() throws Exception {
811 File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI());
812 File dependenciesDir = new File(getClass().getResource("/parse-methods/dependencies").toURI());
813 YangContextParser parser = new YangParserImpl();
814 modules = parser.parseFile(yangFile, dependenciesDir).getModules();
815 assertEquals(6, modules.size());
819 public void testSorting() throws Exception {
820 // Correct order: m2, m4, m6, m8, m7, m6, m3, m1
821 File yangFile = new File(getClass().getResource("/sorting-test/m1.yang").toURI());
822 File dependenciesDir = new File(getClass().getResource("/sorting-test").toURI());
823 YangContextParser parser = new YangParserImpl();
824 modules = parser.parseFile(yangFile, dependenciesDir).getModules();
825 SchemaContext ctx = new SchemaContextImpl(modules, Collections.emptyMap());
827 assertSetEquals(modules, ctx.getModules());
830 parser = new YangParserImpl();
831 final File testDir = dependenciesDir;
832 final String[] fileList = testDir.list();
833 final List<File> testFiles = new ArrayList<>();
834 if (fileList == null) {
835 throw new FileNotFoundException(dependenciesDir.getAbsolutePath());
837 for (String fileName : fileList) {
838 testFiles.add(new File(testDir, fileName));
840 Set<Module> newModules = parser.parseFiles(testFiles).getModules();
841 assertSetEquals(newModules, modules);
842 ctx = new SchemaContextImpl(newModules, Collections.emptyMap());
843 assertSetEquals(newModules, ctx.getModules());
845 newModules = parser.parseFiles(testFiles, null).getModules();
846 assertSetEquals(newModules, modules);
847 ctx = new SchemaContextImpl(newModules, Collections.emptyMap());
848 assertSetEquals(newModules, ctx.getModules());
850 List<InputStream> streams = new ArrayList<>();
851 for (File f : testFiles) {
852 streams.add(new FileInputStream(f));
854 newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles)).getModules();
855 assertSetEquals(newModules, modules);
856 ctx = new SchemaContextImpl(newModules, Collections.emptyMap());
857 assertSetEquals(newModules, ctx.getModules());
860 for (File f : testFiles) {
861 streams.add(new FileInputStream(f));
863 newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles), null).getModules();
864 assertSetEquals(newModules, modules);
865 ctx = new SchemaContextImpl(newModules, Collections.emptyMap());
866 assertSetEquals(newModules, ctx.getModules());
869 private static void checkOrder(final Collection<Module> modules) {
870 Iterator<Module> it = modules.iterator();
871 Module m = it.next();
872 assertEquals("m2", m.getName());
874 assertEquals("m4", m.getName());
876 assertEquals("m6", m.getName());
878 assertEquals("m8", m.getName());
880 assertEquals("m7", m.getName());
882 assertEquals("m5", m.getName());
884 assertEquals("m3", m.getName());
886 assertEquals("m1", m.getName());
889 private static void assertSetEquals(final Set<Module> s1, final Set<Module> s2) {
890 assertEquals(s1, s2);
891 Iterator<Module> it = s1.iterator();
892 for (Module m : s2) {
893 assertEquals(m, it.next());
898 public void testSubmodules() throws Exception {
899 Module foo = TestUtils.findModule(modules, "foo");
901 DataSchemaNode id = foo.getDataChildByName("id");
903 DataSchemaNode subExt = foo.getDataChildByName("sub-ext");
904 assertNotNull(subExt);
905 DataSchemaNode subTransfer = foo.getDataChildByName("sub-transfer");
906 assertNotNull(subTransfer);
908 assertEquals(2, foo.getExtensionSchemaNodes().size());
909 assertEquals(2, foo.getAugmentations().size());
913 public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException {
915 File yang = new File(getClass().getResource("/yang-grammar-test/submodule-header-extension.yang").toURI());
918 YangParserImpl.getInstance().parseFile(yang, yang.getParentFile());
919 } catch (YangSyntaxErrorException | YangParseException e) {
921 fail("YangSyntaxErrorException or YangParseException should not be thrown");
927 public void unknownStatementBetweenRevisionsTest() throws IOException, URISyntaxException {
929 File yangModul = new File(getClass().getResource("/yang-grammar-test/revisions-extension.yang").toURI());
930 File yangSubmodul = new File(getClass().getResource("/yang-grammar-test/submodule-header-extension.yang")
933 List<File> yangs = new ArrayList<>();
934 yangs.add(yangModul);
935 yangs.add(yangSubmodul);
938 YangParserImpl.getInstance().parseFiles(yangs);
939 } catch (YangParseException e) {
941 fail("YangParseException should not be thrown");
946 public void unknownStatementsInStatementsTest() throws IOException, URISyntaxException {
947 File yangModule1 = new File(getClass().getResource("/yang-grammar-test/stmtsep-in-statements.yang").toURI());
948 File yangModule2 = new File(getClass().getResource("/yang-grammar-test/stmtsep-in-statements2.yang").toURI());
949 File yangSubModule = new File(getClass().getResource("/yang-grammar-test/stmtsep-in-statements-sub.yang").toURI());
951 List<File> yangs = new ArrayList<>();
952 yangs.add(yangModule1);
953 yangs.add(yangModule2);
954 yangs.add(yangSubModule);
957 YangParserImpl.getInstance().parseFiles(yangs);
958 } catch (YangParseException e) {
960 fail("YangParseException should not be thrown");