[ONOS-6694] Multi augment with same name.
Change-Id: Ib319944816679c5c9a703ff771bdfbd0d6af67ab
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
index 934a869..c7a2422 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangAugment.java
@@ -158,6 +158,11 @@
private String setterMethodName;
/**
+ * Logical node of YANG augment.
+ */
+ private YangAugment logicalNode;
+
+ /**
* Create a YANG augment node.
*/
public YangAugment() {
@@ -569,4 +574,22 @@
public void setSetterMethodName(String name) {
setterMethodName = name;
}
+
+ /**
+ * Returns the logical YANG augment node.
+ *
+ * @return logical YANG augment
+ */
+ public YangAugment getLogicalNode() {
+ return logicalNode;
+ }
+
+ /**
+ * Sets the logical YANG augment node.
+ *
+ * @param logicalNode logical YANG augment
+ */
+ public void setLogicalNode(YangAugment logicalNode) {
+ this.logicalNode = logicalNode;
+ }
}
diff --git a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
index 4f77d69..dbe46a8 100644
--- a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
+++ b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/listeners/AugmentListener.java
@@ -16,6 +16,7 @@
package org.onosproject.yang.compiler.parser.impl.listeners;
+import org.antlr.v4.runtime.Token;
import org.onosproject.yang.compiler.datamodel.YangAtomicPath;
import org.onosproject.yang.compiler.datamodel.YangAugment;
import org.onosproject.yang.compiler.datamodel.YangModule;
@@ -49,9 +50,12 @@
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.checkAugNameCollision;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.getPrefixRemovedName;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.getValidAbsoluteSchemaNodeId;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.isDuplicateNode;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.parseUsesAugment;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.removeAugment;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerValidation.validateCardinalityEitherOne;
@@ -141,6 +145,7 @@
augment.setName(removeQuotesAndHandleConcat(ctx.augment().getText()));
augment.setPrefixRemovedName(name);
+ checkAugNameCollision(root, augment);
try {
root.addChild(augment);
} catch (DataModelException e) {
@@ -149,11 +154,6 @@
ctx.augment().getText(), ENTRY, e.getMessage()));
}
listener.getParsedDataStack().push(augment);
-
- // Adds resolution info to the list
- YangResolutionInfoImpl<YangAugment> info =
- new YangResolutionInfoImpl<>(augment, root, line, pos);
- addToResolution(info, ctx);
}
/**
@@ -175,7 +175,19 @@
MISSING_CURRENT_HOLDER, AUGMENT_DATA,
ctx.augment().getText(), EXIT));
}
- listener.getParsedDataStack().pop();
+ YangAugment augment = (YangAugment) listener.getParsedDataStack().pop();
+
+ boolean isDup = isDuplicateNode(augment);
+ if (isDup) {
+ removeAugment(augment);
+ } else {
+ Token txt = ctx.getStart();
+ YangResolutionInfoImpl<YangAugment> info =
+ new YangResolutionInfoImpl<>(augment, augment.getParent(),
+ txt.getLine(),
+ txt.getCharPositionInLine());
+ addToResolution(info, ctx);
+ }
}
/**
diff --git a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
index aaadaf2..25ec87b 100644
--- a/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
+++ b/compiler/base/parser/src/main/java/org/onosproject/yang/compiler/parser/impl/parserutils/ListenerUtil.java
@@ -18,7 +18,10 @@
import org.antlr.v4.runtime.ParserRuleContext;
import org.onosproject.yang.compiler.datamodel.YangAtomicPath;
+import org.onosproject.yang.compiler.datamodel.YangAugment;
import org.onosproject.yang.compiler.datamodel.YangImport;
+import org.onosproject.yang.compiler.datamodel.YangLeaf;
+import org.onosproject.yang.compiler.datamodel.YangLeafList;
import org.onosproject.yang.compiler.datamodel.YangLeafRef;
import org.onosproject.yang.compiler.datamodel.YangModule;
import org.onosproject.yang.compiler.datamodel.YangNode;
@@ -29,9 +32,11 @@
import org.onosproject.yang.compiler.datamodel.YangRelativePath;
import org.onosproject.yang.compiler.datamodel.YangSubModule;
import org.onosproject.yang.compiler.datamodel.YangUniqueHolder;
+import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
import org.onosproject.yang.compiler.datamodel.utils.YangConstructType;
import org.onosproject.yang.compiler.parser.antlrgencode.GeneratedYangParser.AugmentStatementContext;
import org.onosproject.yang.compiler.parser.exceptions.ParserException;
+import org.onosproject.yang.compiler.translator.tojava.javamodel.YangJavaAugmentTranslator;
import org.slf4j.Logger;
import java.text.ParseException;
@@ -51,6 +56,9 @@
import static org.onosproject.yang.compiler.datamodel.utils.YangConstructType.getYangConstructType;
import static org.onosproject.yang.compiler.parser.antlrgencode.GeneratedYangParser.PathStatementContext;
import static org.onosproject.yang.compiler.parser.antlrgencode.GeneratedYangParser.YangVersionStatementContext;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
+import static org.onosproject.yang.compiler.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
import static org.onosproject.yang.compiler.utils.UtilConstants.ADD;
import static org.onosproject.yang.compiler.utils.UtilConstants.ANCESTOR;
import static org.onosproject.yang.compiler.utils.UtilConstants.AT;
@@ -1030,4 +1038,145 @@
}
return builder.toString();
}
+
+ /**
+ * Checks if the augment node is a duplicate node. If the augment is
+ * duplicate, then it adds all its children to the logical node.
+ *
+ * @param augment YANG augment
+ * @return true if it is a duplicate node; false otherwise
+ */
+ public static boolean isDuplicateNode(YangAugment augment) {
+ YangAugment logical = augment.getLogicalNode();
+ if (logical == null) {
+ return false;
+ }
+ YangNode lastChild = logical;
+
+ YangNode child = logical.getChild();
+ while (child != null) {
+ lastChild = child;
+ child = child.getNextSibling();
+ }
+ addChildToLogicalNode(logical, augment, lastChild);
+ addLeafAndLeafList(logical, augment);
+ return true;
+ }
+
+ /**
+ * Adds the child and its sibling in duplicate augment to the logical
+ * augment node.
+ *
+ * @param logical logical augment node
+ * @param augment YANG augment
+ * @param lastChild logical node's last node
+ */
+ private static void addChildToLogicalNode(YangAugment logical,
+ YangAugment augment,
+ YangNode lastChild) {
+ YangNode augChild = augment.getChild();
+ while (augChild != null) {
+ if (lastChild == logical) {
+ augChild.setParent(lastChild);
+ try {
+ lastChild.addChild(augChild);
+ } catch (DataModelException e) {
+ throw new ParserException(
+ constructExtendedListenerErrorMessage(
+ UNHANDLED_PARSED_DATA, AUGMENT_DATA,
+ augment.getName(), ENTRY, e.getMessage()));
+ }
+ } else {
+ augChild.setParent(lastChild.getParent());
+ augChild.setPreviousSibling(lastChild);
+ lastChild.setNextSibling(augChild);
+ }
+ lastChild = augChild;
+ augChild = augChild.getNextSibling();
+ }
+ }
+
+ /**
+ * Adds leaf and leaf-list from the YANG augment to the logical augment
+ * node.
+ *
+ * @param logical logical YANG augment
+ * @param augment duplicate YANG augment
+ */
+ private static void addLeafAndLeafList(YangAugment logical,
+ YangAugment augment) {
+
+ List<YangLeaf> logLeaves = logical.getListOfLeaf();
+ List<YangLeafList> logLl = logical.getListOfLeafList();
+ List<YangLeaf> augLeaves = augment.getListOfLeaf();
+ List<YangLeafList> augLl = augment.getListOfLeafList();
+
+ if (augLeaves != null && !augLeaves.isEmpty()) {
+ for (YangLeaf leaf : augLeaves) {
+ leaf.setContainedIn(logical);
+ if (logLeaves == null) {
+ logLeaves = new LinkedList<>();
+ }
+ logLeaves.add(leaf);
+ }
+ }
+ if (augLl != null && !augLl.isEmpty()) {
+ for (YangLeafList ll : augLl) {
+ ll.setContainedIn(logical);
+ if (logLl == null) {
+ logLl = new LinkedList<>();
+ }
+ logLl.add(ll);
+ }
+ }
+ }
+
+ /**
+ * Checks for the augment name name collision. If there are augments with
+ * the same name present, then the new augment will be set with a logical
+ * node.
+ *
+ * @param root augment parent node
+ * @param aug YANG augment node
+ */
+ public static void checkAugNameCollision(YangNode root, YangAugment aug) {
+ YangNode child = root.getChild();
+ while (child != null) {
+ if (child instanceof YangAugment) {
+ if (child.getName().equals(aug.getName())) {
+ aug.setLogicalNode((YangAugment) child);
+ }
+ }
+ child = child.getNextSibling();
+ }
+ }
+
+ /**
+ * Removes the duplicate YANG augment from the data tree by detaching it
+ * from its parent and from its sibling.
+ *
+ * @param augment duplicate YANG augment
+ */
+ public static void removeAugment(YangAugment augment) {
+ YangNode root = augment.getParent();
+ YangNode child = root.getChild();
+ YangNode pSib = null;
+ if (child == null) {
+ throw new ParserException("The root node of augment " + augment
+ .getName() + " must have atleast one child");
+ }
+ while (child != null) {
+ if (child == augment) {
+ if (pSib == null) {
+ root.setChild(null);
+ } else {
+ pSib.setNextSibling(null);
+ }
+ }
+ pSib = child;
+ child = child.getNextSibling();
+ }
+ augment = new YangJavaAugmentTranslator();
+ augment = null;
+ }
}
diff --git a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
index 156194e..97e2a86 100644
--- a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
+++ b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/AugmentTranslatorTest.java
@@ -435,4 +435,67 @@
YangPluginConfig.compileCode(COMP);
deleteDirectory(DIR);
}
+
+ /**
+ * Checks multiple augment handling which has the same name for open
+ * config YANG files.
+ *
+ * @throws IOException if any error occurs during IO on files
+ * @throws ParserException if any error occurs during parsing
+ * @throws MojoExecutionException if any mojo operation fails
+ */
+ @Test
+ public void processOpenConfigAugment() throws IOException,
+ ParserException, MojoExecutionException {
+
+ deleteDirectory(DIR);
+ String dir = "src/test/resources/augwithsamename/oc/";
+
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(dir)) {
+ paths.add(Paths.get(file));
+ }
+
+ utilManager.createYangFileInfoSet(paths);
+ utilManager.parseYangFileInfoSet();
+ utilManager.createYangNodeSet();
+ utilManager.resolveDependenciesUsingLinker();
+
+ YangPluginConfig yangPluginConfig = new YangPluginConfig();
+ yangPluginConfig.setCodeGenDir(DIR);
+ utilManager.translateToJava(yangPluginConfig);
+ YangPluginConfig.compileCode(COMP);
+ deleteDirectory(DIR);
+ }
+
+ /**
+ * Checks multiple augment handling which has the same name.
+ *
+ * @throws IOException if any error occurs during IO on files
+ * @throws ParserException if any error occurs during parsing
+ * @throws MojoExecutionException if any mojo operation fail
+ */
+ @Test
+ public void processSameAugName() throws IOException,
+ ParserException, MojoExecutionException {
+
+ deleteDirectory(DIR);
+ String dir = "src/test/resources/augwithsamename/multiaugwithsamename/";
+
+ Set<Path> paths = new HashSet<>();
+ for (String file : getYangFiles(dir)) {
+ paths.add(Paths.get(file));
+ }
+
+ utilManager.createYangFileInfoSet(paths);
+ utilManager.parseYangFileInfoSet();
+ utilManager.createYangNodeSet();
+ utilManager.resolveDependenciesUsingLinker();
+
+ YangPluginConfig yangPluginConfig = new YangPluginConfig();
+ yangPluginConfig.setCodeGenDir(DIR);
+ utilManager.translateToJava(yangPluginConfig);
+ YangPluginConfig.compileCode(COMP);
+ deleteDirectory(DIR);
+ }
}
diff --git a/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module1.yang b/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module1.yang
new file mode 100644
index 0000000..fedf735
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module1.yang
@@ -0,0 +1,14 @@
+module module1 {
+
+ namespace "urn:ietf:params:xml:ns:aug:module:1";
+
+ prefix mod-a;
+
+ container cont{
+ container val {
+ leaf-list create {
+ type string;
+ }
+ }
+ }
+}
diff --git a/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module2.yang b/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module2.yang
new file mode 100644
index 0000000..7ec09aa
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/augwithsamename/multiaugwithsamename/module2.yang
@@ -0,0 +1,39 @@
+module module2 {
+
+ namespace "urn:ietf:params:xml:ns:aug:module:2";
+
+ prefix mod-b;
+
+ import module1 {
+ prefix mod-a;
+ }
+
+ augment "/mod-a:cont/mod-a:val" {
+ leaf arg {
+ type string;
+ }
+ }
+
+ augment "/mod-a:cont/mod-a:val" {
+ leaf-list arg-lis {
+ type string;
+ }
+ }
+
+ augment "/mod-a:cont/mod-a:val" {
+ container cont {
+ leaf ll {
+ type binary;
+ }
+ }
+ }
+
+ augment "/mod-a:cont/mod-a:val" {
+ list contlist {
+ key true;
+ leaf true {
+ type boolean;
+ }
+ }
+ }
+}
diff --git a/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-if-ip.yang b/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-if-ip.yang
new file mode 100644
index 0000000..1c7a8ce
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-if-ip.yang
@@ -0,0 +1,69 @@
+module openconfig-if-ip {
+
+ yang-version "1";
+
+ namespace "http://openconfig.net/yang/interfaces/ip";
+
+ prefix "oc-ip";
+
+ import openconfig-interfaces {
+ prefix oc-if;
+ }
+
+ grouping ip-vrrp-top {
+ container vrrp {
+ list vrrp-group {
+ key "virtual-router-id";
+ leaf virtual-router-id {
+ type string;
+ }
+ }
+ }
+ }
+
+ grouping ipv4-top {
+ container ipv4 {
+ container addresses {
+ list address {
+ key "ip";
+ leaf ip {
+ type string;
+ }
+ }
+ }
+ }
+ }
+
+ grouping ipv6-top {
+ container ipv6 {
+ container addresses {
+ list address {
+ key "ip";
+ leaf ip {
+ type string;
+ }
+ }
+ }
+ }
+ }
+
+ augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+ "oc-if:subinterface" {
+ uses ipv4-top;
+ }
+
+ augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+ "oc-if:subinterface" {
+ uses ipv6-top;
+ }
+
+ augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+ "oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address" {
+ uses ip-vrrp-top;
+ }
+
+ augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" +
+ "oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address" {
+ uses ip-vrrp-top;
+ }
+}
diff --git a/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-interfaces.yang b/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-interfaces.yang
new file mode 100644
index 0000000..2804dc6
--- /dev/null
+++ b/compiler/plugin/maven/src/test/resources/augwithsamename/oc/openconfig-interfaces.yang
@@ -0,0 +1,42 @@
+module openconfig-interfaces {
+
+ yang-version "1";
+
+ namespace "http://openconfig.net/yang/interfaces";
+
+ prefix "oc-if";
+
+ contact
+ "OpenConfig working group
+ netopenconfig@googlegroups.com";
+
+ grouping subinterfaces-top {
+ container subinterfaces {
+ list subinterface {
+ key "index";
+ leaf index {
+ type int8;
+ }
+ }
+ }
+ }
+
+ grouping interfaces-top {
+ description
+ "Top-level grouping for interface configuration and
+ operational state data";
+
+ container interfaces {
+ list interface {
+ key "name";
+
+ leaf name {
+ type string;
+ }
+ uses subinterfaces-top;
+ }
+ }
+ }
+
+ uses interfaces-top;
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DataTreeContextSwitchTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DataTreeContextSwitchTest.java
index 3277212..69fb3f6 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DataTreeContextSwitchTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DataTreeContextSwitchTest.java
@@ -18,6 +18,15 @@
import org.junit.Test;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.PrivateIp;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.AugmentedSchValid;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.DefaultAugmentedSchValid;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.AugCaseModKey;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.DefaultAugCaseModKey;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.DefaultTestedCont;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.DefaultUnlistedVal;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.TestedCont;
+import org.onosproject.yang.gen.v1.augmentchoice.rev20160826.augmentchoice.contenttest.valid.augmentedschvalid.UnlistedVal;
import org.onosproject.yang.gen.v1.modeldatatoresourcedata.rev20160826.modeldatatoresourcedata.BinaryTypedef;
import org.onosproject.yang.gen.v1.modeldatatoresourcedata.rev20160826.modeldatatoresourcedata.DefaultFirstLevel;
import org.onosproject.yang.gen.v1.modeldatatoresourcedata.rev20160826.modeldatatoresourcedata.UnionTypedef;
@@ -43,6 +52,8 @@
import org.onosproject.yang.gen.v1.modulelistandkeyaugment.rev20160826.modulelistandkeyaugment.modkey.DefaultAugmentedSchModKey;
import org.onosproject.yang.gen.v1.modulelistandkeyaugment.rev20160826.modulelistandkeyaugment.modkey.augmentedschmodkey.AugListModKey;
import org.onosproject.yang.gen.v1.modulelistandkeyaugment.rev20160826.modulelistandkeyaugment.modkey.augmentedschmodkey.DefaultAugListModKey;
+import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.DefaultValid;
+import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.Valid;
import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.ChoiceContainer;
import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.DefaultChoiceContainer;
import org.onosproject.yang.gen.v1.ytbchoicewithcontainerandleaflist.rev20160826.ytbchoicewithcontainerandleaflist.contenttest.choicecontainer.choicecontainer.DefaultPredict;
@@ -59,6 +70,7 @@
import org.onosproject.yang.gen.v1.ytbsimplechoicecase.rev20160826.ytbsimplechoicecase.ytbfood.ytbsnack.DefaultYtbLateNight;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.InnerModelObject;
import org.onosproject.yang.model.InnerNode;
import org.onosproject.yang.model.KeyLeaf;
import org.onosproject.yang.model.ListKey;
@@ -80,9 +92,9 @@
import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_NODE;
import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE;
import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_NODE;
-import static org.onosproject.yang.runtime.impl.TestUtils.validateDataNode;
import static org.onosproject.yang.runtime.impl.MockYangSchemaNodeProvider.processSchemaRegistry;
import static org.onosproject.yang.runtime.impl.MockYangSchemaNodeProvider.registry;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateDataNode;
/**
* Unit test cases for YANG tree builder for context switch for augment, RPC
@@ -1379,6 +1391,97 @@
true, "namespace");
}
+ /**
+ * Unit test case for multi augments with the same augment name.
+ */
+ @Test
+ public void processMultiAugWithSameName() {
+ setUp();
+
+ AugmentedSchValid valid = new DefaultAugmentedSchValid();
+ valid.chTest(PrivateIp.class);
+ byte b1 = 8;
+ byte b2 = 110;
+ valid.addToTest(b1);
+ valid.addToTest(b2);
+ TestedCont cont = new DefaultTestedCont();
+ cont.presence("true");
+ valid.testedCont(cont);
+ UnlistedVal val = new DefaultUnlistedVal();
+ val.presence("false");
+ valid.addToUnlistedVal(val);
+ AugCaseModKey modKey = new DefaultAugCaseModKey();
+ modKey.types(12);
+ valid.addToAugCaseModKey(modKey);
+ Valid valid1 = new DefaultValid();
+ valid1.addAugmentation((InnerModelObject) valid);
+
+ data = new DefaultModelObjectData.Builder();
+ data.addModelObject((InnerModelObject) valid1);
+
+ rscData = treeBuilder.getResourceData(data.build());
+
+ nameSpace = "yms:test:ytb:choice:with:container:and:leaf:list";
+
+ id = rscData.resourceId();
+ keys = id.nodeKeys();
+ assertThat(1, is(keys.size()));
+
+ sid = keys.get(0).schemaId();
+ assertThat("/", is(sid.name()));
+ assertThat(null, is(sid.namespace()));
+
+ dataNodes = rscData.dataNodes();
+ assertThat(6, is(dataNodes.size()));
+
+ node = dataNodes.get(0);
+ validateDataNode(node, "ch-test", nameSpace,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "private-ip");
+
+ node = dataNodes.get(1);
+ validateDataNode(node, "test", nameSpace,
+ MULTI_INSTANCE_LEAF_VALUE_NODE, true, "8");
+
+ node = dataNodes.get(2);
+ validateDataNode(node, "test", nameSpace,
+ MULTI_INSTANCE_LEAF_VALUE_NODE, true, "110");
+
+ node = dataNodes.get(3);
+ validateDataNode(node, "unlisted-val", nameSpace, MULTI_INSTANCE_NODE,
+ true, null);
+
+ Map<NodeKey, DataNode> child = ((InnerNode) node).childNodes();
+ assertThat(1, is(child.size()));
+
+ Iterator<Map.Entry<NodeKey, DataNode>> it = child.entrySet().iterator();
+ Map.Entry<NodeKey, DataNode> n = it.next();
+ validateDataNode(n.getValue(), "presence", nameSpace,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "false");
+
+ node = dataNodes.get(4);
+ validateDataNode(node, "aug-case-modKey", nameSpace,
+ MULTI_INSTANCE_NODE, true, null);
+
+ child = ((InnerNode) node).childNodes();
+ assertThat(1, is(child.size()));
+
+ it = child.entrySet().iterator();
+ n = it.next();
+ validateDataNode(n.getValue(), "types", nameSpace,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "12");
+
+ node = dataNodes.get(5);
+ validateDataNode(node, "tested-cont", nameSpace, SINGLE_INSTANCE_NODE,
+ true, null);
+
+ child = ((InnerNode) node).childNodes();
+ assertThat(1, is(child.size()));
+
+ it = child.entrySet().iterator();
+ n = it.next();
+ validateDataNode(n.getValue(), "presence", nameSpace,
+ SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "true");
+ }
/**
* Unit test for inter file augment. Model object is null so resource id
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
index 6afb987..d1bf76a 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
@@ -97,6 +97,35 @@
value = "str2";
dBlr = addDataNode(dBlr, "router-ip", IP_TOPO_NAME_SPACE, value, null);
dBlr = exitDataNode(dBlr);
+
+ value = "r1tor2";
+ dBlr = addDataNode(dBlr, "router-path", IP_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = null;
+ dBlr = addDataNode(dBlr, "aug-route", IP_TOPO_NAME_SPACE, value, null);
+ value = "r2tor1";
+ dBlr = addDataNode(dBlr, "router-path", IP_TOPO_NAME_SPACE, value, null);
+
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+
+ value = "17";
+ dBlr = addDataNode(dBlr, "value", IP_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "18";
+ dBlr = addDataNode(dBlr, "value", IP_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = null;
+ dBlr = addDataNode(dBlr, "aug-route-c", IP_TOPO_NAME_SPACE, value, null);
+
+ value = "valid";
+ dBlr = addDataNode(dBlr, "val", IP_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ dBlr = exitDataNode(dBlr);
return dBlr.build();
}
@@ -197,6 +226,11 @@
.augmentation(DefaultAugmentedTopoNode.class);
assertThat(obj.routerId(), is("str1"));
assertThat(obj.routerIp(), is("str2"));
+ assertThat(obj.routerPath(), is("r1tor2"));
+ assertThat(obj.augRoute().routerPath(), is("r2tor1"));
+ assertThat(obj.value().get(0).toString(), is("17"));
+ assertThat(obj.value().get(1).toString(), is("18"));
+ assertThat(obj.augRoutec().get(0).val(), is("valid"));
}
@Test
diff --git a/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang b/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang
index cb56c41..cd24d2e 100644
--- a/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang
+++ b/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang
@@ -20,6 +20,32 @@
}
}
+ augment /topo:node{
+ leaf router-path {
+ type string;
+ }
+ container aug-route {
+ leaf router-path {
+ type string;
+ }
+ }
+ }
+
+ augment /topo:node{
+ leaf-list value {
+ type uint8;
+ }
+ }
+
+ augment /topo:node{
+ list aug-route-c {
+ key val;
+ leaf val {
+ type string;
+ }
+ }
+ }
+
augment /topo:node/topo:termination-points/topo:termination-point {
leaf ip-address {
type string;
diff --git a/runtime/src/test/resources/ytbTestYangFiles/AugmentChoice.yang b/runtime/src/test/resources/ytbTestYangFiles/AugmentChoice.yang
index cc68691..637fa45 100644
--- a/runtime/src/test/resources/ytbTestYangFiles/AugmentChoice.yang
+++ b/runtime/src/test/resources/ytbTestYangFiles/AugmentChoice.yang
@@ -2,14 +2,26 @@
yang-version 1;
namespace yms:test:ytb:choice:with:container:and:leaf:list";
prefix "sch1";
- import YtbChoiceWithContainerAndLeafList {
- prefix sch;
- }
+
+ import YtbChoiceWithContainerAndLeafList {
+ prefix sch;
+ }
revision "2016-08-26";
+ identity ip {
+ }
+
+ identity private-ip {
+ base ip;
+ }
+
+ identity public-ip {
+ base ip;
+ }
+
augment /sch:content-test/ {
list aug-choice-modKey {
- key "types";
+ key "types";
leaf types {
type int32;
}
@@ -17,11 +29,36 @@
}
augment /sch:content-test/sch:valid {
+ leaf ch-test {
+ type identityref {
+ base ip;
+ }
+ }
+
+ leaf-list test {
+ type int8;
+ }
+
+ container tested-cont {
+ leaf presence {
+ type string;
+ }
+ }
+
+ list unlisted-val {
+ key "presence";
+ leaf presence {
+ type string;
+ }
+ }
+ }
+
+ augment /sch:content-test/sch:valid {
list aug-case-modKey {
key "types";
leaf types {
type int32;
}
}
- }
+ }
}
\ No newline at end of file