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