197 lines
6.3 KiB
C++
197 lines
6.3 KiB
C++
#include <di/rpc/lowlevel.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "tests/buffer.h"
|
|
|
|
extern "C" {
|
|
#include "rpc/lowlevel.c"
|
|
}
|
|
|
|
#define TEST_DI_RPC_LL_MSG_DATA_SIZE 64
|
|
|
|
DI_BUFFER_DECL(buf1, TEST_DI_RPC_LL_MSG_DATA_SIZE);
|
|
|
|
/**
|
|
* Verify the lowlevel decode returns with status ERR_MORE_DATA_NEEDED
|
|
* Only a small piece of the header is written (magic-only)
|
|
*/
|
|
TEST(rpc_ll_decode, need_more_data)
|
|
{
|
|
struct di_rpc_ll_msg msg;
|
|
|
|
/* Only write "DJR", 3 bytes */
|
|
di_buffer_init(&buf1, buf1_data, sizeof(buf1_data));
|
|
di_buffer_flush(&buf1);
|
|
|
|
di_buffer_write_data(&buf1, DI_RPC_LL_MSG_HDR_MAGIC, DI_RPC_LL_MSG_HDR_MAGIC_SIZE);
|
|
|
|
/* Check if buffer is correctly set */
|
|
EXPECT_EQ(buf1.used, DI_RPC_LL_MSG_HDR_MAGIC_SIZE);
|
|
ASSERT_STREQ(DI_RPC_LL_MSG_HDR_MAGIC, (const char *)buf1.data);
|
|
|
|
/* Decode needs more data, then only the header (3 bytes) */
|
|
EXPECT_EQ(DI_RPC_LL_MSG_STAT_ERR_MORE_DATA_NEEDED, di_rpc_ll_decode(&buf1, &msg));
|
|
EXPECT_EQ(DI_RPC_LL_MSG_STAT_ERR_MORE_DATA_NEEDED, msg.status);
|
|
}
|
|
|
|
/**
|
|
* Verify the lowlevel decode returns with status ERR_MORE_DATA_NEEDED when there is a
|
|
* header and no data payload.
|
|
*/
|
|
TEST(rpc_ll_decode, need_more_after_header)
|
|
{
|
|
const size_t msg_size = sizeof("DEADBEEFCAFEBABE");
|
|
struct di_rpc_ll_msg msg;
|
|
|
|
/* Write "DJR" + DI_RPC_LL_MSG_TYPE_PLAIN + (DI_RPC_LL_MSG_HDR_SIZE + 16 bytes data payload) */
|
|
di_buffer_init(&buf1, buf1_data, sizeof(buf1_data));
|
|
di_buffer_flush(&buf1);
|
|
|
|
di_rpc_ll_write_header(&buf1, DI_RPC_LL_MSG_TYPE_PLAIN, msg_size);
|
|
|
|
/* Check if buffer is correctly set */
|
|
ASSERT_EQ(DI_RPC_LL_MSG_HDR_SIZE, buf1.used);
|
|
|
|
/* Decode needs more data, then only the header */
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_ERR_MORE_DATA_NEEDED, di_rpc_ll_decode(&buf1, &msg));
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_ERR_MORE_DATA_NEEDED, msg.status);
|
|
|
|
/* Write data */
|
|
ASSERT_EQ(DNOK, di_rpc_ll_write_data(&buf1, (const uint8_t *)"DEADBEEFCAFEBABE", msg_size));
|
|
|
|
/* Decode */
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, di_rpc_ll_decode(&buf1, &msg));
|
|
ASSERT_EQ(DI_RPC_LL_MSG_TYPE_PLAIN, msg.type);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, msg.status);
|
|
ASSERT_EQ(msg_size, msg.size);
|
|
ASSERT_STREQ("DEADBEEFCAFEBABE", (const char *)msg.data);
|
|
}
|
|
|
|
/**
|
|
* Verify the lowlevel decode returns with status ERR_MORE_DATA_NEEDED when there is a
|
|
* header and no data payload.
|
|
*/
|
|
TEST(rpc_ll_decode, reply_ok__mkay_payload)
|
|
{
|
|
struct di_rpc_ll_msg msg;
|
|
|
|
di_buffer_init(&buf1, buf1_data, sizeof(buf1_data));
|
|
di_buffer_flush(&buf1);
|
|
|
|
di_rpc_ll_write_header(&buf1, DI_RPC_LL_MSG_TYPE_REPLY, DI_RPC_LL_MSG_REPLY_MKAY_SIZE);
|
|
ASSERT_EQ(DNOK, di_rpc_ll_write_data(&buf1,
|
|
(const uint8_t *)DI_RPC_LL_MSG_REPLY_MKAY, DI_RPC_LL_MSG_REPLY_MKAY_SIZE));
|
|
|
|
/* Decode */
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, di_rpc_ll_decode(&buf1, &msg));
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, msg.status);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_TYPE_REPLY, msg.type);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_REPLY_OK, msg.reply);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_REPLY_MKAY_SIZE, msg.size);
|
|
ASSERT_STREQ(DI_RPC_LL_MSG_REPLY_MKAY, (const char *)msg.data);
|
|
}
|
|
|
|
/**
|
|
* Check if reply which matches the size of "WTF" payload. But "ABC" payload is read
|
|
* it should set DI_RPC_LL_MSG_TYPE_REPLY and DI_RPC_LL_MSG_REPLY_UNKNOWN
|
|
*/
|
|
TEST(rpc_ll_decode, reply_unknown__abc_payload)
|
|
{
|
|
struct di_rpc_ll_msg msg;
|
|
|
|
di_buffer_init(&buf1, buf1_data, sizeof(buf1_data));
|
|
di_buffer_flush(&buf1);
|
|
|
|
di_rpc_ll_write_header(&buf1, DI_RPC_LL_MSG_TYPE_REPLY, DI_RPC_LL_MSG_REPLY_WTF_SIZE);
|
|
ASSERT_EQ(DNOK, di_rpc_ll_write_data(&buf1,
|
|
(const uint8_t *)"ABC", DI_RPC_LL_MSG_REPLY_WTF_SIZE));
|
|
|
|
/* Decode */
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, di_rpc_ll_decode(&buf1, &msg));
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, msg.status);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_TYPE_REPLY, msg.type);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_REPLY_UNKNOWN, msg.reply);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_REPLY_WTF_SIZE, msg.size);
|
|
}
|
|
|
|
/**
|
|
* Verify the lowlevel decode returns with status ERR_MORE_DATA_NEEDED when there is a
|
|
* header and no data payload.
|
|
*/
|
|
TEST(rpc_ll_decode, reply_error__wtf_payload)
|
|
{
|
|
struct di_rpc_ll_msg msg;
|
|
|
|
di_buffer_init(&buf1, buf1_data, sizeof(buf1_data));
|
|
di_buffer_flush(&buf1);
|
|
|
|
di_rpc_ll_write_header(&buf1, DI_RPC_LL_MSG_TYPE_REPLY, DI_RPC_LL_MSG_REPLY_WTF_SIZE);
|
|
ASSERT_EQ(DNOK, di_rpc_ll_write_data(&buf1,
|
|
(const uint8_t *)DI_RPC_LL_MSG_REPLY_WTF, DI_RPC_LL_MSG_REPLY_WTF_SIZE));
|
|
|
|
/* Decode */
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, di_rpc_ll_decode(&buf1, &msg));
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, msg.status);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_TYPE_REPLY, msg.type);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_REPLY_ERROR, msg.reply);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_REPLY_WTF_SIZE, msg.size);
|
|
ASSERT_STREQ(DI_RPC_LL_MSG_REPLY_WTF, (const char *)msg.data);
|
|
}
|
|
|
|
/**
|
|
* Verify the lowlevel decode returns with status ERR_MORE_DATA_NEEDED when there is a
|
|
* header and no data payload.
|
|
*/
|
|
TEST(rpc_ll_decode, reply_unknown_more_data_needed__abc_payload)
|
|
{
|
|
const size_t data_size = sizeof("ABC");
|
|
struct di_rpc_ll_msg msg;
|
|
|
|
di_buffer_init(&buf1, buf1_data, sizeof(buf1_data));
|
|
di_buffer_flush(&buf1);
|
|
|
|
di_rpc_ll_write_header(&buf1, DI_RPC_LL_MSG_TYPE_REPLY, data_size);
|
|
ASSERT_EQ(DNOK, di_rpc_ll_write_data(&buf1,
|
|
(const uint8_t *)"ABC", data_size));
|
|
|
|
/* Decode */
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, di_rpc_ll_decode(&buf1, &msg));
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_OK, msg.status);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_TYPE_REPLY, msg.type);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_REPLY_UNKNOWN, msg.reply);
|
|
ASSERT_EQ(data_size, msg.size);
|
|
ASSERT_STREQ("ABC", (const char *)msg.data);
|
|
}
|
|
|
|
/**
|
|
* Test if unknown lowlevel message (where header is not found) is correctly handled
|
|
*/
|
|
TEST(rpc_ll_decode, unknown_msg)
|
|
{
|
|
struct di_rpc_ll_msg msg;
|
|
const char llmsg[] = "\x12\x13\x14\x15\x16\x17\x18\x19\x20";
|
|
|
|
di_buffer_init(&buf1, buf1_data, sizeof(buf1_data));
|
|
di_buffer_memcpy(&buf1, 0, llmsg, sizeof(llmsg));
|
|
buf1.used = sizeof(llmsg);
|
|
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_UNKNOWN, di_rpc_ll_decode(&buf1, &msg));
|
|
}
|
|
|
|
/**
|
|
* Test if invalid msg type (field in header) returns DI_RPC_LL_MSG_STAT_ERR_INVALID_TYPE
|
|
*/
|
|
TEST(rpc_ll_decode, unknown_msg_type)
|
|
{
|
|
struct di_rpc_ll_msg msg;
|
|
const char llmsg[] = "DJR\x11\xff\xff\xde\xad\xbe\xef";
|
|
|
|
di_buffer_init(&buf1, buf1_data, sizeof(buf1_data));
|
|
di_buffer_memcpy(&buf1, 0, llmsg, sizeof(llmsg));
|
|
buf1.used = sizeof(llmsg);
|
|
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_ERR_INVALID_TYPE, di_rpc_ll_decode(&buf1, &msg));
|
|
ASSERT_EQ(DI_RPC_LL_MSG_TYPE_UNKNOWN, msg.type);
|
|
ASSERT_EQ(DI_RPC_LL_MSG_STAT_ERR_INVALID_TYPE, msg.status);
|
|
}
|