[ONOS-5884]YANG Serializer: Implement XML serializer.

Change-Id: Idffda88938d9c6c7b7c7814127a340bd2dc35039
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java
new file mode 100644
index 0000000..138d22d
--- /dev/null
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2017-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.yang.serializers.xml;
+
+import org.onosproject.yang.YangModel;
+import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.runtime.AppModuleInfo;
+import org.onosproject.yang.runtime.DefaultAppModuleInfo;
+import org.onosproject.yang.runtime.DefaultModelRegistrationParam;
+import org.onosproject.yang.runtime.ModelRegistrationParam;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.onosproject.yang.runtime.ymrimpl.DefaultYangModelRegistry;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.deSerializeDataModel;
+import static org.onosproject.yang.compiler.plugin.utils.YangApacheUtils.processModuleId;
+import static org.onosproject.yang.compiler.plugin.utils.YangApacheUtils.processYangModel;
+import static org.onosproject.yang.compiler.utils.UtilConstants.TEMP;
+import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.deleteDirectory;
+import static org.onosproject.yang.runtime.helperutils.RuntimeHelper.getInterfaceClassName;
+
+/**
+ * Represents mock bundle context. provides bundle context for YSR to do unit
+ * testing.
+ */
+public class MockYangSchemaNodeProvider {
+
+    private static final String FS = File.separator;
+    private static final String PATH = System.getProperty("user.dir") +
+            FS + "target" + FS + "classes" + FS;
+    private static final String SER_FILE_PATH = "yang" + FS + "resources" +
+            FS + "YangMetaData.ser";
+    private static final String META_PATH = PATH + SER_FILE_PATH;
+    private static final String TEMP_FOLDER_PATH = PATH + TEMP;
+    private YangModelRegistry reg = new DefaultYangModelRegistry();
+    private List<YangNode> nodes = new ArrayList<>();
+
+    /**
+     * Creates an instance of mock bundle context.
+     */
+    public MockYangSchemaNodeProvider() {
+    }
+
+    /**
+     * Process YANG schema node for a application.
+     */
+    public void processSchemaRegistry() {
+        try {
+            //Need to deserialize generated meta data file for unit tests.
+            Set<YangNode> appNode = deSerializeDataModel(META_PATH);
+            nodes.addAll(appNode);
+            reg.registerModel(prepareParam(nodes));
+            deleteDirectory(TEMP_FOLDER_PATH);
+        } catch (IOException e) {
+        }
+    }
+
+    /**
+     * Unregister given nodes from runtime service.
+     *
+     * @param nodes list of nodes
+     */
+    public void unRegister(List<YangNode> nodes) {
+        reg.unregisterModel(prepareParam(nodes));
+    }
+
+    /**
+     * Prepares model registration parameter.
+     *
+     * @param nodes list of nodes
+     * @return model registration parameter
+     */
+    private ModelRegistrationParam prepareParam(List<YangNode> nodes) {
+        //Process loading class file.
+        String appName;
+        ClassLoader classLoader = getClass().getClassLoader();
+
+        //Create model registration param.
+        ModelRegistrationParam.Builder b =
+                DefaultModelRegistrationParam.builder();
+
+        //create a new YANG model
+        YangModel model = processYangModel(META_PATH, nodes);
+        //set YANG model
+        b.setYangModel(model);
+
+        Iterator<YangNode> it = nodes.iterator();
+        while (it.hasNext()) {
+            YangSchemaNode node = it.next();
+
+            //If service class is not generated then use
+            // interface file to load this class.
+            appName = getInterfaceClassName(node);
+            Class<?> cls;
+            try {
+                cls = classLoader.loadClass(appName);
+            } catch (ClassNotFoundException e) {
+                continue;
+            }
+
+            //generate app info.
+            AppModuleInfo info = new DefaultAppModuleInfo(cls, null);
+            b.addAppModuleInfo(processModuleId((YangNode) node), info);
+        }
+        return b.build();
+    }
+
+    /**
+     * Returns schema registry.
+     *
+     * @return schema registry
+     */
+    public DefaultYangModelRegistry registry() {
+        return (DefaultYangModelRegistry) reg;
+    }
+}
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java
new file mode 100644
index 0000000..dfc8d06
--- /dev/null
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017-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.yang.serializers.xml;
+
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.runtime.Annotation;
+import org.onosproject.yang.runtime.DefaultAnnotation;
+import org.onosproject.yang.runtime.YangSerializerContext;
+import org.onosproject.yang.runtime.ymrimpl.DefaultYangModelRegistry;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Tests the default schema context provider methods.
+ */
+public class MockYangSerializerContext implements YangSerializerContext {
+
+    private static MockYangSchemaNodeProvider schemaProvider =
+            new MockYangSchemaNodeProvider();
+    private static final String NETCONF_NS =
+            "urn:ietf:params:xml:ns:netconf:base:1.0";
+    private static final String XMNLS_NC = "xmlns:xc";
+
+
+    @Override
+    public SchemaContext getContext() {
+        schemaProvider.processSchemaRegistry();
+        DefaultYangModelRegistry registry = schemaProvider.registry();
+        return registry;
+    }
+
+    @Override
+    public List<Annotation> getProtocolAnnotations() {
+        Annotation annotation = new DefaultAnnotation(XMNLS_NC, NETCONF_NS);
+        List<Annotation> protocolAnnotation = new LinkedList<>();
+        protocolAnnotation.add(annotation);
+        return protocolAnnotation;
+    }
+}
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
new file mode 100644
index 0000000..1f53ac5
--- /dev/null
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2017-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.yang.serializers.xml;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.InnerNode;
+import org.onosproject.yang.model.LeafListKey;
+import org.onosproject.yang.model.LeafNode;
+import org.onosproject.yang.model.ListKey;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.SchemaId;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
+import org.onosproject.yang.runtime.Annotation;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.CompositeStream;
+import org.onosproject.yang.runtime.DefaultCompositeStream;
+import org.onosproject.yang.runtime.YangSerializer;
+import org.onosproject.yang.runtime.YangSerializerContext;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ *
+ */
+public class XmlSerializerTest {
+
+    private static YangSerializerContext context;
+    private static YangSerializer xmlSerializer;
+
+    @BeforeClass
+    public static void prepare() {
+        context = new MockYangSerializerContext();
+        xmlSerializer = new XmlSerializer();
+    }
+
+    /**
+     * Validates data node in which XML element is of type YANG container.
+     */
+    @Test
+    public void testContainer() {
+        String path = "src/test/resources/testContainer.xml";
+
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        DataNode food = validateContainerDataNode(rootNode, "food", "yrt:food");
+        validateLeafDataNode(food, "p1", "yrt:food", "p1_value");
+        validateLeafListDataNode(food, "p2", "yrt:food", "p2_value");
+        validateLeafListDataNode(food, "p2", "yrt:food", "p2_value1");
+        DataNode c2 = validateContainerDataNode(rootNode, "c2", "yrt:food");
+        validateLeafDataNode(c2, "p3", "yrt:food", "p3_value");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is of type YANG leaf.
+     */
+    @Test
+    public void testModuleLevelLeaf() {
+        String path = "src/test/resources/testModuleLevelLeaf.xml";
+
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        validateLeafDataNode(rootNode, "bool", "yrt:food", "true");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is of type YANG list.
+     */
+    @Test
+    public void testListWithKeyleaves() {
+        String path = "src/test/resources/testListWithKeyleaves.xml";
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        List<String> keyNames = new LinkedList<>();
+        keyNames.add("k1");
+        keyNames.add("k2");
+        keyNames.add("k3");
+
+        List<String> keyNs = new LinkedList<>();
+        keyNs.add("yrt:list");
+        keyNs.add("yrt:list");
+        keyNs.add("yrt:list");
+
+        List<Object> values = new LinkedList<>();
+        values.add("k1_Value");
+        values.add("k2_Value");
+        values.add("k3_Value");
+
+        DataNode listl1 = validateListDataNode(rootNode, "l1", "yrt:list",
+                                               keyNames, keyNs, values);
+        validateLeafDataNode(listl1, "k1", "yrt:list", "k1_Value");
+        validateLeafDataNode(listl1, "k2", "yrt:list", "k2_Value");
+        validateLeafDataNode(listl1, "k3", "yrt:list", "k3_Value");
+        DataNode c1 = validateContainerDataNode(listl1, "c1", "yrt:list");
+        validateLeafDataNode(c1, "leaf_c1", "yrt:list", "l1_value");
+
+        values = new LinkedList<>();
+        values.add("k1_Value1");
+        values.add("k2_Value2");
+        values.add("k3_Value3");
+
+        DataNode listl2 = validateListDataNode(rootNode, "l1", "yrt:list",
+                                               keyNames, keyNs, values);
+        validateLeafDataNode(listl2, "k1", "yrt:list", "k1_Value1");
+        validateLeafDataNode(listl2, "k2", "yrt:list", "k2_Value2");
+        validateLeafDataNode(listl2, "k3", "yrt:list", "k3_Value3");
+        c1 = validateContainerDataNode(listl2, "c1", "yrt:list");
+        validateLeafDataNode(c1, "leaf_c1", "yrt:list", "l1_value1");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is child of YANG
+     * choice-case.
+     */
+    @Test
+    public void testChoiceCase() {
+        String path = "src/test/resources/testChoiceCase.xml";
+
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        DataNode list1 = validateListDataNode(rootNode, "banana",
+                                              "yrt:choice-case", null, null, null);
+        validateLeafDataNode(list1, "l1", "yrt:choice-case", "value2");
+        DataNode coldDrink = validateContainerDataNode(rootNode, "cold-drink",
+                                                       "yrt:choice-case");
+        validateLeafListDataNode(coldDrink, "flavor", "yrt:choice-case",
+                                 "value3");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is of YANG augmented nodes.
+     */
+    @Test
+    public void testAugment() {
+        String path = "src/test/resources/testAugment.xml";
+
+        String uri = "urn:ietf:params:xml:ns:yang:yrt-ietf-network:networks/network/node";
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(uri, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        ResourceData resourceData = compositeData.resourceData();
+        List<DataNode> dataNodes = resourceData.dataNodes();
+        DataNode dataNode = dataNodes.get(0);
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is("t-point"));
+        assertThat(schemaId.namespace(), is("urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology"));
+        validateLeafDataNode(dataNode, "tp-id",
+                             "urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology", "Stub");
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates data node in which XML element is child of YANG grouping.
+     */
+    @Test
+    public void testGroupingUsesDataNode() {
+        String path = "src/test/resources/testGroupingUses.xml";
+
+        String uri = "urn:ietf:params:xml:ns:yang:yrt-ietf-network:networks-state/network";
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(uri, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        ResourceData resourceData = compositeData.resourceData();
+        List<DataNode> dataNodes = resourceData.dataNodes();
+        LeafNode dataNode = ((LeafNode) dataNodes.get(0));
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is("network-ref"));
+        assertThat(schemaId.namespace(), is("urn:ietf:params:xml:ns:yang:yrt-ietf-network"));
+        assertThat(dataNode.value().toString(), is("abc"));
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates whether XML attributes is converted to annotations.
+     */
+    @Test
+    public void testXmlAttributes() {
+        String path = "src/test/resources/testXmlAttributes.xml";
+        String namespace = "http://example.com/schema/1.2/config";
+
+        DefaultCompositeStream external =
+                new DefaultCompositeStream(null, parseInput(path));
+        CompositeData compositeData = xmlSerializer.decode(external, context);
+        DataNode rootNode = validateRootDataNode(compositeData.resourceData());
+        DataNode top = validateContainerDataNode(rootNode, "top", namespace);
+        DataNode interfaceDn = validateContainerDataNode(top, "interface",
+                                                         namespace);
+        validateLeafDataNode(interfaceDn, "name", namespace, "Ethernet0/0");
+        validateLeafDataNode(interfaceDn, "mtu", namespace, "1500");
+        DataNode address = validateContainerDataNode(interfaceDn, "address",
+                                                     namespace);
+        validateLeafDataNode(address, "name", namespace, "192.0.2.4");
+        validateLeafDataNode(address, "prefix-length", namespace, "24");
+
+        List<AnnotatedNodeInfo> annotatedNodeInfos = compositeData
+                .annotatedNodesInfo();
+        AnnotatedNodeInfo annotatedNodeInfo = annotatedNodeInfos.get(0);
+        List<Annotation> annotationList = annotatedNodeInfo.annotations();
+        Annotation annotation = annotationList.get(0);
+        assertThat(annotation.name(), is("xc:operation"));
+        assertThat(annotation.value(), is("replace"));
+
+        // encode test
+        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+                                                               context);
+        InputStream inputStream = compositeStream.resourceData();
+        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
+    }
+
+    /**
+     * Validates and returns container data node.
+     *
+     * @param parent    data node holding container
+     * @param name      name of the container
+     * @param namespace namespace of the container
+     * @return container data node
+     */
+    private static DataNode validateContainerDataNode(DataNode parent,
+                                                      String name,
+                                                      String namespace) {
+        Map<NodeKey, DataNode> childNodes = ((InnerNode) parent).childNodes();
+        NodeKey key = NodeKey.builder().schemaId(name, namespace).build();
+        DataNode dataNode = childNodes.get(key);
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is(name));
+        assertThat(schemaId.namespace(), is(namespace));
+        return dataNode;
+    }
+
+    /**
+     * Validates and returns list data node.
+     *
+     * @param parent    data node holding list
+     * @param name      name of the list
+     * @param namespace namespace of the list
+     * @param keynames  list of key leaf names
+     * @param keyNs     list of key leaf namespace
+     * @param keyVal    list of key leaf values
+     * @return list data node
+     */
+    private static DataNode validateListDataNode(DataNode parent,
+                                                 String name, String namespace,
+                                                 List<String> keynames,
+                                                 List<String> keyNs,
+                                                 List<Object> keyVal) {
+        Map<NodeKey, DataNode> childNodes = ((InnerNode) parent).childNodes();
+        NodeKey key = NodeKey.builder().schemaId(name, namespace).build();
+        DataNode dataNode;
+        if (keynames != null && !keynames.isEmpty()) {
+            ListKey.ListKeyBuilder listKeyBldr = new ListKey.ListKeyBuilder();
+            listKeyBldr.schemaId(key.schemaId());
+            for (int i = 0; i < keynames.size(); i++) {
+                listKeyBldr.addKeyLeaf(keynames.get(i), keyNs.get(i),
+                                       keyVal.get(i));
+            }
+            dataNode = childNodes.get(listKeyBldr.build());
+        } else {
+            dataNode = childNodes.get(key);
+        }
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is(name));
+        assertThat(schemaId.namespace(), is(namespace));
+        return dataNode;
+    }
+
+    /**
+     * Validates leaf data node.
+     *
+     * @param parent    data node holding leaf
+     * @param name      name of the leaf
+     * @param namespace namespace of the leaf
+     * @param value     leaf value
+     */
+    private static void validateLeafDataNode(DataNode parent,
+                                             String name, String namespace,
+                                             Object value) {
+        Map<NodeKey, DataNode> childNodes = ((InnerNode) parent).childNodes();
+        NodeKey key = NodeKey.builder().schemaId(name, namespace).build();
+        LeafNode dataNode = ((LeafNode) childNodes.get(key));
+        SchemaId schemaId = dataNode.key().schemaId();
+        assertThat(schemaId.name(), is(name));
+        assertThat(schemaId.namespace(), is(namespace));
+        assertThat(dataNode.value().toString(), is(value));
+    }
+
+    /**
+     * Validates leaf-list data node.
+     *
+     * @param parent    data node holding leaf-list
+     * @param name      name of the leaf-list
+     * @param namespace namespace of the leaf-list
+     * @param value     leaf-list value
+     */
+    private static void validateLeafListDataNode(DataNode parent,
+                                                 String name, String namespace,
+                                                 Object value) {
+        Map<NodeKey, DataNode> childNodes = ((InnerNode) parent).childNodes();
+        NodeKey key = NodeKey.builder().schemaId(name, namespace).build();
+        LeafListKey.LeafListKeyBuilder leafListBldr =
+                new LeafListKey.LeafListKeyBuilder();
+        leafListBldr.schemaId(key.schemaId());
+        leafListBldr.value(value);
+        DataNode leafListNode = childNodes.get(leafListBldr.build());
+        SchemaId schemaId = leafListNode.key().schemaId();
+        assertThat(schemaId.name(), is(name));
+        assertThat(schemaId.namespace(), is(namespace));
+        assertThat(((LeafNode) leafListNode).value().toString(), is(value));
+    }
+
+    /**
+     * Validates root data node.
+     *
+     * @param resourceData resource data which holds data node
+     * @return root data node
+     */
+    private static DataNode validateRootDataNode(ResourceData resourceData) {
+        List<DataNode> dataNodes = resourceData.dataNodes();
+        DataNode rootNode = dataNodes.get(0);
+        SchemaId rootSchemaId = rootNode.key().schemaId();
+        assertThat(rootSchemaId.name(), is("/"));
+        return rootNode;
+    }
+
+    /**
+     * Reads XML contents from file path and returns input stream.
+     *
+     * @param path path of XML file
+     * @return input stream
+     */
+    private static InputStream parseInput(String path) {
+        String temp;
+        StringBuilder sb = new StringBuilder();
+        try (BufferedReader br = new BufferedReader(new FileReader(path))) {
+            while ((temp = br.readLine()) != null) {
+                sb.append(temp);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return IOUtils.toInputStream(sb);
+    }
+
+    /**
+     * Reads XML contents from file path and returns input stream.
+     *
+     * @param path path of XML file
+     * @return input stream
+     */
+    private static String parseXml(String path) {
+        String temp;
+        StringBuilder sb = new StringBuilder();
+        try (BufferedReader br = new BufferedReader(new FileReader(path))) {
+            while ((temp = br.readLine()) != null) {
+                sb.append(temp);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Converts input stream to string format.
+     *
+     * @param inputStream input stream of xml
+     * @return XML string
+     */
+    private static String convertInputStreamToString(InputStream inputStream) {
+        BufferedReader br;
+        StringBuilder sb = new StringBuilder();
+        String xmlData;
+        br = new BufferedReader(new InputStreamReader(inputStream));
+        try {
+            while ((xmlData = br.readLine()) != null) {
+                sb.append(xmlData);
+            }
+        } catch (IOException e) {
+            throw new XmlSerializerException(e.getMessage());
+        }
+        return sb.toString();
+    }
+}
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/package-info.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/package-info.java
new file mode 100644
index 0000000..43b4abc
--- /dev/null
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/package-info.java
@@ -0,0 +1,20 @@
+/*
+ *  Copyright 2017-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.
+ */
+
+/**
+ * The XML serializer implementation of the YangSerializer interface.
+ */
+package org.onosproject.yang.serializers.xml;
diff --git a/serializers/xml/src/test/resources/testAugment.xml b/serializers/xml/src/test/resources/testAugment.xml
new file mode 100644
index 0000000..4c883f6
--- /dev/null
+++ b/serializers/xml/src/test/resources/testAugment.xml
@@ -0,0 +1,3 @@
+<t-point xmlns="urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology">
+<tp-id>Stub</tp-id>
+</t-point>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testChoiceCase.xml b/serializers/xml/src/test/resources/testChoiceCase.xml
new file mode 100644
index 0000000..22590a1
--- /dev/null
+++ b/serializers/xml/src/test/resources/testChoiceCase.xml
@@ -0,0 +1,6 @@
+<banana xmlns="yrt:choice-case">
+<l1>value2</l1>
+</banana>
+<cold-drink xmlns="yrt:choice-case">
+<flavor>value3</flavor>
+</cold-drink>
diff --git a/serializers/xml/src/test/resources/testContainer.xml b/serializers/xml/src/test/resources/testContainer.xml
new file mode 100644
index 0000000..ee679b8
--- /dev/null
+++ b/serializers/xml/src/test/resources/testContainer.xml
@@ -0,0 +1,8 @@
+<food xmlns="yrt:food">
+<p1>p1_value</p1>
+<p2>p2_value</p2>
+<p2>p2_value1</p2>
+</food>
+<c2 xmlns="yrt:food">
+<p3>p3_value</p3>
+</c2>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testGroupingUses.xml b/serializers/xml/src/test/resources/testGroupingUses.xml
new file mode 100644
index 0000000..45d3d05
--- /dev/null
+++ b/serializers/xml/src/test/resources/testGroupingUses.xml
@@ -0,0 +1,2 @@
+<network-ref xmlns="urn:ietf:params:xml:ns:yang:yrt-ietf-network">abc
+</network-ref>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testListWithKeyleaves.xml b/serializers/xml/src/test/resources/testListWithKeyleaves.xml
new file mode 100644
index 0000000..1f9616a
--- /dev/null
+++ b/serializers/xml/src/test/resources/testListWithKeyleaves.xml
@@ -0,0 +1,16 @@
+<l1 xmlns="yrt:list" operation="replace">
+<k1>k1_Value</k1>
+<k2>k2_Value</k2>
+<k3>k3_Value</k3>
+<c1>
+<leaf_c1>l1_value</leaf_c1>
+</c1>
+</l1>
+<l1 xmlns="yrt:list" operation="replace">
+<k1>k1_Value1</k1>
+<k2>k2_Value2</k2>
+<k3>k3_Value3</k3>
+<c1>
+<leaf_c1>l1_value1</leaf_c1>
+</c1>
+</l1>
diff --git a/serializers/xml/src/test/resources/testModuleLevelLeaf.xml b/serializers/xml/src/test/resources/testModuleLevelLeaf.xml
new file mode 100644
index 0000000..13da6e6
--- /dev/null
+++ b/serializers/xml/src/test/resources/testModuleLevelLeaf.xml
@@ -0,0 +1,2 @@
+<bool xmlns="yrt:food">true</bool>
+<boolean xmlns="yrt:food">true</boolean>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testMultipleLevelAugment.xml b/serializers/xml/src/test/resources/testMultipleLevelAugment.xml
new file mode 100644
index 0000000..ab31d06
--- /dev/null
+++ b/serializers/xml/src/test/resources/testMultipleLevelAugment.xml
@@ -0,0 +1,6 @@
+<interface xmlns="ser.ospf" operation="replace">
+<area-type>Stub</area-type>
+</interface>
+<statistics xmlns="ser.ospf" operation="replace">
+<spf-runs-count>3</spf-runs-count>
+</statistics>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/testXmlAttributes.xml b/serializers/xml/src/test/resources/testXmlAttributes.xml
new file mode 100644
index 0000000..0ca9a71
--- /dev/null
+++ b/serializers/xml/src/test/resources/testXmlAttributes.xml
@@ -0,0 +1,10 @@
+<top xmlns="http://example.com/schema/1.2/config">
+<interface xc:operation="replace">
+<name>Ethernet0/0</name>
+<mtu>1500</mtu>
+<address>
+<name>192.0.2.4</name>
+<prefix-length>24</prefix-length>
+</address>
+</interface>
+</top>
\ No newline at end of file