YANGTOOLS-813: add parent schemapath to error report
[yangtools.git] / yang / yang-data-codec-xml / src / test / java / org / opendaylight / yangtools / yang / data / codec / xml / XmlToNormalizedNodesTest.java
index 30977e39117df63349eaffff5c8e784aac1a8c2f..7414efb14e0c95cda386bdc88f974b19bdd489f8 100644 (file)
@@ -13,23 +13,22 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableList;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.text.ParseException;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
-import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
@@ -45,45 +44,52 @@ import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStre
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 import org.xml.sax.SAXException;
 
 public class XmlToNormalizedNodesTest {
 
-    private QNameModule bazModule;
-
-    private QName outerContainer;
-
-    private QName myContainer1;
-    private QName myKeyedList;
-    private QName myKeyLeaf;
-    private QName myLeafInList1;
-    private QName myLeafInList2;
-    private QName myLeaf1;
-    private QName myLeafList;
-
-    private QName myContainer2;
-    private QName innerContainer;
-    private QName myLeaf2;
-    private QName myLeaf3;
-    private QName myChoice;
-    private QName myLeafInCase2;
-
-    private QName myContainer3;
-    private QName myDoublyKeyedList;
-    private QName myFirstKeyLeaf;
-    private QName mySecondKeyLeaf;
-    private QName myLeafInList3;
-
-    @Before
-    public void setup() throws URISyntaxException, ParseException {
-        bazModule = QNameModule.create(new URI("baz-namespace"), SimpleDateFormatUtil.getRevisionFormat().parse
-                ("1970-01-01"));
-
+    private static SchemaContext schemaContext;
+    private static ContainerSchemaNode outerContainerSchema;
+    private static ContainerSchemaNode parentContainerSchema;
+
+    private static QNameModule fooModule;
+    private static QName parentContainer;
+
+    private static QNameModule bazModule;
+    private static QName outerContainer;
+
+    private static QName myContainer1;
+    private static QName myKeyedList;
+    private static QName myKeyLeaf;
+    private static QName myLeafInList1;
+    private static QName myLeafInList2;
+    private static QName myLeaf1;
+    private static QName myLeafList;
+
+    private static QName myContainer2;
+    private static QName innerContainer;
+    private static QName myLeaf2;
+    private static QName myLeaf3;
+    private static QName myChoice;
+    private static QName myLeafInCase2;
+
+    private static QName myContainer3;
+    private static QName myDoublyKeyedList;
+    private static QName myFirstKeyLeaf;
+    private static QName mySecondKeyLeaf;
+    private static QName myLeafInList3;
+
+    @BeforeClass
+    public static void setup() {
+        fooModule = QNameModule.create(URI.create("foo-namespace"));
+        parentContainer = QName.create(fooModule, "parent-container");
+
+        bazModule = QNameModule.create(URI.create("baz-namespace"));
         outerContainer = QName.create(bazModule, "outer-container");
 
         myContainer1 = QName.create(bazModule, "my-container-1");
@@ -106,16 +112,17 @@ public class XmlToNormalizedNodesTest {
         myFirstKeyLeaf = QName.create(bazModule, "my-first-key-leaf");
         mySecondKeyLeaf = QName.create(bazModule, "my-second-key-leaf");
         myLeafInList3 = QName.create(bazModule, "my-leaf-in-list-3");
+
+        schemaContext = YangParserTestUtils.parseYangResourceDirectory("/");
+        parentContainerSchema = (ContainerSchemaNode) SchemaContextUtil.findNodeInSchemaContext(schemaContext,
+                ImmutableList.of(parentContainer));
+        outerContainerSchema = (ContainerSchemaNode) SchemaContextUtil.findNodeInSchemaContext(schemaContext,
+                ImmutableList.of(outerContainer));
     }
 
     @Test
     public void testComplexXmlParsing() throws IOException, URISyntaxException, ReactorException, XMLStreamException,
             ParserConfigurationException, SAXException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/baz.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/baz.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -124,9 +131,12 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, outerContainerSchema);
         xmlParser.parse(reader);
 
+        xmlParser.flush();
+        xmlParser.close();
+
         final NormalizedNode<?, ?> transformedInput = result.getResult();
         assertNotNull(transformedInput);
 
@@ -139,11 +149,6 @@ public class XmlToNormalizedNodesTest {
     @Test
     public void testSimpleXmlParsing() throws IOException, URISyntaxException, ReactorException, XMLStreamException,
             ParserConfigurationException, SAXException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/foo.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/foo.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -152,7 +157,7 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, parentContainerSchema);
         xmlParser.parse(reader);
 
         final NormalizedNode<?, ?> transformedInput = result.getResult();
@@ -162,11 +167,6 @@ public class XmlToNormalizedNodesTest {
     @Test
     public void shouldFailOnDuplicateLeaf() throws ReactorException, XMLStreamException, IOException,
             ParserConfigurationException, SAXException, URISyntaxException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/foo.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/invalid-foo.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -175,7 +175,7 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, parentContainerSchema);
         try {
             xmlParser.parse(reader);
             fail("IllegalStateException should have been thrown because of duplicate leaf.");
@@ -188,11 +188,6 @@ public class XmlToNormalizedNodesTest {
     @Test
     public void shouldFailOnDuplicateAnyXml() throws ReactorException, XMLStreamException, IOException,
             ParserConfigurationException, SAXException, URISyntaxException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/foo.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/invalid-foo-2.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -201,7 +196,7 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, parentContainerSchema);
         try {
             xmlParser.parse(reader);
             fail("IllegalStateException should have been thrown because of duplicate anyxml");
@@ -213,11 +208,6 @@ public class XmlToNormalizedNodesTest {
     @Test
     public void shouldFailOnDuplicateContainer() throws ReactorException, XMLStreamException, IOException,
             ParserConfigurationException, SAXException, URISyntaxException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/foo.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/invalid-foo-3.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -226,7 +216,7 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, parentContainerSchema);
         try {
             xmlParser.parse(reader);
             fail("IllegalStateException should have been thrown because of duplicate container");
@@ -238,11 +228,6 @@ public class XmlToNormalizedNodesTest {
     @Test
     public void shouldFailOnUnterminatedLeafElement() throws ReactorException, XMLStreamException, IOException,
             ParserConfigurationException, SAXException, URISyntaxException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/baz.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/invalid-baz.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -251,24 +236,19 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, outerContainerSchema);
         try {
             xmlParser.parse(reader);
             fail("XMLStreamException should have been thrown because of unterminated leaf element.");
         } catch (XMLStreamException ex) {
-            assertTrue(ex.getMessage().contains("elementGetText() function expects text only elment but " +
-                    "START_ELEMENT was encountered."));
+            assertTrue(ex.getMessage().contains("elementGetText() function expects text only elment but "
+                        + "START_ELEMENT was encountered."));
         }
     }
 
     @Test
     public void shouldFailOnUnterminatedLeafElement2() throws ReactorException, XMLStreamException, IOException,
             ParserConfigurationException, SAXException, URISyntaxException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/baz.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/invalid-baz-2.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -277,24 +257,19 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, outerContainerSchema);
         try {
             xmlParser.parse(reader);
             fail("XMLStreamException should have been thrown because of unterminated leaf element.");
         } catch (XMLStreamException ex) {
-            assertTrue(ex.getMessage().contains("The element type \"my-leaf-1\" must be terminated by the matching " +
-                    "end-tag \"</my-leaf-1>\"."));
+            assertTrue(ex.getMessage().contains("The element type \"my-leaf-1\" must be terminated by the matching "
+                        + "end-tag \"</my-leaf-1>\"."));
         }
     }
 
     @Test
     public void shouldFailOnUnterminatedContainerElement() throws ReactorException, XMLStreamException, IOException,
             ParserConfigurationException, SAXException, URISyntaxException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/baz.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/invalid-baz-4.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -303,24 +278,19 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, outerContainerSchema);
         try {
             xmlParser.parse(reader);
             fail("XMLStreamException should have been thrown because of unterminated container element.");
         } catch (XMLStreamException ex) {
-            assertTrue(ex.getMessage().contains("The element type \"my-container-1\" must be terminated by the " +
-                    "matching end-tag \"</my-container-1>\"."));
+            assertTrue(ex.getMessage().contains("The element type \"my-container-1\" must be terminated by the "
+                        + "matching end-tag \"</my-container-1>\"."));
         }
     }
 
     @Test
