Add tests for codecs and P4Info parser when P4Runtime Translation is used

Change-Id: Ied0e83e81dad29f5b250548d2e26ec960b98f560
diff --git a/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4InfoParserTest.java b/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4InfoParserTest.java
index c05a84c..0432a18 100644
--- a/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4InfoParserTest.java
+++ b/protocols/p4runtime/model/src/test/java/org/onosproject/p4runtime/model/P4InfoParserTest.java
@@ -65,8 +65,10 @@
  */
 public class P4InfoParserTest {
     private static final String PATH = "basic.p4info";
+    private static final String PATH2 = "test_p4runtime_translation_p4info.txt";
 
     private final URL p4InfoUrl = P4InfoParserTest.class.getResource(PATH);
+    private final URL p4InfoUrl2 = P4InfoParserTest.class.getResource(PATH2);
 
     private static final Long DEFAULT_MAX_TABLE_SIZE = 1024L;
     private static final Long DEFAULT_MAX_ACTION_PROFILE_SIZE = 64L;
@@ -279,6 +281,96 @@
     }
 
     /**
+     * Tests parse method with P4Runtime translation fields.
+     * @throws Exception if equality group objects dose not match as expected
+     */
+    @Test
+    public void testParseP4RuntimeTranslation() throws Exception {
+        PiPipelineModel model = P4InfoParser.parse(p4InfoUrl2);
+        // Generate a P4Info object from the file
+        final P4Info p4info;
+        try {
+            p4info = getP4InfoMessage(p4InfoUrl2);
+        } catch (IOException e) {
+            throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
+        }
+        List<Table> tableMsgs =  p4info.getTablesList();
+        PiTableId table0Id = PiTableId.of(tableMsgs.get(0).getPreamble().getName());
+
+        //parse tables
+        PiTableModel table0Model = model.table(table0Id).orElse(null);
+
+        // Check matchFields
+        List<MatchField> matchFieldList = tableMsgs.get(0).getMatchFieldsList();
+        List<PiMatchFieldModel> piMatchFieldList = new ArrayList<>();
+
+        for (MatchField matchFieldIter : matchFieldList) {
+            MatchField.MatchType matchType = matchFieldIter.getMatchType();
+            PiMatchType piMatchType;
+            switch (matchType) {
+                case EXACT: piMatchType = PiMatchType.EXACT; break;
+                case LPM: piMatchType = PiMatchType.LPM; break;
+                case TERNARY: piMatchType = PiMatchType.TERNARY; break;
+                case RANGE: piMatchType = PiMatchType.RANGE; break;
+                default: Assert.fail(); return;
+            }
+            if (matchFieldIter.getTypeName().getName().equals("mac_addr_t")) {
+                piMatchFieldList.add(new P4MatchFieldModel(PiMatchFieldId.of(matchFieldIter.getName()),
+                                                           P4MatchFieldModel.BIT_WIDTH_UNDEFINED, piMatchType));
+            } else {
+                piMatchFieldList.add(new P4MatchFieldModel(PiMatchFieldId.of(matchFieldIter.getName()),
+                                                           matchFieldIter.getBitwidth(), piMatchType));
+            }
+        }
+        assertThat("Incorrect order for matchFields",
+                   table0Model.matchFields(),
+                   IsIterableContainingInOrder.contains(
+                           piMatchFieldList.get(0), piMatchFieldList.get(1),
+                           piMatchFieldList.get(2), piMatchFieldList.get(3)));
+
+        //check table0 actionsRefs
+        List<ActionRef> actionRefList = tableMsgs.get(0).getActionRefsList();
+        assertThat("Incorrect size for actionRefs",
+                   actionRefList.size(),
+                   is(equalTo(4)));
+
+        //create action instances
+        // Set egress with string as parameter
+        PiActionId actionId = PiActionId.of("set_egress_port");
+        PiActionParamId piActionParamId = PiActionParamId.of("port");
+        PiActionParamModel actionParamModel = new P4ActionParamModel(
+                piActionParamId, P4ActionParamModel.BIT_WIDTH_UNDEFINED);
+        ImmutableMap<PiActionParamId, PiActionParamModel> params = new
+                ImmutableMap.Builder<PiActionParamId, PiActionParamModel>()
+                .put(piActionParamId, actionParamModel).build();
+        PiActionModel setEgressPortAction = new P4ActionModel(actionId, params);
+
+        // Set egress with 32 bit as parameter
+        actionId = PiActionId.of("set_egress_port2");
+        piActionParamId = PiActionParamId.of("port");
+        int bitWitdth = 32;
+        actionParamModel = new P4ActionParamModel(
+                piActionParamId, bitWitdth);
+        params = new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>()
+                .put(piActionParamId, actionParamModel).build();
+
+        PiActionModel setEgressPortAction2 = new P4ActionModel(actionId, params);
+
+        actionId = PiActionId.of("send_to_cpu");
+        PiActionModel sendToCpuAction =
+                new P4ActionModel(actionId, new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().build());
+
+        actionId = PiActionId.of("drop");
+        PiActionModel dropAction =
+                new P4ActionModel(actionId, new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>().build());
+
+        //check table0 actions
+        assertThat("action dose not match",
+                   table0Model.actions(), IsIterableContainingInAnyOrder.containsInAnyOrder(
+                        setEgressPortAction, setEgressPortAction2, sendToCpuAction, dropAction));
+    }
+
+    /**
      * Gets P4Info message from the URL.
      * @param p4InfoUrl link to the p4Info file
      * @return a P4Info object
diff --git a/protocols/p4runtime/model/src/test/resources/org/onosproject/p4runtime/model/test_p4runtime_translation_p4info.txt b/protocols/p4runtime/model/src/test/resources/org/onosproject/p4runtime/model/test_p4runtime_translation_p4info.txt
new file mode 100644
index 0000000..241d989
--- /dev/null
+++ b/protocols/p4runtime/model/src/test/resources/org/onosproject/p4runtime/model/test_p4runtime_translation_p4info.txt
@@ -0,0 +1,162 @@
+pkg_info {
+  arch: "v1model"
+}
+tables {
+  preamble {
+    id: 36960149
+    name: "table0"
+    alias: "table0"
+  }
+  match_fields {
+    id: 1
+    name: "local_metadata.ingress_port"
+    bitwidth: 32
+    match_type: EXACT
+    type_name {
+      name: "port_id_bit_t"
+    }
+  }
+  match_fields {
+    id: 2
+    name: "hdr.ethernet.srcAddr"
+    match_type: EXACT
+    type_name {
+      name: "mac_addr_t"
+    }
+  }
+  match_fields {
+    id: 3
+    name: "hdr.ethernet.dstAddr"
+    match_type: EXACT
+    type_name {
+      name: "mac_addr_t"
+    }
+  }
+  match_fields {
+    id: 4
+    name: "hdr.ethernet.etherType"
+    bitwidth: 16
+    match_type: EXACT
+  }
+  action_refs {
+    id: 27607748
+  }
+  action_refs {
+    id: 32872817
+  }
+  action_refs {
+    id: 24562328
+  }
+  action_refs {
+    id: 18759588
+  }
+  const_default_action_id: 18759588
+  size: 1024
+}
+actions {
+  preamble {
+    id: 24562328
+    name: "send_to_cpu"
+    alias: "send_to_cpu"
+  }
+}
+actions {
+  preamble {
+    id: 27607748
+    name: "set_egress_port"
+    alias: "set_egress_port"
+  }
+  params {
+    id: 1
+    name: "port"
+    type_name {
+      name: "port_id_str_t"
+    }
+  }
+}
+actions {
+  preamble {
+    id: 32872817
+    name: "set_egress_port2"
+    alias: "set_egress_port2"
+  }
+  params {
+    id: 1
+    name: "port"
+    bitwidth: 32
+    type_name {
+      name: "port_id_bit_t"
+    }
+  }
+}
+actions {
+  preamble {
+    id: 18759588
+    name: "drop"
+    alias: "drop"
+  }
+}
+controller_packet_metadata {
+  preamble {
+    id: 81826293
+    name: "packet_in"
+    alias: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "_padding"
+    bitwidth: 7
+  }
+}
+controller_packet_metadata {
+  preamble {
+    id: 76689799
+    name: "packet_out"
+    alias: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "_padding"
+    bitwidth: 7
+  }
+}
+type_info {
+  new_types {
+    key: "mac_addr_t"
+    value {
+      translated_type {
+        sdn_string {
+        }
+      }
+    }
+  }
+  new_types {
+    key: "port_id_bit_t"
+    value {
+      translated_type {
+        sdn_bitwidth: 32
+      }
+    }
+  }
+  new_types {
+    key: "port_id_str_t"
+    value {
+      translated_type {
+        sdn_string {
+        }
+      }
+    }
+  }
+}