diff --git a/tests/build.mk b/tests/build.mk index 584fb0270..f91d68c8e 100644 --- a/tests/build.mk +++ b/tests/build.mk @@ -10,6 +10,12 @@ TEST_CFLAGS-$(win) += -mconsole TEST_DEF_OBJS := tests/c/test.o # Defines the list of test sets +TESTS += buffer + +# Describe how to build each test +buffer.src-y := ./tests/c/buffer.cpp \ + $(PATH_LIBQB)/src/buffer.cpp + TEST_OBJS := $(TEST_DEF_OBJS) TEST_OBJS += $(foreach test,$(TESTS),$(filter ./tests/c/%,$($(test)).objs-y)) diff --git a/tests/c/buffer.cpp b/tests/c/buffer.cpp new file mode 100644 index 000000000..3a89c842b --- /dev/null +++ b/tests/c/buffer.cpp @@ -0,0 +1,318 @@ + +#include +#include +#include + +#include "test.h" +#include "buffer.h" + +// A single read and write of the same size from the buffer +void test_single_rw() { + struct libqb_buffer buffer; + + libqb_buffer_init(&buffer); + const char str[] = "FOOBAR"; + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + libqb_buffer_write(&buffer, str, sizeof(str)); + + test_assert_ints(sizeof(str), libqb_buffer_length(&buffer)); + + char read_buf[sizeof(str)]; + size_t read_len = libqb_buffer_read(&buffer, read_buf, sizeof(str)); + + test_assert_ints(sizeof(str), read_len); + test_assert_buffers(str, read_buf, sizeof(str)); + test_assert_ints(0, libqb_buffer_length(&buffer)); + + libqb_buffer_clear(&buffer); +} + +// Multple writes and reads of the same size from the buffer +void test_multiple_rw() { + int count = 10; + struct libqb_buffer buffer; + + libqb_buffer_init(&buffer); + const char str[] = "FOOBAR"; + int length = 0; + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + for (int i = 0; i < count; i++) { + char id[20]; + snprintf(id, sizeof(id), "%d", i); + + libqb_buffer_write(&buffer, str, sizeof(str)); + + length += sizeof(str); + test_assert_ints_with_name(id, length, libqb_buffer_length(&buffer)); + } + + for (int i = 0; i < count; i++) { + char id[20]; + snprintf(id, sizeof(id), "%d", i); + + char read_buf[sizeof(str)]; + size_t read_len = libqb_buffer_read(&buffer, read_buf, sizeof(str)); + + length -= sizeof(str); + + test_assert_ints_with_name(id, sizeof(str), read_len); + test_assert_buffers_with_name(id, str, read_buf, sizeof(str)); + test_assert_ints_with_name(id, length, libqb_buffer_length(&buffer)); + } + + libqb_buffer_clear(&buffer); +} + +// Single write, multiple reads +void test_partial_read() { + struct libqb_buffer buffer; + + libqb_buffer_init(&buffer); + const char str[] = "FOOBAR1" "FOOBAR2" "FOOBAR3" "FOOBAR4" "FOOBAR5" "FOOBAR6"; + const int str_len = 7; + const int length = sizeof(str) - 1; + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + libqb_buffer_write(&buffer, str, length); + + int length_left = length; + for (int i = 0; i < length / str_len; i++) { + char id[20]; + snprintf(id, sizeof(id), "%d", i); + + char read_buf[str_len]; + size_t read_len = libqb_buffer_read(&buffer, read_buf, sizeof(read_buf)); + + length_left -= str_len; + + test_assert_ints_with_name(id, str_len, read_len); + + // Check the prefix, without the number + test_assert_buffers_with_name(id, "FOOBAR", read_buf, str_len - 1); + + // Check the number at the end + test_assert_ints_with_name(id, '1' + i, read_buf[6]); + + test_assert_ints_with_name(id, length_left, libqb_buffer_length(&buffer)); + } + + libqb_buffer_clear(&buffer); +} + +void test_full_read() { + int count = 6; + struct libqb_buffer buffer; + + libqb_buffer_init(&buffer); + const char str[] = "FOOBAR"; + const int str_len = sizeof(str) - 1; + int length = 0; + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + for (int i = 0; i < count; i++) { + char id[20]; + snprintf(id, sizeof(id), "%d", i); + + libqb_buffer_write(&buffer, str, str_len); + + length += str_len; + test_assert_ints_with_name(id, length, libqb_buffer_length(&buffer)); + } + + char full_buf[str_len * count]; + + size_t read_len = libqb_buffer_read(&buffer, full_buf, sizeof(full_buf)); + + test_assert_ints(sizeof(full_buf), read_len); + test_assert_buffers("FOOBAR" "FOOBAR" "FOOBAR" "FOOBAR" "FOOBAR" "FOOBAR", full_buf, sizeof(full_buf)); + + libqb_buffer_clear(&buffer); +} + +void test_read_past_end() { + struct libqb_buffer buffer; + + libqb_buffer_init(&buffer); + const char str[] = "FOOBAR1" "FOOBAR2"; + int str_len = sizeof(str); + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + libqb_buffer_write(&buffer, str, str_len); + + test_assert_ints(str_len, libqb_buffer_length(&buffer)); + + char read_buf[200]; + size_t read_len = libqb_buffer_read(&buffer, read_buf, sizeof(read_buf)); + + test_assert_ints(str_len, read_len); + test_assert_buffers(str, read_buf, str_len); + test_assert_ints(0, libqb_buffer_length(&buffer)); + + read_len = libqb_buffer_read(&buffer, read_buf, sizeof(read_buf)); + + test_assert_ints(0, read_len); + test_assert_ints(0, libqb_buffer_length(&buffer)); + + libqb_buffer_clear(&buffer); +} + +void test_read_write_multiple_partial() { + struct libqb_buffer buffer; + + libqb_buffer_init(&buffer); + const char *strs[] = { + "FOOBAR1", + "FOOBAR2", + "FOOBAR3", + "FOOBAR4", + "FOOBAR5", + "FOOBAR6", + "FOOBAR7", + "FOOBAR8", + "FOOBAR9", + }; + int str_len = 7; + int length = 0; + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + for (int i = 0; i < sizeof(strs) / sizeof(*strs); i++) { + libqb_buffer_write(&buffer, strs[i], str_len); + + length += str_len; + test_assert_ints(length, libqb_buffer_length(&buffer)); + } + + char temp_buf[50]; + size_t read_len; + + read_len = libqb_buffer_read(&buffer, temp_buf, 12); + length -= 12; + + test_assert_ints(12, read_len); + test_assert_ints(length, libqb_buffer_length(&buffer)); + test_assert_buffers("FOOBAR1FOOBA", temp_buf, 12); + + read_len = libqb_buffer_read(&buffer, temp_buf, 20); + length -= 20; + + test_assert_ints(20, read_len); + test_assert_ints(length, libqb_buffer_length(&buffer)); + test_assert_buffers("R2FOOBAR3FOOBAR4FOOB", temp_buf, 20); + + read_len = libqb_buffer_read(&buffer, temp_buf, 25); + length -= 25; + + test_assert_ints(25, read_len); + test_assert_ints(length, libqb_buffer_length(&buffer)); + test_assert_buffers("AR5FOOBAR6FOOBAR7FOOBAR8F", temp_buf, 25); + + // Read past the end, should only read the 6 characters left + read_len = libqb_buffer_read(&buffer, temp_buf, 20); + length -= 6; + + test_assert_ints(6, read_len); + test_assert_ints(length, libqb_buffer_length(&buffer)); + test_assert_buffers("OOBAR9", temp_buf, 6); + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + libqb_buffer_clear(&buffer); +} + +void test_read_write_interweaved() { + struct libqb_buffer buffer; + + libqb_buffer_init(&buffer); + const char *strs[] = { + "FOOBAR1", + "FOOBAR2", + "FOOBAR3", + "FOOBAR4", + "FOOBAR5", + "FOOBAR6", + "FOOBAR7", + "FOOBAR8", + "FOOBAR9", + }; + int str_len = 7; + int length = 0; + char temp_buf[50]; + size_t read_len; + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + // WRITE + libqb_buffer_write(&buffer, "FOOBAR1", 7); + length += 7; + test_assert_ints(length, libqb_buffer_length(&buffer)); + + // WRITE + libqb_buffer_write(&buffer, "FOOBAR2", 7); + length += 7; + test_assert_ints(length, libqb_buffer_length(&buffer)); + + // READ + read_len = libqb_buffer_read(&buffer, temp_buf, 12); + length -= 12; + + test_assert_ints(12, read_len); + test_assert_ints(length, libqb_buffer_length(&buffer)); + test_assert_buffers("FOOBAR1FOOBA", temp_buf, 12); + + // WRITE + libqb_buffer_write(&buffer, "FOOBAR3", 7); + length += 7; + test_assert_ints(length, libqb_buffer_length(&buffer)); + + // READ + read_len = libqb_buffer_read(&buffer, temp_buf, 50); + length -= 9; + + test_assert_ints(9, read_len); + test_assert_ints(length, libqb_buffer_length(&buffer)); + test_assert_buffers("R2FOOBAR3", temp_buf, 9); + + // WRITE + libqb_buffer_write(&buffer, "FOOBAR4", 7); + length += 7; + test_assert_ints(length, libqb_buffer_length(&buffer)); + + // WRITE + libqb_buffer_write(&buffer, "FOOBAR5", 7); + length += 7; + test_assert_ints(length, libqb_buffer_length(&buffer)); + + // READ + read_len = libqb_buffer_read(&buffer, temp_buf, 50); + length -= 14; + + test_assert_ints(14, read_len); + test_assert_ints(length, libqb_buffer_length(&buffer)); + test_assert_buffers("FOOBAR4FOOBAR5", temp_buf, 14); + + test_assert_ints(0, libqb_buffer_length(&buffer)); + + libqb_buffer_clear(&buffer); +} + +int main() { + struct unit_test tests[] = { + { test_single_rw, "test-single-read-write" }, + { test_multiple_rw, "test-multiple-read-write" }, + { test_partial_read, "test-partial-read" }, + { test_full_read, "test-full-read" }, + { test_read_past_end, "test-read-past-end" }, + { test_read_write_multiple_partial, "test-read-write-multiple-partial" }, + { test_read_write_interweaved, "test-read-write-interweaved" }, + }; + + return run_tests("buffer", tests, sizeof(tests) / sizeof(*tests)); +}