From 8d839d7aab1b1894040085d5bad80743b21706ce Mon Sep 17 00:00:00 2001 From: Igor Foltin Date: Tue, 9 Aug 2016 15:20:11 +0200 Subject: [PATCH] Bug 3899: Milestone: Increase test coverage for Yangtools Added test for SchemaContextEmitter Change-Id: If60531f0a84579519487075a340f73e68c2526eb Signed-off-by: Igor Foltin (cherry picked from commit f77f673e129e7a866bd21f6072c600f75471a068) --- .../export/test/SchemaContextEmitterTest.java | 118 +++++++ .../schema-context-emitter-test/foo.xml | 329 ++++++++++++++++++ .../schema-context-emitter-test/foo.yang | 206 +++++++++++ 3 files changed, 653 insertions(+) create mode 100644 yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/SchemaContextEmitterTest.java create mode 100644 yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.xml create mode 100644 yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.yang 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 index 0000000000..1216b706b4 --- /dev/null +++ b/yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/SchemaContextEmitterTest.java @@ -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 index 0000000000..e73e09ab08 --- /dev/null +++ b/yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.xml @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + test-feature description + + + test-feature reference + + + + + + + test-identity description + + + test-identity reference + + + + + + + + + + The argument is out of bounds <50, 100> + + + + + + + + + + + + The argument is out of bounds <50, 100> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The argument is out of bounds <10, 10> + + + + + + + + + + + + + + + + The argument is out of bounds <10, 10> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The argument is out of bounds <-9223372036854775.808, 9223372036854775.807> + + + + https://tools.ietf.org/html/rfc6020#section-9.3.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 index 0000000000..f96f696d84 --- /dev/null +++ b/yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.yang @@ -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 -- 2.36.6