Add tests for codecs and P4Info parser when P4Runtime Translation is used
Change-Id: Ied0e83e81dad29f5b250548d2e26ec960b98f560
diff --git a/protocols/p4runtime/ctl/src/test/resources/Makefile b/protocols/p4runtime/ctl/src/test/resources/Makefile
new file mode 100644
index 0000000..964ca18
--- /dev/null
+++ b/protocols/p4runtime/ctl/src/test/resources/Makefile
@@ -0,0 +1,7 @@
+all: test
+
+test: test_p4runtime_translation.p4
+ @./bmv2-compile.sh "test_p4runtime_translation" ""
+
+clean:
+ rm test_p4runtime_translation_p4info.txt
diff --git a/protocols/p4runtime/ctl/src/test/resources/bmv2-compile.sh b/protocols/p4runtime/ctl/src/test/resources/bmv2-compile.sh
new file mode 100755
index 0000000..4bcf40b
--- /dev/null
+++ b/protocols/p4runtime/ctl/src/test/resources/bmv2-compile.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+set -e
+
+PROFILE=$1
+OTHER_FLAGS=$2
+
+SRC_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+
+echo
+echo "## Compiling profile ${PROFILE} in ${SRC_DIR}..."
+
+# Using stable-20210108 because stable doesn't support @p4runtime_translation annotations
+dockerImage=opennetworking/p4c:stable-20210108
+dockerRun="docker run --rm -w ${SRC_DIR} -v ${SRC_DIR}:${SRC_DIR} ${dockerImage}"
+
+
+# Generate BMv2 JSON and P4Info.
+(set -x; ${dockerRun} p4c-bm2-ss --arch v1model \
+ ${OTHER_FLAGS} \
+ --p4runtime-files ${SRC_DIR}/${PROFILE}_p4info.txt ${PROFILE}.p4)
diff --git a/protocols/p4runtime/ctl/src/test/resources/test_p4runtime_translation.p4 b/protocols/p4runtime/ctl/src/test/resources/test_p4runtime_translation.p4
new file mode 100644
index 0000000..6ebf306
--- /dev/null
+++ b/protocols/p4runtime/ctl/src/test/resources/test_p4runtime_translation.p4
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <core.p4>
+#include <v1model.p4>
+
+typedef bit<9> port_t;
+
+@p4runtime_translation("", string)
+type bit<48> mac_addr_t;
+
+@p4runtime_translation("", 32)
+type port_t port_id_bit_t;
+
+@p4runtime_translation("", string)
+type port_t port_id_str_t;
+
+const port_t CPU_PORT = 255;
+
+@controller_header("packet_in")
+header packet_in_header_t {
+ bit<9> ingress_port;
+ bit<7> _padding;
+}
+
+@controller_header("packet_out")
+header packet_out_header_t {
+ bit<9> egress_port;
+ bit<7> _padding;
+}
+
+header ethernet_t {
+ mac_addr_t dstAddr;
+ mac_addr_t srcAddr;
+ bit<16> etherType;
+}
+
+struct headers_t {
+ packet_out_header_t packet_out;
+ packet_in_header_t packet_in;
+ ethernet_t ethernet;
+}
+
+struct local_metadata_t {
+ port_id_bit_t ingress_port;
+}
+
+// Test P4 Program for P4Runtime translation (simplified version of basic.p4).
+
+//------------------------------------------------------------------------------
+// PARSER
+//------------------------------------------------------------------------------
+parser parser_impl(packet_in packet,
+ out headers_t hdr,
+ inout local_metadata_t local_metadata,
+ inout standard_metadata_t standard_metadata) {
+
+ state start {
+ local_metadata.ingress_port = (port_id_bit_t) standard_metadata.ingress_port;
+ transition select(standard_metadata.ingress_port) {
+ CPU_PORT: parse_packet_out;
+ default: parse_ethernet;
+ }
+ }
+
+ state parse_packet_out {
+ packet.extract(hdr.packet_out);
+ transition parse_ethernet;
+ }
+
+ state parse_ethernet {
+ packet.extract(hdr.ethernet);
+ transition accept;
+ }
+}
+
+//------------------------------------------------------------------------------
+// DEPARSER
+//------------------------------------------------------------------------------
+control deparser(packet_out packet, in headers_t hdr) {
+ apply {
+ packet.emit(hdr.packet_in);
+ packet.emit(hdr.ethernet);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+// INGRESS PIPELINE
+//------------------------------------------------------------------------------
+
+control ingress(inout headers_t hdr,
+ inout local_metadata_t local_metadata,
+ inout standard_metadata_t standard_metadata) {
+
+ @name(".send_to_cpu")
+ action send_to_cpu() {
+ standard_metadata.egress_spec = CPU_PORT;
+ }
+
+ @name(".set_egress_port")
+ action set_egress_port(port_id_str_t port) {
+ standard_metadata.egress_spec = (bit<9>) port;
+ }
+ @name(".set_egress_port2")
+ action set_egress_port2(port_id_bit_t port) {
+ standard_metadata.egress_spec = (bit<9>) port;
+ }
+
+ @name(".drop")
+ action drop() {
+ mark_to_drop(standard_metadata);
+ }
+ @name(".table0")
+ table table0 {
+ key = {
+ local_metadata.ingress_port : exact;
+ hdr.ethernet.srcAddr : exact;
+ hdr.ethernet.dstAddr : exact;
+ hdr.ethernet.etherType : exact;
+ }
+ actions = {
+ set_egress_port;
+ set_egress_port2;
+ send_to_cpu;
+ drop;
+ }
+ const default_action = drop();
+ }
+
+ apply {
+ table0.apply();
+ }
+}
+
+//------------------------------------------------------------------------------
+// EGRESS PIPELINE
+//------------------------------------------------------------------------------
+
+control egress(inout headers_t hdr,
+ inout local_metadata_t local_metadata,
+ inout standard_metadata_t standard_metadata) {
+
+ apply {
+ // no-op
+ }
+}
+
+control verify_checksum_control(inout headers_t hdr,
+ inout local_metadata_t local_metadata) {
+ apply {
+ // Assume checksum is always correct.
+ }
+}
+
+control compute_checksum_control(inout headers_t hdr,
+ inout local_metadata_t local_metadata) {
+ apply {
+ // no-op for the test program
+ }
+}
+
+//------------------------------------------------------------------------------
+// SWITCH INSTANTIATION
+//------------------------------------------------------------------------------
+
+V1Switch(parser_impl(),
+ verify_checksum_control(),
+ ingress(),
+ egress(),
+ compute_checksum_control(),
+ deparser()) main;
diff --git a/protocols/p4runtime/ctl/src/test/resources/test_p4runtime_translation_p4info.txt b/protocols/p4runtime/ctl/src/test/resources/test_p4runtime_translation_p4info.txt
new file mode 100644
index 0000000..241d989
--- /dev/null
+++ b/protocols/p4runtime/ctl/src/test/resources/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 {
+ }
+ }
+ }
+ }
+}