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