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