| /* |
| * Copyright (c) 2022 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <ztest.h> |
| #include <ipc/ipc_icmsg_buf.h> |
| |
| /* The buffer size itself would be 199 bytes. |
| * 212 - sizeof(struct icmsg_buf) - 1 = 199. |
| * -1 because internal rd/wr_idx is reserved to mean the buffer is empty. |
| */ |
| static uint8_t memory_area[212]; |
| |
| static void test_icmsg_buf_ut(void) |
| { |
| static uint8_t rbuf[198]; |
| static uint8_t message[20] = {'a'}; |
| struct icmsg_buf *ib; |
| int rlen; |
| int wlen; |
| |
| ib = icmsg_buf_init(memory_area, sizeof(memory_area)); |
| zassert_equal_ptr(ib, memory_area, NULL); |
| zassert_equal(ib->len, (sizeof(memory_area) - sizeof(*ib)), NULL); |
| zassert_equal(ib->wr_idx, 0, NULL); |
| zassert_equal(ib->rd_idx, 0, NULL); |
| |
| /* Try to write more than buffer can store. */ |
| rlen = icmsg_buf_write(ib, rbuf, sizeof(rbuf)); |
| zassert_equal(rlen, -ENOMEM, NULL); |
| zassert_equal(ib->wr_idx, 0, NULL); |
| zassert_equal(ib->rd_idx, 0, NULL); |
| |
| /* Read empty buffer. */ |
| rlen = icmsg_buf_read(ib, rbuf, sizeof(rbuf)); |
| zassert_equal(rlen, 0, NULL); |
| |
| /* Single write and read. */ |
| wlen = icmsg_buf_write(ib, message, sizeof(message)); |
| zassert_equal(wlen, sizeof(message), NULL); |
| zassert_equal(ib->wr_idx, (sizeof(message) + sizeof(uint16_t)), NULL); |
| zassert_equal(ib->rd_idx, 0, NULL); |
| |
| rlen = icmsg_buf_read(ib, rbuf, sizeof(rbuf)); |
| zassert_equal(rlen, sizeof(message), NULL); |
| zassert_equal(ib->wr_idx, (sizeof(message) + sizeof(uint16_t)), NULL); |
| zassert_equal(ib->rd_idx, (sizeof(message) + sizeof(uint16_t)), NULL); |
| |
| /* Buffer size is 212 - 12 = 200 Bytes for len, wr_idx, rd_idx. |
| * When writing message of 20 Bytes, actually 22 Bytes are stored, |
| * (2 Bytes reserved for message len). Test if after 9 writes, 10th write |
| * would return -ENOMEM. 200 - (9 * 22) = 2 bytes left. |
| * |
| * Reset the buffer first. |
| */ |
| ib = icmsg_buf_init(memory_area, sizeof(memory_area)); |
| zassert_equal_ptr(ib, memory_area, NULL); |
| zassert_equal(ib->len, (sizeof(memory_area) - sizeof(*ib)), NULL); |
| zassert_equal(ib->wr_idx, 0, NULL); |
| zassert_equal(ib->rd_idx, 0, NULL); |
| |
| for (size_t i = 0; i < 9; i++) { |
| wlen = icmsg_buf_write(ib, message, sizeof(message)); |
| zassert_equal(wlen, sizeof(message), NULL); |
| } |
| |
| wlen = icmsg_buf_write(ib, message, sizeof(message)); |
| zassert_equal(wlen, -ENOMEM, NULL); |
| |
| /* Test reading with buf == NULL, should return len of the next message to read. */ |
| rlen = icmsg_buf_read(ib, NULL, 0); |
| zassert_equal(rlen, sizeof(message), NULL); |
| |
| /* Read with len == 0 and correct buf pointer. */ |
| rlen = icmsg_buf_read(ib, rbuf, 0); |
| zassert_equal(rlen, -ENOMEM, NULL); |
| |
| /* Read whole data from the buffer. */ |
| for (size_t i = 0; i < 9; i++) { |
| zassert_equal(ib->rd_idx, i * (sizeof(message) + sizeof(uint16_t)), NULL); |
| wlen = icmsg_buf_read(ib, rbuf, sizeof(rbuf)); |
| zassert_equal(wlen, sizeof(message), NULL); |
| } |
| |
| zassert_equal(ib->wr_idx, 9 * (sizeof(message) + sizeof(uint16_t)), NULL); |
| zassert_equal(ib->rd_idx, 9 * (sizeof(message) + sizeof(uint16_t)), NULL); |
| |
| /* Write message that would be wrapped around. */ |
| wlen = icmsg_buf_write(ib, message, sizeof(message)); |
| zassert_equal(wlen, sizeof(message), NULL); |
| /* Have to store 22 bytes in total. |
| * 2 Bytes left in tail of the buffer 20 bytes go in front. |
| */ |
| zassert_equal(ib->wr_idx, 20, NULL); |
| |
| /* Read wrapped message. */ |
| rlen = icmsg_buf_read(ib, rbuf, sizeof(rbuf)); |
| zassert_equal(rlen, sizeof(message), NULL); |
| zassert_equal(message[0], 'a', NULL); |
| } |
| |
| void test_main(void) |
| { |
| ztest_test_suite(icmsg_buf, |
| ztest_unit_test(test_icmsg_buf_ut) |
| ); |
| ztest_run_test_suite(icmsg_buf); |
| } |