Bug 3899: Milestone: Increase test coverage for Yangtools 88/43688/2
authorIgor Foltin <ifoltin@cisco.com>
Tue, 9 Aug 2016 13:20:11 +0000 (15:20 +0200)
committerRobert Varga <nite@hq.sk>
Fri, 12 Aug 2016 12:21:18 +0000 (12:21 +0000)
Added test for SchemaContextEmitter

Change-Id: If60531f0a84579519487075a340f73e68c2526eb
Signed-off-by: Igor Foltin <ifoltin@cisco.com>
(cherry picked from commit f77f673e129e7a866bd21f6072c600f75471a068)

yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/SchemaContextEmitterTest.java [new file with mode: 0644]
yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.xml [new file with mode: 0644]
yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.yang [new file with mode: 0644]

diff --git a/yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/SchemaContextEmitterTest.java b/yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/SchemaContextEmitterTest.java
new file mode 100644 (file)
index 0000000..1216b70
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.yangtools.yang.model.export.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import com.google.common.base.Preconditions;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.net.URISyntaxException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.ElementNameAndAttributeQualifier;
+import org.custommonkey.xmlunit.XMLAssert;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.export.YinExportUtils;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+public class SchemaContextEmitterTest {
+
+    @Test
+    public void testSchemaContextEmitter() throws ReactorException, IOException, URISyntaxException,
+            XMLStreamException, SAXException {
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSources("/schema-context-emitter-test");
+        assertNotNull(schemaContext);
+        assertEquals(1, schemaContext.getModules().size());
+
+        final OutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream);
+
+        for (Module module : schemaContext.getModules()) {
+            YinExportUtils.writeModuleToOutputStream(schemaContext, module, bufferedOutputStream);
+        }
+
+        final String output = byteArrayOutputStream.toString();
+        assertNotNull(output);
+        assertNotEquals(0, output.length());
+
+        final Document doc = loadDocument("/schema-context-emitter-test/foo.xml");
+        final String expected = toString(doc.getDocumentElement());
+
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setNormalize(true);
+
+        final Diff diff = new Diff(expected, output);
+        diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
+        XMLAssert.assertXMLEqual(diff, true);
+    }
+
+    private static Document loadDocument(final String xmlPath) throws IOException, SAXException {
+        final InputStream resourceAsStream = SchemaContextEmitterTest.class.getResourceAsStream(xmlPath);
+        final Document currentConfigElement = readXmlToDocument(resourceAsStream);
+        Preconditions.checkNotNull(currentConfigElement);
+        return currentConfigElement;
+    }
+
+    private static Document readXmlToDocument(final InputStream xmlContent) throws IOException, SAXException {
+        final DocumentBuilder dBuilder;
+        try {
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            factory.setCoalescing(true);
+            factory.setIgnoringElementContentWhitespace(true);
+            factory.setIgnoringComments(true);
+            dBuilder = factory.newDocumentBuilder();
+        } catch (final ParserConfigurationException e) {
+            throw new RuntimeException("Failed to parse XML document", e);
+        }
+        final Document doc = dBuilder.parse(xmlContent);
+
+        doc.getDocumentElement().normalize();
+        return doc;
+    }
+
+    private static String toString(final Node xml) {
+        try {
+            final Transformer transformer = TransformerFactory.newInstance().newTransformer();
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+
+            final StreamResult result = new StreamResult(new StringWriter());
+            final DOMSource source = new DOMSource(xml);
+            transformer.transform(source, result);
+
+            return result.getWriter().toString();
+        } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
+            throw new RuntimeException("Unable to serialize xml element " + xml, e);
+        }
+    }
+}
diff --git a/yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.xml b/yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.xml
new file mode 100644 (file)
index 0000000..e73e09a
--- /dev/null
@@ -0,0 +1,329 @@
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:foo-prefix="foo-namespace" name="foo">
+    <yang-version value="1"></yang-version>
+    <namespace uri="foo-namespace"></namespace>
+    <prefix value="foo-prefix"></prefix>
+    <organization>
+        <text></text>
+    </organization>
+    <contact>
+        <text></text>
+    </contact>
+    <revision date="2016-08-05"></revision>
+    <extension name="test-extension">
+        <status value="current"></status>
+    </extension>
+    <feature name="test-feature">
+        <status value="current"></status>
+        <description>
+            <text>test-feature description</text>
+        </description>
+        <reference>
+            <text>test-feature reference</text>
+        </reference>
+    </feature>
+    <identity name="test-identity">
+        <base name="test-base-identity"></base>
+        <status value="current"></status>
+        <description>
+            <text>test-identity description</text>
+        </description>
+        <reference>
+            <text>test-identity reference</text>
+        </reference>
+    </identity>
+    <identity name="test-base-identity">
+        <status value="current"></status>
+    </identity>
+    <typedef name="test-uint32-typedef">
+        <type name="uint32">
+            <range value="50..100">
+                <error-message>
+                    <value>The argument is out of bounds &lt;50, 100&gt;</value>
+                </error-message>
+                <error-app-tag value="range-out-of-specified-bounds"></error-app-tag>
+            </range>
+        </type>
+        <units name="seconds"></units>
+        <status value="current"></status>
+    </typedef>
+    <typedef name="test-int32-typedef">
+        <type name="int32">
+            <range value="50..100">
+                <error-message>
+                    <value>The argument is out of bounds &lt;50, 100&gt;</value>
+                </error-message>
+                <error-app-tag value="range-out-of-specified-bounds"></error-app-tag>
+            </range>
+        </type>
+        <status value="current"></status>
+    </typedef>
+    <typedef name="test-leafref-typedef">
+        <type name="leafref">
+            <path value="../leafref-target-leaf"></path>
+        </type>
+        <status value="current"></status>
+    </typedef>
+    <typedef name="test-iid-typedef">
+        <type name="instance-identifier">
+            <require-instance value="false"></require-instance>
+        </type>
+        <status value="current"></status>
+    </typedef>
+    <grouping name="test-grouping-1">
+        <status value="current"></status>
+        <leaf name="test-leaf-1">
+            <type name="string"></type>
+            <default value="def-val"></default>
+            <config value="true"></config>
+            <mandatory value="false"></mandatory>
+            <status value="current"></status>
+        </leaf>
+        <leaf-list name="test-leaf-list">
+            <type name="string"></type>
+            <config value="false"></config>
+            <min-elements value="0"></min-elements>
+            <max-elements value="2147483647"></max-elements>
+            <ordered-by value="user"></ordered-by>
+            <status value="current"></status>
+        </leaf-list>
+        <list name="test-list">
+            <key value="key-leaf-1 key-leaf-2"></key>
+            <config value="true"></config>
+            <min-elements value="5"></min-elements>
+            <max-elements value="2147483647"></max-elements>
+            <ordered-by value="system"></ordered-by>
+            <status value="current"></status>
+            <leaf name="key-leaf-1">
+                <type name="string"></type>
+                <config value="true"></config>
+                <mandatory value="false"></mandatory>
+                <status value="current"></status>
+            </leaf>
+            <leaf name="key-leaf-2">
+                <type name="string"></type>
+                <config value="true"></config>
+                <mandatory value="false"></mandatory>
+                <status value="current"></status>
+            </leaf>
+        </list>
+        <container name="test-container-2">
+            <presence value="false"></presence>
+            <config value="false"></config>
+            <status value="current"></status>
+        </container>
+    </grouping>
+    <grouping name="test-grouping-2">
+        <status value="current"></status>
+        <anyxml name="test-anyxml-2">
+            <config value="false"></config>
+            <mandatory value="false"></mandatory>
+            <status value="current"></status>
+        </anyxml>
+        <choice name="test-choice-2">
+            <config value="false"></config>
+            <mandatory value="false"></mandatory>
+            <status value="current"></status>
+            <case name="first">
+                <status value="current"></status>
+                <leaf name="first-case-leaf">
+                    <type name="string">
+                        <length value="10|15">
+                            <error-message>
+                                <value>The argument is out of bounds &lt;10, 10&gt;</value>
+                            </error-message>
+                            <error-app-tag value="length-out-of-specified-bounds"></error-app-tag>
+                        </length>
+                    </type>
+                    <config value="false"></config>
+                    <mandatory value="false"></mandatory>
+                    <status value="current"></status>
+                </leaf>
+            </case>
+            <case name="second">
+                <status value="current"></status>
+                <leaf name="second-case-leaf">
+                    <type name="int32">
+                        <range value="10|15">
+                            <error-message>
+                                <value>The argument is out of bounds &lt;10, 10&gt;</value>
+                            </error-message>
+                            <error-app-tag value="range-out-of-specified-bounds"></error-app-tag>
+                        </range>
+                    </type>
+                    <config value="false"></config>
+                    <mandatory value="false"></mandatory>
+                    <status value="current"></status>
+                </leaf>
+            </case>
+        </choice>
+    </grouping>
+    <anyxml name="test-anyxml">
+        <when condition="foo != 'bar'"></when>
+        <must condition="bar != 'foo'"></must>
+        <config value="true"></config>
+        <mandatory value="false"></mandatory>
+        <status value="current"></status>
+        <foo-prefix:test-extension></foo-prefix:test-extension>
+    </anyxml>
+    <leaf name="leafref-target-leaf">
+        <type name="string"></type>
+        <config value="true"></config>
+        <mandatory value="false"></mandatory>
+        <status value="current"></status>
+    </leaf>
+    <container name="test-container-1">
+        <must condition="bar != 'foo'"></must>
+        <must condition="bar != 'foo'"></must>
+        <presence value="false"></presence>
+        <config value="true"></config>
+        <status value="current"></status>
+    </container>
+    <container name="test-container-3">
+        <presence value="false"></presence>
+        <config value="true"></config>
+        <status value="current"></status>
+        <choice name="test-choice">
+            <config value="true"></config>
+            <mandatory value="false"></mandatory>
+            <status value="current"></status>
+            <case name="a">
+                <status value="current"></status>
+                <leaf name="case-a-leaf">
+                    <type name="int32"></type>
+                    <config value="true"></config>
+                    <mandatory value="false"></mandatory>
+                    <status value="current"></status>
+                </leaf>
+            </case>
+            <case name="b">
+                <status value="current"></status>
+                <leaf name="case-b-leaf">
+                    <type name="decimal64">
+                        <fraction-digits value="3"></fraction-digits>
+                        <range value="-9223372036854775.808..9223372036854775.807">
+                            <error-message>
+                                <value>The argument is out of bounds &lt;-9223372036854775.808, 9223372036854775.807&gt;</value>
+                            </error-message>
+                            <error-app-tag value="range-out-of-specified-bounds"></error-app-tag>
+                            <reference>
+                                <text>https://tools.ietf.org/html/rfc6020#section-9.3.4</text>
+                            </reference>
+                        </range>
+                    </type>
+                    <config value="true"></config>
+                    <mandatory value="false"></mandatory>
+                    <status value="current"></status>
+                </leaf>
+            </case>
+        </choice>
+        <leaf name="bits-leaf">
+            <type name="bits">
+                <bit name="one">
+                    <position value="1"></position>
+                    <status value="current"></status>
+                </bit>
+                <bit name="two">
+                    <position value="2"></position>
+                    <status value="current"></status>
+                </bit>
+            </type>
+            <config value="true"></config>
+            <mandatory value="false"></mandatory>
+            <status value="current"></status>
+        </leaf>
+        <leaf name="identityref-leaf">
+            <type name="identityref">
+                <base name="identityref"></base>
+            </type>
+            <config value="true"></config>
+            <mandatory value="false"></mandatory>
+            <status value="current"></status>
+        </leaf>
+    </container>
+    <augment target-node="/test-container-3/test-choice">
+        <status value="current"></status>
+        <case name="c">
+            <status value="current"></status>
+            <leaf name="case-c-leaf">
+                <type name="string"></type>
+                <config value="true"></config>
+                <mandatory value="false"></mandatory>
+                <status value="current"></status>
+            </leaf>
+        </case>
+    </augment>
+    <augment target-node="/test-container-1">
+        <status value="current"></status>
+        <uses name="test-grouping-1">
+            <refine target-node="test-list">
+                <config value="true"></config>
+                <min-elements value="5"></min-elements>
+                <max-elements value="2147483647"></max-elements>
+            </refine>
+            <refine target-node="test-leaf-list">
+                <config value="false"></config>
+                <min-elements value="0"></min-elements>
+                <max-elements value="2147483647"></max-elements>
+            </refine>
+            <refine target-node="test-leaf-1">
+                <default value="def-val"></default>
+                <config value="true"></config>
+                <mandatory value="false"></mandatory>
+            </refine>
+            <refine target-node="test-container-2">
+                <presence value="false"></presence>
+                <config value="false"></config>
+            </refine>
+            <augment target-node="test-container-2">
+                <status value="current"></status>
+                <leaf name="test-leaf-2">
+                    <type name="string"></type>
+                    <config value="true"></config>
+                    <mandatory value="false"></mandatory>
+                    <status value="current"></status>
+                </leaf>
+            </augment>
+        </uses>
+    </augment>
+    <rpc name="test-rpc">
+        <status value="current"></status>
+        <grouping name="rpc-grouping">
+            <status value="current"></status>
+            <leaf name="rpc-grouping-leaf">
+                <type name="string"></type>
+                <config value="true"></config>
+                <mandatory value="false"></mandatory>
+                <status value="current"></status>
+            </leaf>
+        </grouping>
+        <input>
+            <leaf name="input-leaf">
+                <type name="string"></type>
+                <config value="true"></config>
+                <mandatory value="false"></mandatory>
+                <status value="current"></status>
+            </leaf>
+        </input>
+        <output>
+            <leaf name="output-leaf">
+                <type name="string"></type>
+                <config value="true"></config>
+                <mandatory value="false"></mandatory>
+                <status value="current"></status>
+            </leaf>
+        </output>
+    </rpc>
+    <notification name="test-notification">
+        <status value="current"></status>
+        <uses name="test-grouping-2">
+            <refine target-node="test-choice-2">
+                <config value="false"></config>
+                <mandatory value="false"></mandatory>
+            </refine>
+            <refine target-node="test-anyxml-2">
+                <config value="false"></config>
+                <mandatory value="false"></mandatory>
+            </refine>
+        </uses>
+    </notification>
+</module>
\ No newline at end of file
diff --git a/yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.yang b/yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.yang
new file mode 100644 (file)
index 0000000..f96f696
--- /dev/null
@@ -0,0 +1,206 @@
+module foo {
+    namespace foo-namespace;
+    prefix foo-prefix;
+
+    revision 2016-08-05;
+
+    feature test-feature {
+        status current;
+        description "test-feature description";
+        reference "test-feature reference";
+    }
+
+    typedef test-uint32-typedef {
+        type uint32 {
+            range "50..100";
+        }
+        units seconds;
+    }
+
+    typedef test-int32-typedef {
+        type int32 {
+            range "50..100";
+        }
+    }
+
+    typedef test-leafref-typedef {
+        type leafref {
+            path "../leafref-target-leaf";
+        }
+    }
+
+    typedef test-iid-typedef {
+        type instance-identifier {
+            require-instance false;
+        }
+    }
+
+    identity test-base-identity;
+
+    identity test-identity {
+        base test-base-identity;
+        status current;
+        description "test-identity description";
+        reference "test-identity reference";
+    }
+
+    extension test-extension;
+
+    rpc test-rpc {
+        input {
+            leaf input-leaf {
+                type string;
+            }
+        }
+        output {
+            leaf output-leaf {
+                type string;
+            }
+        }
+
+        grouping rpc-grouping {
+            leaf rpc-grouping-leaf {
+                type string;
+            }
+        }
+    }
+
+    notification test-notification {
+        uses test-grouping-2 {
+            refine test-anyxml-2 {
+                config false;
+            }
+            refine test-choice-2 {
+                config false;
+            }
+        }
+    }
+
+    anyxml test-anyxml {
+        when "foo != 'bar'";
+        must "bar != 'foo'";
+
+        foo-prefix:test-extension;
+    }
+
+    leaf leafref-target-leaf {
+        type string;
+    }
+
+    container test-container-1 {
+        must "bar != 'foo'";
+    }
+
+    container test-container-3 {
+        choice test-choice {
+            case a {
+                leaf case-a-leaf {
+                    type int32;
+                }
+            }
+            case b {
+                leaf case-b-leaf {
+                    type decimal64 {
+                        fraction-digits 3;
+                    }
+                }
+            }
+        }
+        leaf bits-leaf {
+            type bits {
+                bit one {
+                    position 1;
+                }
+                bit two {
+                    position 2;
+                }
+            }
+        }
+        leaf identityref-leaf {
+            type identityref {
+                base test-base-identity;
+            }
+        }
+    }
+
+    augment "/test-container-3/test-choice" {
+        case c {
+            leaf case-c-leaf {
+                type string;
+            }
+        }
+    }
+
+    augment "/test-container-1" {
+        uses test-grouping-1 {
+            refine test-leaf-1 {
+                default "def-val";
+            }
+            refine test-leaf-list {
+                config false;
+            }
+            refine test-list {
+                min-elements 5;
+            }
+            refine test-container-2 {
+                config false;
+            }
+            augment test-container-2 {
+                leaf test-leaf-2 {
+                    type string;
+                }
+            }
+        }
+    }
+
+    grouping test-grouping-1 {
+        leaf test-leaf-1 {
+            type string;
+            default "def-val";
+        }
+        leaf-list test-leaf-list {
+            type string;
+            config false;
+            ordered-by user;
+        }
+        list test-list {
+            key "key-leaf-1 key-leaf-2";
+            min-elements 5;
+
+            leaf key-leaf-1 {
+                type string;
+            }
+
+            leaf key-leaf-2 {
+                type string;
+            }
+        }
+        container test-container-2 {
+            config false;
+        }
+    }
+
+    grouping test-grouping-2 {
+        anyxml test-anyxml-2 {
+            config false;
+        }
+        choice test-choice-2 {
+            config false;
+
+            case first {
+                leaf first-case-leaf {
+                    type string {
+                        length "10..10 | 15";
+                    }
+                }
+            }
+            case second {
+                leaf second-case-leaf {
+                    type int32 {
+                        range "10..10 | 15";
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file