BUG-1382: eliminate use of QName.getPrefix from yang parser
[yangtools.git] / yang / yang-parser-impl / src / test / java / org / opendaylight / yangtools / yang / parser / impl / YangParserTest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.impl;
9
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
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.FileNotFoundException;
19 import java.io.InputStream;
20 import java.math.BigInteger;
21 import java.net.URI;
22 import java.text.DateFormat;
23 import java.text.ParseException;
24 import java.text.SimpleDateFormat;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Date;
29 import java.util.Iterator;
30 import java.util.LinkedHashSet;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
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.ChoiceNode;
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.util.Decimal64;
64 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
65 import org.opendaylight.yangtools.yang.model.util.Int16;
66 import org.opendaylight.yangtools.yang.model.util.Int32;
67 import org.opendaylight.yangtools.yang.model.util.StringType;
68 import org.opendaylight.yangtools.yang.model.util.Uint32;
69 import org.opendaylight.yangtools.yang.model.util.UnionType;
70 import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
71
72 public class YangParserTest {
73     public static final String FS = File.separator;
74
75     private final URI fooNS = URI.create("urn:opendaylight.foo");
76     private final URI barNS = URI.create("urn:opendaylight.bar");
77     private final URI bazNS = URI.create("urn:opendaylight.baz");
78     private Date fooRev;
79     private Date barRev;
80     private Date bazRev;
81
82     private Set<Module> modules;
83
84     @Before
85     public void init() throws Exception {
86         DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
87         fooRev = simpleDateFormat.parse("2013-02-27");
88         barRev = simpleDateFormat.parse("2013-07-03");
89         bazRev = simpleDateFormat.parse("2013-02-27");
90
91         modules = TestUtils.loadModules(getClass().getResource("/model").toURI());
92         assertEquals(3, modules.size());
93     }
94
95     @Test
96     public void testHeaders() throws ParseException {
97         Module foo = TestUtils.findModule(modules, "foo");
98
99         assertEquals("foo", foo.getName());
100         assertEquals("1", foo.getYangVersion());
101         assertEquals(fooNS, foo.getNamespace());
102         assertEquals("foo", foo.getPrefix());
103
104         Set<ModuleImport> imports = foo.getImports();
105         assertEquals(2, imports.size());
106
107         ModuleImport import2 = TestUtils.findImport(imports, "br");
108         assertEquals("bar", import2.getModuleName());
109         assertEquals(barRev, import2.getRevision());
110
111         ModuleImport import3 = TestUtils.findImport(imports, "bz");
112         assertEquals("baz", import3.getModuleName());
113         assertEquals(bazRev, import3.getRevision());
114
115         assertEquals("opendaylight", foo.getOrganization());
116         assertEquals("http://www.opendaylight.org/", foo.getContact());
117         Date expectedRevision = TestUtils.createDate("2013-02-27");
118         assertEquals(expectedRevision, foo.getRevision());
119         assertEquals(" WILL BE DEFINED LATER", foo.getReference());
120     }
121
122     @Test
123     public void testParseList() {
124         Module bar = TestUtils.findModule(modules, "bar");
125         URI expectedNamespace = URI.create("urn:opendaylight.bar");
126         String expectedPrefix = "bar";
127
128         ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName("interfaces");
129
130         ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
131         // test SchemaNode args
132         QName expectedQName = new QName(expectedNamespace, barRev, expectedPrefix, "ifEntry");
133         assertEquals(expectedQName, ifEntry.getQName());
134         SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, barRev, expectedPrefix, "interfaces",
135                 "ifEntry");
136         assertEquals(expectedPath, ifEntry.getPath());
137         assertNull(ifEntry.getDescription());
138         assertNull(ifEntry.getReference());
139         assertEquals(Status.CURRENT, ifEntry.getStatus());
140         assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
141         // test DataSchemaNode args
142         assertFalse(ifEntry.isAugmenting());
143         assertTrue(ifEntry.isConfiguration());
144         ConstraintDefinition constraints = ifEntry.getConstraints();
145         assertNull(constraints.getWhenCondition());
146         assertEquals(0, constraints.getMustConstraints().size());
147         assertFalse(constraints.isMandatory());
148         assertEquals(1, (int) constraints.getMinElements());
149         assertEquals(11, (int) constraints.getMaxElements());
150         // test AugmentationTarget args
151         Set<AugmentationSchema> availableAugmentations = ifEntry.getAvailableAugmentations();
152         assertEquals(2, availableAugmentations.size());
153         // test ListSchemaNode args
154         List<QName> expectedKey = new ArrayList<>();
155         expectedKey.add(new QName(expectedNamespace, barRev, expectedPrefix, "ifIndex"));
156         assertEquals(expectedKey, ifEntry.getKeyDefinition());
157         assertFalse(ifEntry.isUserOrdered());
158         // test DataNodeContainer args
159         assertEquals(0, ifEntry.getTypeDefinitions().size());
160         assertEquals(4, ifEntry.getChildNodes().size());
161         assertEquals(0, ifEntry.getGroupings().size());
162         assertEquals(0, ifEntry.getUses().size());
163
164         LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName("ifIndex");
165         assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
166         assertTrue(ifIndex.getType() instanceof Uint32);
167         LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName("ifMtu");
168         assertTrue(ifMtu.getType() instanceof Int32);
169     }
170
171     @Test
172     public void testTypedefRangesResolving() throws ParseException {
173         Module foo = TestUtils.findModule(modules, "foo");
174         LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName("int32-leaf");
175
176         ExtendedType leafType = (ExtendedType) int32Leaf.getType();
177         QName leafTypeQName = leafType.getQName();
178         assertEquals("int32-ext2", leafTypeQName.getLocalName());
179         assertEquals(fooNS, leafTypeQName.getNamespace());
180         assertEquals(fooRev, leafTypeQName.getRevision());
181         assertNull(leafType.getUnits());
182         assertNull(leafType.getDefaultValue());
183         assertTrue(leafType.getLengthConstraints().isEmpty());
184         assertTrue(leafType.getPatternConstraints().isEmpty());
185         List<RangeConstraint> ranges = leafType.getRangeConstraints();
186         assertEquals(1, ranges.size());
187         RangeConstraint range = ranges.get(0);
188         assertEquals(BigInteger.valueOf(12), range.getMin());
189         assertEquals(BigInteger.valueOf(20), range.getMax());
190
191         ExtendedType baseType = (ExtendedType) leafType.getBaseType();
192         QName baseTypeQName = baseType.getQName();
193         assertEquals("int32-ext2", baseTypeQName.getLocalName());
194         assertEquals(barNS, baseTypeQName.getNamespace());
195         assertEquals(barRev, baseTypeQName.getRevision());
196         assertEquals("mile", baseType.getUnits());
197         assertEquals("11", baseType.getDefaultValue());
198         assertTrue(leafType.getLengthConstraints().isEmpty());
199         assertTrue(leafType.getPatternConstraints().isEmpty());
200         List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
201         assertEquals(2, baseTypeRanges.size());
202         RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
203         assertEquals(BigInteger.valueOf(3), baseTypeRange1.getMin());
204         assertEquals(BigInteger.valueOf(9), baseTypeRange1.getMax());
205         RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
206         assertEquals(BigInteger.valueOf(11), baseTypeRange2.getMin());
207         assertEquals(BigInteger.valueOf(20), baseTypeRange2.getMax());
208
209         ExtendedType base = (ExtendedType) baseType.getBaseType();
210         QName baseQName = base.getQName();
211         assertEquals("int32-ext1", baseQName.getLocalName());
212         assertEquals(barNS, baseQName.getNamespace());
213         assertEquals(barRev, baseQName.getRevision());
214         assertNull(base.getUnits());
215         assertNull(base.getDefaultValue());
216         assertTrue(leafType.getLengthConstraints().isEmpty());
217         assertTrue(leafType.getPatternConstraints().isEmpty());
218         List<RangeConstraint> baseRanges = base.getRangeConstraints();
219         assertEquals(1, baseRanges.size());
220         RangeConstraint baseRange = baseRanges.get(0);
221         assertEquals(BigInteger.valueOf(2), baseRange.getMin());
222         assertEquals(BigInteger.valueOf(20), baseRange.getMax());
223
224         assertTrue(base.getBaseType() instanceof Int32);
225     }
226
227     @Test
228     public void testTypedefPatternsResolving() {
229         Module foo = TestUtils.findModule(modules, "foo");
230         LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName("string-leaf");
231
232         ExtendedType type = (ExtendedType) stringleaf.getType();
233         QName typeQName = type.getQName();
234         assertEquals("string-ext4", typeQName.getLocalName());
235         assertEquals(barNS, typeQName.getNamespace());
236         assertEquals(barRev, typeQName.getRevision());
237         assertNull(type.getUnits());
238         assertNull(type.getDefaultValue());
239         List<PatternConstraint> patterns = type.getPatternConstraints();
240         assertEquals(1, patterns.size());
241         PatternConstraint pattern = patterns.iterator().next();
242         assertEquals("[e-z]*", pattern.getRegularExpression());
243         assertTrue(type.getLengthConstraints().isEmpty());
244         assertTrue(type.getRangeConstraints().isEmpty());
245
246         ExtendedType baseType1 = (ExtendedType) type.getBaseType();
247         QName baseType1QName = baseType1.getQName();
248         assertEquals("string-ext3", baseType1QName.getLocalName());
249         assertEquals(barNS, baseType1QName.getNamespace());
250         assertEquals(barRev, baseType1QName.getRevision());
251         assertNull(baseType1.getUnits());
252         assertNull(baseType1.getDefaultValue());
253         patterns = baseType1.getPatternConstraints();
254         assertEquals(1, patterns.size());
255         pattern = patterns.iterator().next();
256         assertEquals("[b-u]*", pattern.getRegularExpression());
257         assertTrue(baseType1.getLengthConstraints().isEmpty());
258         assertTrue(baseType1.getRangeConstraints().isEmpty());
259
260         ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
261         QName baseType2QName = baseType2.getQName();
262         assertEquals("string-ext2", baseType2QName.getLocalName());
263         assertEquals(barNS, baseType2QName.getNamespace());
264         assertEquals(barRev, baseType2QName.getRevision());
265         assertNull(baseType2.getUnits());
266         assertNull(baseType2.getDefaultValue());
267         assertTrue(baseType2.getPatternConstraints().isEmpty());
268         List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
269         assertEquals(1, baseType2Lengths.size());
270         LengthConstraint length = baseType2Lengths.get(0);
271         assertEquals(BigInteger.valueOf(6), length.getMin());
272         assertEquals(BigInteger.TEN, length.getMax());
273         assertTrue(baseType2.getRangeConstraints().isEmpty());
274
275         ExtendedType baseType3 = (ExtendedType) baseType2.getBaseType();
276         QName baseType3QName = baseType3.getQName();
277         assertEquals("string-ext1", baseType3QName.getLocalName());
278         assertEquals(barNS, baseType3QName.getNamespace());
279         assertEquals(barRev, baseType3QName.getRevision());
280         assertNull(baseType3.getUnits());
281         assertNull(baseType3.getDefaultValue());
282         patterns = baseType3.getPatternConstraints();
283         assertEquals(1, patterns.size());
284         pattern = patterns.iterator().next();
285         assertEquals("[a-k]*", pattern.getRegularExpression());
286         List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
287         assertEquals(1, baseType3Lengths.size());
288         length = baseType3Lengths.get(0);
289         assertEquals(BigInteger.valueOf(5), length.getMin());
290         assertEquals(BigInteger.valueOf(11), length.getMax());
291         assertTrue(baseType3.getRangeConstraints().isEmpty());
292
293         assertTrue(baseType3.getBaseType() instanceof StringType);
294     }
295
296     @Test
297     public void testTypedefLengthsResolving() {
298         Module foo = TestUtils.findModule(modules, "foo");
299
300         LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName("length-leaf");
301         ExtendedType type = (ExtendedType) lengthLeaf.getType();
302
303         QName typeQName = type.getQName();
304         assertEquals("string-ext2", typeQName.getLocalName());
305         assertEquals(fooNS, typeQName.getNamespace());
306         assertEquals(fooRev, typeQName.getRevision());
307         assertNull(type.getUnits());
308         assertNull(type.getDefaultValue());
309         assertTrue(type.getPatternConstraints().isEmpty());
310         List<LengthConstraint> typeLengths = type.getLengthConstraints();
311         assertEquals(1, typeLengths.size());
312         LengthConstraint length = typeLengths.get(0);
313         assertEquals(BigInteger.valueOf(7), length.getMin());
314         assertEquals(BigInteger.TEN, length.getMax());
315         assertTrue(type.getRangeConstraints().isEmpty());
316
317         ExtendedType baseType1 = (ExtendedType) type.getBaseType();
318         QName baseType1QName = baseType1.getQName();
319         assertEquals("string-ext2", baseType1QName.getLocalName());
320         assertEquals(barNS, baseType1QName.getNamespace());
321         assertEquals(barRev, baseType1QName.getRevision());
322         assertNull(baseType1.getUnits());
323         assertNull(baseType1.getDefaultValue());
324         assertTrue(baseType1.getPatternConstraints().isEmpty());
325         List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
326         assertEquals(1, baseType2Lengths.size());
327         length = baseType2Lengths.get(0);
328         assertEquals(BigInteger.valueOf(6), length.getMin());
329         assertEquals(BigInteger.TEN, length.getMax());
330         assertTrue(baseType1.getRangeConstraints().isEmpty());
331
332         ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
333         QName baseType2QName = baseType2.getQName();
334         assertEquals("string-ext1", baseType2QName.getLocalName());
335         assertEquals(barNS, baseType2QName.getNamespace());
336         assertEquals(barRev, baseType2QName.getRevision());
337         assertNull(baseType2.getUnits());
338         assertNull(baseType2.getDefaultValue());
339         List<PatternConstraint> patterns = baseType2.getPatternConstraints();
340         assertEquals(1, patterns.size());
341         PatternConstraint pattern = patterns.iterator().next();
342         assertEquals("[a-k]*", pattern.getRegularExpression());
343         List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
344         assertEquals(1, baseType3Lengths.size());
345         length = baseType3Lengths.get(0);
346         assertEquals(BigInteger.valueOf(5), length.getMin());
347         assertEquals(BigInteger.valueOf(11), length.getMax());
348         assertTrue(baseType2.getRangeConstraints().isEmpty());
349
350         assertTrue(baseType2.getBaseType() instanceof StringType);
351     }
352
353     @Test
354     public void testTypedefDecimal1() {
355         Module foo = TestUtils.findModule(modules, "foo");
356         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf");
357
358         ExtendedType type = (ExtendedType) testleaf.getType();
359         QName typeQName = type.getQName();
360         assertEquals("my-decimal-type", typeQName.getLocalName());
361         assertEquals(fooNS, typeQName.getNamespace());
362         assertEquals(fooRev, typeQName.getRevision());
363         assertNull(type.getUnits());
364         assertNull(type.getDefaultValue());
365         assertEquals(4, (int) type.getFractionDigits());
366         assertTrue(type.getLengthConstraints().isEmpty());
367         assertTrue(type.getPatternConstraints().isEmpty());
368         assertTrue(type.getRangeConstraints().isEmpty());
369
370         ExtendedType typeBase = (ExtendedType) type.getBaseType();
371         QName typeBaseQName = typeBase.getQName();
372         assertEquals("my-decimal-type", typeBaseQName.getLocalName());
373         assertEquals(barNS, typeBaseQName.getNamespace());
374         assertEquals(barRev, typeBaseQName.getRevision());
375         assertNull(typeBase.getUnits());
376         assertNull(typeBase.getDefaultValue());
377         assertNull(typeBase.getFractionDigits());
378         assertTrue(typeBase.getLengthConstraints().isEmpty());
379         assertTrue(typeBase.getPatternConstraints().isEmpty());
380         assertTrue(typeBase.getRangeConstraints().isEmpty());
381
382         Decimal64 decimal = (Decimal64) typeBase.getBaseType();
383         assertEquals(6, (int) decimal.getFractionDigits());
384     }
385
386     @Test
387     public void testTypedefDecimal2() {
388         Module foo = TestUtils.findModule(modules, "foo");
389         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf2");
390
391         ExtendedType type = (ExtendedType) testleaf.getType();
392         QName typeQName = type.getQName();
393         assertEquals("my-decimal-type", typeQName.getLocalName());
394         assertEquals(barNS, typeQName.getNamespace());
395         assertEquals(barRev, typeQName.getRevision());
396         assertNull(type.getUnits());
397         assertNull(type.getDefaultValue());
398         assertNull(type.getFractionDigits());
399         assertTrue(type.getLengthConstraints().isEmpty());
400         assertTrue(type.getPatternConstraints().isEmpty());
401         assertTrue(type.getRangeConstraints().isEmpty());
402
403         Decimal64 baseTypeDecimal = (Decimal64) type.getBaseType();
404         assertEquals(6, (int) baseTypeDecimal.getFractionDigits());
405     }
406
407     @Test
408     public void testTypedefUnion() {
409         Module foo = TestUtils.findModule(modules, "foo");
410         LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName("union-leaf");
411
412         ExtendedType type = (ExtendedType) unionleaf.getType();
413         QName typeQName = type.getQName();
414         assertEquals("my-union-ext", typeQName.getLocalName());
415         assertEquals(barNS, typeQName.getNamespace());
416         assertEquals(barRev, typeQName.getRevision());
417         assertNull(type.getUnits());
418         assertNull(type.getDefaultValue());
419         assertNull(type.getFractionDigits());
420         assertTrue(type.getLengthConstraints().isEmpty());
421         assertTrue(type.getPatternConstraints().isEmpty());
422         assertTrue(type.getRangeConstraints().isEmpty());
423
424         ExtendedType baseType = (ExtendedType) type.getBaseType();
425         QName baseTypeQName = baseType.getQName();
426         assertEquals("my-union", baseTypeQName.getLocalName());
427         assertEquals(barNS, baseTypeQName.getNamespace());
428         assertEquals(barRev, baseTypeQName.getRevision());
429         assertNull(baseType.getUnits());
430         assertNull(baseType.getDefaultValue());
431         assertNull(baseType.getFractionDigits());
432         assertTrue(baseType.getLengthConstraints().isEmpty());
433         assertTrue(baseType.getPatternConstraints().isEmpty());
434         assertTrue(baseType.getRangeConstraints().isEmpty());
435
436         UnionType unionType = (UnionType) baseType.getBaseType();
437         List<TypeDefinition<?>> unionTypes = unionType.getTypes();
438         assertEquals(2, unionTypes.size());
439
440         ExtendedType unionType1 = (ExtendedType) unionTypes.get(0);
441         QName unionType1QName = baseType.getQName();
442         assertEquals("my-union", unionType1QName.getLocalName());
443         assertEquals(barNS, unionType1QName.getNamespace());
444         assertEquals(barRev, unionType1QName.getRevision());
445         assertNull(unionType1.getUnits());
446         assertNull(unionType1.getDefaultValue());
447         assertNull(unionType1.getFractionDigits());
448         assertTrue(unionType1.getLengthConstraints().isEmpty());
449         assertTrue(unionType1.getPatternConstraints().isEmpty());
450         List<RangeConstraint> ranges = unionType1.getRangeConstraints();
451         assertEquals(1, ranges.size());
452         RangeConstraint range = ranges.get(0);
453         assertEquals(BigInteger.ONE, range.getMin());
454         assertEquals(BigInteger.valueOf(100), range.getMax());
455         assertTrue(unionType1.getBaseType() instanceof Int16);
456
457         assertTrue(unionTypes.get(1) instanceof Int32);
458     }
459
460     @Test
461     public void testNestedUnionResolving() {
462         Module foo = TestUtils.findModule(modules, "foo");
463         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("custom-union-leaf");
464
465         ExtendedType type = (ExtendedType) testleaf.getType();
466         QName testleafTypeQName = type.getQName();
467         assertEquals(bazNS, testleafTypeQName.getNamespace());
468         assertEquals(bazRev, testleafTypeQName.getRevision());
469         assertEquals("union1", testleafTypeQName.getLocalName());
470         assertNull(type.getUnits());
471         assertNull(type.getDefaultValue());
472         assertNull(type.getFractionDigits());
473         assertTrue(type.getLengthConstraints().isEmpty());
474         assertTrue(type.getPatternConstraints().isEmpty());
475         assertTrue(type.getRangeConstraints().isEmpty());
476
477         ExtendedType typeBase = (ExtendedType) type.getBaseType();
478         QName typeBaseQName = typeBase.getQName();
479         assertEquals(bazNS, typeBaseQName.getNamespace());
480         assertEquals(bazRev, typeBaseQName.getRevision());
481         assertEquals("union2", typeBaseQName.getLocalName());
482         assertNull(typeBase.getUnits());
483         assertNull(typeBase.getDefaultValue());
484         assertNull(typeBase.getFractionDigits());
485         assertTrue(typeBase.getLengthConstraints().isEmpty());
486         assertTrue(typeBase.getPatternConstraints().isEmpty());
487         assertTrue(typeBase.getRangeConstraints().isEmpty());
488
489         UnionType union = (UnionType) typeBase.getBaseType();
490         List<TypeDefinition<?>> unionTypes = union.getTypes();
491         assertEquals(2, unionTypes.size());
492         assertTrue(unionTypes.get(0) instanceof Int32);
493         assertTrue(unionTypes.get(1) instanceof ExtendedType);
494
495         ExtendedType unionType1 = (ExtendedType) unionTypes.get(1);
496         QName uniontType1QName = unionType1.getQName();
497         assertEquals(barNS, uniontType1QName.getNamespace());
498         assertEquals(barRev, uniontType1QName.getRevision());
499         assertEquals("nested-union2", uniontType1QName.getLocalName());
500         assertNull(unionType1.getUnits());
501         assertNull(unionType1.getDefaultValue());
502         assertNull(unionType1.getFractionDigits());
503         assertTrue(unionType1.getLengthConstraints().isEmpty());
504         assertTrue(unionType1.getPatternConstraints().isEmpty());
505         assertTrue(unionType1.getRangeConstraints().isEmpty());
506
507         UnionType nestedUnion = (UnionType) unionType1.getBaseType();
508         List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
509         assertEquals(2, nestedUnion2Types.size());
510         assertTrue(nestedUnion2Types.get(0) instanceof StringType);
511         assertTrue(nestedUnion2Types.get(1) instanceof ExtendedType);
512
513         ExtendedType myUnionExt = (ExtendedType) nestedUnion2Types.get(1);
514         QName myUnionExtQName = myUnionExt.getQName();
515         assertEquals(barNS, myUnionExtQName.getNamespace());
516         assertEquals(barRev, myUnionExtQName.getRevision());
517         assertEquals("my-union-ext", myUnionExtQName.getLocalName());
518         assertNull(myUnionExt.getUnits());
519         assertNull(myUnionExt.getDefaultValue());
520         assertNull(myUnionExt.getFractionDigits());
521         assertTrue(myUnionExt.getLengthConstraints().isEmpty());
522         assertTrue(myUnionExt.getPatternConstraints().isEmpty());
523         assertTrue(myUnionExt.getRangeConstraints().isEmpty());
524
525         ExtendedType myUnion = (ExtendedType) myUnionExt.getBaseType();
526         QName myUnionQName = myUnion.getQName();
527         assertEquals(barNS, myUnionQName.getNamespace());
528         assertEquals(barRev, myUnionQName.getRevision());
529         assertEquals("my-union", myUnionQName.getLocalName());
530         assertNull(myUnion.getUnits());
531         assertNull(myUnion.getDefaultValue());
532         assertNull(myUnion.getFractionDigits());
533         assertTrue(myUnion.getLengthConstraints().isEmpty());
534         assertTrue(myUnion.getPatternConstraints().isEmpty());
535         assertTrue(myUnion.getRangeConstraints().isEmpty());
536
537         UnionType myUnionBase = (UnionType) myUnion.getBaseType();
538         List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
539         assertEquals(2, myUnionBaseTypes.size());
540         assertTrue(myUnionBaseTypes.get(0) instanceof ExtendedType);
541         assertTrue(myUnionBaseTypes.get(1) instanceof Int32);
542
543         ExtendedType int16Ext = (ExtendedType) myUnionBaseTypes.get(0);
544         QName int16ExtQName = int16Ext.getQName();
545         assertEquals(barNS, int16ExtQName.getNamespace());
546         assertEquals(barRev, int16ExtQName.getRevision());
547         assertEquals("int16", int16ExtQName.getLocalName());
548         assertNull(int16Ext.getUnits());
549         assertNull(int16Ext.getDefaultValue());
550         assertNull(int16Ext.getFractionDigits());
551         assertTrue(int16Ext.getLengthConstraints().isEmpty());
552         assertTrue(int16Ext.getPatternConstraints().isEmpty());
553         List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
554         assertEquals(1, ranges.size());
555         RangeConstraint range = ranges.get(0);
556         assertEquals(BigInteger.ONE, range.getMin());
557         assertEquals(BigInteger.valueOf(100), range.getMax());
558
559         assertTrue(int16Ext.getBaseType() instanceof Int16);
560     }
561
562     @Test
563     public void testChoice() {
564         Module foo = TestUtils.findModule(modules, "foo");
565         ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName("transfer");
566         ChoiceNode how = (ChoiceNode) transfer.getDataChildByName("how");
567         Set<ChoiceCaseNode> cases = how.getCases();
568         assertEquals(5, cases.size());
569         ChoiceCaseNode input = null;
570         ChoiceCaseNode output = null;
571         for (ChoiceCaseNode caseNode : cases) {
572             if ("input".equals(caseNode.getQName().getLocalName())) {
573                 input = caseNode;
574             } else if ("output".equals(caseNode.getQName().getLocalName())) {
575                 output = caseNode;
576             }
577         }
578         assertNotNull(input);
579         assertNotNull(input.getPath());
580         assertNotNull(output);
581         assertNotNull(output.getPath());
582     }
583
584     @Test
585     public void testDeviation() {
586         Module foo = TestUtils.findModule(modules, "foo");
587         Set<Deviation> deviations = foo.getDeviations();
588         assertEquals(1, deviations.size());
589         Deviation dev = deviations.iterator().next();
590         assertEquals("system/user ref", dev.getReference());
591
592         List<QName> path = new ArrayList<>();
593         path.add(new QName(barNS, barRev, "br", "interfaces"));
594         path.add(new QName(barNS, barRev, "br", "ifEntry"));
595         SchemaPath expectedPath = SchemaPath.create(path, true);
596
597         assertEquals(expectedPath, dev.getTargetPath());
598         assertEquals(Deviate.ADD, dev.getDeviate());
599     }
600
601     @Test
602     public void testUnknownNode() {
603         Module baz = TestUtils.findModule(modules, "baz");
604         ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName("network");
605         List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
606         assertEquals(1, unknownNodes.size());
607         UnknownSchemaNode unknownNode = unknownNodes.get(0);
608         assertNotNull(unknownNode.getNodeType());
609         assertEquals("point", unknownNode.getNodeParameter());
610     }
611
612     @Test
613     public void testFeature() {
614         Module baz = TestUtils.findModule(modules, "baz");
615         Set<FeatureDefinition> features = baz.getFeatures();
616         assertEquals(1, features.size());
617     }
618
619     @Test
620     public void testExtension() {
621         Module baz = TestUtils.findModule(modules, "baz");
622         List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
623         assertEquals(1, extensions.size());
624         ExtensionDefinition extension = extensions.get(0);
625         assertEquals("name", extension.getArgument());
626         assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.",
627                 extension.getDescription());
628         assertTrue(extension.isYinElement());
629     }
630
631     @Test
632     public void testNotification() {
633         Module baz = TestUtils.findModule(modules, "baz");
634         String expectedPrefix = "c";
635
636         Set<NotificationDefinition> notifications = baz.getNotifications();
637         assertEquals(1, notifications.size());
638
639         NotificationDefinition notification = notifications.iterator().next();
640         // test SchemaNode args
641         QName expectedQName = new QName(bazNS, bazRev, expectedPrefix, "event");
642         assertEquals(expectedQName, notification.getQName());
643         SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event");
644         assertEquals(expectedPath, notification.getPath());
645         assertNull(notification.getDescription());
646         assertNull(notification.getReference());
647         assertEquals(Status.CURRENT, notification.getStatus());
648         assertEquals(0, notification.getUnknownSchemaNodes().size());
649         // test DataNodeContainer args
650         assertEquals(0, notification.getTypeDefinitions().size());
651         assertEquals(3, notification.getChildNodes().size());
652         assertEquals(0, notification.getGroupings().size());
653         assertEquals(0, notification.getUses().size());
654
655         LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName("event-class");
656         assertTrue(eventClass.getType() instanceof StringType);
657         LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName("severity");
658         assertTrue(severity.getType() instanceof StringType);
659     }
660
661     @Test
662     public void testRpc() {
663         Module baz = TestUtils.findModule(modules, "baz");
664
665         Set<RpcDefinition> rpcs = baz.getRpcs();
666         assertEquals(1, rpcs.size());
667
668         RpcDefinition rpc = rpcs.iterator().next();
669         assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
670         assertEquals("RFC 6241, Section 7.1", rpc.getReference());
671     }
672
673     @Test
674     public void testTypePath() throws ParseException {
675         Module bar = TestUtils.findModule(modules, "bar");
676         Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
677
678         // int32-ext1
679         ExtendedType int32ext1 = (ExtendedType) TestUtils.findTypedef(types, "int32-ext1");
680         QName int32TypedefQName = int32ext1.getQName();
681
682         assertEquals(barNS, int32TypedefQName.getNamespace());
683         assertEquals(barRev, int32TypedefQName.getRevision());
684         assertEquals("int32-ext1", int32TypedefQName.getLocalName());
685
686         SchemaPath typeSchemaPath = int32ext1.getPath();
687         Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
688         Iterator<QName> typePathIt = typePath.iterator();
689         assertEquals(int32TypedefQName, typePathIt.next());
690         assertFalse(typePathIt.hasNext());
691
692         // int32-ext1/int32
693         Int32 int32 = (Int32) int32ext1.getBaseType();
694         assertEquals(Int32.getInstance(), int32);
695     }
696
697     @Test
698     public void testTypePath2() throws ParseException {
699         Module bar = TestUtils.findModule(modules, "bar");
700         Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
701
702         // my-decimal-type
703         ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types, "my-decimal-type");
704         QName myDecTypeQName = myDecType.getQName();
705
706         assertEquals(barNS, myDecTypeQName.getNamespace());
707         assertEquals(barRev, myDecTypeQName.getRevision());
708         assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
709
710         SchemaPath typeSchemaPath = myDecType.getPath();
711         Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
712         Iterator<QName> typePathIt = typePath.iterator();
713         assertEquals(myDecTypeQName, typePathIt.next());
714         assertFalse(typePathIt.hasNext());
715
716         // my-base-int32-type/int32
717         Decimal64 dec64 = (Decimal64) myDecType.getBaseType();
718         QName dec64QName = dec64.getQName();
719
720         assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), dec64QName.getNamespace());
721         assertNull(dec64QName.getRevision());
722         assertEquals("decimal64", dec64QName.getLocalName());
723
724         SchemaPath dec64SchemaPath = dec64.getPath();
725         Iterable<QName> dec64Path = dec64SchemaPath.getPathFromRoot();
726         Iterator<QName> dec64PathIt = dec64Path.iterator();
727         assertEquals(myDecTypeQName, dec64PathIt.next());
728         assertEquals(dec64QName, dec64PathIt.next());
729         assertFalse(dec64PathIt.hasNext());
730     }
731
732     @Test
733     public void testParseMethod1() throws Exception {
734         File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI());
735         File dependenciesDir = new File(getClass().getResource("/parse-methods").toURI());
736         YangContextParser parser = new YangParserImpl();
737         modules = parser.parseFile(yangFile, dependenciesDir).getModules();
738         assertEquals(6, modules.size());
739     }
740
741     @Test
742     public void testParseMethod2() throws Exception {
743         File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI());
744         File dependenciesDir = new File(getClass().getResource("/parse-methods/dependencies").toURI());
745         YangContextParser parser = new YangParserImpl();
746         modules = parser.parseFile(yangFile, dependenciesDir).getModules();
747         assertEquals(6, modules.size());
748     }
749
750     @Test
751     public void testSorting() throws Exception {
752         // Correct order: m2, m4, m6, m8, m7, m6, m3, m1
753         File yangFile = new File(getClass().getResource("/sorting-test/m1.yang").toURI());
754         File dependenciesDir = new File(getClass().getResource("/sorting-test").toURI());
755         YangContextParser parser = new YangParserImpl();
756         modules = parser.parseFile(yangFile, dependenciesDir).getModules();
757         SchemaContext ctx = new SchemaContextImpl(modules, Collections.<ModuleIdentifier, String> emptyMap());
758         checkOrder(modules);
759         assertSetEquals(modules, ctx.getModules());
760
761         // ##########
762         parser = new YangParserImpl();
763         final File testDir = dependenciesDir;
764         final String[] fileList = testDir.list();
765         final List<File> testFiles = new ArrayList<>();
766         if (fileList == null) {
767             throw new FileNotFoundException(dependenciesDir.getAbsolutePath());
768         }
769         for (String fileName : fileList) {
770             testFiles.add(new File(testDir, fileName));
771         }
772         Set<Module> newModules = parser.parseFiles(testFiles).getModules();
773         assertSetEquals(newModules, modules);
774         ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
775         assertSetEquals(newModules, ctx.getModules());
776         // ##########
777         newModules = parser.parseFiles(testFiles, null).getModules();
778         assertSetEquals(newModules, modules);
779         ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
780         assertSetEquals(newModules, ctx.getModules());
781         // ##########
782         List<InputStream> streams = new ArrayList<>();
783         for (File f : testFiles) {
784             streams.add(new FileInputStream(f));
785         }
786         newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles)).getModules();
787         assertSetEquals(newModules, modules);
788         ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
789         assertSetEquals(newModules, ctx.getModules());
790         // ##########
791         streams.clear();
792         for (File f : testFiles) {
793             streams.add(new FileInputStream(f));
794         }
795         newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles), null).getModules();
796         assertSetEquals(newModules, modules);
797         ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
798         assertSetEquals(newModules, ctx.getModules());
799         // ##########
800         Map<File, Module> mapped = parser.parseYangModelsMapped(testFiles);
801         newModules = new LinkedHashSet<>(mapped.values());
802         assertSetEquals(newModules, modules);
803         ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
804         assertSetEquals(newModules, ctx.getModules());
805         // ##########
806         streams.clear();
807         for (File f : testFiles) {
808             streams.add(new FileInputStream(f));
809         }
810         Map<InputStream, Module> mappedStreams = parser.parseYangModelsFromStreamsMapped(streams);
811         newModules = new LinkedHashSet<>(mappedStreams.values());
812         assertSetEquals(newModules, modules);
813         ctx = new SchemaContextImpl(newModules, Collections.<ModuleIdentifier, String> emptyMap());
814         assertSetEquals(newModules, ctx.getModules());
815     }
816
817     private void checkOrder(final Collection<Module> modules) {
818         Iterator<Module> it = modules.iterator();
819         Module m = it.next();
820         assertEquals("m2", m.getName());
821         m = it.next();
822         assertEquals("m4", m.getName());
823         m = it.next();
824         assertEquals("m6", m.getName());
825         m = it.next();
826         assertEquals("m8", m.getName());
827         m = it.next();
828         assertEquals("m7", m.getName());
829         m = it.next();
830         assertEquals("m5", m.getName());
831         m = it.next();
832         assertEquals("m3", m.getName());
833         m = it.next();
834         assertEquals("m1", m.getName());
835     }
836
837     private void assertSetEquals(final Set<Module> s1, final Set<Module> s2) {
838         assertEquals(s1, s2);
839         Iterator<Module> it = s1.iterator();
840         for (Module m : s2) {
841             assertEquals(m, it.next());
842         }
843     }
844
845     @Test
846     public void testSubmodules() throws Exception {
847         URI yangFilePath = getClass().getResource("/submodule-test/subfoo.yang").toURI();
848         URI directoryPath = getClass().getResource("/model").toURI();
849
850         File directory = new File(directoryPath);
851         File yangFile = new File(yangFilePath);
852
853         Set<Module> modules = new YangParserImpl().parseFile(yangFile, directory).getModules();
854         assertEquals(3, modules.size());
855
856         Module foo = TestUtils.findModule(modules, "foo");
857
858         DataSchemaNode id = foo.getDataChildByName("id");
859         assertNotNull(id);
860         DataSchemaNode subExt = foo.getDataChildByName("sub-ext");
861         assertNotNull(subExt);
862         DataSchemaNode subTransfer = foo.getDataChildByName("sub-transfer");
863         assertNotNull(subTransfer);
864
865         assertEquals(2, foo.getExtensionSchemaNodes().size());
866         assertEquals(2, foo.getAugmentations().size());
867     }
868
869 }