Instance identifier in XML output was added
[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         assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
217         assertTrue(ifIndex.getType() instanceof Uint32);
218         LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName("ifMtu");
219         assertTrue(ifMtu.getType() instanceof Int32);
220     }
221
222     @Test
223     public void testTypedefRangesResolving() throws ParseException {
224         Module foo = TestUtils.findModule(modules, "foo");
225         LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName("int32-leaf");
226
227         ExtendedType leafType = (ExtendedType) int32Leaf.getType();
228         QName leafTypeQName = leafType.getQName();
229         assertEquals("int32-ext2", leafTypeQName.getLocalName());
230         assertEquals("foo", leafTypeQName.getPrefix());
231         assertEquals(fooNS, leafTypeQName.getNamespace());
232         assertEquals(fooRev, leafTypeQName.getRevision());
233         assertNull(leafType.getUnits());
234         assertNull(leafType.getDefaultValue());
235         assertTrue(leafType.getLengthConstraints().isEmpty());
236         assertTrue(leafType.getPatternConstraints().isEmpty());
237         List<RangeConstraint> ranges = leafType.getRangeConstraints();
238         assertEquals(1, ranges.size());
239         RangeConstraint range = ranges.get(0);
240         assertEquals(12L, range.getMin());
241         assertEquals(20L, range.getMax());
242
243         ExtendedType baseType = (ExtendedType) leafType.getBaseType();
244         QName baseTypeQName = baseType.getQName();
245         assertEquals("int32-ext2", baseTypeQName.getLocalName());
246         assertEquals("bar", baseTypeQName.getPrefix());
247         assertEquals(barNS, baseTypeQName.getNamespace());
248         assertEquals(barRev, baseTypeQName.getRevision());
249         assertEquals("mile", baseType.getUnits());
250         assertEquals("11", baseType.getDefaultValue());
251         assertTrue(leafType.getLengthConstraints().isEmpty());
252         assertTrue(leafType.getPatternConstraints().isEmpty());
253         List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
254         assertEquals(2, baseTypeRanges.size());
255         RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
256         assertEquals(3L, baseTypeRange1.getMin());
257         assertEquals(9L, baseTypeRange1.getMax());
258         RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
259         assertEquals(11L, baseTypeRange2.getMin());
260         assertEquals(20L, baseTypeRange2.getMax());
261
262         ExtendedType base = (ExtendedType) baseType.getBaseType();
263         QName baseQName = base.getQName();
264         assertEquals("int32-ext1", baseQName.getLocalName());
265         assertEquals("bar", baseQName.getPrefix());
266         assertEquals(barNS, baseQName.getNamespace());
267         assertEquals(barRev, baseQName.getRevision());
268         assertNull(base.getUnits());
269         assertNull(base.getDefaultValue());
270         assertTrue(leafType.getLengthConstraints().isEmpty());
271         assertTrue(leafType.getPatternConstraints().isEmpty());
272         List<RangeConstraint> baseRanges = base.getRangeConstraints();
273         assertEquals(1, baseRanges.size());
274         RangeConstraint baseRange = baseRanges.get(0);
275         assertEquals(2L, baseRange.getMin());
276         assertEquals(20L, baseRange.getMax());
277
278         assertTrue(base.getBaseType() instanceof Int32);
279     }
280
281     @Test
282     public void testTypedefPatternsResolving() {
283         Module foo = TestUtils.findModule(modules, "foo");
284         LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName("string-leaf");
285
286         ExtendedType type = (ExtendedType) stringleaf.getType();
287         QName typeQName = type.getQName();
288         assertEquals("string-ext4", typeQName.getLocalName());
289         assertEquals("bar", typeQName.getPrefix());
290         assertEquals(barNS, typeQName.getNamespace());
291         assertEquals(barRev, typeQName.getRevision());
292         assertNull(type.getUnits());
293         assertNull(type.getDefaultValue());
294         List<PatternConstraint> patterns = type.getPatternConstraints();
295         assertEquals(1, patterns.size());
296         PatternConstraint pattern = patterns.iterator().next();
297         assertEquals("[e-z]*", pattern.getRegularExpression());
298         assertTrue(type.getLengthConstraints().isEmpty());
299         assertTrue(type.getRangeConstraints().isEmpty());
300
301         ExtendedType baseType1 = (ExtendedType) type.getBaseType();
302         QName baseType1QName = baseType1.getQName();
303         assertEquals("string-ext3", baseType1QName.getLocalName());
304         assertEquals("bar", baseType1QName.getPrefix());
305         assertEquals(barNS, baseType1QName.getNamespace());
306         assertEquals(barRev, baseType1QName.getRevision());
307         assertNull(baseType1.getUnits());
308         assertNull(baseType1.getDefaultValue());
309         patterns = baseType1.getPatternConstraints();
310         assertEquals(1, patterns.size());
311         pattern = patterns.iterator().next();
312         assertEquals("[b-u]*", pattern.getRegularExpression());
313         assertTrue(baseType1.getLengthConstraints().isEmpty());
314         assertTrue(baseType1.getRangeConstraints().isEmpty());
315
316         ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
317         QName baseType2QName = baseType2.getQName();
318         assertEquals("string-ext2", baseType2QName.getLocalName());
319         assertEquals("bar", baseType2QName.getPrefix());
320         assertEquals(barNS, baseType2QName.getNamespace());
321         assertEquals(barRev, baseType2QName.getRevision());
322         assertNull(baseType2.getUnits());
323         assertNull(baseType2.getDefaultValue());
324         assertTrue(baseType2.getPatternConstraints().isEmpty());
325         List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
326         assertEquals(1, baseType2Lengths.size());
327         LengthConstraint length = baseType2Lengths.get(0);
328         assertEquals(6L, length.getMin());
329         assertEquals(10L, length.getMax());
330         assertTrue(baseType2.getRangeConstraints().isEmpty());
331
332         ExtendedType baseType3 = (ExtendedType) baseType2.getBaseType();
333         QName baseType3QName = baseType3.getQName();
334         assertEquals("string-ext1", baseType3QName.getLocalName());
335         assertEquals("bar", baseType3QName.getPrefix());
336         assertEquals(barNS, baseType3QName.getNamespace());
337         assertEquals(barRev, baseType3QName.getRevision());
338         assertNull(baseType3.getUnits());
339         assertNull(baseType3.getDefaultValue());
340         patterns = baseType3.getPatternConstraints();
341         assertEquals(1, patterns.size());
342         pattern = patterns.iterator().next();
343         assertEquals("[a-k]*", pattern.getRegularExpression());
344         List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
345         assertEquals(1, baseType3Lengths.size());
346         length = baseType3Lengths.get(0);
347         assertEquals(5L, length.getMin());
348         assertEquals(11L, length.getMax());
349         assertTrue(baseType3.getRangeConstraints().isEmpty());
350
351         assertTrue(baseType3.getBaseType() instanceof StringType);
352     }
353
354     @Test
355     public void testTypedefLengthsResolving() {
356         Module foo = TestUtils.findModule(modules, "foo");
357
358         LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName("length-leaf");
359         ExtendedType type = (ExtendedType) lengthLeaf.getType();
360
361         QName typeQName = type.getQName();
362         assertEquals("string-ext2", typeQName.getLocalName());
363         assertEquals("foo", typeQName.getPrefix());
364         assertEquals(fooNS, typeQName.getNamespace());
365         assertEquals(fooRev, typeQName.getRevision());
366         assertNull(type.getUnits());
367         assertNull(type.getDefaultValue());
368         assertTrue(type.getPatternConstraints().isEmpty());
369         List<LengthConstraint> typeLengths = type.getLengthConstraints();
370         assertEquals(1, typeLengths.size());
371         LengthConstraint length = typeLengths.get(0);
372         assertEquals(7L, length.getMin());
373         assertEquals(10L, length.getMax());
374         assertTrue(type.getRangeConstraints().isEmpty());
375
376         ExtendedType baseType1 = (ExtendedType) type.getBaseType();
377         QName baseType1QName = baseType1.getQName();
378         assertEquals("string-ext2", baseType1QName.getLocalName());
379         assertEquals("bar", baseType1QName.getPrefix());
380         assertEquals(barNS, baseType1QName.getNamespace());
381         assertEquals(barRev, baseType1QName.getRevision());
382         assertNull(baseType1.getUnits());
383         assertNull(baseType1.getDefaultValue());
384         assertTrue(baseType1.getPatternConstraints().isEmpty());
385         List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
386         assertEquals(1, baseType2Lengths.size());
387         length = baseType2Lengths.get(0);
388         assertEquals(6L, length.getMin());
389         assertEquals(10L, length.getMax());
390         assertTrue(baseType1.getRangeConstraints().isEmpty());
391
392         ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType();
393         QName baseType2QName = baseType2.getQName();
394         assertEquals("string-ext1", baseType2QName.getLocalName());
395         assertEquals("bar", baseType2QName.getPrefix());
396         assertEquals(barNS, baseType2QName.getNamespace());
397         assertEquals(barRev, baseType2QName.getRevision());
398         assertNull(baseType2.getUnits());
399         assertNull(baseType2.getDefaultValue());
400         List<PatternConstraint> patterns = baseType2.getPatternConstraints();
401         assertEquals(1, patterns.size());
402         PatternConstraint pattern = patterns.iterator().next();
403         assertEquals("[a-k]*", pattern.getRegularExpression());
404         List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
405         assertEquals(1, baseType3Lengths.size());
406         length = baseType3Lengths.get(0);
407         assertEquals(5L, length.getMin());
408         assertEquals(11L, length.getMax());
409         assertTrue(baseType2.getRangeConstraints().isEmpty());
410
411         assertTrue(baseType2.getBaseType() instanceof StringType);
412     }
413
414     @Test
415     public void testTypedefDecimal1() {
416         Module foo = TestUtils.findModule(modules, "foo");
417         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf");
418
419         ExtendedType type = (ExtendedType) testleaf.getType();
420         QName typeQName = type.getQName();
421         assertEquals("my-decimal-type", typeQName.getLocalName());
422         assertEquals("foo", typeQName.getPrefix());
423         assertEquals(fooNS, typeQName.getNamespace());
424         assertEquals(fooRev, typeQName.getRevision());
425         assertNull(type.getUnits());
426         assertNull(type.getDefaultValue());
427         assertEquals(4, (int) type.getFractionDigits());
428         assertTrue(type.getLengthConstraints().isEmpty());
429         assertTrue(type.getPatternConstraints().isEmpty());
430         assertTrue(type.getRangeConstraints().isEmpty());
431
432         ExtendedType typeBase = (ExtendedType) type.getBaseType();
433         QName typeBaseQName = typeBase.getQName();
434         assertEquals("my-decimal-type", typeBaseQName.getLocalName());
435         assertEquals("bar", typeBaseQName.getPrefix());
436         assertEquals(barNS, typeBaseQName.getNamespace());
437         assertEquals(barRev, typeBaseQName.getRevision());
438         assertNull(typeBase.getUnits());
439         assertNull(typeBase.getDefaultValue());
440         assertNull(typeBase.getFractionDigits());
441         assertTrue(typeBase.getLengthConstraints().isEmpty());
442         assertTrue(typeBase.getPatternConstraints().isEmpty());
443         assertTrue(typeBase.getRangeConstraints().isEmpty());
444
445         Decimal64 decimal = (Decimal64) typeBase.getBaseType();
446         assertEquals(6, (int) decimal.getFractionDigits());
447     }
448
449     @Test
450     public void testTypedefDecimal2() {
451         Module foo = TestUtils.findModule(modules, "foo");
452         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf2");
453
454         ExtendedType type = (ExtendedType) testleaf.getType();
455         QName typeQName = type.getQName();
456         assertEquals("my-decimal-type", typeQName.getLocalName());
457         assertEquals("bar", typeQName.getPrefix());
458         assertEquals(barNS, typeQName.getNamespace());
459         assertEquals(barRev, typeQName.getRevision());
460         assertNull(type.getUnits());
461         assertNull(type.getDefaultValue());
462         assertNull(type.getFractionDigits());
463         assertTrue(type.getLengthConstraints().isEmpty());
464         assertTrue(type.getPatternConstraints().isEmpty());
465         assertTrue(type.getRangeConstraints().isEmpty());
466
467         Decimal64 baseTypeDecimal = (Decimal64) type.getBaseType();
468         assertEquals(6, (int) baseTypeDecimal.getFractionDigits());
469     }
470
471     @Test
472     public void testTypedefUnion() {
473         Module foo = TestUtils.findModule(modules, "foo");
474         LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName("union-leaf");
475
476         ExtendedType type = (ExtendedType) unionleaf.getType();
477         QName typeQName = type.getQName();
478         assertEquals("my-union-ext", typeQName.getLocalName());
479         assertEquals("bar", typeQName.getPrefix());
480         assertEquals(barNS, typeQName.getNamespace());
481         assertEquals(barRev, typeQName.getRevision());
482         assertNull(type.getUnits());
483         assertNull(type.getDefaultValue());
484         assertNull(type.getFractionDigits());
485         assertTrue(type.getLengthConstraints().isEmpty());
486         assertTrue(type.getPatternConstraints().isEmpty());
487         assertTrue(type.getRangeConstraints().isEmpty());
488
489         ExtendedType baseType = (ExtendedType) type.getBaseType();
490         QName baseTypeQName = baseType.getQName();
491         assertEquals("my-union", baseTypeQName.getLocalName());
492         assertEquals("bar", baseTypeQName.getPrefix());
493         assertEquals(barNS, baseTypeQName.getNamespace());
494         assertEquals(barRev, baseTypeQName.getRevision());
495         assertNull(baseType.getUnits());
496         assertNull(baseType.getDefaultValue());
497         assertNull(baseType.getFractionDigits());
498         assertTrue(baseType.getLengthConstraints().isEmpty());
499         assertTrue(baseType.getPatternConstraints().isEmpty());
500         assertTrue(baseType.getRangeConstraints().isEmpty());
501
502         UnionType unionType = (UnionType) baseType.getBaseType();
503         List<TypeDefinition<?>> unionTypes = unionType.getTypes();
504         assertEquals(2, unionTypes.size());
505
506         ExtendedType unionType1 = (ExtendedType) unionTypes.get(0);
507         QName unionType1QName = baseType.getQName();
508         assertEquals("my-union", unionType1QName.getLocalName());
509         assertEquals("bar", unionType1QName.getPrefix());
510         assertEquals(barNS, unionType1QName.getNamespace());
511         assertEquals(barRev, unionType1QName.getRevision());
512         assertNull(unionType1.getUnits());
513         assertNull(unionType1.getDefaultValue());
514         assertNull(unionType1.getFractionDigits());
515         assertTrue(unionType1.getLengthConstraints().isEmpty());
516         assertTrue(unionType1.getPatternConstraints().isEmpty());
517         List<RangeConstraint> ranges = unionType1.getRangeConstraints();
518         assertEquals(1, ranges.size());
519         RangeConstraint range = ranges.get(0);
520         assertEquals(1L, range.getMin());
521         assertEquals(100L, range.getMax());
522         assertTrue(unionType1.getBaseType() instanceof Int16);
523
524         assertTrue(unionTypes.get(1) instanceof Int32);
525     }
526
527     @Test
528     public void testNestedUnionResolving() {
529         Module foo = TestUtils.findModule(modules, "foo");
530         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("custom-union-leaf");
531
532         ExtendedType type = (ExtendedType) testleaf.getType();
533         QName testleafTypeQName = type.getQName();
534         assertEquals(bazNS, testleafTypeQName.getNamespace());
535         assertEquals(bazRev, testleafTypeQName.getRevision());
536         assertEquals("baz", testleafTypeQName.getPrefix());
537         assertEquals("union1", testleafTypeQName.getLocalName());
538         assertNull(type.getUnits());
539         assertNull(type.getDefaultValue());
540         assertNull(type.getFractionDigits());
541         assertTrue(type.getLengthConstraints().isEmpty());
542         assertTrue(type.getPatternConstraints().isEmpty());
543         assertTrue(type.getRangeConstraints().isEmpty());
544
545         ExtendedType typeBase = (ExtendedType) type.getBaseType();
546         QName typeBaseQName = typeBase.getQName();
547         assertEquals(bazNS, typeBaseQName.getNamespace());
548         assertEquals(bazRev, typeBaseQName.getRevision());
549         assertEquals("baz", typeBaseQName.getPrefix());
550         assertEquals("union2", typeBaseQName.getLocalName());
551         assertNull(typeBase.getUnits());
552         assertNull(typeBase.getDefaultValue());
553         assertNull(typeBase.getFractionDigits());
554         assertTrue(typeBase.getLengthConstraints().isEmpty());
555         assertTrue(typeBase.getPatternConstraints().isEmpty());
556         assertTrue(typeBase.getRangeConstraints().isEmpty());
557
558         UnionType union = (UnionType) typeBase.getBaseType();
559         List<TypeDefinition<?>> unionTypes = union.getTypes();
560         assertEquals(2, unionTypes.size());
561         assertTrue(unionTypes.get(0) instanceof Int32);
562         assertTrue(unionTypes.get(1) instanceof ExtendedType);
563
564         ExtendedType unionType1 = (ExtendedType) unionTypes.get(1);
565         QName uniontType1QName = unionType1.getQName();
566         assertEquals(barNS, uniontType1QName.getNamespace());
567         assertEquals(barRev, uniontType1QName.getRevision());
568         assertEquals("bar", uniontType1QName.getPrefix());
569         assertEquals("nested-union2", uniontType1QName.getLocalName());
570         assertNull(unionType1.getUnits());
571         assertNull(unionType1.getDefaultValue());
572         assertNull(unionType1.getFractionDigits());
573         assertTrue(unionType1.getLengthConstraints().isEmpty());
574         assertTrue(unionType1.getPatternConstraints().isEmpty());
575         assertTrue(unionType1.getRangeConstraints().isEmpty());
576
577         UnionType nestedUnion = (UnionType) unionType1.getBaseType();
578         List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
579         assertEquals(2, nestedUnion2Types.size());
580         assertTrue(nestedUnion2Types.get(0) instanceof StringType);
581         assertTrue(nestedUnion2Types.get(1) instanceof ExtendedType);
582
583         ExtendedType myUnionExt = (ExtendedType) nestedUnion2Types.get(1);
584         QName myUnionExtQName = myUnionExt.getQName();
585         assertEquals(barNS, myUnionExtQName.getNamespace());
586         assertEquals(barRev, myUnionExtQName.getRevision());
587         assertEquals("bar", myUnionExtQName.getPrefix());
588         assertEquals("my-union-ext", myUnionExtQName.getLocalName());
589         assertNull(myUnionExt.getUnits());
590         assertNull(myUnionExt.getDefaultValue());
591         assertNull(myUnionExt.getFractionDigits());
592         assertTrue(myUnionExt.getLengthConstraints().isEmpty());
593         assertTrue(myUnionExt.getPatternConstraints().isEmpty());
594         assertTrue(myUnionExt.getRangeConstraints().isEmpty());
595
596         ExtendedType myUnion = (ExtendedType) myUnionExt.getBaseType();
597         QName myUnionQName = myUnion.getQName();
598         assertEquals(barNS, myUnionQName.getNamespace());
599         assertEquals(barRev, myUnionQName.getRevision());
600         assertEquals("bar", myUnionQName.getPrefix());
601         assertEquals("my-union", myUnionQName.getLocalName());
602         assertNull(myUnion.getUnits());
603         assertNull(myUnion.getDefaultValue());
604         assertNull(myUnion.getFractionDigits());
605         assertTrue(myUnion.getLengthConstraints().isEmpty());
606         assertTrue(myUnion.getPatternConstraints().isEmpty());
607         assertTrue(myUnion.getRangeConstraints().isEmpty());
608
609         UnionType myUnionBase = (UnionType) myUnion.getBaseType();
610         List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
611         assertEquals(2, myUnionBaseTypes.size());
612         assertTrue(myUnionBaseTypes.get(0) instanceof ExtendedType);
613         assertTrue(myUnionBaseTypes.get(1) instanceof Int32);
614
615         ExtendedType int16Ext = (ExtendedType) myUnionBaseTypes.get(0);
616         QName int16ExtQName = int16Ext.getQName();
617         assertEquals(barNS, int16ExtQName.getNamespace());
618         assertEquals(barRev, int16ExtQName.getRevision());
619         assertEquals("bar", int16ExtQName.getPrefix());
620         assertEquals("int16", int16ExtQName.getLocalName());
621         assertNull(int16Ext.getUnits());
622         assertNull(int16Ext.getDefaultValue());
623         assertNull(int16Ext.getFractionDigits());
624         assertTrue(int16Ext.getLengthConstraints().isEmpty());
625         assertTrue(int16Ext.getPatternConstraints().isEmpty());
626         List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
627         assertEquals(1, ranges.size());
628         RangeConstraint range = ranges.get(0);
629         assertEquals(1L, range.getMin());
630         assertEquals(100L, range.getMax());
631
632         assertTrue(int16Ext.getBaseType() instanceof Int16);
633     }
634
635     @Test
636     public void testChoice() {
637         Module foo = TestUtils.findModule(modules, "foo");
638         ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName("transfer");
639         ChoiceNode how = (ChoiceNode) transfer.getDataChildByName("how");
640         Set<ChoiceCaseNode> cases = how.getCases();
641         assertEquals(5, cases.size());
642         ChoiceCaseNode input = null;
643         ChoiceCaseNode output = null;
644         for (ChoiceCaseNode caseNode : cases) {
645             if ("input".equals(caseNode.getQName().getLocalName())) {
646                 input = caseNode;
647             } else if ("output".equals(caseNode.getQName().getLocalName())) {
648                 output = caseNode;
649             }
650         }
651         assertNotNull(input);
652         assertNotNull(input.getPath());
653         assertNotNull(output);
654         assertNotNull(output.getPath());
655     }
656
657     @Test
658     public void testDeviation() {
659         Module foo = TestUtils.findModule(modules, "foo");
660         Set<Deviation> deviations = foo.getDeviations();
661         assertEquals(1, deviations.size());
662         Deviation dev = deviations.iterator().next();
663         assertEquals("system/user ref", dev.getReference());
664
665         List<QName> path = new ArrayList<>();
666         path.add(new QName(barNS, barRev, "br", "interfaces"));
667         path.add(new QName(barNS, barRev, "br", "ifEntry"));
668         SchemaPath expectedPath = new SchemaPath(path, true);
669
670         assertEquals(expectedPath, dev.getTargetPath());
671         assertEquals(Deviate.ADD, dev.getDeviate());
672     }
673
674     @Test
675     public void testUnknownNode() {
676         Module baz = TestUtils.findModule(modules, "baz");
677         ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName("network");
678         List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
679         assertEquals(1, unknownNodes.size());
680         UnknownSchemaNode unknownNode = unknownNodes.get(0);
681         assertNotNull(unknownNode.getNodeType());
682         assertEquals("point", unknownNode.getNodeParameter());
683     }
684
685     @Test
686     public void testFeature() {
687         Module baz = TestUtils.findModule(modules, "baz");
688         Set<FeatureDefinition> features = baz.getFeatures();
689         assertEquals(1, features.size());
690     }
691
692     @Test
693     public void testExtension() {
694         Module baz = TestUtils.findModule(modules, "baz");
695         List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
696         assertEquals(1, extensions.size());
697         ExtensionDefinition extension = extensions.get(0);
698         assertEquals("name", extension.getArgument());
699         assertTrue(extension.isYinElement());
700     }
701
702     @Test
703     public void testNotification() {
704         Module baz = TestUtils.findModule(modules, "baz");
705         String expectedPrefix = "c";
706
707         Set<NotificationDefinition> notifications = baz.getNotifications();
708         assertEquals(1, notifications.size());
709
710         NotificationDefinition notification = notifications.iterator().next();
711         // test SchemaNode args
712         QName expectedQName = new QName(bazNS, bazRev, expectedPrefix, "event");
713         assertEquals(expectedQName, notification.getQName());
714         SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event");
715         assertEquals(expectedPath, notification.getPath());
716         assertNull(notification.getDescription());
717         assertNull(notification.getReference());
718         assertEquals(Status.CURRENT, notification.getStatus());
719         assertEquals(0, notification.getUnknownSchemaNodes().size());
720         // test DataNodeContainer args
721         assertEquals(0, notification.getTypeDefinitions().size());
722         assertEquals(3, notification.getChildNodes().size());
723         assertEquals(0, notification.getGroupings().size());
724         assertEquals(0, notification.getUses().size());
725
726         LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName("event-class");
727         assertTrue(eventClass.getType() instanceof StringType);
728         LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName("severity");
729         assertTrue(severity.getType() instanceof StringType);
730     }
731
732     @Test
733     public void testRpc() {
734         Module baz = TestUtils.findModule(modules, "baz");
735
736         Set<RpcDefinition> rpcs = baz.getRpcs();
737         assertEquals(1, rpcs.size());
738
739         RpcDefinition rpc = rpcs.iterator().next();
740         assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
741         assertEquals("RFC 6241, Section 7.1", rpc.getReference());
742     }
743
744     @Test
745     public void testTypePath() throws ParseException {
746         Module bar = TestUtils.findModule(modules, "bar");
747         Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
748
749         // int32-ext1
750         ExtendedType int32ext1 = (ExtendedType) TestUtils.findTypedef(types, "int32-ext1");
751         QName int32TypedefQName = int32ext1.getQName();
752
753         assertEquals(barNS, int32TypedefQName.getNamespace());
754         assertEquals(barRev, int32TypedefQName.getRevision());
755         assertEquals("bar", int32TypedefQName.getPrefix());
756         assertEquals("int32-ext1", int32TypedefQName.getLocalName());
757
758         SchemaPath typeSchemaPath = int32ext1.getPath();
759         List<QName> typePath = typeSchemaPath.getPath();
760         assertEquals(1, typePath.size());
761         assertEquals(int32TypedefQName, typePath.get(0));
762
763         // int32-ext1/int32
764         Int32 int32 = (Int32) int32ext1.getBaseType();
765         assertEquals(Int32.getInstance(), int32);
766     }
767
768     @Test
769     public void testTypePath2() throws ParseException {
770         Module bar = TestUtils.findModule(modules, "bar");
771         Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
772
773         // my-decimal-type
774         ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types, "my-decimal-type");
775         QName myDecTypeQName = myDecType.getQName();
776
777         assertEquals(barNS, myDecTypeQName.getNamespace());
778         assertEquals(barRev, myDecTypeQName.getRevision());
779         assertEquals("bar", myDecTypeQName.getPrefix());
780         assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
781
782         SchemaPath typeSchemaPath = myDecType.getPath();
783         List<QName> typePath = typeSchemaPath.getPath();
784         assertEquals(1, typePath.size());
785         assertEquals(myDecTypeQName, typePath.get(0));
786
787         // my-base-int32-type/int32
788         Decimal64 dec64 = (Decimal64) myDecType.getBaseType();
789         QName dec64QName = dec64.getQName();
790
791         assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), dec64QName.getNamespace());
792         assertNull(dec64QName.getRevision());
793         assertEquals("", dec64QName.getPrefix());
794         assertEquals("decimal64", dec64QName.getLocalName());
795
796         SchemaPath dec64SchemaPath = dec64.getPath();
797         List<QName> dec64Path = dec64SchemaPath.getPath();
798         assertEquals(2, dec64Path.size());
799         assertEquals(myDecTypeQName, dec64Path.get(0));
800         assertEquals(dec64QName, dec64Path.get(1));
801     }
802
803     @Test
804     public void testParseMethod1() throws ParseException {
805         File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").getPath());
806         File dependenciesDir = new File(getClass().getResource("/parse-methods").getPath());
807         YangModelParser parser = new YangParserImpl();
808         modules = parser.parseYangModels(yangFile, dependenciesDir);
809         assertEquals(6, modules.size());
810     }
811
812     @Test
813     public void testParseMethod2() throws ParseException {
814         File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").getPath());
815         File dependenciesDir = new File(getClass().getResource("/parse-methods/dependencies").getPath());
816         YangModelParser parser = new YangParserImpl();
817         modules = parser.parseYangModels(yangFile, dependenciesDir);
818         assertEquals(6, modules.size());
819     }
820
821     @Test
822     public void testSorting() throws FileNotFoundException {
823         // Correct order: m2, m4, m6, m8, m7, m6, m3, m1
824         File yangFile = new File(getClass().getResource("/sorting-test/m1.yang").getPath());
825         File dependenciesDir = new File(getClass().getResource("/sorting-test").getPath());
826         YangModelParser parser = new YangParserImpl();
827         modules = parser.parseYangModels(yangFile, dependenciesDir);
828         SchemaContext ctx = new SchemaContextImpl(modules);
829         checkOrder(modules);
830         assertSetEquals(modules, ctx.getModules());
831
832         // ##########
833         parser = new YangParserImpl();
834         final File testDir = dependenciesDir;
835         final String[] fileList = testDir.list();
836         final List<File> testFiles = new ArrayList<>();
837         if (fileList == null) {
838             throw new FileNotFoundException(dependenciesDir.getAbsolutePath());
839         }
840         for (String fileName : fileList) {
841             testFiles.add(new File(testDir, fileName));
842         }
843         Set<Module> newModules = parser.parseYangModels(testFiles);
844         assertSetEquals(newModules, modules);
845         ctx = new SchemaContextImpl(newModules);
846         assertSetEquals(newModules, ctx.getModules());
847         // ##########
848         newModules = parser.parseYangModels(testFiles, null);
849         assertSetEquals(newModules, modules);
850         ctx = new SchemaContextImpl(newModules);
851         assertSetEquals(newModules, ctx.getModules());
852         // ##########
853         List<InputStream> streams = new ArrayList<>();
854         for (File f : testFiles) {
855             streams.add(new FileInputStream(f));
856         }
857         newModules = parser.parseYangModelsFromStreams(streams);
858         assertSetEquals(newModules, modules);
859         ctx = new SchemaContextImpl(newModules);
860         assertSetEquals(newModules, ctx.getModules());
861         // ##########
862         streams.clear();
863         for (File f : testFiles) {
864             streams.add(new FileInputStream(f));
865         }
866         newModules = parser.parseYangModelsFromStreams(streams, null);
867         assertSetEquals(newModules, modules);
868         ctx = new SchemaContextImpl(newModules);
869         assertSetEquals(newModules, ctx.getModules());
870         // ##########
871         Map<File, Module> mapped = parser.parseYangModelsMapped(testFiles);
872         newModules = new LinkedHashSet<>(mapped.values());
873         assertSetEquals(newModules, modules);
874         ctx = new SchemaContextImpl(newModules);
875         assertSetEquals(newModules, ctx.getModules());
876         // ##########
877         streams.clear();
878         for (File f : testFiles) {
879             streams.add(new FileInputStream(f));
880         }
881         Map<InputStream, Module> mappedStreams = parser.parseYangModelsFromStreamsMapped(streams);
882         newModules = new LinkedHashSet<>(mappedStreams.values());
883         assertSetEquals(newModules, modules);
884         ctx = new SchemaContextImpl(newModules);
885         assertSetEquals(newModules, ctx.getModules());
886     }
887
888     private void checkOrder(Collection<Module> modules) {
889         Iterator<Module> it = modules.iterator();
890         Module m = it.next();
891         assertEquals("m2", m.getName());
892         m = it.next();
893         assertEquals("m4", m.getName());
894         m = it.next();
895         assertEquals("m6", m.getName());
896         m = it.next();
897         assertEquals("m8", m.getName());
898         m = it.next();
899         assertEquals("m7", m.getName());
900         m = it.next();
901         assertEquals("m5", m.getName());
902         m = it.next();
903         assertEquals("m3", m.getName());
904         m = it.next();
905         assertEquals("m1", m.getName());
906     }
907
908     private void assertSetEquals(Set<Module> s1, Set<Module> s2) {
909         assertEquals(s1, s2);
910         Iterator<Module> it = s1.iterator();
911         for (Module m : s2) {
912             assertEquals(m, it.next());
913         }
914     }
915
916     @Test
917     public void testSubmodules() {
918         String yangFilePath = getClass().getResource("/submodule-test/subfoo.yang").getPath();
919         String directoryPath = getClass().getResource("/model").getPath();
920
921         File directory = new File(directoryPath);
922         File yangFile = new File(yangFilePath);
923
924         Set<Module> modules = new YangParserImpl().parseYangModels(yangFile, directory);
925         assertEquals(3, modules.size());
926
927         Module foo = TestUtils.findModule(modules, "foo");
928
929         DataSchemaNode id = foo.getDataChildByName("id");
930         assertNotNull(id);
931         DataSchemaNode subExt = foo.getDataChildByName("sub-ext");
932         assertNotNull(subExt);
933         DataSchemaNode subTransfer = foo.getDataChildByName("sub-transfer");
934         assertNotNull(subTransfer);
935
936         assertEquals(2, foo.getExtensionSchemaNodes().size());
937         assertEquals(2, foo.getAugmentations().size());
938     }
939
940 }