Bug 3670: Replaced YANG parser for new statement parser
[yangtools.git] / yang / yang-data-codec-gson / src / test / java / org / opendaylight / yangtools / yang / data / codec / gson / retest / JsonStreamToNormalizedNodeTest.java
diff --git a/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/retest/JsonStreamToNormalizedNodeTest.java b/yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/retest/JsonStreamToNormalizedNodeTest.java
new file mode 100644 (file)
index 0000000..00178ef
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2015 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.data.codec.gson.retest;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.opendaylight.yangtools.yang.data.codec.gson.retest.TestUtils.loadModules;
+import static org.opendaylight.yangtools.yang.data.codec.gson.retest.TestUtils.loadTextFile;
+import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.augmentationBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.choiceBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.containerBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.leafNode;
+
+import com.google.common.collect.Sets;
+import com.google.gson.stream.JsonReader;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URISyntaxException;
+
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
+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.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+
+/**
+ *
+ * Each test tests whether json input is correctly transformed to normalized node structure
+ */
+public class JsonStreamToNormalizedNodeTest {
+
+    private static final QName CONT_1 = QName.create("ns:complex:json", "2014-08-11", "cont1");
+    private static final QName EMPTY_LEAF = QName.create(CONT_1,"empty");
+    private static SchemaContext schemaContext;
+
+    @BeforeClass
+    public static void initialization() throws IOException, URISyntaxException, ReactorException {
+        schemaContext = loadModules("/complexjson/yang");
+    }
+
+    /**
+     * case when anyxml contains simple value will be implemented when anyxml normalized node reprezentation will be
+     * specified
+     */
+    @Ignore
+    @Test
+    public void anyXmlNodeWithSimpleValueInContainer() throws IOException, URISyntaxException {
+
+    }
+
+    /**
+     * case when anyxml contains complex xml will be implemented when anyxml normalized node reprezentation will be
+     * specified
+     */
+    @Ignore
+    @Test
+    public void anyXmlNodeWithCompositeValueInContainer() throws IOException, URISyntaxException {
+
+    }
+
+    @Test
+    public void leafNodeInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/leaf-node-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.leafNodeInContainer());
+    }
+
+    @Test
+    public void leafNodeViaAugmentationInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/leaf-node-via-augmentation-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson,
+                TestingNormalizedNodeStructuresCreator.leafNodeViaAugmentationInContainer());
+    }
+
+    @Test
+    public void leafListNodeInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/leaflist-node-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson,
+                TestingNormalizedNodeStructuresCreator.leafListNodeInContainer());
+    }
+
+    @Test
+    public void keyedListNodeInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/keyed-list-node-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson,
+                TestingNormalizedNodeStructuresCreator.keyedListNodeInContainer());
+    }
+
+    @Test
+    public void choiceNodeInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/choice-node-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.choiceNodeInContainer());
+    }
+
+    /**
+     * Test of translating internal augmentations to normalized nodes structure
+     *
+     * 2 nodes are added via internal augmentation A, 1 node via internal augmentation B and one node is originally
+     * member of case.
+     *
+     */
+    @Test
+    public void caseNodeAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/case-node-augmentation-in-choice-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson,
+                TestingNormalizedNodeStructuresCreator.caseNodeAugmentationInChoiceInContainer());
+    }
+
+    /**
+     * also test using of namesakes (equal local names with different
+     *
+     * @throws IOException
+     * @throws URISyntaxException
+     */
+    @Test
+    public void caseNodeExternalAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/case-node-external-augmentation-in-choice-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson,
+                TestingNormalizedNodeStructuresCreator.caseNodeExternalAugmentationInChoiceInContainer());
+    }
+
+    /**
+     * augmentation of choice - adding new case
+     */
+    @Test
+    public void choiceNodeAugmentationInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/choice-node-augmentation-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson,
+                TestingNormalizedNodeStructuresCreator.choiceNodeAugmentationInContainer());
+    }
+
+    @Test
+    public void unkeyedNodeInContainer() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/unkeyed-node-in-container.json");
+        verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.unkeyedNodeInContainer());
+    }
+
+    /**
+     * Top level JSON element contains no information about module name.
+     *
+     * It should be possible to find out potential module name from available schema context.
+     *
+     */
+    @Test
+    public void missingModuleInfoInTopLevelElement() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/missing-module-in-top-level.json");
+        verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.topLevelContainer());
+    }
+
+    /**
+     *
+     * Exception expected.
+     *
+     * It tests case when several elements with the same name and various namespaces exists and are in JSON specified
+     * without module name prefix.
+     */
+    @Test
+    public void leafNamesakes() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/namesakes.json");
+        try {
+            //second parameter isn't necessary because error will be raised before it is used.
+            verifyTransformationToNormalizedNode(inputJson, null);
+                       fail("Expected exception not raised");
+        } catch (final IllegalStateException e) {
+            final String errorMessage = e.getMessage();
+            assertTrue(errorMessage.contains("Choose suitable module name for element lf11-namesake:"));
+            assertTrue(errorMessage.contains("complexjson-augmentation"));
+            assertTrue(errorMessage.contains("complexjson-augmentation-namesake"));
+        }
+    }
+
+    @Test
+    public void emptyTypeTest() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/type-empty.json");
+        final ContainerNode awaitedStructure = containerBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONT_1))
+                .addChild(leafNode(EMPTY_LEAF, null))
+                .build();
+
+        verifyTransformationToNormalizedNode(inputJson, awaitedStructure);
+    }
+
+    /**
+     *
+     * Exception expected.
+     *
+     * Json input contains element which doesn't exist in YANG schema
+     */
+    @Test
+    public void parsingNotExistingElement() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/not-existing-element.json");
+        try {
+            //second parameter isn't necessary because error will be raised before it is used.
+            verifyTransformationToNormalizedNode(inputJson, null);
+        } catch (final IllegalStateException e) {
+            assertTrue(e.getMessage().contains("Schema node with name dummy-element wasn't found"));
+        }
+    }
+
+
+    @Test
+    public void listItemWithoutArray() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/keyed-list-restconf-behaviour.json");
+
+        final NormalizedNodeResult result = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+        final SchemaNode parentNode = schemaContext.getDataChildByName("cont1");
+        final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext, parentNode);
+        jsonParser.parse(new JsonReader(new StringReader(inputJson)));
+        final NormalizedNode<?, ?> transformedInput = result.getResult();
+        assertNotNull(transformedInput);
+    }
+
+    @Test
+    public void listItemWithArray() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/keyed-list-yang-json-behaviour.json");
+
+        final NormalizedNodeResult result = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+        final SchemaNode parentNode = schemaContext.getDataChildByName("cont1");
+        final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext, parentNode);
+        jsonParser.parse(new JsonReader(new StringReader(inputJson)));
+        final NormalizedNode<?, ?> transformedInput = result.getResult();
+        assertNotNull(transformedInput);
+    }
+
+   @Test
+    public void multipleChoiceAugmentation() throws IOException, URISyntaxException {
+        final String inputJson = loadTextFile("/complexjson/multiple-choice-augmentation-in-container.json");
+
+        final NormalizedNodeResult result = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+        final SchemaNode parentNode = schemaContext.getDataChildByName("cont1");
+
+        QName augmentChoice1QName = QName.create(parentNode.getQName(), "augment-choice1");
+        QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
+        final QName containerQName = QName.create(augmentChoice1QName, "case11-choice-case-container");
+        final QName leafQName = QName.create(augmentChoice1QName, "case11-choice-case-leaf");
+
+        final YangInstanceIdentifier.AugmentationIdentifier aug1Id =
+                new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(augmentChoice1QName));
+        final YangInstanceIdentifier.AugmentationIdentifier aug2Id =
+                new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(augmentChoice2QName));
+        final YangInstanceIdentifier.NodeIdentifier augmentChoice1Id =
+                new YangInstanceIdentifier.NodeIdentifier(augmentChoice1QName);
+        final YangInstanceIdentifier.NodeIdentifier augmentChoice2Id =
+                new YangInstanceIdentifier.NodeIdentifier(augmentChoice2QName);
+        final YangInstanceIdentifier.NodeIdentifier containerId =
+                new YangInstanceIdentifier.NodeIdentifier(containerQName);
+
+        final NormalizedNode<?, ?> cont1Normalized =
+                containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(parentNode.getQName()))
+                        .withChild(augmentationBuilder().withNodeIdentifier(aug1Id)
+                                .withChild(choiceBuilder().withNodeIdentifier(augmentChoice1Id)
+                                        .withChild(augmentationBuilder().withNodeIdentifier(aug2Id)
+                                                .withChild(choiceBuilder().withNodeIdentifier(augmentChoice2Id)
+                                                        .withChild(containerBuilder().withNodeIdentifier(containerId)
+                                                                .withChild(leafNode(leafQName, "leaf-value"))
+                                                                .build())
+                                                        .build())
+                                                .build())
+                                        .build())
+                                .build()).build();
+
+        final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext);
+        jsonParser.parse(new JsonReader(new StringReader(inputJson)));
+        final NormalizedNode<?, ?> transformedInput = result.getResult();
+        assertNotNull(transformedInput);
+        assertEquals(cont1Normalized, transformedInput);
+    }
+
+    private void verifyTransformationToNormalizedNode(final String inputJson,
+            final NormalizedNode<?, ?> awaitedStructure) {
+        final NormalizedNodeResult result = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+        final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext);
+        jsonParser.parse(new JsonReader(new StringReader(inputJson)));
+        final NormalizedNode<?, ?> transformedInput = result.getResult();
+        assertEquals("Transformation of json input to normalized node wasn't successful.", awaitedStructure,
+                transformedInput);
+    }
+
+}