Vidyashree Rama
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)
......
...@@ -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 }
......
...@@ -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 + list valid {
6 + config false;
7 + leaf invalid-interval {
8 + type "string";
9 + units "seconds";
10 + status current;
11 + reference "RFC 6020";
12 + }
13 + }
14 +}
1 +module Test {
2 + yang-version 1;
3 + namespace http://huawei.com;
4 + prefix Ant;
5 + container valid {
6 + config false;
7 + leaf invalid-interval {
8 + type "uint16";
9 + units "seconds";
10 + status current;
11 + config true;
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 + leaf-list invalid-interval {
8 + type "uint16";
9 + units "seconds";
10 + status current;
11 + config true;
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 + config true;
7 + container container1 {
8 + leaf leaf1 {
9 + type "string";
10 + }
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 + 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 + key "invalid-interval";
7 + leaf invalid-interval {
8 + type "string";
9 + units "seconds";
10 + status current;
11 + reference "RFC 6020";
12 + }
13 + }
14 +}
...@@ -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
...@@ -12,5 +12,8 @@ module Test { ...@@ -12,5 +12,8 @@ module Test {
12 reference "RFC 6020"; 12 reference "RFC 6020";
13 } 13 }
14 } 14 }
15 + leaf process-id {
16 + type "string";
17 + }
15 } 18 }
16 } 19 }
...\ 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 +}