Committed by
Gerrit Code Review
config ang key validation and UT for the same
Change-Id: I507740fc9da3f3da5fb3c88a7414f87db6251c5b
Showing
42 changed files
with
901 additions
and
65 deletions
... | @@ -99,7 +99,7 @@ public class YangContainer extends YangNode implements YangLeavesHolder, YangCom | ... | @@ -99,7 +99,7 @@ public class YangContainer extends YangNode implements YangLeavesHolder, YangCom |
99 | /** | 99 | /** |
100 | * If container maintains config data. | 100 | * If container maintains config data. |
101 | */ | 101 | */ |
102 | - private boolean isConfig; | 102 | + private Boolean isConfig; |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Description of container. | 105 | * Description of container. |
... | @@ -174,7 +174,7 @@ public class YangContainer extends YangNode implements YangLeavesHolder, YangCom | ... | @@ -174,7 +174,7 @@ public class YangContainer extends YangNode implements YangLeavesHolder, YangCom |
174 | * | 174 | * |
175 | * @return the isConfig | 175 | * @return the isConfig |
176 | */ | 176 | */ |
177 | - public boolean isConfig() { | 177 | + public Boolean isConfig() { |
178 | return isConfig; | 178 | return isConfig; |
179 | } | 179 | } |
180 | 180 | ||
... | @@ -378,7 +378,70 @@ public class YangContainer extends YangNode implements YangLeavesHolder, YangCom | ... | @@ -378,7 +378,70 @@ public class YangContainer extends YangNode implements YangLeavesHolder, YangCom |
378 | */ | 378 | */ |
379 | @Override | 379 | @Override |
380 | public void validateDataOnExit() throws DataModelException { | 380 | public void validateDataOnExit() throws DataModelException { |
381 | - // TODO auto-generated method stub, to be implemented by parser | 381 | + List<YangLeaf> leaves = getListOfLeaf(); |
382 | + List<YangLeafList> leafLists = getListOfLeafList(); | ||
383 | + | ||
384 | + setDefaultConfigValueToChild(leaves, leafLists); | ||
385 | + validateConfig(leaves, leafLists); | ||
386 | + } | ||
387 | + | ||
388 | + /** | ||
389 | + * Sets the config's value to all leaf if leaf's config statement is not specified. | ||
390 | + * | ||
391 | + * @param leaves list of leaf attributes of container. | ||
392 | + * @param leafLists list of leaf-list attributes of container. | ||
393 | + */ | ||
394 | + private void setDefaultConfigValueToChild(List<YangLeaf> leaves, List<YangLeafList> leafLists) { | ||
395 | + | ||
396 | + /* If "config" is not specified, the default is the same as the parent | ||
397 | + schema node's "config" value.*/ | ||
398 | + if (leaves != null) { | ||
399 | + for (YangLeaf leaf : leaves) { | ||
400 | + if (leaf.isConfig() == null) { | ||
401 | + leaf.setConfig(isConfig); | ||
402 | + } | ||
403 | + } | ||
404 | + } | ||
405 | + | ||
406 | + /* If "config" is not specified, the default is the same as the parent | ||
407 | + schema node's "config" value.*/ | ||
408 | + if (leafLists != null) { | ||
409 | + for (YangLeafList leafList : leafLists) { | ||
410 | + if (leafList.isConfig() == null) { | ||
411 | + leafList.setConfig(isConfig); | ||
412 | + } | ||
413 | + } | ||
414 | + } | ||
415 | + } | ||
416 | + | ||
417 | + /** | ||
418 | + * Validates config statement of container. | ||
419 | + * | ||
420 | + * @param leaves list of leaf attributes of container. | ||
421 | + * @param leafLists list of leaf-list attributes of container. | ||
422 | + * @throws DataModelException a violation of data model rules. | ||
423 | + */ | ||
424 | + private void validateConfig(List<YangLeaf> leaves, List<YangLeafList> leafLists) throws DataModelException { | ||
425 | + | ||
426 | + /* If a node has "config" set to "false", no node underneath it can have | ||
427 | + "config" set to "true".*/ | ||
428 | + if ((!isConfig) && (leaves != null)) { | ||
429 | + for (YangLeaf leaf : leaves) { | ||
430 | + if (leaf.isConfig()) { | ||
431 | + throw new DataModelException("If a container has \"config\" set to \"false\", no node underneath " + | ||
432 | + "it can have \"config\" set to \"true\"."); | ||
433 | + } | ||
434 | + } | ||
435 | + } | ||
436 | + | ||
437 | + if ((!isConfig) && (leafLists != null)) { | ||
438 | + for (YangLeafList leafList : leafLists) { | ||
439 | + if (leafList.isConfig()) { | ||
440 | + throw new DataModelException("If a container has \"config\" set to \"false\", no node underneath " + | ||
441 | + "it can have \"config\" set to \"true\"."); | ||
442 | + } | ||
443 | + } | ||
444 | + } | ||
382 | } | 445 | } |
383 | 446 | ||
384 | /** | 447 | /** | ... | ... |
... | @@ -67,7 +67,7 @@ public class YangLeaf implements YangCommonInfo, Parsable { | ... | @@ -67,7 +67,7 @@ public class YangLeaf implements YangCommonInfo, Parsable { |
67 | /** | 67 | /** |
68 | * If the leaf is a config parameter. | 68 | * If the leaf is a config parameter. |
69 | */ | 69 | */ |
70 | - private boolean isConfig; | 70 | + private Boolean isConfig; |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * description of leaf. | 73 | * description of leaf. |
... | @@ -128,7 +128,7 @@ public class YangLeaf implements YangCommonInfo, Parsable { | ... | @@ -128,7 +128,7 @@ public class YangLeaf implements YangCommonInfo, Parsable { |
128 | * | 128 | * |
129 | * @return if config flag. | 129 | * @return if config flag. |
130 | */ | 130 | */ |
131 | - public boolean isConfig() { | 131 | + public Boolean isConfig() { |
132 | return isConfig; | 132 | return isConfig; |
133 | } | 133 | } |
134 | 134 | ... | ... |
... | @@ -62,7 +62,7 @@ public class YangLeafList implements YangCommonInfo, Parsable { | ... | @@ -62,7 +62,7 @@ public class YangLeafList implements YangCommonInfo, Parsable { |
62 | /** | 62 | /** |
63 | * If the leaf-list is a config parameter. | 63 | * If the leaf-list is a config parameter. |
64 | */ | 64 | */ |
65 | - private boolean isConfig; | 65 | + private Boolean isConfig; |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * Description of leaf-list. | 68 | * Description of leaf-list. |
... | @@ -150,7 +150,7 @@ public class YangLeafList implements YangCommonInfo, Parsable { | ... | @@ -150,7 +150,7 @@ public class YangLeafList implements YangCommonInfo, Parsable { |
150 | * | 150 | * |
151 | * @return the config flag. | 151 | * @return the config flag. |
152 | */ | 152 | */ |
153 | - public boolean isConfig() { | 153 | + public Boolean isConfig() { |
154 | return isConfig; | 154 | return isConfig; |
155 | } | 155 | } |
156 | 156 | ... | ... |
... | @@ -77,7 +77,7 @@ public class YangList extends YangNode | ... | @@ -77,7 +77,7 @@ public class YangList extends YangNode |
77 | /** | 77 | /** |
78 | * If list maintains config data. | 78 | * If list maintains config data. |
79 | */ | 79 | */ |
80 | - private boolean isConfig; | 80 | + private Boolean isConfig; |
81 | 81 | ||
82 | /** | 82 | /** |
83 | * Description of list. | 83 | * Description of list. |
... | @@ -199,7 +199,7 @@ public class YangList extends YangNode | ... | @@ -199,7 +199,7 @@ public class YangList extends YangNode |
199 | * | 199 | * |
200 | * @return the isConfig | 200 | * @return the isConfig |
201 | */ | 201 | */ |
202 | - public boolean isConfig() { | 202 | + public Boolean isConfig() { |
203 | return isConfig; | 203 | return isConfig; |
204 | } | 204 | } |
205 | 205 | ||
... | @@ -254,11 +254,18 @@ public class YangList extends YangNode | ... | @@ -254,11 +254,18 @@ public class YangList extends YangNode |
254 | * Add a key field name. | 254 | * Add a key field name. |
255 | * | 255 | * |
256 | * @param key key field name. | 256 | * @param key key field name. |
257 | + * @throws DataModelException a violation of data model rules. | ||
257 | */ | 258 | */ |
258 | - public void addKey(String key) { | 259 | + public void addKey(String key) throws DataModelException { |
259 | if (getKeyList() == null) { | 260 | if (getKeyList() == null) { |
260 | setKeyList(new LinkedList<String>()); | 261 | setKeyList(new LinkedList<String>()); |
261 | } | 262 | } |
263 | + | ||
264 | + if (getKeyList().contains(key)) { | ||
265 | + throw new DataModelException("A leaf identifier must not appear more than once in the\n" + | ||
266 | + " key"); | ||
267 | + } | ||
268 | + | ||
262 | getKeyList().add(key); | 269 | getKeyList().add(key); |
263 | } | 270 | } |
264 | 271 | ||
... | @@ -431,7 +438,167 @@ public class YangList extends YangNode | ... | @@ -431,7 +438,167 @@ public class YangList extends YangNode |
431 | */ | 438 | */ |
432 | @Override | 439 | @Override |
433 | public void validateDataOnExit() throws DataModelException { | 440 | public void validateDataOnExit() throws DataModelException { |
434 | - // TODO auto-generated method stub, to be implemented by parser | 441 | + List<String> keyList = getKeyList(); |
442 | + List<YangLeaf> leaves = getListOfLeaf(); | ||
443 | + List<YangLeafList> leafLists = getListOfLeafList(); | ||
444 | + | ||
445 | + setDefaultConfigValueToChild(leaves, leafLists); | ||
446 | + validateConfig(leaves, leafLists); | ||
447 | + | ||
448 | + /* A list must have atleast one key leaf if config is true */ | ||
449 | + if ((isConfig) | ||
450 | + && ((keyList == null) || (leaves == null && leafLists == null))) { | ||
451 | + throw new DataModelException("A list must have atleast one key leaf if config is true;"); | ||
452 | + } else if (keyList != null) { | ||
453 | + if (leaves != null) { | ||
454 | + validateLeafKey(leaves, keyList); | ||
455 | + } | ||
456 | + | ||
457 | + if (leafLists != null) { | ||
458 | + validateLeafListKey(leafLists, keyList); | ||
459 | + } | ||
460 | + } | ||
461 | + } | ||
462 | + | ||
463 | + /** | ||
464 | + * Sets the config's value to all leaf if leaf's config statement is not specified. | ||
465 | + * | ||
466 | + * @param leaves list of leaf attributes of YANG list. | ||
467 | + * @param leafLists list of leaf-list attributes of YANG list. | ||
468 | + */ | ||
469 | + private void setDefaultConfigValueToChild(List<YangLeaf> leaves, List<YangLeafList> leafLists) { | ||
470 | + | ||
471 | + /* If "config" is not specified, the default is the same as the parent | ||
472 | + schema node's "config" value.*/ | ||
473 | + if (leaves != null) { | ||
474 | + for (YangLeaf leaf : leaves) { | ||
475 | + if (leaf.isConfig() == null) { | ||
476 | + leaf.setConfig(isConfig); | ||
477 | + } | ||
478 | + } | ||
479 | + } | ||
480 | + | ||
481 | + /* If "config" is not specified, the default is the same as the parent | ||
482 | + schema node's "config" value.*/ | ||
483 | + if (leafLists != null) { | ||
484 | + for (YangLeafList leafList : leafLists) { | ||
485 | + if (leafList.isConfig() == null) { | ||
486 | + leafList.setConfig(isConfig); | ||
487 | + } | ||
488 | + } | ||
489 | + } | ||
490 | + } | ||
491 | + | ||
492 | + /** | ||
493 | + * Validates config statement of YANG list. | ||
494 | + * | ||
495 | + * @param leaves list of leaf attributes of YANG list. | ||
496 | + * @param leafLists list of leaf-list attributes of YANG list. | ||
497 | + * @throws DataModelException a violation of data model rules. | ||
498 | + */ | ||
499 | + private void validateConfig(List<YangLeaf> leaves, List<YangLeafList> leafLists) throws DataModelException { | ||
500 | + | ||
501 | + /* If a node has "config" set to "false", no node underneath it can have | ||
502 | + "config" set to "true".*/ | ||
503 | + if ((!isConfig) && (leaves != null)) { | ||
504 | + for (YangLeaf leaf : leaves) { | ||
505 | + if (leaf.isConfig()) { | ||
506 | + throw new DataModelException("If a list has \"config\" set to \"false\", no node underneath " + | ||
507 | + "it can have \"config\" set to \"true\"."); | ||
508 | + } | ||
509 | + } | ||
510 | + } | ||
511 | + | ||
512 | + if ((!isConfig) && (leafLists != null)) { | ||
513 | + for (YangLeafList leafList : leafLists) { | ||
514 | + if (leafList.isConfig()) { | ||
515 | + throw new DataModelException("If a list has \"config\" set to \"false\", no node underneath " + | ||
516 | + "it can have \"config\" set to \"true\"."); | ||
517 | + } | ||
518 | + } | ||
519 | + } | ||
520 | + } | ||
521 | + | ||
522 | + /** | ||
523 | + * Validates key statement of list. | ||
524 | + * | ||
525 | + * @param leaves list of leaf attributes of list. | ||
526 | + * @param keyList list of key attributes of list. | ||
527 | + * @throws DataModelException a violation of data model rules. | ||
528 | + */ | ||
529 | + private void validateLeafKey(List<YangLeaf> leaves, List<String> keyList) throws DataModelException { | ||
530 | + boolean leafFound = false; | ||
531 | + List<YangLeaf> keyLeaves = new LinkedList<>(); | ||
532 | + | ||
533 | + /* 1. Leaf identifier must refer to a child leaf of the list | ||
534 | + 2. A leaf that is part of the key must not be the built-in type "empty". */ | ||
535 | + for (String key : keyList) { | ||
536 | + for (YangLeaf leaf : leaves) { | ||
537 | + if (key.equals(leaf.getLeafName())) { | ||
538 | + if (leaf.getDataType().getDataTypeName().replace("\"", "").equals("empty")) { | ||
539 | + throw new DataModelException(" A leaf that is part of the key must not be the built-in " + | ||
540 | + "type \"empty\"."); | ||
541 | + } | ||
542 | + leafFound = true; | ||
543 | + keyLeaves.add(leaf); | ||
544 | + break; | ||
545 | + } | ||
546 | + } | ||
547 | + if (!leafFound) { | ||
548 | + throw new DataModelException("Leaf identifier must refer to a child leaf of the list"); | ||
549 | + } | ||
550 | + leafFound = false; | ||
551 | + } | ||
552 | + | ||
553 | + /* All key leafs in a list MUST have the same value for their "config" | ||
554 | + as the list itself. */ | ||
555 | + for (YangLeaf keyLeaf : keyLeaves) { | ||
556 | + if (isConfig != keyLeaf.isConfig()) { | ||
557 | + throw new DataModelException("All key leafs in a list must have the same value for their" + | ||
558 | + " \"config\" as the list itself."); | ||
559 | + } | ||
560 | + } | ||
561 | + } | ||
562 | + | ||
563 | + /** | ||
564 | + * Validates key statement of list. | ||
565 | + * | ||
566 | + * @param leafLists list of leaf-list attributes of list. | ||
567 | + * @param keyList list of key attributes of list. | ||
568 | + * @throws DataModelException a violation of data model rules. | ||
569 | + */ | ||
570 | + private void validateLeafListKey(List<YangLeafList> leafLists, List<String> keyList) throws DataModelException { | ||
571 | + boolean leafFound = false; | ||
572 | + List<YangLeafList> keyLeafLists = new LinkedList<>(); | ||
573 | + | ||
574 | + /* 1. Leaf identifier must refer to a child leaf of the list | ||
575 | + 2. A leaf that is part of the key must not be the built-in type "empty". */ | ||
576 | + for (String key : keyList) { | ||
577 | + for (YangLeafList leafList : leafLists) { | ||
578 | + if (key.equals(leafList.getLeafName())) { | ||
579 | + if (leafList.getDataType().getDataTypeName().replace("\"", "").equals("empty")) { | ||
580 | + throw new DataModelException(" A leaf-list that is part of the key must not be the built-in " + | ||
581 | + "type \"empty\"."); | ||
582 | + } | ||
583 | + leafFound = true; | ||
584 | + keyLeafLists.add(leafList); | ||
585 | + break; | ||
586 | + } | ||
587 | + } | ||
588 | + if (!leafFound) { | ||
589 | + throw new DataModelException("Leaf-list identifier must refer to a child leaf of the list"); | ||
590 | + } | ||
591 | + leafFound = false; | ||
592 | + } | ||
593 | + | ||
594 | + /* All key leafs in a list MUST have the same value for their "config" | ||
595 | + as the list itself. */ | ||
596 | + for (YangLeafList keyLeafList : keyLeafLists) { | ||
597 | + if (isConfig() != keyLeafList.isConfig()) { | ||
598 | + throw new DataModelException("All key leaf-lists in a list must have the same value for their" + | ||
599 | + " \"config\" as the list itself."); | ||
600 | + } | ||
601 | + } | ||
435 | } | 602 | } |
436 | 603 | ||
437 | /* (non-Javadoc) | 604 | /* (non-Javadoc) | ... | ... |
utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ContainerListener.java
... | @@ -27,6 +27,7 @@ import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser; | ... | @@ -27,6 +27,7 @@ import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser; |
27 | import org.onosproject.yangutils.parser.exceptions.ParserException; | 27 | import org.onosproject.yangutils.parser.exceptions.ParserException; |
28 | import org.onosproject.yangutils.parser.impl.TreeWalkListener; | 28 | import org.onosproject.yangutils.parser.impl.TreeWalkListener; |
29 | import org.onosproject.yangutils.parser.impl.YangUtilsParserManager; | 29 | import org.onosproject.yangutils.parser.impl.YangUtilsParserManager; |
30 | +import org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation; | ||
30 | 31 | ||
31 | import static org.onosproject.yangutils.parser.ParsableDataType.CONTAINER_DATA; | 32 | import static org.onosproject.yangutils.parser.ParsableDataType.CONTAINER_DATA; |
32 | import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY; | 33 | import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY; |
... | @@ -94,6 +95,7 @@ public final class ContainerListener { | ... | @@ -94,6 +95,7 @@ public final class ContainerListener { |
94 | public static void processContainerEntry(TreeWalkListener listener, | 95 | public static void processContainerEntry(TreeWalkListener listener, |
95 | GeneratedYangParser.ContainerStatementContext ctx) { | 96 | GeneratedYangParser.ContainerStatementContext ctx) { |
96 | 97 | ||
98 | + YangNode parentNode; | ||
97 | // Check for stack to be non empty. | 99 | // Check for stack to be non empty. |
98 | checkStackIsNotEmpty(listener, MISSING_HOLDER, CONTAINER_DATA, ctx.IDENTIFIER().getText(), ENTRY); | 100 | checkStackIsNotEmpty(listener, MISSING_HOLDER, CONTAINER_DATA, ctx.IDENTIFIER().getText(), ENTRY); |
99 | 101 | ||
... | @@ -105,8 +107,14 @@ public final class ContainerListener { | ... | @@ -105,8 +107,14 @@ public final class ContainerListener { |
105 | YangContainer container = new YangContainer(); | 107 | YangContainer container = new YangContainer(); |
106 | container.setName(ctx.IDENTIFIER().getText()); | 108 | container.setName(ctx.IDENTIFIER().getText()); |
107 | 109 | ||
108 | - Parsable curData = listener.getParsedDataStack().peek(); | 110 | + /* If "config" is not specified, the default is the same as the parent |
111 | + schema node's "config" value. */ | ||
112 | + if (ctx.configStatement().isEmpty()) { | ||
113 | + boolean parentConfig = ListenerValidation.getParentNodeConfig(listener); | ||
114 | + container.setConfig(parentConfig); | ||
115 | + } | ||
109 | 116 | ||
117 | + Parsable curData = listener.getParsedDataStack().peek(); | ||
110 | if ((curData instanceof YangModule) || (curData instanceof YangContainer) | 118 | if ((curData instanceof YangModule) || (curData instanceof YangContainer) |
111 | || (curData instanceof YangList)) { | 119 | || (curData instanceof YangList)) { |
112 | YangNode curNode = (YangNode) curData; | 120 | YangNode curNode = (YangNode) curData; |
... | @@ -137,6 +145,13 @@ public final class ContainerListener { | ... | @@ -137,6 +145,13 @@ public final class ContainerListener { |
137 | checkStackIsNotEmpty(listener, MISSING_HOLDER, CONTAINER_DATA, ctx.IDENTIFIER().getText(), EXIT); | 145 | checkStackIsNotEmpty(listener, MISSING_HOLDER, CONTAINER_DATA, ctx.IDENTIFIER().getText(), EXIT); |
138 | 146 | ||
139 | if (listener.getParsedDataStack().peek() instanceof YangContainer) { | 147 | if (listener.getParsedDataStack().peek() instanceof YangContainer) { |
148 | + YangContainer yangContainer = (YangContainer) listener.getParsedDataStack().peek(); | ||
149 | + try { | ||
150 | + yangContainer.validateDataOnExit(); | ||
151 | + } catch (DataModelException e) { | ||
152 | + throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, | ||
153 | + CONTAINER_DATA, ctx.IDENTIFIER().getText(), EXIT, e.getMessage())); | ||
154 | + } | ||
140 | listener.getParsedDataStack().pop(); | 155 | listener.getParsedDataStack().pop(); |
141 | } else { | 156 | } else { |
142 | throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, CONTAINER_DATA, | 157 | throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, CONTAINER_DATA, | ... | ... |
... | @@ -17,15 +17,20 @@ | ... | @@ -17,15 +17,20 @@ |
17 | package org.onosproject.yangutils.parser.impl.listeners; | 17 | package org.onosproject.yangutils.parser.impl.listeners; |
18 | 18 | ||
19 | import org.onosproject.yangutils.datamodel.YangList; | 19 | import org.onosproject.yangutils.datamodel.YangList; |
20 | +import org.onosproject.yangutils.datamodel.exceptions.DataModelException; | ||
20 | import org.onosproject.yangutils.parser.Parsable; | 21 | import org.onosproject.yangutils.parser.Parsable; |
21 | -import org.onosproject.yangutils.parser.ParsableDataType; | ||
22 | import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser; | 22 | import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser; |
23 | import org.onosproject.yangutils.parser.exceptions.ParserException; | 23 | import org.onosproject.yangutils.parser.exceptions.ParserException; |
24 | import org.onosproject.yangutils.parser.impl.TreeWalkListener; | 24 | import org.onosproject.yangutils.parser.impl.TreeWalkListener; |
25 | -import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation; | 25 | + |
26 | -import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction; | 26 | +import static org.onosproject.yangutils.parser.ParsableDataType.KEY_DATA; |
27 | -import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType; | 27 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY; |
28 | -import org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation; | 28 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage; |
29 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage; | ||
30 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER; | ||
31 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA; | ||
32 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER; | ||
33 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty; | ||
29 | 34 | ||
30 | /* | 35 | /* |
31 | * Reference: RFC6020 and YANG ANTLR Grammar | 36 | * Reference: RFC6020 and YANG ANTLR Grammar |
... | @@ -61,9 +66,7 @@ public final class KeyListener { | ... | @@ -61,9 +66,7 @@ public final class KeyListener { |
61 | GeneratedYangParser.KeyStatementContext ctx) { | 66 | GeneratedYangParser.KeyStatementContext ctx) { |
62 | 67 | ||
63 | // Check for stack to be non empty. | 68 | // Check for stack to be non empty. |
64 | - ListenerValidation.checkStackIsNotEmpty(listener, ListenerErrorType.MISSING_HOLDER, | 69 | + checkStackIsNotEmpty(listener, MISSING_HOLDER, KEY_DATA, ctx.string().getText(), ENTRY); |
65 | - ParsableDataType.KEY_DATA, String.valueOf(ctx.string().getText()), | ||
66 | - ListenerErrorLocation.ENTRY); | ||
67 | 70 | ||
68 | Parsable tmpData = listener.getParsedDataStack().peek(); | 71 | Parsable tmpData = listener.getParsedDataStack().peek(); |
69 | if (listener.getParsedDataStack().peek() instanceof YangList) { | 72 | if (listener.getParsedDataStack().peek() instanceof YangList) { |
... | @@ -72,17 +75,24 @@ public final class KeyListener { | ... | @@ -72,17 +75,24 @@ public final class KeyListener { |
72 | if (tmpKeyValue.contains(" ")) { | 75 | if (tmpKeyValue.contains(" ")) { |
73 | String[] keyValues = tmpKeyValue.split(" "); | 76 | String[] keyValues = tmpKeyValue.split(" "); |
74 | for (String keyValue : keyValues) { | 77 | for (String keyValue : keyValues) { |
75 | - yangList.addKey(keyValue); | 78 | + try { |
79 | + yangList.addKey(keyValue); | ||
80 | + } catch (DataModelException e) { | ||
81 | + throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, KEY_DATA, | ||
82 | + ctx.string().getText(), ENTRY, e.getMessage())); | ||
83 | + } | ||
76 | } | 84 | } |
77 | } else { | 85 | } else { |
78 | - yangList.addKey(tmpKeyValue); | 86 | + try { |
87 | + yangList.addKey(tmpKeyValue); | ||
88 | + } catch (DataModelException e) { | ||
89 | + throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, KEY_DATA, | ||
90 | + ctx.string().getText(), ENTRY, e.getMessage())); | ||
91 | + } | ||
79 | } | 92 | } |
80 | } else { | 93 | } else { |
81 | - throw new ParserException(ListenerErrorMessageConstruction | 94 | + throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, KEY_DATA, ctx.string().getText(), |
82 | - .constructListenerErrorMessage(ListenerErrorType.INVALID_HOLDER, | 95 | + ENTRY)); |
83 | - ParsableDataType.KEY_DATA, | ||
84 | - String.valueOf(ctx.string().getText()), | ||
85 | - ListenerErrorLocation.ENTRY)); | ||
86 | } | 96 | } |
87 | } | 97 | } |
88 | } | 98 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -17,6 +17,8 @@ | ... | @@ -17,6 +17,8 @@ |
17 | package org.onosproject.yangutils.parser.impl.listeners; | 17 | package org.onosproject.yangutils.parser.impl.listeners; |
18 | 18 | ||
19 | import org.onosproject.yangutils.datamodel.YangList; | 19 | import org.onosproject.yangutils.datamodel.YangList; |
20 | +import org.onosproject.yangutils.datamodel.YangContainer; | ||
21 | +import org.onosproject.yangutils.datamodel.YangModule; | ||
20 | import org.onosproject.yangutils.datamodel.YangNode; | 22 | import org.onosproject.yangutils.datamodel.YangNode; |
21 | import org.onosproject.yangutils.datamodel.YangNodeType; | 23 | import org.onosproject.yangutils.datamodel.YangNodeType; |
22 | import org.onosproject.yangutils.datamodel.exceptions.DataModelException; | 24 | import org.onosproject.yangutils.datamodel.exceptions.DataModelException; |
... | @@ -26,11 +28,20 @@ import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser; | ... | @@ -26,11 +28,20 @@ import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser; |
26 | import org.onosproject.yangutils.parser.exceptions.ParserException; | 28 | import org.onosproject.yangutils.parser.exceptions.ParserException; |
27 | import org.onosproject.yangutils.parser.impl.TreeWalkListener; | 29 | import org.onosproject.yangutils.parser.impl.TreeWalkListener; |
28 | import org.onosproject.yangutils.parser.impl.YangUtilsParserManager; | 30 | import org.onosproject.yangutils.parser.impl.YangUtilsParserManager; |
29 | -import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation; | ||
30 | -import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction; | ||
31 | -import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType; | ||
32 | import org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation; | 31 | import org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation; |
33 | 32 | ||
33 | +import static org.onosproject.yangutils.parser.ParsableDataType.LIST_DATA; | ||
34 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY; | ||
35 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT; | ||
36 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage; | ||
37 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage; | ||
38 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER; | ||
39 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER; | ||
40 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER; | ||
41 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA; | ||
42 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_CARDINALITY; | ||
43 | +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty; | ||
44 | + | ||
34 | /* | 45 | /* |
35 | * Reference: RFC6020 and YANG ANTLR Grammar | 46 | * Reference: RFC6020 and YANG ANTLR Grammar |
36 | * | 47 | * |
... | @@ -89,40 +100,37 @@ public final class ListListener { | ... | @@ -89,40 +100,37 @@ public final class ListListener { |
89 | 100 | ||
90 | YangNode curNode; | 101 | YangNode curNode; |
91 | 102 | ||
92 | - ListenerValidation.checkStackIsNotEmpty(listener, ListenerErrorType.MISSING_HOLDER, | 103 | + checkStackIsNotEmpty(listener, MISSING_HOLDER, LIST_DATA, ctx.IDENTIFIER().getText(), ENTRY); |
93 | - ParsableDataType.LIST_DATA, String.valueOf(ctx.IDENTIFIER().getText()), | ||
94 | - ListenerErrorLocation.ENTRY); | ||
95 | 104 | ||
96 | boolean result = validateSubStatementsCardinality(ctx); | 105 | boolean result = validateSubStatementsCardinality(ctx); |
97 | if (!result) { | 106 | if (!result) { |
98 | - throw new ParserException(ListenerErrorMessageConstruction | 107 | + throw new ParserException(constructListenerErrorMessage(INVALID_CARDINALITY, yangConstruct, "", ENTRY)); |
99 | - .constructListenerErrorMessage(ListenerErrorType.INVALID_CARDINALITY, | ||
100 | - yangConstruct, "", ListenerErrorLocation.ENTRY)); | ||
101 | } | 108 | } |
102 | 109 | ||
103 | YangList yangList = new YangList(YangNodeType.LIST_NODE); | 110 | YangList yangList = new YangList(YangNodeType.LIST_NODE); |
104 | yangList.setName(ctx.IDENTIFIER().getText()); | 111 | yangList.setName(ctx.IDENTIFIER().getText()); |
105 | 112 | ||
113 | + /* If "config" is not specified, the default is the same as the parent | ||
114 | + schema node's "config" value. */ | ||
115 | + if (ctx.configStatement().isEmpty()) { | ||
116 | + boolean parentConfig = ListenerValidation.getParentNodeConfig(listener); | ||
117 | + yangList.setConfig(parentConfig); | ||
118 | + } | ||
119 | + | ||
106 | Parsable curData = listener.getParsedDataStack().peek(); | 120 | Parsable curData = listener.getParsedDataStack().peek(); |
107 | - if (curData instanceof YangNode) { | 121 | + if ((curData instanceof YangModule) || (curData instanceof YangContainer) |
122 | + || (curData instanceof YangList)) { | ||
108 | curNode = (YangNode) curData; | 123 | curNode = (YangNode) curData; |
109 | try { | 124 | try { |
110 | curNode.addChild(yangList); | 125 | curNode.addChild(yangList); |
111 | } catch (DataModelException e) { | 126 | } catch (DataModelException e) { |
112 | - throw new ParserException(ListenerErrorMessageConstruction | 127 | + throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, |
113 | - .constructExtendedListenerErrorMessage(ListenerErrorType.UNHANDLED_PARSED_DATA, | 128 | + LIST_DATA, ctx.IDENTIFIER().getText(), ENTRY, e.getMessage())); |
114 | - ParsableDataType.LIST_DATA, | ||
115 | - String.valueOf(ctx.IDENTIFIER().getText()), | ||
116 | - ListenerErrorLocation.ENTRY, | ||
117 | - e.getMessage())); | ||
118 | } | 129 | } |
119 | listener.getParsedDataStack().push(yangList); | 130 | listener.getParsedDataStack().push(yangList); |
120 | } else { | 131 | } else { |
121 | - throw new ParserException(ListenerErrorMessageConstruction | 132 | + throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LIST_DATA, |
122 | - .constructListenerErrorMessage(ListenerErrorType.INVALID_HOLDER, | 133 | + ctx.IDENTIFIER().getText(), ENTRY)); |
123 | - ParsableDataType.LIST_DATA, | ||
124 | - String.valueOf(ctx.IDENTIFIER().getText()), | ||
125 | - ListenerErrorLocation.ENTRY)); | ||
126 | } | 134 | } |
127 | } | 135 | } |
128 | 136 | ||
... | @@ -136,18 +144,20 @@ public final class ListListener { | ... | @@ -136,18 +144,20 @@ public final class ListListener { |
136 | public static void processListExit(TreeWalkListener listener, | 144 | public static void processListExit(TreeWalkListener listener, |
137 | GeneratedYangParser.ListStatementContext ctx) { | 145 | GeneratedYangParser.ListStatementContext ctx) { |
138 | 146 | ||
139 | - ListenerValidation.checkStackIsNotEmpty(listener, ListenerErrorType.MISSING_HOLDER, | 147 | + checkStackIsNotEmpty(listener, MISSING_HOLDER, LIST_DATA, ctx.IDENTIFIER().getText(), EXIT); |
140 | - ParsableDataType.LIST_DATA, String.valueOf(ctx.IDENTIFIER().getText()), | ||
141 | - ListenerErrorLocation.EXIT); | ||
142 | 148 | ||
143 | if (listener.getParsedDataStack().peek() instanceof YangList) { | 149 | if (listener.getParsedDataStack().peek() instanceof YangList) { |
150 | + YangList yangList = (YangList) listener.getParsedDataStack().peek(); | ||
151 | + try { | ||
152 | + yangList.validateDataOnExit(); | ||
153 | + } catch (DataModelException e) { | ||
154 | + throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, | ||
155 | + LIST_DATA, ctx.IDENTIFIER().getText(), EXIT, e.getMessage())); | ||
156 | + } | ||
144 | listener.getParsedDataStack().pop(); | 157 | listener.getParsedDataStack().pop(); |
145 | } else { | 158 | } else { |
146 | - throw new ParserException(ListenerErrorMessageConstruction | 159 | + throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, LIST_DATA, |
147 | - .constructListenerErrorMessage(ListenerErrorType.INVALID_HOLDER, | 160 | + ctx.IDENTIFIER().getText(), EXIT)); |
148 | - ParsableDataType.LIST_DATA, | ||
149 | - String.valueOf(ctx.IDENTIFIER().getText()), | ||
150 | - ListenerErrorLocation.EXIT)); | ||
151 | } | 161 | } |
152 | } | 162 | } |
153 | 163 | ||
... | @@ -157,7 +167,7 @@ public final class ListListener { | ... | @@ -157,7 +167,7 @@ public final class ListListener { |
157 | * @param ctx context object of the grammar rule. | 167 | * @param ctx context object of the grammar rule. |
158 | * @return true/false validation success or failure. | 168 | * @return true/false validation success or failure. |
159 | */ | 169 | */ |
160 | - public static boolean validateSubStatementsCardinality(GeneratedYangParser.ListStatementContext ctx) { | 170 | + private static boolean validateSubStatementsCardinality(GeneratedYangParser.ListStatementContext ctx) { |
161 | 171 | ||
162 | if ((!ctx.keyStatement().isEmpty()) | 172 | if ((!ctx.keyStatement().isEmpty()) |
163 | && (ctx.keyStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) { | 173 | && (ctx.keyStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) { | ... | ... |
... | @@ -16,6 +16,10 @@ | ... | @@ -16,6 +16,10 @@ |
16 | 16 | ||
17 | package org.onosproject.yangutils.parser.impl.parserutils; | 17 | package org.onosproject.yangutils.parser.impl.parserutils; |
18 | 18 | ||
19 | +import org.onosproject.yangutils.datamodel.YangContainer; | ||
20 | +import org.onosproject.yangutils.datamodel.YangList; | ||
21 | +import org.onosproject.yangutils.datamodel.YangNode; | ||
22 | +import org.onosproject.yangutils.parser.Parsable; | ||
19 | import org.onosproject.yangutils.parser.ParsableDataType; | 23 | import org.onosproject.yangutils.parser.ParsableDataType; |
20 | import org.onosproject.yangutils.parser.exceptions.ParserException; | 24 | import org.onosproject.yangutils.parser.exceptions.ParserException; |
21 | import org.onosproject.yangutils.parser.impl.TreeWalkListener; | 25 | import org.onosproject.yangutils.parser.impl.TreeWalkListener; |
... | @@ -83,4 +87,25 @@ public final class ListenerValidation { | ... | @@ -83,4 +87,25 @@ public final class ListenerValidation { |
83 | throw new ParserException(message); | 87 | throw new ParserException(message); |
84 | } | 88 | } |
85 | } | 89 | } |
90 | + | ||
91 | + /** | ||
92 | + * Returns parent node config value, if top node does not specify a config statement | ||
93 | + * then default value true is returned. | ||
94 | + * | ||
95 | + * @param listener listener's object. | ||
96 | + * @return true/false parent's config value. | ||
97 | + */ | ||
98 | + public static boolean getParentNodeConfig(TreeWalkListener listener) { | ||
99 | + YangNode parentNode; | ||
100 | + Parsable curData = listener.getParsedDataStack().peek(); | ||
101 | + if (curData instanceof YangNode) { | ||
102 | + parentNode = ((YangNode) curData).getParent(); | ||
103 | + if (parentNode instanceof YangContainer) { | ||
104 | + return ((YangContainer) parentNode).isConfig(); | ||
105 | + } else if (parentNode instanceof YangList) { | ||
106 | + return ((YangList) parentNode).isConfig(); | ||
107 | + } | ||
108 | + } | ||
109 | + return true; | ||
110 | + } | ||
86 | } | 111 | } | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -104,4 +104,141 @@ public class KeyListenerTest { | ... | @@ -104,4 +104,141 @@ public class KeyListenerTest { |
104 | thrown.expectMessage("mismatched input 'leaf' expecting {';', '+'}"); | 104 | thrown.expectMessage("mismatched input 'leaf' expecting {';', '+'}"); |
105 | YangNode node = manager.getDataModel("src/test/resources/KeyWithoutStatementEnd.yang"); | 105 | YangNode node = manager.getDataModel("src/test/resources/KeyWithoutStatementEnd.yang"); |
106 | } | 106 | } |
107 | + | ||
108 | + /** | ||
109 | + * Checks key values are set correctly. | ||
110 | + */ | ||
111 | + @Test | ||
112 | + public void processConfigFalseNoKey() throws IOException, ParserException { | ||
113 | + YangNode node = manager.getDataModel("src/test/resources/ConfigFalseNoKey.yang"); | ||
114 | + | ||
115 | + assertThat((node instanceof YangModule), is(true)); | ||
116 | + assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE)); | ||
117 | + YangModule yangNode = (YangModule) node; | ||
118 | + assertThat(yangNode.getName(), is("Test")); | ||
119 | + | ||
120 | + // Check whether the list is child of module | ||
121 | + YangList yangList = (YangList) yangNode.getChild(); | ||
122 | + assertThat(yangList.getName(), is("valid")); | ||
123 | + } | ||
124 | + | ||
125 | + /** | ||
126 | + * Checks key values are set correctly. | ||
127 | + */ | ||
128 | + @Test | ||
129 | + public void processConfigFalseValidKeyValidLeaf() throws IOException, ParserException { | ||
130 | + YangNode node = manager.getDataModel("src/test/resources/ConfigFalseValidKeyValidLeaf.yang"); | ||
131 | + | ||
132 | + assertThat((node instanceof YangModule), is(true)); | ||
133 | + assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE)); | ||
134 | + YangModule yangNode = (YangModule) node; | ||
135 | + assertThat(yangNode.getName(), is("Test")); | ||
136 | + | ||
137 | + // Check whether the list is child of module | ||
138 | + YangList yangList = (YangList) yangNode.getChild(); | ||
139 | + assertThat(yangList.getName(), is("valid")); | ||
140 | + | ||
141 | + ListIterator<String> keyList = yangList.getKeyList().listIterator(); | ||
142 | + assertThat(keyList.next(), is("invalid-interval")); | ||
143 | + } | ||
144 | + | ||
145 | + /** | ||
146 | + * Checks key values are set correctly. | ||
147 | + */ | ||
148 | + @Test | ||
149 | + public void processConfigFalseValidKeyValidLeafList() throws IOException, ParserException { | ||
150 | + YangNode node = manager.getDataModel("src/test/resources/ConfigFalseValidKeyValidLeafList.yang"); | ||
151 | + | ||
152 | + assertThat((node instanceof YangModule), is(true)); | ||
153 | + assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE)); | ||
154 | + YangModule yangNode = (YangModule) node; | ||
155 | + assertThat(yangNode.getName(), is("Test")); | ||
156 | + | ||
157 | + // Check whether the list is child of module | ||
158 | + YangList yangList = (YangList) yangNode.getChild(); | ||
159 | + assertThat(yangList.getName(), is("valid")); | ||
160 | + | ||
161 | + ListIterator<String> keyList = yangList.getKeyList().listIterator(); | ||
162 | + assertThat(keyList.next(), is("invalid-interval")); | ||
163 | + } | ||
164 | + | ||
165 | + /** | ||
166 | + * Checks whether exception is thrown when list's config is set to true and there is no key. | ||
167 | + */ | ||
168 | + @Test | ||
169 | + public void processConfigTrueNoKey() throws IOException, ParserException { | ||
170 | + thrown.expect(ParserException.class); | ||
171 | + thrown.expectMessage("A list must have atleast one key leaf if config is true"); | ||
172 | + YangNode node = manager.getDataModel("src/test/resources/ConfigTrueNoKey.yang"); | ||
173 | + } | ||
174 | + | ||
175 | + /** | ||
176 | + * Checks whether exception is thrown when list's config is set to true and there is no leaf. | ||
177 | + */ | ||
178 | + @Test | ||
179 | + public void processConfigTrueNoleafNoLeafList() throws IOException, ParserException { | ||
180 | + thrown.expect(ParserException.class); | ||
181 | + thrown.expectMessage("A list must have atleast one key leaf if config is true"); | ||
182 | + YangNode node = manager.getDataModel("src/test/resources/ConfigTrueNoleafNoLeafList.yang"); | ||
183 | + } | ||
184 | + | ||
185 | + /** | ||
186 | + * Checks key values are set correctly. | ||
187 | + */ | ||
188 | + @Test | ||
189 | + public void processConfigTrueValidKeyValidLeaf() throws IOException, ParserException { | ||
190 | + YangNode node = manager.getDataModel("src/test/resources/ConfigTrueValidKeyValidLeaf.yang"); | ||
191 | + | ||
192 | + assertThat((node instanceof YangModule), is(true)); | ||
193 | + assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE)); | ||
194 | + YangModule yangNode = (YangModule) node; | ||
195 | + assertThat(yangNode.getName(), is("Test")); | ||
196 | + | ||
197 | + // Check whether the list is child of module | ||
198 | + YangList yangList = (YangList) yangNode.getChild(); | ||
199 | + assertThat(yangList.getName(), is("valid")); | ||
200 | + | ||
201 | + ListIterator<String> keyList = yangList.getKeyList().listIterator(); | ||
202 | + assertThat(keyList.next(), is("invalid-interval")); | ||
203 | + } | ||
204 | + | ||
205 | + /** | ||
206 | + * Checks whether exception is thrown when key leaf identifier is not found in list. | ||
207 | + */ | ||
208 | + @Test | ||
209 | + public void processInvalidLeafIdentifier() throws IOException, ParserException { | ||
210 | + thrown.expect(ParserException.class); | ||
211 | + thrown.expectMessage("Leaf identifier must refer to a child leaf of the list"); | ||
212 | + YangNode node = manager.getDataModel("src/test/resources/InvalidLeafIdentifier.yang"); | ||
213 | + } | ||
214 | + | ||
215 | + /** | ||
216 | + * Checks whether exception is thrown when key leaf-list identifier is not found in list. | ||
217 | + */ | ||
218 | + @Test | ||
219 | + public void processInvalidLeafListIdentifier() throws IOException, ParserException { | ||
220 | + thrown.expect(ParserException.class); | ||
221 | + thrown.expectMessage("Leaf-list identifier must refer to a child leaf of the list"); | ||
222 | + YangNode node = manager.getDataModel("src/test/resources/InvalidLeafListIdentifier.yang"); | ||
223 | + } | ||
224 | + | ||
225 | + /** | ||
226 | + * Checks whether exception is thrown when key leaf-list is of type empty. | ||
227 | + */ | ||
228 | + @Test | ||
229 | + public void processKeyLeafListTypeEmpty() throws IOException, ParserException { | ||
230 | + thrown.expect(ParserException.class); | ||
231 | + thrown.expectMessage("A leaf-list that is part of the key must not be the built-in type \"empty\"."); | ||
232 | + YangNode node = manager.getDataModel("src/test/resources/KeyLeafListTypeEmpty.yang"); | ||
233 | + } | ||
234 | + | ||
235 | + /** | ||
236 | + * Checks whether exception is thrown when key leaf is of type empty. | ||
237 | + */ | ||
238 | + @Test | ||
239 | + public void processKeyLeafTypeEmpty() throws IOException, ParserException { | ||
240 | + thrown.expect(ParserException.class); | ||
241 | + thrown.expectMessage("A leaf that is part of the key must not be the built-in type \"empty\"."); | ||
242 | + YangNode node = manager.getDataModel("src/test/resources/KeyLeafTypeEmpty.yang"); | ||
243 | + } | ||
107 | } | 244 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -68,7 +68,7 @@ public class ListListenerTest { | ... | @@ -68,7 +68,7 @@ public class ListListenerTest { |
68 | assertThat(yangList.getName(), is("valid")); | 68 | assertThat(yangList.getName(), is("valid")); |
69 | 69 | ||
70 | ListIterator<String> keyList = yangList.getKeyList().listIterator(); | 70 | ListIterator<String> keyList = yangList.getKeyList().listIterator(); |
71 | - assertThat(keyList.next(), is("invalid")); | 71 | + assertThat(keyList.next(), is("invalid-interval")); |
72 | } | 72 | } |
73 | 73 | ||
74 | /** | 74 | /** |
... | @@ -95,7 +95,7 @@ public class ListListenerTest { | ... | @@ -95,7 +95,7 @@ public class ListListenerTest { |
95 | // Check whether the list is child of container | 95 | // Check whether the list is child of container |
96 | YangList yangList = (YangList) yangContainer.getChild(); | 96 | YangList yangList = (YangList) yangContainer.getChild(); |
97 | assertThat(yangList.getName(), is("valid")); | 97 | assertThat(yangList.getName(), is("valid")); |
98 | - assertThat(yangList.getKeyList().contains("invalid"), is(true)); | 98 | + assertThat(yangList.getKeyList().contains("invalid-interval"), is(true)); |
99 | } | 99 | } |
100 | 100 | ||
101 | /** | 101 | /** |
... | @@ -123,7 +123,7 @@ public class ListListenerTest { | ... | @@ -123,7 +123,7 @@ public class ListListenerTest { |
123 | // Check whether the list is child of list | 123 | // Check whether the list is child of list |
124 | YangList yangList = (YangList) yangList1.getChild(); | 124 | YangList yangList = (YangList) yangList1.getChild(); |
125 | assertThat(yangList.getName(), is("valid")); | 125 | assertThat(yangList.getName(), is("valid")); |
126 | - assertThat(yangList.getKeyList().contains("invalid"), is(true)); | 126 | + assertThat(yangList.getKeyList().contains("invalid-interval"), is(true)); |
127 | } | 127 | } |
128 | 128 | ||
129 | /** | 129 | /** |
... | @@ -148,7 +148,7 @@ public class ListListenerTest { | ... | @@ -148,7 +148,7 @@ public class ListListenerTest { |
148 | 148 | ||
149 | // Check whether list properties as set correctly. | 149 | // Check whether list properties as set correctly. |
150 | assertThat(yangList.getName(), is("ospf")); | 150 | assertThat(yangList.getName(), is("ospf")); |
151 | - assertThat(yangList.getKeyList().contains("process-id"), is(true)); | 151 | + assertThat(yangList.getKeyList().contains("invalid-interval"), is(true)); |
152 | 152 | ||
153 | assertThat(yangList.isConfig(), is(true)); | 153 | assertThat(yangList.isConfig(), is(true)); |
154 | assertThat(yangList.getMaxElelements(), is(10)); | 154 | assertThat(yangList.getMaxElelements(), is(10)); | ... | ... |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + container valid { | ||
6 | + leaf invalid-interval { | ||
7 | + type "uint16"; | ||
8 | + units "seconds"; | ||
9 | + description "Interval before a route is declared invalid"; | ||
10 | + mandatory true; | ||
11 | + status current; | ||
12 | + reference "RFC 6020"; | ||
13 | + } | ||
14 | + } | ||
15 | +} |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + container valid { | ||
6 | + config false; | ||
7 | + list valid { | ||
8 | + key "invalid-interval"; | ||
9 | + config true; | ||
10 | + leaf invalid-interval { | ||
11 | + type "uint16"; | ||
12 | + units "seconds"; | ||
13 | + status current; | ||
14 | + reference "RFC 6020"; | ||
15 | + } | ||
16 | + } | ||
17 | + } | ||
18 | +} |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + config false; | ||
7 | + key "invalid-interval"; | ||
8 | + leaf invalid-interval { | ||
9 | + type "uint16"; | ||
10 | + units "seconds"; | ||
11 | + status current; | ||
12 | + reference "RFC 6020"; | ||
13 | + } | ||
14 | + container valid { | ||
15 | + config true; | ||
16 | + leaf invalid-interval { | ||
17 | + type "uint16"; | ||
18 | + units "seconds"; | ||
19 | + status current; | ||
20 | + reference "RFC 6020"; | ||
21 | + } | ||
22 | + } | ||
23 | + } | ||
24 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + config false; | ||
8 | + leaf invalid-interval { | ||
9 | + type "uint16"; | ||
10 | + config true; | ||
11 | + units "seconds"; | ||
12 | + status current; | ||
13 | + reference "RFC 6020"; | ||
14 | + } | ||
15 | + } | ||
16 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + config false; | ||
8 | + leaf-list invalid-interval { | ||
9 | + type "uint16"; | ||
10 | + config true; | ||
11 | + units "seconds"; | ||
12 | + status current; | ||
13 | + reference "RFC 6020"; | ||
14 | + } | ||
15 | + } | ||
16 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + config false; | ||
8 | + leaf invalid-interval { | ||
9 | + type "string"; | ||
10 | + units "seconds"; | ||
11 | + status current; | ||
12 | + reference "RFC 6020"; | ||
13 | + } | ||
14 | + } | ||
15 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf-list invalid-interval { | ||
8 | + type "string"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + config true; | ||
7 | + leaf invalid-interval { | ||
8 | + type "string"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf-list invalid-interval { | ||
8 | + type "string"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -4,7 +4,7 @@ module Test { | ... | @@ -4,7 +4,7 @@ module Test { |
4 | prefix Ant; | 4 | prefix Ant; |
5 | container ospf { | 5 | container ospf { |
6 | list valid { | 6 | list valid { |
7 | - key "invalid"; | 7 | + key "invalid-interval"; |
8 | leaf invalid-interval { | 8 | leaf invalid-interval { |
9 | type "uint16"; | 9 | type "uint16"; |
10 | units "seconds"; | 10 | units "seconds"; | ... | ... |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf invalid { | ||
8 | + type "string"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf-list invalid { | ||
8 | + type "string"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf-list invalid-interval { | ||
8 | + type "empty"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf invalid-interval { | ||
8 | + type "empty"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -5,7 +5,7 @@ module Test { | ... | @@ -5,7 +5,7 @@ module Test { |
5 | list ospf { | 5 | list ospf { |
6 | key "process-id"; | 6 | key "process-id"; |
7 | list valid { | 7 | list valid { |
8 | - key "invalid"; | 8 | + key "invalid-interval"; |
9 | leaf invalid-interval { | 9 | leaf invalid-interval { |
10 | type "uint16"; | 10 | type "uint16"; |
11 | units "seconds"; | 11 | units "seconds"; |
... | @@ -13,5 +13,8 @@ module Test { | ... | @@ -13,5 +13,8 @@ module Test { |
13 | reference "RFC 6020"; | 13 | reference "RFC 6020"; |
14 | } | 14 | } |
15 | } | 15 | } |
16 | + leaf process-id { | ||
17 | + type "string"; | ||
18 | + } | ||
16 | } | 19 | } |
17 | } | 20 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -3,7 +3,7 @@ module Test { | ... | @@ -3,7 +3,7 @@ module Test { |
3 | namespace http://huawei.com; | 3 | namespace http://huawei.com; |
4 | prefix Ant; | 4 | prefix Ant; |
5 | list ospf { | 5 | list ospf { |
6 | - key "process-id"; | 6 | + key "invalid-interval"; |
7 | config true; | 7 | config true; |
8 | max-elements 10; | 8 | max-elements 10; |
9 | min-elements 3; | 9 | min-elements 3; | ... | ... |
... | @@ -3,7 +3,7 @@ module Test { | ... | @@ -3,7 +3,7 @@ module Test { |
3 | namespace http://huawei.com; | 3 | namespace http://huawei.com; |
4 | prefix Ant; | 4 | prefix Ant; |
5 | list valid { | 5 | list valid { |
6 | - key "invalid"; | 6 | + key "invalid-interval"; |
7 | leaf invalid-interval { | 7 | leaf invalid-interval { |
8 | type "uint16"; | 8 | type "uint16"; |
9 | units "seconds"; | 9 | units "seconds"; | ... | ... |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + container hello { | ||
6 | + container valid { | ||
7 | + leaf invalid-interval { | ||
8 | + type "uint16"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | + } | ||
15 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + container valid { | ||
6 | + leaf invalid-interval { | ||
7 | + type "uint16"; | ||
8 | + units "seconds"; | ||
9 | + status current; | ||
10 | + reference "RFC 6020"; | ||
11 | + } | ||
12 | + } | ||
13 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + container valid { | ||
6 | + leaf-list invalid-interval { | ||
7 | + type "uint16"; | ||
8 | + units "seconds"; | ||
9 | + status current; | ||
10 | + reference "RFC 6020"; | ||
11 | + } | ||
12 | + } | ||
13 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + container hello { | ||
6 | + list valid { | ||
7 | + key "invalid-interval"; | ||
8 | + leaf invalid-interval { | ||
9 | + type "uint16"; | ||
10 | + units "seconds"; | ||
11 | + status current; | ||
12 | + reference "RFC 6020"; | ||
13 | + } | ||
14 | + } | ||
15 | + } | ||
16 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list list1 { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf invalid-interval { | ||
8 | + type "uint16"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + container container1 { | ||
14 | + leaf leaf1 { | ||
15 | + type "uint16"; | ||
16 | + units "seconds"; | ||
17 | + status current; | ||
18 | + reference "RFC 6020"; | ||
19 | + } | ||
20 | + } | ||
21 | + } | ||
22 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf invalid-interval { | ||
8 | + type "uint16"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf-list invalid-interval { | ||
8 | + type "uint16"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + } | ||
14 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +module Test { | ||
2 | + yang-version 1; | ||
3 | + namespace http://huawei.com; | ||
4 | + prefix Ant; | ||
5 | + list valid { | ||
6 | + key "invalid-interval"; | ||
7 | + leaf invalid-interval { | ||
8 | + type "uint16"; | ||
9 | + units "seconds"; | ||
10 | + status current; | ||
11 | + reference "RFC 6020"; | ||
12 | + } | ||
13 | + list list1 { | ||
14 | + key "leaf1"; | ||
15 | + leaf leaf1 { | ||
16 | + type "uint16"; | ||
17 | + units "seconds"; | ||
18 | + status current; | ||
19 | + reference "RFC 6020"; | ||
20 | + } | ||
21 | + } | ||
22 | + } | ||
23 | +} |
-
Please register or login to post a comment