Mock YdtBuilder and YdtNode to do UT for Restconf
fix the java code problems.
add more test cases
Change-Id: I034d35e8a41a6c12e293fad867d6540dd5f37e95
diff --git a/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/JsonToYdtListener.java b/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/JsonToYdtListener.java
index 7c59e11..1118116 100755
--- a/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/JsonToYdtListener.java
+++ b/protocols/restconf/server/utils/src/main/java/org/onosproject/protocol/restconf/server/utils/parser/json/JsonToYdtListener.java
@@ -110,21 +110,26 @@
@Override
public void exitJsonNode(JsonNode jsonNode) {
- if (jsonNode.getNodeType() == ARRAY && nameStack.empty()) {
+
+ if (isListArray) {
+ isListArray = false;
+ ydtBuilder.traverseToParent();
return;
}
- if (jsonNode.getNodeType() == ARRAY && !isListArray) {
+ if (jsonNode.getNodeType() == ARRAY) {
+ //check empty before pop
+ if (nameStack.empty()) {
+ return;
+ }
nameStack.pop();
+ //check empty after pop
if (nameStack.empty()) {
return;
}
defaultMultiInsNode = nameStack.get(nameStack.size() - 1);
return;
}
- if (isListArray) {
- isListArray = false;
- }
ydtBuilder.traverseToParent();
}
diff --git a/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYangSchemaId.java b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYangSchemaId.java
new file mode 100644
index 0000000..fb04710
--- /dev/null
+++ b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYangSchemaId.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.protocol.restconf.server.utils.parser.api;
+
+import java.util.Objects;
+
+/**
+ * A test class which represents YANG data node identifier which is a
+ * combination of name and namespace.
+ */
+public class TestYangSchemaId {
+ private String name;
+ private String namespace;
+
+ /**
+ * Returns the name of the node.
+ *
+ * @return name of the node
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Sets name of the node.
+ *
+ * @param name name of the node
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns namespace of the node.
+ *
+ * @return namespace of the node
+ */
+ public String getNameSpace() {
+ return this.namespace;
+ }
+
+ /**
+ * Sets namespace of the node.
+ *
+ * @param namespace namespace of the node
+ */
+ public void setNameSpace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (!(obj instanceof TestYangSchemaId)) {
+ return false;
+ } else {
+ TestYangSchemaId other = (TestYangSchemaId) obj;
+ return Objects.equals(this.name, other.name) &&
+ Objects.equals(this.namespace, other.namespace);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.name, this.namespace);
+ }
+}
diff --git a/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYdtBuilder.java b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYdtBuilder.java
new file mode 100644
index 0000000..c411ebe
--- /dev/null
+++ b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYdtBuilder.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.protocol.restconf.server.utils.parser.api;
+
+import org.onosproject.yms.ydt.YdtBuilder;
+import org.onosproject.yms.ydt.YdtContext;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+import org.onosproject.yms.ydt.YdtType;
+import org.onosproject.yms.ydt.YmsOperationType;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.onosproject.yms.ydt.YdtContextOperationType.NONE;
+import static org.onosproject.yms.ydt.YdtType.*;
+
+/**
+ * A test class which represents YANG request work bench which contains all
+ * parameters for request handling and methods to build and obtain YANG data
+ * tree which is data (sub)instance representation, abstract of protocol.
+ */
+public class TestYdtBuilder implements YdtBuilder {
+
+ private TestYdtNode curNode;
+
+ private TestYdtNode rootNode;
+
+ private final YmsOperationType ymsOperationType;
+
+ private YdtContextOperationType ydtDefaultOpType;
+
+ /**
+ * Creates an instance of YANG request work bench which is use to initialize
+ * logical rootNode and and schema registry.
+ *
+ * @param name name of logical container of a protocol
+ * which is a holder of the complete tree
+ * @param namespace namespace of logical container
+ * @param opType type of operation done by using YANG
+ * interface
+ */
+ public TestYdtBuilder(String name, String namespace,
+ YmsOperationType opType) {
+ TestYangSchemaId nodeId = new TestYangSchemaId();
+ nodeId.setName(name);
+ nodeId.setNameSpace(namespace);
+ setRootNode(new TestYdtNode(nodeId, SINGLE_INSTANCE_NODE));
+ ymsOperationType = opType;
+ }
+
+ private void setRootNode(TestYdtNode node) {
+ rootNode = node;
+ curNode = node;
+ }
+
+ @Override
+ public YdtContext getRootNode() {
+ return rootNode;
+ }
+
+ @Override
+ public YmsOperationType getYmsOperationType() {
+ return ymsOperationType;
+ }
+
+ @Override
+ public void setRootTagAttributeMap(Map<String, String> attributeTag) {
+
+ }
+
+ @Override
+ public Map<String, String> getRootTagAttributeMap() {
+ return null;
+ }
+
+ @Override
+ public void addChild(String name, String namespace) {
+ addChild(name, namespace, SINGLE_INSTANCE_NODE, NONE);
+ }
+
+ @Override
+ public void addChild(String name, String namespace, YdtType ydtType) {
+ addChild(name, namespace, ydtType, NONE);
+
+ }
+
+ @Override
+ public void addChild(String name, String namespace,
+ YdtContextOperationType opType) {
+ addChild(name, namespace, SINGLE_INSTANCE_NODE, opType);
+ }
+
+ @Override
+ public void addChild(String name, String namespace, YdtType ydtType,
+ YdtContextOperationType opType) {
+ TestYangSchemaId id = new TestYangSchemaId();
+ id.setName(name);
+ String ns = namespace != null ? namespace :
+ curNode.getYdtNodeIdentifier().getNameSpace();
+ id.setNameSpace(ns);
+ TestYdtNode childNode = new TestYdtNode(id, ydtType);
+
+ YdtContextOperationType type = opType == null ? NONE : opType;
+ childNode.setYdtContextOperationType(type);
+
+ curNode.addChild(childNode);
+
+ // Updating the curNode.
+ curNode = childNode;
+ }
+
+ @Override
+ public void addLeaf(String name, String namespace, String value) {
+ addLeaf(name, namespace, value, null, SINGLE_INSTANCE_LEAF_VALUE_NODE);
+ }
+
+ @Override
+ public void addLeaf(String name, String namespace, Set<String> valueSet) {
+ addLeaf(name, namespace, null, valueSet, MULTI_INSTANCE_LEAF_VALUE_NODE);
+ }
+
+ @Override
+ public void addMultiInstanceChild(String name, String namespace,
+ List<String> valueList) {
+ addChild(name, namespace, MULTI_INSTANCE_LEAF_VALUE_NODE, NONE);
+ if (curNode.getYdtType() == MULTI_INSTANCE_LEAF_VALUE_NODE) {
+ for (String value : valueList) {
+ curNode.addValue(value);
+ }
+ }
+ }
+
+ private void addLeaf(String name, String namespace, String value,
+ Set<String> valueSet, YdtType ydtType) {
+ addChild(name, namespace, ydtType, NONE);
+
+ if (value != null) {
+ curNode.addValue(value);
+ } else if (valueSet != null) {
+ curNode.addValueSet(valueSet);
+ }
+ }
+
+ @Override
+ public void traverseToParent() {
+ curNode = curNode.getParent();
+ }
+
+ @Override
+ public YdtContext getCurNode() {
+ return curNode;
+ }
+
+ @Override
+ public void setDefaultEditOperationType(YdtContextOperationType opType) {
+ ydtDefaultOpType = opType;
+ }
+
+ /**
+ * Returns the default context operation type of a YDT builder.
+ *
+ * @return default context operation type
+ */
+ public YdtContextOperationType getYdtDefaultOpType() {
+ return ydtDefaultOpType;
+ }
+}
diff --git a/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYdtNode.java b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYdtNode.java
new file mode 100644
index 0000000..4e609a1
--- /dev/null
+++ b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/api/TestYdtNode.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.protocol.restconf.server.utils.parser.api;
+
+import org.onosproject.yms.ydt.YdtContext;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+import org.onosproject.yms.ydt.YdtExtendedInfoType;
+import org.onosproject.yms.ydt.YdtType;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A test class which represents a general instance node in YANG data tree.
+ */
+public class TestYdtNode implements YdtContext {
+
+ private TestYdtNode parent;
+ private TestYdtNode child;
+ private TestYdtNode nextSibling;
+ private TestYdtNode previousSibling;
+ private TestYdtNode lastChild;
+ private YdtType ydtType;
+ private String value;
+ private final Set<String> valueSet = new HashSet<>();
+ private TestYangSchemaId id;
+ private YdtContextOperationType ydtContextOperationType;
+
+ /**
+ * Creates a general YANG instance node object.
+ *
+ * @param id node identifier of YDT multi instance node .
+ * @param ydtType type of YDT node to be added
+ */
+ public TestYdtNode(TestYangSchemaId id, YdtType ydtType) {
+ this.id = id;
+ this.ydtType = ydtType;
+ }
+
+ @Override
+ public String getName() {
+ return id.getName();
+ }
+
+ @Override
+ public String getNamespace() {
+ return id.getNameSpace();
+ }
+
+ @Override
+ public <T> T getYdtContextExtendedInfo() {
+ return null;
+ }
+
+ @Override
+ public YdtExtendedInfoType getYdtExtendedInfoType() {
+ return null;
+ }
+
+ @Override
+ public YdtType getYdtType() {
+ return ydtType;
+ }
+
+ @Override
+ public TestYdtNode getParent() {
+ return parent;
+ }
+
+ @Override
+ public TestYdtNode getFirstChild() {
+ return child;
+ }
+
+ @Override
+ public TestYdtNode getLastChild() {
+ return lastChild;
+ }
+
+ @Override
+ public TestYdtNode getNextSibling() {
+ return nextSibling;
+ }
+
+ @Override
+ public YdtContext getPreviousSibling() {
+ return previousSibling;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public Set<String> getValueSet() {
+ return valueSet;
+ }
+
+ /**
+ * Sets the parent of node.
+ *
+ * @param parent node
+ */
+ public void setParent(TestYdtNode parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Sets the first instance of a child node.
+ *
+ * @param child is only child to be set
+ */
+ public void setChild(TestYdtNode child) {
+ this.child = child;
+ }
+
+ /**
+ * Sets the last instance of a child node.
+ *
+ * @param child is last child to be set
+ */
+ public void setLastChild(TestYdtNode child) {
+ lastChild = child;
+ }
+
+ /**
+ * Sets the next sibling of node.
+ *
+ * @param sibling YANG node
+ */
+ public void setNextSibling(TestYdtNode sibling) {
+ nextSibling = sibling;
+ }
+
+ /**
+ * Sets the previous sibling.
+ *
+ * @param previousSibling points to predecessor sibling
+ */
+ public void setPreviousSibling(TestYdtNode previousSibling) {
+ this.previousSibling = previousSibling;
+ }
+
+ /**
+ * Returns object node identifier.
+ *
+ * @return node identifier
+ */
+ public TestYangSchemaId getYdtNodeIdentifier() {
+ return id;
+ }
+
+ /**
+ * Adds a child node.
+ * The children sibling list will be sorted based on node
+ * type. This will add single child or sub-tree based on isAtomic flag.
+ *
+ * @param newChild refers to a new child to be added
+ */
+ public void addChild(YdtContext newChild) {
+ TestYdtNode node = (TestYdtNode) newChild;
+
+ if (node.getParent() == null) {
+ node.setParent(this);
+ }
+
+ // If new node needs to be added as first child.
+ if (getFirstChild() == null) {
+ setChild(node);
+ setLastChild(node);
+ return;
+ }
+
+ // If new node needs to be added as last child.
+ TestYdtNode curNode = getLastChild();
+ curNode.setNextSibling(node);
+ node.setPreviousSibling(curNode);
+ setLastChild(node);
+ }
+
+ /**
+ * Adds the given value to the non single instance leaf node.
+ *
+ * @param value value in a single instance node
+ */
+ public void addValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Adds the given valueSet to the non multi instance leaf node.
+ *
+ * @param values value set in a multi instance leaf node
+ */
+ public void addValueSet(Set<String> values) {
+ valueSet.addAll(values);
+ }
+
+
+ /**
+ * Sets the context operation type for the YDT node.
+ *
+ * @param opType context operation type
+ */
+ public void setYdtContextOperationType(YdtContextOperationType opType) {
+ this.ydtContextOperationType = opType;
+ }
+
+ /**
+ * Returns the context operation type for the YDT node.
+ *
+ * @return context operation type
+ */
+ public YdtContextOperationType getYdtContextOperationType() {
+ return ydtContextOperationType;
+ }
+}
diff --git a/protocols/restconf/server/utils/src/test/java/org/onosproject/restconf/utils/parser/json/DefaultJsonWalkerTest.java b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/json/DefaultJsonWalkerTest.java
similarity index 97%
rename from protocols/restconf/server/utils/src/test/java/org/onosproject/restconf/utils/parser/json/DefaultJsonWalkerTest.java
rename to protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/json/DefaultJsonWalkerTest.java
index c82f0f8..0c4f9b0 100644
--- a/protocols/restconf/server/utils/src/test/java/org/onosproject/restconf/utils/parser/json/DefaultJsonWalkerTest.java
+++ b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/json/DefaultJsonWalkerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.onosproject.restconf.utils.parser.json;
+package org.onosproject.protocol.restconf.server.utils.parser.json;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -22,7 +22,6 @@
import org.junit.Before;
import org.junit.Test;
import org.onosproject.protocol.restconf.server.utils.parser.api.JsonListener;
-import org.onosproject.protocol.restconf.server.utils.parser.json.DefaultJsonWalker;
import java.io.InputStream;
import java.util.ArrayList;
diff --git a/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/json/JsonToYdtListenerTest.java b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/json/JsonToYdtListenerTest.java
new file mode 100644
index 0000000..07cc223
--- /dev/null
+++ b/protocols/restconf/server/utils/src/test/java/org/onosproject/protocol/restconf/server/utils/parser/json/JsonToYdtListenerTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.protocol.restconf.server.utils.parser.json;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.protocol.restconf.server.utils.parser.api.JsonWalker;
+import org.onosproject.protocol.restconf.server.utils.parser.api.TestYdtBuilder;
+import org.onosproject.yms.ydt.YdtBuilder;
+import org.onosproject.yms.ydt.YdtContext;
+
+import java.io.InputStream;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.yms.ydt.YdtType.*;
+import static org.onosproject.yms.ydt.YmsOperationType.QUERY_REQUEST;
+
+/**
+ * Unit tests for JsonToYtdListener.
+ */
+public class JsonToYdtListenerTest {
+ private static final String RESTCONF_ROOT = "/onos/restconf";
+ private static final String WRONG_STRUCTURE = "The Ydt structure is wrong!";
+ private static final String WRONG_TYPE = "The Ydt type is wrong!";
+
+ private YdtBuilder builder;
+ private JsonToYdtListener listener;
+ private JsonWalker jsonWalker;
+
+ @Before
+ public void setup() throws Exception {
+ builder = new TestYdtBuilder(RESTCONF_ROOT, null, QUERY_REQUEST);
+ listener = new JsonToYdtListener(builder);
+ jsonWalker = new DefaultJsonWalker();
+ }
+
+ private ObjectNode loadJsonFile(String path) throws Exception {
+ InputStream jsonStream = getClass().getResourceAsStream(path);
+ ObjectMapper mapper = new ObjectMapper();
+ return (ObjectNode) mapper.readTree(jsonStream);
+ }
+
+ @Test
+ public void testArrayNodeTransfer() throws Exception {
+ ObjectNode arrayNode = loadJsonFile("/arrayNode.json");
+ jsonWalker.walk(listener, null, arrayNode);
+ YdtContext rootNode = builder.getRootNode();
+ YdtContext firstChild = rootNode.getFirstChild();
+ YdtContext nextSibling = firstChild.getNextSibling();
+ assertEquals(WRONG_TYPE, SINGLE_INSTANCE_LEAF_VALUE_NODE,
+ firstChild.getYdtType());
+ assertEquals(WRONG_STRUCTURE, "surname", firstChild.getName());
+ assertEquals(WRONG_TYPE, MULTI_INSTANCE_NODE, nextSibling.getYdtType());
+ assertEquals(WRONG_STRUCTURE, "networklist", nextSibling.getName());
+ assertEquals(WRONG_STRUCTURE, "networklist",
+ nextSibling.getNextSibling().getName());
+ assertEquals(WRONG_STRUCTURE, "networklist",
+ rootNode.getLastChild().getName());
+ }
+
+ @Test
+ public void testListInListNodeTransfer() throws Exception {
+ ObjectNode arrayNode = loadJsonFile("/listInList.json");
+ jsonWalker.walk(listener, null, arrayNode);
+ YdtContext rootNode = builder.getRootNode();
+ YdtContext firstChild = rootNode.getFirstChild();
+ YdtContext levelOneArray = firstChild.getFirstChild();
+ assertEquals(WRONG_STRUCTURE, "container-identifier1",
+ firstChild.getName());
+ assertEquals(WRONG_STRUCTURE, "list-identifier2",
+ levelOneArray.getName());
+ assertEquals(WRONG_STRUCTURE, "list-identifier2",
+ levelOneArray.getNextSibling().getName());
+
+ YdtContext identifier3Node = levelOneArray.getLastChild();
+ assertEquals(WRONG_STRUCTURE, "container-identifier3",
+ identifier3Node.getName());
+ YdtContext identifier4Node = identifier3Node.getLastChild();
+ assertEquals(WRONG_STRUCTURE, "list-identifier4",
+ identifier4Node.getName());
+ YdtContext identifier5ListNode = identifier4Node.getLastChild();
+ assertEquals(WRONG_STRUCTURE, "leaf-list-identifier5",
+ identifier5ListNode.getName());
+ assertEquals(WRONG_TYPE, MULTI_INSTANCE_LEAF_VALUE_NODE,
+ identifier5ListNode.getYdtType());
+ }
+
+ @Test
+ public void testListAfterLeafList() throws Exception {
+ ObjectNode arrayNode = loadJsonFile("/listAfterLeaflist.json");
+ jsonWalker.walk(listener, null, arrayNode);
+ YdtContext rootNode = builder.getRootNode();
+ YdtContext firstChild = rootNode.getFirstChild();
+ YdtContext second = firstChild.getNextSibling();
+ YdtContext lastChild = rootNode.getLastChild();
+ assertEquals(WRONG_STRUCTURE, "leaf-identifier1", firstChild.getName());
+ assertEquals(WRONG_STRUCTURE, "leaf-list-identifier1", second.getName());
+ assertEquals(WRONG_STRUCTURE, "list-identifier1", lastChild.getName());
+ }
+
+ @Test
+ public void testLeafListAfterList() throws Exception {
+ ObjectNode arrayNode = loadJsonFile("/leaflistAfterlist.json");
+ jsonWalker.walk(listener, null, arrayNode);
+ YdtContext rootNode = builder.getRootNode();
+ YdtContext firstChild = rootNode.getFirstChild();
+ YdtContext second = firstChild.getNextSibling();
+ YdtContext lastChild = rootNode.getLastChild();
+ assertEquals(WRONG_STRUCTURE, "leaf-identifier1", firstChild.getName());
+ assertEquals(WRONG_STRUCTURE, "list-identifier1", second.getName());
+ YdtContext level2Child = second.getFirstChild();
+ assertEquals(WRONG_STRUCTURE, "leaf-identifier2", level2Child.getName());
+ assertEquals(WRONG_STRUCTURE, "5", level2Child.getValue());
+ assertEquals(WRONG_STRUCTURE, "leaf-list-identifier1", lastChild.getName());
+ Set<String> sets = ImmutableSet.of("5", "12");
+ assertEquals(WRONG_STRUCTURE, sets, lastChild.getValueSet());
+ }
+}
\ No newline at end of file
diff --git a/protocols/restconf/server/utils/src/test/resources/leaflistAfterlist.json b/protocols/restconf/server/utils/src/test/resources/leaflistAfterlist.json
new file mode 100644
index 0000000..8b0c4e1
--- /dev/null
+++ b/protocols/restconf/server/utils/src/test/resources/leaflistAfterlist.json
@@ -0,0 +1,12 @@
+{
+ "leaf-identifier1": "1",
+ "list-identifier1": [
+ {
+ "leaf-identifier2": "5"
+ }
+ ],
+ "leaf-list-identifier1": [
+ "5",
+ "12"
+ ]
+}
\ No newline at end of file
diff --git a/protocols/restconf/server/utils/src/test/resources/listAfterLeaflist.json b/protocols/restconf/server/utils/src/test/resources/listAfterLeaflist.json
new file mode 100644
index 0000000..bbe25e1
--- /dev/null
+++ b/protocols/restconf/server/utils/src/test/resources/listAfterLeaflist.json
@@ -0,0 +1,12 @@
+{
+ "leaf-identifier1": "1",
+ "leaf-list-identifier1": [
+ "5",
+ "12"
+ ],
+ "list-identifier1": [
+ {
+ "leaf-identifier2": "5"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/protocols/restconf/server/utils/src/test/resources/listInList.json b/protocols/restconf/server/utils/src/test/resources/listInList.json
new file mode 100644
index 0000000..185d878
--- /dev/null
+++ b/protocols/restconf/server/utils/src/test/resources/listInList.json
@@ -0,0 +1,39 @@
+{
+ "container-identifier1": {
+ "list-identifier2": [
+ {
+ "leaf-identifier3": "enum1",
+ "container-identifier3": {
+ "leaf-identifier4": "",
+ "leaf-list-identifier4": [
+ "type-pattern-string6"
+ ],
+ "list-identifier4": [
+ {
+ "leaf-identifier5": "type-pattern-string7",
+ "leaf-list-identifier5": [
+ "type-pattern-string7",
+ "type-pattern-string7",
+ "type-pattern-string7"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "leaf-identifier3": "enum2",
+ "list-identifier3": [
+ {
+ "leaf-identifier4": "myidentity",
+ "container-identifier4": {
+ "leaf-identifier5": "type-pattern-string3",
+ "leaf-list-identifier5": [
+ "type-pattern-string3"
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file