Mock YdtBuilder and YdtNode to do UT for Restconf

fix the java code problems.
add more test cases

Change-Id: I034d35e8a41a6c12e293fad867d6540dd5f37e95
This commit is contained in:
chengfan 2016-10-11 21:03:23 +08:00 committed by Gerrit Code Review
parent 528007c085
commit 0c32d71d3f
9 changed files with 706 additions and 7 deletions

View File

@ -110,21 +110,26 @@ public class JsonToYdtListener implements JsonListener {
@Override @Override
public void exitJsonNode(JsonNode jsonNode) { public void exitJsonNode(JsonNode jsonNode) {
if (jsonNode.getNodeType() == ARRAY && nameStack.empty()) {
if (isListArray) {
isListArray = false;
ydtBuilder.traverseToParent();
return; return;
} }
if (jsonNode.getNodeType() == ARRAY && !isListArray) { if (jsonNode.getNodeType() == ARRAY) {
//check empty before pop
if (nameStack.empty()) {
return;
}
nameStack.pop(); nameStack.pop();
//check empty after pop
if (nameStack.empty()) { if (nameStack.empty()) {
return; return;
} }
defaultMultiInsNode = nameStack.get(nameStack.size() - 1); defaultMultiInsNode = nameStack.get(nameStack.size() - 1);
return; return;
} }
if (isListArray) {
isListArray = false;
}
ydtBuilder.traverseToParent(); ydtBuilder.traverseToParent();
} }

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -14,7 +14,7 @@
* limitations under the License. * 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.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@ -22,7 +22,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.onosproject.protocol.restconf.server.utils.parser.api.JsonListener; 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.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -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());
}
}

View File

@ -0,0 +1,12 @@
{
"leaf-identifier1": "1",
"list-identifier1": [
{
"leaf-identifier2": "5"
}
],
"leaf-list-identifier1": [
"5",
"12"
]
}

View File

@ -0,0 +1,12 @@
{
"leaf-identifier1": "1",
"leaf-list-identifier1": [
"5",
"12"
],
"list-identifier1": [
{
"leaf-identifier2": "5"
}
]
}

View File

@ -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"
]
}
}
]
}
]
}
}