-    public void shouldFailOnUnexistingContainerElement() throws ReactorException, XMLStreamException, IOException,
+    public void shouldFailOnUnknownChildNode() throws ReactorException, XMLStreamException, IOException,
             ParserConfigurationException, SAXException, URISyntaxException {
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSource(new YangStatementSourceImpl("/baz.yang", false));
-
-        SchemaContext schemaContext = reactor.buildEffective();
-
         final InputStream resourceAsStream = XmlToNormalizedNodesTest.class.getResourceAsStream("/invalid-baz-3.xml");
 
         final XMLInputFactory factory = XMLInputFactory.newInstance();
@@ -329,13 +299,14 @@ public class XmlToNormalizedNodesTest {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
-        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, outerContainerSchema);
         try {
             xmlParser.parse(reader);
-            fail("IllegalStateException should have been thrown because of an unexisting container element.");
+            fail("IllegalStateException should have been thrown because of an unknown child node.");
         } catch (IllegalStateException ex) {
-            assertTrue(ex.getMessage().contains("Schema for node with name my-container-1 and namespace baz-namespace" +
-                    " doesn't exist."));
+            assertEquals("Schema for node with name my-container-1 and namespace baz-namespace doesn't exist at "
+                    + "AbsoluteSchemaPath{path=[(baz-namespace)outer-container, (baz-namespace)my-container-1]}",
+                    ex.getMessage());
         }
     }
 
@@ -402,7 +373,7 @@ public class XmlToNormalizedNodesTest {
                 .build();
 
         AugmentationNode myDoublyKeyedListAugNode = Builders.augmentationBuilder().withNodeIdentifier(
-                new AugmentationIdentifier(Sets.newHashSet(myDoublyKeyedList)))
+                new AugmentationIdentifier(Collections.singleton(myDoublyKeyedList)))
                 .withChild(myDoublyKeyedListNode).build();
 
         ContainerNode myContainer3Node = Builders.containerBuilder().withNodeIdentifier(
@@ -410,7 +381,7 @@ public class XmlToNormalizedNodesTest {
                 .withChild(myDoublyKeyedListAugNode).build();
 
         AugmentationNode myContainer3AugNode = Builders.augmentationBuilder().withNodeIdentifier(
-                new AugmentationIdentifier(Sets.newHashSet(myContainer3)))
+                new AugmentationIdentifier(Collections.singleton(myContainer3)))
                 .withChild(myContainer3Node).build();
 
         ContainerNode outerContainerNode = Builders.containerBuilder().withNodeIdentifier(