Merge "test for ModelObjectId & bugfix"
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModelConverterUtil.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModelConverterUtil.java
index 2ba6e78..8a9cfa2 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModelConverterUtil.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModelConverterUtil.java
@@ -43,6 +43,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Arrays;
+import java.util.Base64;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -84,6 +85,7 @@
                                         UINT16, UINT32, BOOLEAN, EMPTY));
     private static final String TO_STRING = "toString";
     private static final String IS_VAL_SET = "isLeafValueSet";
+    private static final Base64.Encoder BASE64_BASIC_ENCODER = Base64.getEncoder();
 
     // No instantiation.
     private ModelConverterUtil() {
@@ -293,7 +295,7 @@
                 return String.valueOf(fieldObj).trim();
 
             case BINARY:
-                return new String((byte[]) fieldObj);
+                return BASE64_BASIC_ENCODER.encodeToString((byte[]) fieldObj);
 
             case BITS:
                 return getBitsValue(holder, holderObj, name, fieldObj).trim();
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilderTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilderTest.java
index 519bf81..dbc768b 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilderTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilderTest.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.yang.runtime.impl;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -91,6 +92,8 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.onosproject.yang.gen.v1.simpledatatypes.rev20131112.simpledatatypes.Cont.LeafIdentifier.LFENUM1;
 import static org.onosproject.yang.gen.v1.simpledatatypes.rev20131112.simpledatatypes.tpdfun0.Tpdfun0Enum.SUCCESSFUL_EXIT;
 import static org.onosproject.yang.gen.v1.ytbdatatypes.rev20160826.YtbDataTypes.LeafIdentifier.LEAF1;
@@ -167,7 +170,8 @@
     /**
      * Do the prior setup for each UT.
      */
-    private void setUp() {
+    @Before
+    public void setUp() {
         processSchemaRegistry();
         registry = registry();
         treeBuilder = new DefaultDataTreeBuilder(registry);
@@ -181,8 +185,6 @@
      */
     @Test
     public void processModuleAndLeaf() {
-        setUp();
-
         //  As an application, creates the object.
 
         LeafModelObject modelObject = new LeafModelObject();
@@ -221,8 +223,6 @@
      */
     @Test
     public void processModuleAndLeafList() {
-
-        setUp();
         //As an application, creates the object.
 
         LeafModelObject modelObject = new LeafModelObject();
@@ -271,8 +271,6 @@
      */
     @Test
     public void processModuleListAndKeyOneIn() {
-        setUp();
-
         //As an application, creates the object.
         DefaultModKey m1 = new DefaultModKey();
         m1.types(1);
@@ -319,8 +317,6 @@
      */
     @Test
     public void processModuleListAndKey() {
-        setUp();
-
         //As an application, creates the object.
         DefaultModKey m1 = new DefaultModKey();
         m1.types(1);
@@ -406,9 +402,6 @@
      */
     @Test
     public void processModuleListAndKeyListModId() {
-
-        setUp();
-
         data = new Builder();
 
         LeafModelObject object = new LeafModelObject();
@@ -495,9 +488,6 @@
      */
     @Test
     public void processModuleListAndKeyLeafModId() {
-
-        setUp();
-
         data = new Builder();
         ModKeyKeys keyKeys = new ModKeyKeys();
         keyKeys.types(10);
@@ -550,8 +540,6 @@
      */
     @Test
     public void processWithTypeEnum() {
-        setUp();
-
         data = new Builder();
         //As an application, creates the object.
         LeafModelObject object = new LeafModelObject();
@@ -622,8 +610,6 @@
      */
     @Test
     public void processModuleWithContainer() {
-        setUp();
-
         // As an application, creates the object.
 
         //Creates container object with leaf of decimal type.
@@ -673,8 +659,6 @@
      */
     @Test
     public void processModuleWithContainerModId() {
-
-        setUp();
         data = new Builder();
         //As an application, creates the object.
         LeafModelObject object = new LeafModelObject();
@@ -718,7 +702,6 @@
      */
     @Test
     public void processTreeBuilderForListHavingList() {
-        setUp();
         // Creates two binary leaf -lists for two list app areas.
         List<byte[]> destArea1 = new ArrayList<>();
         byte[] arr = Base64.getDecoder().decode("QXdnRQ==");
@@ -840,10 +823,10 @@
 
         n = it.next();
         key = n.getKey();
-        assertThat(true, is(key instanceof LeafListKey));
+        assertTrue(key instanceof LeafListKey);
 
         LeafListKey leafListKey = (LeafListKey) key;
-        assertThat("BwcH", is(leafListKey.value()));
+        assertEquals("Wrong Base64 value", "QndjSA==", leafListKey.value());
 
         sid = key.schemaId();
         assertThat("destination-areas", is(sid.name()));
@@ -854,7 +837,7 @@
         assertThat(true, is(key instanceof LeafListKey));
 
         leafListKey = (LeafListKey) key;
-        assertThat("AAE=", is(leafListKey.value()));
+        assertEquals("Wrong Base64 value", "QUFFPQ==", leafListKey.value());
 
         sid = key.schemaId();
         assertThat("destination-areas", is(sid.name()));
@@ -896,7 +879,7 @@
         assertThat(true, is(key instanceof LeafListKey));
 
         leafListKey = (LeafListKey) key;
-        assertThat("JHI8", is(leafListKey.value()));
+        assertEquals("Wrong Base64 value", "SkhJOA==", leafListKey.value());
 
         sid = key.schemaId();
         assertThat("destination-areas", is(sid.name()));
@@ -907,7 +890,7 @@
         assertThat(true, is(key instanceof LeafListKey));
 
         leafListKey = (LeafListKey) key;
-        assertThat("1111", is(leafListKey.value()));
+        assertEquals("Wrong Base64 value", "MTExMQ==", leafListKey.value());
 
         sid = key.schemaId();
         assertThat("destination-areas", is(sid.name()));
@@ -1173,7 +1156,6 @@
      */
     @Test
     public void processEnumeration() {
-        setUp();
         data = new Builder();
         ModelObjectId.Builder moIdBdlr = ModelObjectId.builder()
                 .addChild(DefaultCont.class);
@@ -1211,7 +1193,6 @@
      */
     @Test
     public void processIdentityRef() {
-        setUp();
         DefaultState state = new DefaultState();
         state.type(TunnelP2p.class);
         DefaultTunnel tunnel = new DefaultTunnel();
@@ -1246,7 +1227,6 @@
      */
     @Test
     public void processRpc() {
-        setUp();
         InTypedef typedef = new InTypedef("con-leaf");
         DefaultIn con = new DefaultIn();
         DefaultContentInput input = new DefaultContentInput();
@@ -1308,7 +1288,6 @@
      */
     @Test
     public void processDataTypesToDataNode() {
-        setUp();
         data = new Builder();
         data = buildRootLeafAndLeafList(data);
         data = buildContainer(data);
@@ -1357,7 +1336,8 @@
         validateDataNode(it.next(), "leaf2", ns,
                          SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "thousand");
         validateDataNode(it.next(), "leaf3", ns,
-                         SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "11011");
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, true,
+                         "MTEwMTE="); //Base 64 encoding of '11011'
         validateDataNode(it.next(), "leaf4", ns,
                          SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "thousand");
         validateDataNode(it.next(), "leaf5", ns,
@@ -1373,7 +1353,8 @@
         validateDataNode(it.next(), "leaf11", ns,
                          SINGLE_INSTANCE_LEAF_VALUE_NODE, true, null);
         validateDataNode(it.next(), "leaf12", ns,
-                         SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "11011");
+                         SINGLE_INSTANCE_LEAF_VALUE_NODE, true,
+                        "MTEwMTE="); //Base 64 encoding of '11011'
         validateDataNode(it.next(), "leaf13", ns,
                          SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "*");
         validateDataNode(it.next(), "leaf14", ns,
@@ -1389,9 +1370,11 @@
         validateDataNode(it.next(), "ll2", ns,
                          MULTI_INSTANCE_LEAF_VALUE_NODE, true, "ten");
         validateDataNode(it.next(), "ll3", ns,
-                         MULTI_INSTANCE_LEAF_VALUE_NODE, true, "11011");
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, true,
+                         "MTEwMTE="); //Base 64 encoding of '11011'
         validateDataNode(it.next(), "ll3", ns,
-                         MULTI_INSTANCE_LEAF_VALUE_NODE, true, "110111");
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, true,
+                        "MTEwMTEx"); //Base 64 encoding of '110111'
         validateDataNode(it.next(), "ll4", ns,
                          MULTI_INSTANCE_LEAF_VALUE_NODE, true, "thousand");
         validateDataNode(it.next(), "ll4", ns,
@@ -1417,9 +1400,11 @@
         validateDataNode(it.next(), "ll11", ns,
                          MULTI_INSTANCE_LEAF_VALUE_NODE, true, null);
         validateDataNode(it.next(), "ll12", ns,
-                         MULTI_INSTANCE_LEAF_VALUE_NODE, true, "11011");
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, true,
+                         "MTEwMTE="); //Base 64 encoding of '11011'
         validateDataNode(it.next(), "ll12", ns,
-                         MULTI_INSTANCE_LEAF_VALUE_NODE, true, "110111");
+                         MULTI_INSTANCE_LEAF_VALUE_NODE, true,
+                         "MTEwMTEx"); //Base 64 encoding of '110111'
         validateDataNode(it.next(), "ll13", ns,
                          MULTI_INSTANCE_LEAF_VALUE_NODE, true, "*");
         validateDataNode(it.next(), "ll14", ns,
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/RpcContextTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/RpcContextTest.java
index 225c883..4a0e069 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/RpcContextTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/RpcContextTest.java
@@ -19,9 +19,14 @@
 import org.junit.Test;
 import org.onosproject.yang.gen.v1.hello.rev20150105.hello.hellosecond.DefaultHelloSecondInput;
 import org.onosproject.yang.gen.v1.hello.rev20150105.hello.hellosecond.HelloSecondInput;
+import org.onosproject.yang.gen.v1.hello.rev20150105.hello.hellosecond.HelloSecondOutput;
 import org.onosproject.yang.gen.v1.hello.rev20150105.hello.helloworld.DefaultHelloWorldInput;
 import org.onosproject.yang.gen.v1.hello.rev20150105.hello.helloworld.HelloWorldInput;
+import org.onosproject.yang.model.DataNode.Type;
 import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.DefaultResourceData;
+import org.onosproject.yang.model.InnerNode;
+import org.onosproject.yang.model.LeafNode;
 import org.onosproject.yang.model.ModelConverter;
 import org.onosproject.yang.model.ModelObject;
 import org.onosproject.yang.model.ModelObjectData;
@@ -91,11 +96,48 @@
 
         //Now test converting to a second RPC in the same YANG
         HelloSecondInput hsInput = new DefaultHelloSecondInput();
-        hsInput.x("second-input");
+        hsInput.x(new byte[]{0x1, 0x2, 0x3, 0x4}); //In base64 this is AQIDBA==
         ModelObjectData hsInputMod = DefaultModelObjectData.builder().
                 addModelObject((ModelObject) hsInput).build();
-        assertNotNull(hsInputMod);
+        assertEquals(1, hsInputMod.modelObjects().size());
         ResourceData rdSecond = mc.createDataNode(hsInputMod);
-        assertNotNull(rdSecond);
+        assertEquals(1, rdSecond.dataNodes().size());
+        InnerNode in = (InnerNode) rdSecond.dataNodes().get(0);
+        assertEquals(1, in.childNodes().size());
+        in.childNodes().entrySet().iterator().forEachRemaining(node -> {
+            LeafNode leafNode = (LeafNode) node.getValue();
+            assertEquals("Wrong Base64 value", "AQIDBA==",
+                                    leafNode.value().toString());
+        });
+
+        //Now test decoding the output when it's binary (Base64)
+        LeafNode greetingNode = LeafNode
+            .builder("greeting", "urn:params:xml:ns:yang:hello")
+            .type(Type.SINGLE_INSTANCE_LEAF_VALUE_NODE)
+            .value("BQYHCA==") //Base64 encoding of 0x5 0x6 0x7 0x8
+            .build();
+        InnerNode outputNode = InnerNode
+            .builder("output", "urn:params:xml:ns:yang:hello")
+            .addNode(greetingNode)
+            .type(Type.SINGLE_INSTANCE_NODE)
+            .build();
+        ResourceId rid = ResourceId.builder()
+                .addBranchPointSchema("/", null)
+                .addBranchPointSchema("hello-second", "urn:params:xml:ns:yang:hello")
+                .build();
+
+        ResourceData hsOutputRd = DefaultResourceData.builder()
+                    .addDataNode(outputNode)
+                    .resourceId(rid)
+                    .build();
+        assertNotNull(hsOutputRd);
+        ModelObjectData hsOutputMod = mc.createModel(hsOutputRd);
+        assertEquals(1, hsOutputMod.modelObjects().size());
+        HelloSecondOutput hsOutput = (HelloSecondOutput) hsOutputMod.modelObjects().get(0);
+        assertEquals(4, hsOutput.greeting().length);
+        assertEquals(0x05, hsOutput.greeting()[0]);
+        assertEquals(0x06, hsOutput.greeting()[1]);
+        assertEquals(0x07, hsOutput.greeting()[2]);
+        assertEquals(0x08, hsOutput.greeting()[3]);
     }
 }
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
index 302f5d4..9188c7d 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.yang.runtime.impl;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -127,7 +128,8 @@
     /**
      * Prior setup for each UT.
      */
-    private void setUp() {
+    @Before
+    public void setUp() {
         processSchemaRegistry();
         reg = registry();
         treeBuilder = new DefaultDataTreeBuilder(reg);
@@ -139,7 +141,6 @@
      */
     @Test
     public void processKeysInRid() {
-        setUp();
         data = new Builder();
         mid = buildMidWithKeys().build();
         data.identifier(mid);
@@ -155,7 +156,6 @@
      */
     @Test
     public void processNodeAndLeafListInRid() {
-        setUp();
         data = new Builder();
         ModelObjectId.Builder builder = buildMidWithKeys();
         Tdef1 tdef1 = new Tdef1(Tdef1Union.fromString("thousand"));
@@ -173,7 +173,6 @@
      */
     @Test
     public void processAugmentedLeafListRid() {
-        setUp();
         data = new Builder();
         mid = builder().addChild(DefaultVal.class)
                 .addChild(AugmentedSchVal.LeafIdentifier.LL, fromString("num"))
@@ -215,7 +214,7 @@
 
         byte[] arr = Base64.getDecoder().decode("QXdnRQ==");
         key = buildRidForLeafList(LL8, arr);
-        assertThat(key.value(), is("AwgE"));
+        assertThat(key.value(), is("QXdnRQ=="));
 
         Id id = new Id(IdUnion.fromString("true"));
         key = buildRidForLeafList(LL9, id);
@@ -230,7 +229,6 @@
      * @return leaf list key
      */
     private LeafListKey buildRidForLeafList(LeafIdentifier lId, Object val) {
-        setUp();
         data = new Builder();
         mid = ModelObjectId.builder().addChild(lId, val).build();
         data.identifier(mid);
@@ -278,7 +276,8 @@
 
         validateKeyLeaf(it.next(), "leaf7", nameSpace, "num");
 
-        validateKeyLeaf(it.next(), "leaf8", nameSpace, "11011");
+        validateKeyLeaf(it.next(), "leaf8", nameSpace,
+                "MTEwMTE="); //Base 64 encoding of '11011'
 
         //FIXME: Union under object provider.
         validateKeyLeaf(it.next(), "leaf9", nameSpace, "true");
@@ -331,7 +330,6 @@
      */
     @Test
     public void processRpcInputForUsesAug() {
-        setUp();
         EstablishSubscriptionInput input = new
                 DefaultEstablishSubscriptionInput();
         EventStream tgt = new DefaultEventStream();
@@ -370,7 +368,6 @@
      */
     @Test
     public void processRpcOutputForUsesAug() {
-        setUp();
         EstablishSubscriptionOutput output = new
                 DefaultEstablishSubscriptionOutput();
         Success result = new DefaultSuccess();
@@ -403,7 +400,6 @@
      */
     @Test
     public void processContainerForUsesAug() {
-        setUp();
         Subscriptions subs = new DefaultSubscriptions();
         Subscription sub = new DefaultSubscription();
         sub.identifier(new SubscriptionId(1112L));
diff --git a/runtime/src/test/resources/schemaProviderTestYangFiles/rpc_test.yang b/runtime/src/test/resources/schemaProviderTestYangFiles/rpc_test.yang
index fdd4a43..1825b2d 100644
--- a/runtime/src/test/resources/schemaProviderTestYangFiles/rpc_test.yang
+++ b/runtime/src/test/resources/schemaProviderTestYangFiles/rpc_test.yang
@@ -24,13 +24,13 @@
     rpc hello-second {
         input {
             leaf x {
-                type string;
+                type binary;
             }
         }
 
         output {
             leaf greeting {
-                type string;
+                type binary;
             }
         }
     }