transport: Introduce a transport for testing purposes

I've put the test transport header along side the source file as its
presence and implementation is an internal detail to support the test
suite. No consumers of libpldm outside its test suite should have any
need for the test transport. We can always choose to make the header
public if for some reason someone does eventually want to use it.

In addition, add a new test suite exercising the transport interfaces.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: Ie9906bdc6a397436b91198196de04ffd6c93fc46
diff --git a/tests/meson.build b/tests/meson.build
index 834f19c..e9d88ec 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -24,6 +24,7 @@
   'libpldm_pdr_test',
   'libpldm_firmware_update_test',
   'msgbuf',
+  'transport',
 ]
 
 if get_option('oem-ibm').allowed()
diff --git a/tests/transport.cpp b/tests/transport.cpp
new file mode 100644
index 0000000..79b09e8
--- /dev/null
+++ b/tests/transport.cpp
@@ -0,0 +1,163 @@
+#include "libpldm/transport.h"
+
+#include "array.h"
+#include "transport/test.h"
+
+#include <gtest/gtest.h>
+
+#ifdef LIBPLDM_API_TESTING
+TEST(Transport, create)
+{
+    struct pldm_transport_test* test = NULL;
+
+    EXPECT_EQ(pldm_transport_test_init(&test, NULL, 0), 0);
+    EXPECT_NE(pldm_transport_test_core(test), nullptr);
+    pldm_transport_test_destroy(test);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(Transport, send_one)
+{
+    const uint8_t msg[] = {0x81, 0x00, 0x01, 0x01};
+    const struct pldm_transport_test_descriptor seq[] = {
+        {
+            .type = PLDM_TRANSPORT_TEST_ELEMENT_MSG_SEND,
+            .send_msg =
+                {
+                    .dst = 1,
+                    .msg = msg,
+                    .len = sizeof(msg),
+                },
+        },
+    };
+    struct pldm_transport_test* test = NULL;
+    struct pldm_transport* ctx;
+    int rc;
+
+    EXPECT_EQ(pldm_transport_test_init(&test, seq, ARRAY_SIZE(seq)), 0);
+    ctx = pldm_transport_test_core(test);
+    rc = pldm_transport_send_msg(ctx, 1, msg, sizeof(msg));
+    EXPECT_EQ(rc, PLDM_REQUESTER_SUCCESS);
+    pldm_transport_test_destroy(test);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(Transport, recv_one)
+{
+    uint8_t msg[] = {0x01, 0x00, 0x01, 0x00};
+    const struct pldm_transport_test_descriptor seq[] = {
+        {
+            .type = PLDM_TRANSPORT_TEST_ELEMENT_MSG_RECV,
+            .recv_msg =
+                {
+                    .src = 1,
+                    .msg = msg,
+                    .len = sizeof(msg),
+                },
+        },
+    };
+    struct pldm_transport_test* test = NULL;
+    struct pldm_transport* ctx;
+    void* recvd;
+    size_t len;
+    int rc;
+
+    EXPECT_EQ(pldm_transport_test_init(&test, seq, ARRAY_SIZE(seq)), 0);
+    ctx = pldm_transport_test_core(test);
+    rc = pldm_transport_recv_msg(ctx, 1, &recvd, &len);
+    EXPECT_EQ(rc, PLDM_REQUESTER_SUCCESS);
+    EXPECT_EQ(len, sizeof(msg));
+    EXPECT_EQ(memcmp(recvd, msg, len), 0);
+    free(recvd);
+    pldm_transport_test_destroy(test);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(Transport, send_recv_one)
+{
+    uint8_t req[] = {0x81, 0x00, 0x01, 0x01};
+    uint8_t resp[] = {0x01, 0x00, 0x01, 0x00};
+    const struct pldm_transport_test_descriptor seq[] = {
+        {
+            .type = PLDM_TRANSPORT_TEST_ELEMENT_MSG_SEND,
+            .send_msg =
+                {
+                    .dst = 1,
+                    .msg = req,
+                    .len = sizeof(req),
+                },
+        },
+        {
+            .type = PLDM_TRANSPORT_TEST_ELEMENT_LATENCY,
+            .latency =
+                {
+                    .it_interval = {0, 0},
+                    .it_value = {1, 0},
+                },
+        },
+        {
+            .type = PLDM_TRANSPORT_TEST_ELEMENT_MSG_RECV,
+            .recv_msg =
+                {
+                    .src = 1,
+                    .msg = resp,
+                    .len = sizeof(resp),
+                },
+        },
+    };
+    struct pldm_transport_test* test = NULL;
+    struct pldm_transport* ctx;
+    size_t len;
+    void* msg;
+    int rc;
+
+    EXPECT_EQ(pldm_transport_test_init(&test, seq, ARRAY_SIZE(seq)), 0);
+    ctx = pldm_transport_test_core(test);
+    rc = pldm_transport_send_recv_msg(ctx, 1, req, sizeof(req), &msg, &len);
+    EXPECT_EQ(rc, PLDM_REQUESTER_SUCCESS);
+    EXPECT_EQ(len, sizeof(resp));
+    EXPECT_EQ(memcmp(msg, resp, len), 0);
+    free(msg);
+    pldm_transport_test_destroy(test);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(Transport, send_recv_timeout)
+{
+    uint8_t req[] = {0x81, 0x00, 0x01, 0x01};
+    const struct pldm_transport_test_descriptor seq[] = {
+        {
+            .type = PLDM_TRANSPORT_TEST_ELEMENT_MSG_SEND,
+            .send_msg =
+                {
+                    .dst = 1,
+                    .msg = req,
+                    .len = sizeof(req),
+                },
+        },
+        {
+            .type = PLDM_TRANSPORT_TEST_ELEMENT_LATENCY,
+            .latency =
+                {
+                    .it_interval = {0, 0},
+                    .it_value = {5, 0},
+                },
+        },
+    };
+    struct pldm_transport_test* test = NULL;
+    struct pldm_transport* ctx;
+    size_t len;
+    void* msg;
+    int rc;
+
+    EXPECT_EQ(pldm_transport_test_init(&test, seq, ARRAY_SIZE(seq)), 0);
+    ctx = pldm_transport_test_core(test);
+    rc = pldm_transport_send_recv_msg(ctx, 1, req, sizeof(req), &msg, &len);
+    EXPECT_EQ(rc, PLDM_REQUESTER_RECV_FAIL);
+    pldm_transport_test_destroy(test);
+}
+#endif