Bug 5085: Clean-up test and retest JUnit tests
[yangtools.git] / yang / yang-parser-impl / src / test / java / org / opendaylight / yangtools / yang / stmt / YangParserTest.java
1 /*
2  * Copyright (c) 2016 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.stmt;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.junit.Assert.fail;
16 import java.io.File;
17 import java.io.IOException;
18 import java.net.URI;
19 import java.net.URISyntaxException;
20 import java.text.DateFormat;
21 import java.text.ParseException;
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Date;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Set;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.common.YangConstants;
33 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
34 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
35 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
37 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.Deviation;
40 import org.opendaylight.yangtools.yang.model.api.Deviation.Deviate;
41 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
42 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
43 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
44 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
45 import org.opendaylight.yangtools.yang.model.api.Module;
46 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
47 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
48 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
49 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
50 import org.opendaylight.yangtools.yang.model.api.Status;
51 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
52 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
53 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
54 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
55 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
56 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
57 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
58 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
59 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
60 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
61 import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
62 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
63 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
64 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
65 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
66 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
67 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
68 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
69
70 public class YangParserTest {
71     public static final String FS = File.separator;
72
73     private final URI fooNS = URI.create("urn:opendaylight.foo");
74     private final URI barNS = URI.create("urn:opendaylight.bar");
75     private final URI bazNS = URI.create("urn:opendaylight.baz");
76     private Date fooRev;
77     private Date barRev;
78     private Date bazRev;
79
80     private Set<Module> modules;
81
82     @Before
83     public void init() throws Exception {
84         DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
85         fooRev = simpleDateFormat.parse("2013-02-27");
86         barRev = simpleDateFormat.parse("2013-07-03");
87         bazRev = simpleDateFormat.parse("2013-02-27");
88
89         modules = TestUtils.loadModules(getClass().getResource("/model").toURI());
90         assertEquals(3, modules.size());
91     }
92
93     @Test
94     public void testHeaders() throws ParseException {
95         Module foo = TestUtils.findModule(modules, "foo");
96
97         assertEquals("foo", foo.getName());
98         assertEquals("1", foo.getYangVersion());
99         assertEquals(fooNS, foo.getNamespace());
100         assertEquals("foo", foo.getPrefix());
101
102         Set<ModuleImport> imports = foo.getImports();
103         assertEquals(2, imports.size());
104
105         ModuleImport import2 = TestUtils.findImport(imports, "br");
106         assertEquals("bar", import2.getModuleName());
107         assertEquals(barRev, import2.getRevision());
108
109         ModuleImport import3 = TestUtils.findImport(imports, "bz");
110         assertEquals("baz", import3.getModuleName());
111         assertEquals(bazRev, import3.getRevision());
112
113         assertEquals("opendaylight", foo.getOrganization());
114         assertEquals("http://www.opendaylight.org/", foo.getContact());
115         Date expectedRevision = TestUtils.createDate("2013-02-27");
116         assertEquals(expectedRevision, foo.getRevision());
117         assertEquals(" WILL BE DEFINED LATER", foo.getReference());
118     }
119
120     @Test
121     public void testParseList() {
122         Module bar = TestUtils.findModule(modules, "bar");
123         URI expectedNamespace = URI.create("urn:opendaylight.bar");
124         String expectedPrefix = "bar";
125
126         ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName("interfaces");
127
128         ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
129         // test SchemaNode args
130         QName expectedQName = QName.create(expectedNamespace, barRev, "ifEntry");
131         assertEquals(expectedQName, ifEntry.getQName());
132         SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, barRev, expectedPrefix, "interfaces",
133                 "ifEntry");
134         assertEquals(expectedPath, ifEntry.getPath());
135         assertNull(ifEntry.getDescription());
136         assertNull(ifEntry.getReference());
137         assertEquals(Status.CURRENT, ifEntry.getStatus());
138         assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
139         // test DataSchemaNode args
140         assertFalse(ifEntry.isAugmenting());
141         assertTrue(ifEntry.isConfiguration());
142         ConstraintDefinition constraints = ifEntry.getConstraints();
143         // :TODO augment to ifEntry have when condition and so in consequence
144         // ifEntry should be a context node ?
145         // assertNull(constraints.getWhenCondition());
146         assertEquals(0, constraints.getMustConstraints().size());
147         assertTrue(constraints.isMandatory());
148         assertEquals(1, (int) constraints.getMinElements());
149         assertEquals(11, (int) constraints.getMaxElements());
150         // test AugmentationTarget args
151         Set<AugmentationSchema> availableAugmentations = ifEntry.getAvailableAugmentations();
152         assertEquals(2, availableAugmentations.size());
153         // test ListSchemaNode args
154         List<QName> expectedKey = new ArrayList<>();
155         expectedKey.add(QName.create(expectedNamespace, barRev, "ifIndex"));
156         assertEquals(expectedKey, ifEntry.getKeyDefinition());
157         assertFalse(ifEntry.isUserOrdered());
158         // test DataNodeContainer args
159         assertEquals(0, ifEntry.getTypeDefinitions().size());
160         assertEquals(4, ifEntry.getChildNodes().size());
161         assertEquals(0, ifEntry.getGroupings().size());
162         assertEquals(0, ifEntry.getUses().size());
163
164         LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName("ifIndex");
165         assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
166         assertTrue(ifIndex.getType() instanceof UnsignedIntegerTypeDefinition);
167         assertEquals("minutes", ifIndex.getUnits());
168         LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName("ifMtu");
169         assertEquals(BaseTypes.int32Type(), ifMtu.getType());
170     }
171
172     @Test
173     public void testTypedefRangesResolving() throws ParseException {
174         Module foo = TestUtils.findModule(modules, "foo");
175         LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName("int32-leaf");
176
177         IntegerTypeDefinition leafType = (IntegerTypeDefinition) int32Leaf.getType();
178         QName leafTypeQName = leafType.getQName();
179         assertEquals("int32-ext2", leafTypeQName.getLocalName());
180         assertEquals(fooNS, leafTypeQName.getNamespace());
181         assertEquals(fooRev, leafTypeQName.getRevision());
182         assertEquals("mile", leafType.getUnits());
183         assertEquals("11", leafType.getDefaultValue());
184
185         List<RangeConstraint> ranges = leafType.getRangeConstraints();
186         assertEquals(1, ranges.size());
187         RangeConstraint range = ranges.get(0);
188         assertEquals(12, range.getMin().intValue());
189         assertEquals(20, range.getMax().intValue());
190
191         IntegerTypeDefinition baseType = leafType.getBaseType();
192         QName baseTypeQName = baseType.getQName();
193         assertEquals("int32-ext2", baseTypeQName.getLocalName());
194         assertEquals(barNS, baseTypeQName.getNamespace());
195         assertEquals(barRev, baseTypeQName.getRevision());
196         assertEquals("mile", baseType.getUnits());
197         assertEquals("11", baseType.getDefaultValue());
198
199         List<RangeConstraint> baseTypeRanges = baseType.getRangeConstraints();
200         assertEquals(2, baseTypeRanges.size());
201         RangeConstraint baseTypeRange1 = baseTypeRanges.get(0);
202         assertEquals(3, baseTypeRange1.getMin().intValue());
203         assertEquals(9, baseTypeRange1.getMax().intValue());
204         RangeConstraint baseTypeRange2 = baseTypeRanges.get(1);
205         assertEquals(11, baseTypeRange2.getMin().intValue());
206         assertEquals(20, baseTypeRange2.getMax().intValue());
207
208         IntegerTypeDefinition base = baseType.getBaseType();
209         QName baseQName = base.getQName();
210         assertEquals("int32-ext1", baseQName.getLocalName());
211         assertEquals(barNS, baseQName.getNamespace());
212         assertEquals(barRev, baseQName.getRevision());
213         assertNull(base.getUnits());
214         assertNull(base.getDefaultValue());
215
216         List<RangeConstraint> baseRanges = base.getRangeConstraints();
217         assertEquals(1, baseRanges.size());
218         RangeConstraint baseRange = baseRanges.get(0);
219         assertEquals(2, baseRange.getMin().intValue());
220         assertEquals(20, baseRange.getMax().intValue());
221
222         assertEquals(BaseTypes.int32Type(), base.getBaseType());
223     }
224
225     @Test
226     public void testTypedefPatternsResolving() {
227         Module foo = TestUtils.findModule(modules, "foo");
228         LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName("string-leaf");
229
230         assertTrue(stringleaf.getType() instanceof StringTypeDefinition);
231         StringTypeDefinition type = (StringTypeDefinition) stringleaf.getType();
232         QName typeQName = type.getQName();
233         assertEquals("string-ext4", typeQName.getLocalName());
234         assertEquals(barNS, typeQName.getNamespace());
235         assertEquals(barRev, typeQName.getRevision());
236         assertNull(type.getUnits());
237         assertNull(type.getDefaultValue());
238         List<PatternConstraint> patterns = type.getPatternConstraints();
239         assertEquals(1, patterns.size());
240         PatternConstraint pattern = patterns.iterator().next();
241         assertEquals("^[e-z]*$", pattern.getRegularExpression());
242         assertEquals(1, type.getLengthConstraints().size());
243
244         StringTypeDefinition baseType1 = type.getBaseType();
245         QName baseType1QName = baseType1.getQName();
246         assertEquals("string-ext3", baseType1QName.getLocalName());
247         assertEquals(barNS, baseType1QName.getNamespace());
248         assertEquals(barRev, baseType1QName.getRevision());
249         assertNull(baseType1.getUnits());
250         assertNull(baseType1.getDefaultValue());
251         patterns = baseType1.getPatternConstraints();
252         assertEquals(1, patterns.size());
253         pattern = patterns.iterator().next();
254         assertEquals("^[b-u]*$", pattern.getRegularExpression());
255         assertEquals(1, baseType1.getLengthConstraints().size());
256
257         StringTypeDefinition baseType2 = baseType1.getBaseType();
258         QName baseType2QName = baseType2.getQName();
259         assertEquals("string-ext2", baseType2QName.getLocalName());
260         assertEquals(barNS, baseType2QName.getNamespace());
261         assertEquals(barRev, baseType2QName.getRevision());
262         assertNull(baseType2.getUnits());
263         assertNull(baseType2.getDefaultValue());
264         assertTrue(baseType2.getPatternConstraints().isEmpty());
265         List<LengthConstraint> baseType2Lengths = baseType2.getLengthConstraints();
266         assertEquals(1, baseType2Lengths.size());
267         LengthConstraint length = baseType2Lengths.get(0);
268         assertEquals(6, length.getMin().intValue());
269         assertEquals(10, length.getMax().intValue());
270
271         StringTypeDefinition baseType3 = baseType2.getBaseType();
272         QName baseType3QName = baseType3.getQName();
273         assertEquals("string-ext1", baseType3QName.getLocalName());
274         assertEquals(barNS, baseType3QName.getNamespace());
275         assertEquals(barRev, baseType3QName.getRevision());
276         assertNull(baseType3.getUnits());
277         assertNull(baseType3.getDefaultValue());
278         patterns = baseType3.getPatternConstraints();
279         assertEquals(1, patterns.size());
280         pattern = patterns.iterator().next();
281         assertEquals("^[a-k]*$", pattern.getRegularExpression());
282         List<LengthConstraint> baseType3Lengths = baseType3.getLengthConstraints();
283         assertEquals(1, baseType3Lengths.size());
284         length = baseType3Lengths.get(0);
285         assertEquals(5, length.getMin().intValue());
286         assertEquals(11, length.getMax().intValue());
287
288         assertEquals(BaseTypes.stringType(), baseType3.getBaseType());
289     }
290
291     @Test
292     public void testTypedefInvalidPatternsResolving() {
293         Module foo = TestUtils.findModule(modules, "foo");
294         final LeafSchemaNode invalidPatternStringLeaf = (LeafSchemaNode) foo
295                 .getDataChildByName("invalid-pattern-string-leaf");
296         StringTypeDefinition type = (StringTypeDefinition) invalidPatternStringLeaf.getType();
297         QName typeQName = type.getQName();
298         assertEquals("invalid-string-pattern", typeQName.getLocalName());
299         assertEquals(barNS, typeQName.getNamespace());
300         assertEquals(barRev, typeQName.getRevision());
301         assertNull(type.getUnits());
302         assertNull(type.getDefaultValue());
303         List<PatternConstraint> patterns = type.getPatternConstraints();
304         assertTrue(patterns.isEmpty());
305
306         final LeafSchemaNode invalidDirectStringPatternDefLeaf = (LeafSchemaNode) foo
307                 .getDataChildByName("invalid-direct-string-pattern-def-leaf");
308         type = (StringTypeDefinition) invalidDirectStringPatternDefLeaf.getType();
309         typeQName = type.getQName();
310         assertEquals("string", typeQName.getLocalName());
311         assertEquals(YangConstants.RFC6020_YANG_NAMESPACE, typeQName.getNamespace());
312         assertNull(typeQName.getRevision());
313         assertNull(type.getUnits());
314         assertNull(type.getDefaultValue());
315         patterns = type.getPatternConstraints();
316         assertTrue(patterns.isEmpty());
317
318         final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) foo
319                 .getDataChildByName("multiple-pattern-string-leaf");
320         type = (StringTypeDefinition) multiplePatternStringLeaf.getType();
321         typeQName = type.getQName();
322         assertEquals("multiple-pattern-string", typeQName.getLocalName());
323         assertEquals(barNS, typeQName.getNamespace());
324         assertEquals(barRev, typeQName.getRevision());
325         assertNull(type.getUnits());
326         assertNull(type.getDefaultValue());
327         patterns = type.getPatternConstraints();
328         assertTrue(!patterns.isEmpty());
329         assertEquals(1, patterns.size());
330         PatternConstraint pattern = patterns.iterator().next();
331         assertEquals("^[e-z]*$", pattern.getRegularExpression());
332         assertEquals(1, type.getLengthConstraints().size());
333
334         final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) foo
335                 .getDataChildByName("multiple-pattern-direct-string-def-leaf");
336         type = (StringTypeDefinition) multiplePatternDirectStringDefLeaf.getType();
337         typeQName = type.getQName();
338         assertEquals("string", typeQName.getLocalName());
339         assertEquals(fooNS, typeQName.getNamespace());
340         assertEquals(fooRev, typeQName.getRevision());
341         assertNull(type.getUnits());
342         assertNull(type.getDefaultValue());
343         patterns = type.getPatternConstraints();
344         assertTrue(!patterns.isEmpty());
345         assertEquals(2, patterns.size());
346
347         boolean isEZPattern = false;
348         boolean isADPattern = false;
349         for (final PatternConstraint patternConstraint : patterns) {
350             if (patternConstraint.getRegularExpression().equals("^[e-z]*$")) {
351                 isEZPattern = true;
352             } else if (patternConstraint.getRegularExpression().equals("^[a-d]*$")) {
353                 isADPattern = true;
354             }
355         }
356         assertTrue(isEZPattern);
357         assertTrue(isADPattern);
358     }
359
360     @Test
361     public void testTypedefLengthsResolving() {
362         Module foo = TestUtils.findModule(modules, "foo");
363
364         LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName("length-leaf");
365         StringTypeDefinition type = (StringTypeDefinition) lengthLeaf.getType();
366
367         QName typeQName = type.getQName();
368         assertEquals("string-ext2", typeQName.getLocalName());
369         assertEquals(fooNS, typeQName.getNamespace());
370         assertEquals(fooRev, typeQName.getRevision());
371         assertNull(type.getUnits());
372         assertNull(type.getDefaultValue());
373         assertTrue(type.getPatternConstraints().isEmpty());
374         List<LengthConstraint> typeLengths = type.getLengthConstraints();
375         assertEquals(1, typeLengths.size());
376         LengthConstraint length = typeLengths.get(0);
377         assertEquals(7, length.getMin().intValue());
378         assertEquals(10, length.getMax().intValue());
379
380         StringTypeDefinition baseType1 = type.getBaseType();
381         QName baseType1QName = baseType1.getQName();
382         assertEquals("string-ext2", baseType1QName.getLocalName());
383         assertEquals(barNS, baseType1QName.getNamespace());
384         assertEquals(barRev, baseType1QName.getRevision());
385         assertNull(baseType1.getUnits());
386         assertNull(baseType1.getDefaultValue());
387         assertTrue(baseType1.getPatternConstraints().isEmpty());
388         List<LengthConstraint> baseType2Lengths = baseType1.getLengthConstraints();
389         assertEquals(1, baseType2Lengths.size());
390         length = baseType2Lengths.get(0);
391         assertEquals(6, length.getMin().intValue());
392         assertEquals(10, length.getMax().intValue());
393
394         StringTypeDefinition baseType2 = baseType1.getBaseType();
395         QName baseType2QName = baseType2.getQName();
396         assertEquals("string-ext1", baseType2QName.getLocalName());
397         assertEquals(barNS, baseType2QName.getNamespace());
398         assertEquals(barRev, baseType2QName.getRevision());
399         assertNull(baseType2.getUnits());
400         assertNull(baseType2.getDefaultValue());
401         List<PatternConstraint> patterns = baseType2.getPatternConstraints();
402         assertEquals(1, patterns.size());
403         PatternConstraint pattern = patterns.iterator().next();
404         assertEquals("^[a-k]*$", pattern.getRegularExpression());
405         List<LengthConstraint> baseType3Lengths = baseType2.getLengthConstraints();
406         assertEquals(1, baseType3Lengths.size());
407         length = baseType3Lengths.get(0);
408         assertEquals(5, length.getMin().intValue());
409         assertEquals(11, length.getMax().intValue());
410
411         assertEquals(BaseTypes.stringType(), baseType2.getBaseType());
412     }
413
414     @Test
415     public void testTypedefDecimal1() {
416         Module foo = TestUtils.findModule(modules, "foo");
417         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf");
418
419         assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
420         DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
421         QName typeQName = type.getQName();
422         assertEquals("my-decimal-type", typeQName.getLocalName());
423         assertEquals(barNS, typeQName.getNamespace());
424         assertEquals(barRev, typeQName.getRevision());
425         assertNull(type.getUnits());
426         assertNull(type.getDefaultValue());
427         assertEquals(6, type.getFractionDigits().intValue());
428         assertEquals(1, type.getRangeConstraints().size());
429
430         DecimalTypeDefinition typeBase = type.getBaseType();
431         QName typeBaseQName = typeBase.getQName();
432         assertEquals("decimal64", typeBaseQName.getLocalName());
433         assertEquals(barNS, typeBaseQName.getNamespace());
434         assertEquals(barRev, typeBaseQName.getRevision());
435         assertNull(typeBase.getUnits());
436         assertNull(typeBase.getDefaultValue());
437         assertEquals(6, typeBase.getFractionDigits().intValue());
438         assertEquals(1, typeBase.getRangeConstraints().size());
439
440         assertNull(typeBase.getBaseType());
441     }
442
443     @Test
444     public void testTypedefDecimal2() {
445         Module foo = TestUtils.findModule(modules, "foo");
446         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf2");
447
448         assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
449         DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
450         QName typeQName = type.getQName();
451         assertEquals("my-decimal-type", typeQName.getLocalName());
452         assertEquals(barNS, typeQName.getNamespace());
453         assertEquals(barRev, typeQName.getRevision());
454         assertNull(type.getUnits());
455         assertNull(type.getDefaultValue());
456         assertEquals(6, type.getFractionDigits().intValue());
457         assertEquals(1, type.getRangeConstraints().size());
458
459         DecimalTypeDefinition baseTypeDecimal = type.getBaseType();
460         assertEquals(6, baseTypeDecimal.getFractionDigits().intValue());
461     }
462
463     @Test
464     public void testTypedefUnion() {
465         Module foo = TestUtils.findModule(modules, "foo");
466         LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName("union-leaf");
467
468         assertTrue(unionleaf.getType() instanceof UnionTypeDefinition);
469         UnionTypeDefinition type = (UnionTypeDefinition) unionleaf.getType();
470         QName typeQName = type.getQName();
471         assertEquals("my-union-ext", typeQName.getLocalName());
472         assertEquals(barNS, typeQName.getNamespace());
473         assertEquals(barRev, typeQName.getRevision());
474         assertNull(type.getUnits());
475         assertNull(type.getDefaultValue());
476
477         UnionTypeDefinition baseType = type.getBaseType();
478         QName baseTypeQName = baseType.getQName();
479         assertEquals("my-union", baseTypeQName.getLocalName());
480         assertEquals(barNS, baseTypeQName.getNamespace());
481         assertEquals(barRev, baseTypeQName.getRevision());
482         assertNull(baseType.getUnits());
483         assertNull(baseType.getDefaultValue());
484
485         UnionTypeDefinition unionType = baseType.getBaseType();
486         List<TypeDefinition<?>> unionTypes = unionType.getTypes();
487         assertEquals(2, unionTypes.size());
488
489         IntegerTypeDefinition unionType1 = (IntegerTypeDefinition) unionTypes.get(0);
490         QName unionType1QName = baseType.getQName();
491         assertEquals("my-union", unionType1QName.getLocalName());
492         assertEquals(barNS, unionType1QName.getNamespace());
493         assertEquals(barRev, unionType1QName.getRevision());
494         assertNull(unionType1.getUnits());
495         assertNull(unionType1.getDefaultValue());
496
497         List<RangeConstraint> ranges = unionType1.getRangeConstraints();
498         assertEquals(1, ranges.size());
499         RangeConstraint range = ranges.get(0);
500         assertEquals(1, range.getMin().intValue());
501         assertEquals(100, range.getMax().intValue());
502         assertEquals(BaseTypes.int16Type(), unionType1.getBaseType());
503
504         assertEquals(BaseTypes.int32Type(), unionTypes.get(1));
505     }
506
507     @Test
508     public void testNestedUnionResolving() {
509         Module foo = TestUtils.findModule(modules, "foo");
510         LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("custom-union-leaf");
511
512         assertTrue(testleaf.getType() instanceof UnionTypeDefinition);
513         UnionTypeDefinition type = (UnionTypeDefinition) testleaf.getType();
514         QName testleafTypeQName = type.getQName();
515         assertEquals(bazNS, testleafTypeQName.getNamespace());
516         assertEquals(bazRev, testleafTypeQName.getRevision());
517         assertEquals("union1", testleafTypeQName.getLocalName());
518         assertNull(type.getUnits());
519         assertNull(type.getDefaultValue());
520
521         UnionTypeDefinition typeBase = type.getBaseType();
522         QName typeBaseQName = typeBase.getQName();
523         assertEquals(bazNS, typeBaseQName.getNamespace());
524         assertEquals(bazRev, typeBaseQName.getRevision());
525         assertEquals("union2", typeBaseQName.getLocalName());
526         assertNull(typeBase.getUnits());
527         assertNull(typeBase.getDefaultValue());
528
529         UnionTypeDefinition union = typeBase.getBaseType();
530         List<TypeDefinition<?>> unionTypes = union.getTypes();
531         assertEquals(2, unionTypes.size());
532         assertEquals(BaseTypes.int32Type(), unionTypes.get(0));
533         assertTrue(unionTypes.get(1) instanceof UnionTypeDefinition);
534
535         UnionTypeDefinition unionType1 = (UnionTypeDefinition) unionTypes.get(1);
536         QName uniontType1QName = unionType1.getQName();
537         assertEquals(barNS, uniontType1QName.getNamespace());
538         assertEquals(barRev, uniontType1QName.getRevision());
539         assertEquals("nested-union2", uniontType1QName.getLocalName());
540         assertNull(unionType1.getUnits());
541         assertNull(unionType1.getDefaultValue());
542
543         UnionTypeDefinition nestedUnion = unionType1.getBaseType();
544         List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
545         assertEquals(2, nestedUnion2Types.size());
546         assertTrue(nestedUnion2Types.get(1) instanceof StringTypeDefinition);
547         assertTrue(nestedUnion2Types.get(0) instanceof UnionTypeDefinition);
548
549         UnionTypeDefinition myUnionExt = (UnionTypeDefinition) nestedUnion2Types.get(0);
550         QName myUnionExtQName = myUnionExt.getQName();
551         assertEquals(barNS, myUnionExtQName.getNamespace());
552         assertEquals(barRev, myUnionExtQName.getRevision());
553         assertEquals("my-union-ext", myUnionExtQName.getLocalName());
554         assertNull(myUnionExt.getUnits());
555         assertNull(myUnionExt.getDefaultValue());
556
557
558         UnionTypeDefinition myUnion = myUnionExt.getBaseType();
559         QName myUnionQName = myUnion.getQName();
560         assertEquals(barNS, myUnionQName.getNamespace());
561         assertEquals(barRev, myUnionQName.getRevision());
562         assertEquals("my-union", myUnionQName.getLocalName());
563         assertNull(myUnion.getUnits());
564         assertNull(myUnion.getDefaultValue());
565
566         UnionTypeDefinition myUnionBase = myUnion.getBaseType();
567         List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
568         assertEquals(2, myUnionBaseTypes.size());
569         assertTrue(myUnionBaseTypes.get(0) instanceof IntegerTypeDefinition);
570         assertEquals(BaseTypes.int32Type(), myUnionBaseTypes.get(1));
571
572         IntegerTypeDefinition int16Ext = (IntegerTypeDefinition) myUnionBaseTypes.get(0);
573         QName int16ExtQName = int16Ext.getQName();
574         assertEquals(barNS, int16ExtQName.getNamespace());
575         assertEquals(barRev, int16ExtQName.getRevision());
576         assertEquals("int16", int16ExtQName.getLocalName());
577         assertNull(int16Ext.getUnits());
578         assertNull(int16Ext.getDefaultValue());
579         List<RangeConstraint> ranges = int16Ext.getRangeConstraints();
580         assertEquals(1, ranges.size());
581         RangeConstraint range = ranges.get(0);
582         assertEquals(1, range.getMin().intValue());
583         assertEquals(100, range.getMax().intValue());
584
585         assertEquals(BaseTypes.int16Type(), int16Ext.getBaseType());
586     }
587
588     @Test
589     public void testChoice() {
590         Module foo = TestUtils.findModule(modules, "foo");
591         ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName("transfer");
592         ChoiceSchemaNode how = (ChoiceSchemaNode) transfer.getDataChildByName("how");
593         Set<ChoiceCaseNode> cases = how.getCases();
594         assertEquals(5, cases.size());
595         ChoiceCaseNode input = null;
596         ChoiceCaseNode output = null;
597         for (ChoiceCaseNode caseNode : cases) {
598             if ("input".equals(caseNode.getQName().getLocalName())) {
599                 input = caseNode;
600             } else if ("output".equals(caseNode.getQName().getLocalName())) {
601                 output = caseNode;
602             }
603         }
604         assertNotNull(input);
605         assertNotNull(input.getPath());
606         assertNotNull(output);
607         assertNotNull(output.getPath());
608     }
609
610     @Test
611     public void testDeviation() {
612         Module foo = TestUtils.findModule(modules, "foo");
613         Set<Deviation> deviations = foo.getDeviations();
614         assertEquals(1, deviations.size());
615         Deviation dev = deviations.iterator().next();
616         assertEquals("system/user ref", dev.getReference());
617
618         List<QName> path = new ArrayList<>();
619         path.add(QName.create(barNS, barRev, "interfaces"));
620         path.add(QName.create(barNS, barRev, "ifEntry"));
621         SchemaPath expectedPath = SchemaPath.create(path, true);
622
623         assertEquals(expectedPath, dev.getTargetPath());
624         assertEquals(Deviate.ADD, dev.getDeviate());
625     }
626
627     @Test
628     public void testUnknownNode() {
629         Module baz = TestUtils.findModule(modules, "baz");
630         ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName("network");
631         List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
632         assertEquals(1, unknownNodes.size());
633         UnknownSchemaNode unknownNode = unknownNodes.get(0);
634         assertNotNull(unknownNode.getNodeType());
635         assertEquals("point", unknownNode.getNodeParameter());
636     }
637
638     @Test
639     public void testFeature() {
640         Module baz = TestUtils.findModule(modules, "baz");
641         Set<FeatureDefinition> features = baz.getFeatures();
642         assertEquals(1, features.size());
643     }
644
645     @Test
646     public void testExtension() {
647         Module baz = TestUtils.findModule(modules, "baz");
648         List<ExtensionDefinition> extensions = baz.getExtensionSchemaNodes();
649         assertEquals(1, extensions.size());
650         ExtensionDefinition extension = extensions.get(0);
651         assertEquals("name", extension.getArgument());
652         assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.",
653                 extension.getDescription());
654         assertTrue(extension.isYinElement());
655     }
656
657     @Test
658     public void testNotification() {
659         Module baz = TestUtils.findModule(modules, "baz");
660         String expectedPrefix = "c";
661
662         Set<NotificationDefinition> notifications = baz.getNotifications();
663         assertEquals(1, notifications.size());
664
665         NotificationDefinition notification = notifications.iterator().next();
666         // test SchemaNode args
667         QName expectedQName = QName.create(bazNS, bazRev, "event");
668         assertEquals(expectedQName, notification.getQName());
669         SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event");
670         assertEquals(expectedPath, notification.getPath());
671         assertNull(notification.getDescription());
672         assertNull(notification.getReference());
673         assertEquals(Status.CURRENT, notification.getStatus());
674         assertEquals(0, notification.getUnknownSchemaNodes().size());
675         // test DataNodeContainer args
676         assertEquals(0, notification.getTypeDefinitions().size());
677         assertEquals(3, notification.getChildNodes().size());
678         assertEquals(0, notification.getGroupings().size());
679         assertEquals(0, notification.getUses().size());
680
681         LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName("event-class");
682         assertTrue(eventClass.getType() instanceof StringTypeDefinition);
683         LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName("severity");
684         assertTrue(severity.getType() instanceof StringTypeDefinition);
685     }
686
687     @Test
688     public void testRpc() {
689         Module baz = TestUtils.findModule(modules, "baz");
690
691         Set<RpcDefinition> rpcs = baz.getRpcs();
692         assertEquals(1, rpcs.size());
693
694         RpcDefinition rpc = rpcs.iterator().next();
695         assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription());
696         assertEquals("RFC 6241, Section 7.1", rpc.getReference());
697     }
698
699     @Test
700     public void testTypePath() throws ParseException {
701         Module bar = TestUtils.findModule(modules, "bar");
702         Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
703
704         // int32-ext1
705         IntegerTypeDefinition int32ext1 = (IntegerTypeDefinition) TestUtils.findTypedef(types, "int32-ext1");
706         QName int32TypedefQName = int32ext1.getQName();
707
708         assertEquals(barNS, int32TypedefQName.getNamespace());
709         assertEquals(barRev, int32TypedefQName.getRevision());
710         assertEquals("int32-ext1", int32TypedefQName.getLocalName());
711
712         SchemaPath typeSchemaPath = int32ext1.getPath();
713         Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
714         Iterator<QName> typePathIt = typePath.iterator();
715         assertEquals(int32TypedefQName, typePathIt.next());
716         assertFalse(typePathIt.hasNext());
717
718         // int32-ext1/int32
719         IntegerTypeDefinition int32 = int32ext1.getBaseType();
720         assertEquals(BaseTypes.int32Type(), int32);
721     }
722
723     @Test
724     public void testTypePath2() throws ParseException {
725         Module bar = TestUtils.findModule(modules, "bar");
726         Set<TypeDefinition<?>> types = bar.getTypeDefinitions();
727
728         // my-decimal-type
729         DecimalTypeDefinition myDecType = (DecimalTypeDefinition) TestUtils.findTypedef(types, "my-decimal-type");
730         QName myDecTypeQName = myDecType.getQName();
731
732         assertEquals(barNS, myDecTypeQName.getNamespace());
733         assertEquals(barRev, myDecTypeQName.getRevision());
734         assertEquals("my-decimal-type", myDecTypeQName.getLocalName());
735
736         SchemaPath typeSchemaPath = myDecType.getPath();
737         Iterable<QName> typePath = typeSchemaPath.getPathFromRoot();
738         Iterator<QName> typePathIt = typePath.iterator();
739         assertEquals(myDecTypeQName, typePathIt.next());
740         assertFalse(typePathIt.hasNext());
741
742         // my-base-int32-type/int32
743         DecimalTypeDefinition dec64 = myDecType.getBaseType();
744         QName dec64QName = dec64.getQName();
745
746         assertEquals(barNS, dec64QName.getNamespace());
747         assertEquals(barRev, dec64QName.getRevision());
748         assertEquals("decimal64", dec64QName.getLocalName());
749
750         SchemaPath dec64SchemaPath = dec64.getPath();
751         Iterable<QName> dec64Path = dec64SchemaPath.getPathFromRoot();
752         Iterator<QName> dec64PathIt = dec64Path.iterator();
753         assertEquals(myDecTypeQName, dec64PathIt.next());
754         assertEquals(dec64QName, dec64PathIt.next());
755         assertFalse(dec64PathIt.hasNext());
756     }
757
758     private static void checkOrder(final Collection<Module> modules) {
759         Iterator<Module> it = modules.iterator();
760         Module m = it.next();
761         assertEquals("m2", m.getName());
762         m = it.next();
763         assertEquals("m4", m.getName());
764         m = it.next();
765         assertEquals("m6", m.getName());
766         m = it.next();
767         assertEquals("m8", m.getName());
768         m = it.next();
769         assertEquals("m7", m.getName());
770         m = it.next();
771         assertEquals("m5", m.getName());
772         m = it.next();
773         assertEquals("m3", m.getName());
774         m = it.next();
775         assertEquals("m1", m.getName());
776     }
777
778     private static void assertSetEquals(final Set<Module> s1, final Set<Module> s2) {
779         assertEquals(s1, s2);
780         Iterator<Module> it = s1.iterator();
781         for (Module m : s2) {
782             assertEquals(m, it.next());
783         }
784     }
785
786     @Test
787     public void testSubmodules() {
788         Module foo = TestUtils.findModule(modules, "foo");
789
790         DataSchemaNode id = foo.getDataChildByName("id");
791         assertNotNull(id);
792         DataSchemaNode subExt = foo.getDataChildByName("sub-ext");
793         assertNotNull(subExt);
794         DataSchemaNode subTransfer = foo.getDataChildByName("sub-transfer");
795         assertNotNull(subTransfer);
796
797         assertEquals(2, foo.getExtensionSchemaNodes().size());
798         assertEquals(2, foo.getAugmentations().size());
799     }
800
801     @Test
802     public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException, ReactorException {
803         StatementStreamSource yang1 = new YangStatementSourceImpl("/yang-grammar-test/revisions-extension.yang", false);
804         StatementStreamSource yang2 = new YangStatementSourceImpl("/yang-grammar-test/submodule-header-extension.yang",
805                 false);
806
807         try {
808             TestUtils.parseYangSources(yang1, yang2);
809         } catch (YangParseException e) {
810             e.printStackTrace();
811             fail("YangParseException should not be thrown");
812         }
813
814     }
815
816     @Test
817     public void unknownStatementBetweenRevisionsTest() throws ReactorException {
818
819         final YangStatementSourceImpl yangModule = new YangStatementSourceImpl(
820                 "/yang-grammar-test/revisions-extension.yang", false);
821         final YangStatementSourceImpl yangSubmodule = new YangStatementSourceImpl(
822                 "/yang-grammar-test/submodule-header-extension.yang", false);
823
824         CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
825         addSources(reactor, yangModule, yangSubmodule);
826
827         final EffectiveSchemaContext result = reactor.buildEffective();
828         assertNotNull(result);
829     }
830
831     @Test
832     public void unknownStatementsInStatementsTest() throws ReactorException {
833
834         final YangStatementSourceImpl yangFile1 = new YangStatementSourceImpl(
835                 "/yang-grammar-test/stmtsep-in-statements.yang", false);
836         final YangStatementSourceImpl yangFile2 = new YangStatementSourceImpl(
837                 "/yang-grammar-test/stmtsep-in-statements2.yang", false);
838         final YangStatementSourceImpl yangFile3 = new YangStatementSourceImpl(
839                 "/yang-grammar-test/stmtsep-in-statements-sub.yang", false);
840
841         CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
842         addSources(reactor, yangFile1, yangFile2, yangFile3);
843         // TODO: change test or create new module in order to respect new statement parser validations
844         try {
845             final EffectiveSchemaContext result = reactor.buildEffective();
846         } catch (Exception e) {
847             assertEquals(IllegalArgumentException.class, e.getClass());
848             assertTrue(e.getMessage().startsWith("aaa is not a YANG statement or use of extension"));
849         }
850     }
851
852     private static void addSources(final CrossSourceStatementReactor.BuildAction reactor, final YangStatementSourceImpl... sources) {
853         for (YangStatementSourceImpl source : sources) {
854             reactor.addSource(source);
855         }
856     }
857 }