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