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