From 36dbf86806d0464f494a7da80beffa581e9a5843 Mon Sep 17 00:00:00 2001 From: Katze719 Date: Wed, 28 Jan 2026 19:05:27 +0100 Subject: [PATCH 1/4] test: Add unit tests for serialOpen, serialClose, serialRead, and serialWrite functions --- tests/test_serial_functions.cpp | 669 ++++++++++++++++++++++++++++++++ 1 file changed, 669 insertions(+) create mode 100644 tests/test_serial_functions.cpp diff --git a/tests/test_serial_functions.cpp b/tests/test_serial_functions.cpp new file mode 100644 index 0000000..2d4e9c3 --- /dev/null +++ b/tests/test_serial_functions.cpp @@ -0,0 +1,669 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// Helper to capture error callback +struct ErrorCapture +{ + int last_code = 0; + std::string last_message; + + static void callback(int code, const char *message) + { + if (instance != nullptr) + { + instance->last_code = code; + instance->last_message = message != nullptr ? message : ""; + } + } + + static ErrorCapture *instance; +}; + +ErrorCapture *ErrorCapture::instance = nullptr; + +// ============================================================================ +// Tests for serialOpen +// ============================================================================ + +class SerialOpenTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture_; + error_callback_ = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture_; + ErrorCallbackT error_callback_ = nullptr; +}; + +TEST_F(SerialOpenTest, NullPortParameter) +{ + intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); + EXPECT_NE(error_capture_.last_message.find("nullptr"), std::string::npos); +} + +TEST_F(SerialOpenTest, BaudrateTooLow) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 100, 8, 0, 1, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); + EXPECT_NE(error_capture_.last_message.find("baudrate"), std::string::npos); +} + +TEST_F(SerialOpenTest, BaudrateTooLowBoundary) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 299, 8, 0, 1, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, BaudrateBoundaryValid) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 300, 8, 0, 1, error_callback_); + + // /dev/null is not a real serial port, but should pass baudrate validation + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, DataBitsTooLow) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 4, 0, 1, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); + EXPECT_NE(error_capture_.last_message.find("data bits"), std::string::npos); +} + +TEST_F(SerialOpenTest, DataBitsTooHigh) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 9, 0, 1, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidDataBits5) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 5, 0, 1, error_callback_); + + // Should pass data bits validation + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidDataBits6) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 6, 0, 1, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidDataBits7) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 7, 0, 1, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidDataBits8) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, InvalidParity) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 5, 1, error_callback_); + + // Invalid parity should return an error + EXPECT_LT(result, 0); +} + +TEST_F(SerialOpenTest, ValidParityNone) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidParityEven) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 1, 1, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidParityOdd) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 2, 1, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, InvalidStopBits) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 3, error_callback_); + + // Invalid stop bits should return an error + EXPECT_LT(result, 0); +} + +TEST_F(SerialOpenTest, ValidStopBits0) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 0, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidStopBits1) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidStopBits2) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 2, error_callback_); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, NonExistentPort) +{ + const char *port = "/dev/ttyNONEXISTENT99999"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); +} + +TEST_F(SerialOpenTest, VariousBaudrates) +{ + const char *port = "/dev/null"; + + // Test common baudrates + int baudrates[] = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800}; + + for (int baudrate : baudrates) + { + intptr_t result = + serialOpen(const_cast(static_cast(port)), baudrate, 8, 0, 1, error_callback_); + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)) + << "Baudrate " << baudrate << " should be valid"; + } +} + +TEST_F(SerialOpenTest, NoErrorCallbackNullPort) +{ + intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, nullptr); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); +} + +// ============================================================================ +// Tests for serialClose +// ============================================================================ + +class SerialCloseTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture_; + error_callback_ = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture_; + ErrorCallbackT error_callback_ = nullptr; +}; + +TEST_F(SerialCloseTest, CloseInvalidHandleZero) +{ + int result = serialClose(0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandleNegative) +{ + int result = serialClose(-1, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandleNegativeLarge) +{ + int result = serialClose(-12345, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandleTooLarge) +{ + int64_t too_large_handle = static_cast(std::numeric_limits::max()) + 1; + int result = serialClose(too_large_handle, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandleIntMaxBoundary) +{ + int64_t handle = static_cast(std::numeric_limits::max()); + int result = serialClose(handle, error_callback_); + + // Should fail because this fd doesn't exist, but not with InvalidHandleError + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialCloseTest, CloseNoErrorCallback) +{ + int result = serialClose(0, nullptr); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandle) +{ + // Test closing a real invalid fd (one that never existed) + // We should get an error but not crash + int result = serialClose(9999, error_callback_); + + // This will fail because the fd doesn't exist + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kCloseHandleError)); +} + +// ============================================================================ +// Tests for serialRead +// ============================================================================ + +class SerialReadTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture_; + error_callback_ = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture_; + ErrorCallbackT error_callback_ = nullptr; +}; + +TEST_F(SerialReadTest, ReadNullBuffer) +{ + int result = serialRead(1, nullptr, 10, 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); + EXPECT_NE(error_capture_.last_message.find("buffer"), std::string::npos); +} + +TEST_F(SerialReadTest, ReadZeroBufferSize) +{ + char buffer[10] = {0}; + int result = serialRead(1, buffer, 0, 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); +} + +TEST_F(SerialReadTest, ReadNegativeBufferSize) +{ + char buffer[10] = {0}; + int result = serialRead(1, buffer, -1, 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); +} + +TEST_F(SerialReadTest, ReadInvalidHandleZero) +{ + char buffer[10] = {0}; + int result = serialRead(0, buffer, sizeof(buffer), 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialReadTest, ReadInvalidHandleNegative) +{ + char buffer[10] = {0}; + int result = serialRead(-1, buffer, sizeof(buffer), 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialReadTest, ReadInvalidHandleTooLarge) +{ + char buffer[10] = {0}; + int64_t too_large = static_cast(std::numeric_limits::max()) + 1; + int result = serialRead(too_large, buffer, sizeof(buffer), 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialReadTest, ReadFromDevNull) +{ + int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + char buffer[10] = {0}; + int result = serialRead(fd, buffer, sizeof(buffer), 0, 0, error_callback_); + + EXPECT_EQ(result, 0); + close(fd); +} + +TEST_F(SerialReadTest, ReadWithLargeBufferSize) +{ + int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + char buffer[4096] = {0}; + int result = serialRead(fd, buffer, sizeof(buffer), 0, 0, error_callback_); + + EXPECT_EQ(result, 0); + close(fd); +} + +TEST_F(SerialReadTest, ReadNoErrorCallback) +{ + char buffer[10] = {0}; + int result = serialRead(0, buffer, sizeof(buffer), 100, 0, nullptr); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialReadTest, ReadWithVariousTimeouts) +{ + int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + char buffer[10] = {0}; + + // Test various timeout values + for (int timeout : {0, 1, 10, 100, 1000}) + { + int result = serialRead(fd, buffer, sizeof(buffer), timeout, 0, error_callback_); + EXPECT_EQ(result, 0) << "Timeout " << timeout << " should return 0 for /dev/null"; + } + + close(fd); +} + +// ============================================================================ +// Tests for serialWrite +// ============================================================================ + +class SerialWriteTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture_; + error_callback_ = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture_; + ErrorCallbackT error_callback_ = nullptr; +}; + +TEST_F(SerialWriteTest, WriteNullBuffer) +{ + int result = serialWrite(1, nullptr, 10, 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); + EXPECT_NE(error_capture_.last_message.find("buffer"), std::string::npos); +} + +TEST_F(SerialWriteTest, WriteZeroBufferSize) +{ + char buffer[10] = {0}; + int result = serialWrite(1, buffer, 0, 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); +} + +TEST_F(SerialWriteTest, WriteNegativeBufferSize) +{ + char buffer[10] = {0}; + int result = serialWrite(1, buffer, -1, 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); +} + +TEST_F(SerialWriteTest, WriteInvalidHandleZero) +{ + const char *buffer = "test"; + int result = serialWrite(0, buffer, strlen(buffer), 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialWriteTest, WriteInvalidHandleNegative) +{ + const char *buffer = "test"; + int result = serialWrite(-1, buffer, strlen(buffer), 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialWriteTest, WriteInvalidHandleTooLarge) +{ + const char *buffer = "test"; + int64_t too_large = static_cast(std::numeric_limits::max()) + 1; + int result = serialWrite(too_large, buffer, strlen(buffer), 100, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialWriteTest, WriteToDevNull) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *test_data = "Hello World"; + int result = serialWrite(fd, test_data, strlen(test_data), 0, 0, error_callback_); + + EXPECT_EQ(result, static_cast(strlen(test_data))); + close(fd); +} + +TEST_F(SerialWriteTest, WriteLargeBuffer) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + std::string large_data(4096, 'A'); + int result = serialWrite(fd, large_data.c_str(), large_data.size(), 0, 0, error_callback_); + + EXPECT_EQ(result, static_cast(large_data.size())); + close(fd); +} + +TEST_F(SerialWriteTest, WriteMultipleSmallBuffers) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + for (int i = 0; i < 10; ++i) + { + const char *data = "test"; + int result = serialWrite(fd, data, strlen(data), 0, 0, error_callback_); + EXPECT_EQ(result, static_cast(strlen(data))); + } + + close(fd); +} + +TEST_F(SerialWriteTest, WriteNoErrorCallback) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *test_data = "test"; + int result = serialWrite(fd, test_data, strlen(test_data), 0, 0, nullptr); + + EXPECT_EQ(result, static_cast(strlen(test_data))); + close(fd); +} + +TEST_F(SerialWriteTest, WriteWithVariousTimeouts) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *test_data = "test"; + + // Test various timeout values + for (int timeout : {0, 1, 10, 100, 1000}) + { + int result = serialWrite(fd, test_data, strlen(test_data), timeout, 0, error_callback_); + EXPECT_EQ(result, static_cast(strlen(test_data))) + << "Timeout " << timeout << " should succeed for /dev/null"; + } + + close(fd); +} + +TEST_F(SerialWriteTest, WriteEmptyStringToDevNull) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *empty = ""; + // This should fail because buffer_size is 0 + int result = serialWrite(fd, empty, 0, 0, 0, error_callback_); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); + close(fd); +} + +// ============================================================================ +// Integration Tests +// ============================================================================ + +class SerialIntegrationTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture_; + error_callback_ = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture_; + ErrorCallbackT error_callback_ = nullptr; +}; + +TEST_F(SerialIntegrationTest, ReadWritePipeRoundTrip) +{ + int pipefd[2]; + ASSERT_EQ(pipe(pipefd), 0); + + // Set non-blocking + fcntl(pipefd[0], F_SETFL, O_NONBLOCK); + fcntl(pipefd[1], F_SETFL, O_NONBLOCK); + + const char *test_message = "Hello"; + int write_result = serialWrite(pipefd[1], test_message, strlen(test_message), 100, 0, error_callback_); + EXPECT_EQ(write_result, static_cast(strlen(test_message))); + + char read_buffer[10] = {0}; + int read_result = serialRead(pipefd[0], read_buffer, sizeof(read_buffer), 100, 0, error_callback_); + EXPECT_EQ(read_result, static_cast(strlen(test_message))); + EXPECT_EQ(std::string(read_buffer), std::string(test_message)); + + close(pipefd[0]); + close(pipefd[1]); +} + +TEST_F(SerialIntegrationTest, MultipleWrites) +{ + int pipefd[2]; + ASSERT_EQ(pipe(pipefd), 0); + + fcntl(pipefd[0], F_SETFL, O_NONBLOCK); + fcntl(pipefd[1], F_SETFL, O_NONBLOCK); + + const char *msg1 = "Hello"; + const char *msg2 = "World"; + + serialWrite(pipefd[1], msg1, strlen(msg1), 100, 0, error_callback_); + serialWrite(pipefd[1], msg2, strlen(msg2), 100, 0, error_callback_); + + char read_buffer[20] = {0}; + int read_result = serialRead(pipefd[0], read_buffer, sizeof(read_buffer), 100, 0, error_callback_); + EXPECT_GE(read_result, 0); + + close(pipefd[0]); + close(pipefd[1]); +} + +TEST_F(SerialIntegrationTest, CloseAfterOperations) +{ + int pipefd[2]; + ASSERT_EQ(pipe(pipefd), 0); + + const char *test_data = "test"; + serialWrite(pipefd[1], test_data, strlen(test_data), 100, 0, error_callback_); + + char buffer[10] = {0}; + serialRead(pipefd[0], buffer, sizeof(buffer), 100, 0, error_callback_); + + int close_result1 = serialClose(pipefd[0], error_callback_); + int close_result2 = serialClose(pipefd[1], error_callback_); + + EXPECT_EQ(close_result1, static_cast(cpp_core::StatusCodes::kSuccess)); + EXPECT_EQ(close_result2, static_cast(cpp_core::StatusCodes::kSuccess)); +} From 9967cecfa415871b6ed58ae8098e163e0b7b9522 Mon Sep 17 00:00:00 2001 From: Katze719 Date: Wed, 28 Jan 2026 19:17:53 +0100 Subject: [PATCH 2/4] fix warnings --- tests/test_serial_functions.cpp | 249 +++++++++++++++++--------------- 1 file changed, 130 insertions(+), 119 deletions(-) diff --git a/tests/test_serial_functions.cpp b/tests/test_serial_functions.cpp index 2d4e9c3..d11bce9 100644 --- a/tests/test_serial_functions.cpp +++ b/tests/test_serial_functions.cpp @@ -3,14 +3,18 @@ #include #include #include -#include -#include +#include #include #include +#include +#include #include #include +#include +#include + // Helper to capture error callback struct ErrorCapture { @@ -40,8 +44,8 @@ class SerialOpenTest : public ::testing::Test protected: void SetUp() override { - ErrorCapture::instance = &error_capture_; - error_callback_ = &ErrorCapture::callback; + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; } void TearDown() override @@ -49,31 +53,31 @@ class SerialOpenTest : public ::testing::Test ErrorCapture::instance = nullptr; } - ErrorCapture error_capture_; - ErrorCallbackT error_callback_ = nullptr; + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; }; TEST_F(SerialOpenTest, NullPortParameter) { - intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, error_callback_); + intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); - EXPECT_NE(error_capture_.last_message.find("nullptr"), std::string::npos); + EXPECT_NE(error_capture.last_message.find("nullptr"), std::string::npos); } TEST_F(SerialOpenTest, BaudrateTooLow) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 100, 8, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 100, 8, 0, 1, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); - EXPECT_NE(error_capture_.last_message.find("baudrate"), std::string::npos); + EXPECT_NE(error_capture.last_message.find("baudrate"), std::string::npos); } TEST_F(SerialOpenTest, BaudrateTooLowBoundary) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 299, 8, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 299, 8, 0, 1, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -81,7 +85,7 @@ TEST_F(SerialOpenTest, BaudrateTooLowBoundary) TEST_F(SerialOpenTest, BaudrateBoundaryValid) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 300, 8, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 300, 8, 0, 1, error_callback); // /dev/null is not a real serial port, but should pass baudrate validation EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); @@ -90,16 +94,16 @@ TEST_F(SerialOpenTest, BaudrateBoundaryValid) TEST_F(SerialOpenTest, DataBitsTooLow) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 4, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 4, 0, 1, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); - EXPECT_NE(error_capture_.last_message.find("data bits"), std::string::npos); + EXPECT_NE(error_capture.last_message.find("data bits"), std::string::npos); } TEST_F(SerialOpenTest, DataBitsTooHigh) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 9, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 9, 0, 1, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -107,7 +111,7 @@ TEST_F(SerialOpenTest, DataBitsTooHigh) TEST_F(SerialOpenTest, ValidDataBits5) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 5, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 5, 0, 1, error_callback); // Should pass data bits validation EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); @@ -116,7 +120,7 @@ TEST_F(SerialOpenTest, ValidDataBits5) TEST_F(SerialOpenTest, ValidDataBits6) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 6, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 6, 0, 1, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -124,7 +128,7 @@ TEST_F(SerialOpenTest, ValidDataBits6) TEST_F(SerialOpenTest, ValidDataBits7) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 7, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 7, 0, 1, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -132,7 +136,7 @@ TEST_F(SerialOpenTest, ValidDataBits7) TEST_F(SerialOpenTest, ValidDataBits8) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -140,7 +144,7 @@ TEST_F(SerialOpenTest, ValidDataBits8) TEST_F(SerialOpenTest, InvalidParity) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 5, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 5, 1, error_callback); // Invalid parity should return an error EXPECT_LT(result, 0); @@ -149,7 +153,7 @@ TEST_F(SerialOpenTest, InvalidParity) TEST_F(SerialOpenTest, ValidParityNone) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -157,7 +161,7 @@ TEST_F(SerialOpenTest, ValidParityNone) TEST_F(SerialOpenTest, ValidParityEven) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 1, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 1, 1, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -165,7 +169,7 @@ TEST_F(SerialOpenTest, ValidParityEven) TEST_F(SerialOpenTest, ValidParityOdd) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 2, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 2, 1, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -173,7 +177,7 @@ TEST_F(SerialOpenTest, ValidParityOdd) TEST_F(SerialOpenTest, InvalidStopBits) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 3, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 3, error_callback); // Invalid stop bits should return an error EXPECT_LT(result, 0); @@ -182,7 +186,7 @@ TEST_F(SerialOpenTest, InvalidStopBits) TEST_F(SerialOpenTest, ValidStopBits0) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 0, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 0, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -190,7 +194,7 @@ TEST_F(SerialOpenTest, ValidStopBits0) TEST_F(SerialOpenTest, ValidStopBits1) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -198,7 +202,7 @@ TEST_F(SerialOpenTest, ValidStopBits1) TEST_F(SerialOpenTest, ValidStopBits2) { const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 2, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 2, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); } @@ -206,7 +210,7 @@ TEST_F(SerialOpenTest, ValidStopBits2) TEST_F(SerialOpenTest, NonExistentPort) { const char *port = "/dev/ttyNONEXISTENT99999"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback_); + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); } @@ -216,12 +220,12 @@ TEST_F(SerialOpenTest, VariousBaudrates) const char *port = "/dev/null"; // Test common baudrates - int baudrates[] = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800}; + const std::array baudrates = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800}; for (int baudrate : baudrates) { intptr_t result = - serialOpen(const_cast(static_cast(port)), baudrate, 8, 0, 1, error_callback_); + serialOpen(const_cast(static_cast(port)), baudrate, 8, 0, 1, error_callback); EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)) << "Baudrate " << baudrate << " should be valid"; } @@ -243,8 +247,8 @@ class SerialCloseTest : public ::testing::Test protected: void SetUp() override { - ErrorCapture::instance = &error_capture_; - error_callback_ = &ErrorCapture::callback; + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; } void TearDown() override @@ -252,43 +256,43 @@ class SerialCloseTest : public ::testing::Test ErrorCapture::instance = nullptr; } - ErrorCapture error_capture_; - ErrorCallbackT error_callback_ = nullptr; + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; }; TEST_F(SerialCloseTest, CloseInvalidHandleZero) { - int result = serialClose(0, error_callback_); + int result = serialClose(0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); } TEST_F(SerialCloseTest, CloseInvalidHandleNegative) { - int result = serialClose(-1, error_callback_); + int result = serialClose(-1, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); } TEST_F(SerialCloseTest, CloseInvalidHandleNegativeLarge) { - int result = serialClose(-12345, error_callback_); + int result = serialClose(-12345, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); } TEST_F(SerialCloseTest, CloseInvalidHandleTooLarge) { - int64_t too_large_handle = static_cast(std::numeric_limits::max()) + 1; - int result = serialClose(too_large_handle, error_callback_); + auto too_large_handle = static_cast(std::numeric_limits::max()) + 1; + int result = serialClose(too_large_handle, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); } TEST_F(SerialCloseTest, CloseInvalidHandleIntMaxBoundary) { - int64_t handle = static_cast(std::numeric_limits::max()); - int result = serialClose(handle, error_callback_); + auto handle = static_cast(std::numeric_limits::max()); + int result = serialClose(handle, error_callback); // Should fail because this fd doesn't exist, but not with InvalidHandleError EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); @@ -305,7 +309,7 @@ TEST_F(SerialCloseTest, CloseInvalidHandle) { // Test closing a real invalid fd (one that never existed) // We should get an error but not crash - int result = serialClose(9999, error_callback_); + int result = serialClose(9999, error_callback); // This will fail because the fd doesn't exist EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kCloseHandleError)); @@ -320,8 +324,8 @@ class SerialReadTest : public ::testing::Test protected: void SetUp() override { - ErrorCapture::instance = &error_capture_; - error_callback_ = &ErrorCapture::callback; + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; } void TearDown() override @@ -329,55 +333,55 @@ class SerialReadTest : public ::testing::Test ErrorCapture::instance = nullptr; } - ErrorCapture error_capture_; - ErrorCallbackT error_callback_ = nullptr; + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; }; TEST_F(SerialReadTest, ReadNullBuffer) { - int result = serialRead(1, nullptr, 10, 100, 0, error_callback_); + int result = serialRead(1, nullptr, 10, 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); - EXPECT_NE(error_capture_.last_message.find("buffer"), std::string::npos); + EXPECT_NE(error_capture.last_message.find("buffer"), std::string::npos); } TEST_F(SerialReadTest, ReadZeroBufferSize) { - char buffer[10] = {0}; - int result = serialRead(1, buffer, 0, 100, 0, error_callback_); + std::array buffer{}; + int result = serialRead(1, buffer.data(), 0, 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); } TEST_F(SerialReadTest, ReadNegativeBufferSize) { - char buffer[10] = {0}; - int result = serialRead(1, buffer, -1, 100, 0, error_callback_); + std::array buffer{}; + int result = serialRead(1, buffer.data(), -1, 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); } TEST_F(SerialReadTest, ReadInvalidHandleZero) { - char buffer[10] = {0}; - int result = serialRead(0, buffer, sizeof(buffer), 100, 0, error_callback_); + std::array buffer{}; + int result = serialRead(0, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); } TEST_F(SerialReadTest, ReadInvalidHandleNegative) { - char buffer[10] = {0}; - int result = serialRead(-1, buffer, sizeof(buffer), 100, 0, error_callback_); + std::array buffer{}; + int result = serialRead(-1, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); } TEST_F(SerialReadTest, ReadInvalidHandleTooLarge) { - char buffer[10] = {0}; - int64_t too_large = static_cast(std::numeric_limits::max()) + 1; - int result = serialRead(too_large, buffer, sizeof(buffer), 100, 0, error_callback_); + std::array buffer{}; + auto too_large = static_cast(std::numeric_limits::max()) + 1; + int result = serialRead(too_large, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); } @@ -387,8 +391,8 @@ TEST_F(SerialReadTest, ReadFromDevNull) int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); ASSERT_GE(fd, 0); - char buffer[10] = {0}; - int result = serialRead(fd, buffer, sizeof(buffer), 0, 0, error_callback_); + std::array buffer{}; + int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), 0, 0, error_callback); EXPECT_EQ(result, 0); close(fd); @@ -399,8 +403,8 @@ TEST_F(SerialReadTest, ReadWithLargeBufferSize) int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); ASSERT_GE(fd, 0); - char buffer[4096] = {0}; - int result = serialRead(fd, buffer, sizeof(buffer), 0, 0, error_callback_); + std::array buffer{}; + int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), 0, 0, error_callback); EXPECT_EQ(result, 0); close(fd); @@ -408,8 +412,8 @@ TEST_F(SerialReadTest, ReadWithLargeBufferSize) TEST_F(SerialReadTest, ReadNoErrorCallback) { - char buffer[10] = {0}; - int result = serialRead(0, buffer, sizeof(buffer), 100, 0, nullptr); + std::array buffer{}; + int result = serialRead(0, buffer.data(), static_cast(buffer.size()), 100, 0, nullptr); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); } @@ -419,12 +423,12 @@ TEST_F(SerialReadTest, ReadWithVariousTimeouts) int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); ASSERT_GE(fd, 0); - char buffer[10] = {0}; + std::array buffer{}; // Test various timeout values for (int timeout : {0, 1, 10, 100, 1000}) { - int result = serialRead(fd, buffer, sizeof(buffer), timeout, 0, error_callback_); + int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), timeout, 0, error_callback); EXPECT_EQ(result, 0) << "Timeout " << timeout << " should return 0 for /dev/null"; } @@ -440,8 +444,8 @@ class SerialWriteTest : public ::testing::Test protected: void SetUp() override { - ErrorCapture::instance = &error_capture_; - error_callback_ = &ErrorCapture::callback; + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; } void TearDown() override @@ -449,30 +453,30 @@ class SerialWriteTest : public ::testing::Test ErrorCapture::instance = nullptr; } - ErrorCapture error_capture_; - ErrorCallbackT error_callback_ = nullptr; + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; }; TEST_F(SerialWriteTest, WriteNullBuffer) { - int result = serialWrite(1, nullptr, 10, 100, 0, error_callback_); + int result = serialWrite(1, nullptr, 10, 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); - EXPECT_NE(error_capture_.last_message.find("buffer"), std::string::npos); + EXPECT_NE(error_capture.last_message.find("buffer"), std::string::npos); } TEST_F(SerialWriteTest, WriteZeroBufferSize) { - char buffer[10] = {0}; - int result = serialWrite(1, buffer, 0, 100, 0, error_callback_); + std::array buffer{}; + int result = serialWrite(1, buffer.data(), 0, 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); } TEST_F(SerialWriteTest, WriteNegativeBufferSize) { - char buffer[10] = {0}; - int result = serialWrite(1, buffer, -1, 100, 0, error_callback_); + std::array buffer{}; + int result = serialWrite(1, buffer.data(), -1, 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); } @@ -480,7 +484,7 @@ TEST_F(SerialWriteTest, WriteNegativeBufferSize) TEST_F(SerialWriteTest, WriteInvalidHandleZero) { const char *buffer = "test"; - int result = serialWrite(0, buffer, strlen(buffer), 100, 0, error_callback_); + int result = serialWrite(0, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); } @@ -488,7 +492,7 @@ TEST_F(SerialWriteTest, WriteInvalidHandleZero) TEST_F(SerialWriteTest, WriteInvalidHandleNegative) { const char *buffer = "test"; - int result = serialWrite(-1, buffer, strlen(buffer), 100, 0, error_callback_); + int result = serialWrite(-1, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); } @@ -496,8 +500,8 @@ TEST_F(SerialWriteTest, WriteInvalidHandleNegative) TEST_F(SerialWriteTest, WriteInvalidHandleTooLarge) { const char *buffer = "test"; - int64_t too_large = static_cast(std::numeric_limits::max()) + 1; - int result = serialWrite(too_large, buffer, strlen(buffer), 100, 0, error_callback_); + auto too_large = static_cast(std::numeric_limits::max()) + 1; + int result = serialWrite(too_large, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); } @@ -508,9 +512,10 @@ TEST_F(SerialWriteTest, WriteToDevNull) ASSERT_GE(fd, 0); const char *test_data = "Hello World"; - int result = serialWrite(fd, test_data, strlen(test_data), 0, 0, error_callback_); + const int len = static_cast(strlen(test_data)); + int result = serialWrite(fd, test_data, len, 0, 0, error_callback); - EXPECT_EQ(result, static_cast(strlen(test_data))); + EXPECT_EQ(result, len); close(fd); } @@ -520,9 +525,10 @@ TEST_F(SerialWriteTest, WriteLargeBuffer) ASSERT_GE(fd, 0); std::string large_data(4096, 'A'); - int result = serialWrite(fd, large_data.c_str(), large_data.size(), 0, 0, error_callback_); + const int len = static_cast(large_data.size()); + int result = serialWrite(fd, large_data.c_str(), len, 0, 0, error_callback); - EXPECT_EQ(result, static_cast(large_data.size())); + EXPECT_EQ(result, len); close(fd); } @@ -531,11 +537,12 @@ TEST_F(SerialWriteTest, WriteMultipleSmallBuffers) int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); ASSERT_GE(fd, 0); + const char *data = "test"; + const int len = static_cast(strlen(data)); for (int i = 0; i < 10; ++i) { - const char *data = "test"; - int result = serialWrite(fd, data, strlen(data), 0, 0, error_callback_); - EXPECT_EQ(result, static_cast(strlen(data))); + int result = serialWrite(fd, data, len, 0, 0, error_callback); + EXPECT_EQ(result, len); } close(fd); @@ -547,9 +554,10 @@ TEST_F(SerialWriteTest, WriteNoErrorCallback) ASSERT_GE(fd, 0); const char *test_data = "test"; - int result = serialWrite(fd, test_data, strlen(test_data), 0, 0, nullptr); + const int len = static_cast(strlen(test_data)); + int result = serialWrite(fd, test_data, len, 0, 0, nullptr); - EXPECT_EQ(result, static_cast(strlen(test_data))); + EXPECT_EQ(result, len); close(fd); } @@ -559,13 +567,13 @@ TEST_F(SerialWriteTest, WriteWithVariousTimeouts) ASSERT_GE(fd, 0); const char *test_data = "test"; + const int len = static_cast(strlen(test_data)); // Test various timeout values for (int timeout : {0, 1, 10, 100, 1000}) { - int result = serialWrite(fd, test_data, strlen(test_data), timeout, 0, error_callback_); - EXPECT_EQ(result, static_cast(strlen(test_data))) - << "Timeout " << timeout << " should succeed for /dev/null"; + int result = serialWrite(fd, test_data, len, timeout, 0, error_callback); + EXPECT_EQ(result, len) << "Timeout " << timeout << " should succeed for /dev/null"; } close(fd); @@ -578,7 +586,7 @@ TEST_F(SerialWriteTest, WriteEmptyStringToDevNull) const char *empty = ""; // This should fail because buffer_size is 0 - int result = serialWrite(fd, empty, 0, 0, 0, error_callback_); + int result = serialWrite(fd, empty, 0, 0, 0, error_callback); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); close(fd); @@ -593,8 +601,8 @@ class SerialIntegrationTest : public ::testing::Test protected: void SetUp() override { - ErrorCapture::instance = &error_capture_; - error_callback_ = &ErrorCapture::callback; + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; } void TearDown() override @@ -602,27 +610,29 @@ class SerialIntegrationTest : public ::testing::Test ErrorCapture::instance = nullptr; } - ErrorCapture error_capture_; - ErrorCallbackT error_callback_ = nullptr; + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; }; TEST_F(SerialIntegrationTest, ReadWritePipeRoundTrip) { - int pipefd[2]; - ASSERT_EQ(pipe(pipefd), 0); + std::array pipefd{}; + ASSERT_EQ(pipe(pipefd.data()), 0); // Set non-blocking fcntl(pipefd[0], F_SETFL, O_NONBLOCK); fcntl(pipefd[1], F_SETFL, O_NONBLOCK); const char *test_message = "Hello"; - int write_result = serialWrite(pipefd[1], test_message, strlen(test_message), 100, 0, error_callback_); - EXPECT_EQ(write_result, static_cast(strlen(test_message))); + const int msg_len = static_cast(strlen(test_message)); + int write_result = serialWrite(pipefd[1], test_message, msg_len, 100, 0, error_callback); + EXPECT_EQ(write_result, msg_len); - char read_buffer[10] = {0}; - int read_result = serialRead(pipefd[0], read_buffer, sizeof(read_buffer), 100, 0, error_callback_); - EXPECT_EQ(read_result, static_cast(strlen(test_message))); - EXPECT_EQ(std::string(read_buffer), std::string(test_message)); + std::array read_buffer{}; + int read_result = + serialRead(pipefd[0], read_buffer.data(), static_cast(read_buffer.size()), 100, 0, error_callback); + EXPECT_EQ(read_result, msg_len); + EXPECT_EQ(std::string(read_buffer.data()), std::string(test_message)); close(pipefd[0]); close(pipefd[1]); @@ -630,8 +640,8 @@ TEST_F(SerialIntegrationTest, ReadWritePipeRoundTrip) TEST_F(SerialIntegrationTest, MultipleWrites) { - int pipefd[2]; - ASSERT_EQ(pipe(pipefd), 0); + std::array pipefd{}; + ASSERT_EQ(pipe(pipefd.data()), 0); fcntl(pipefd[0], F_SETFL, O_NONBLOCK); fcntl(pipefd[1], F_SETFL, O_NONBLOCK); @@ -639,11 +649,12 @@ TEST_F(SerialIntegrationTest, MultipleWrites) const char *msg1 = "Hello"; const char *msg2 = "World"; - serialWrite(pipefd[1], msg1, strlen(msg1), 100, 0, error_callback_); - serialWrite(pipefd[1], msg2, strlen(msg2), 100, 0, error_callback_); + serialWrite(pipefd[1], msg1, static_cast(strlen(msg1)), 100, 0, error_callback); + serialWrite(pipefd[1], msg2, static_cast(strlen(msg2)), 100, 0, error_callback); - char read_buffer[20] = {0}; - int read_result = serialRead(pipefd[0], read_buffer, sizeof(read_buffer), 100, 0, error_callback_); + std::array read_buffer{}; + int read_result = + serialRead(pipefd[0], read_buffer.data(), static_cast(read_buffer.size()), 100, 0, error_callback); EXPECT_GE(read_result, 0); close(pipefd[0]); @@ -652,17 +663,17 @@ TEST_F(SerialIntegrationTest, MultipleWrites) TEST_F(SerialIntegrationTest, CloseAfterOperations) { - int pipefd[2]; - ASSERT_EQ(pipe(pipefd), 0); + std::array pipefd{}; + ASSERT_EQ(pipe(pipefd.data()), 0); const char *test_data = "test"; - serialWrite(pipefd[1], test_data, strlen(test_data), 100, 0, error_callback_); + serialWrite(pipefd[1], test_data, static_cast(strlen(test_data)), 100, 0, error_callback); - char buffer[10] = {0}; - serialRead(pipefd[0], buffer, sizeof(buffer), 100, 0, error_callback_); + std::array buffer{}; + serialRead(pipefd[0], buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); - int close_result1 = serialClose(pipefd[0], error_callback_); - int close_result2 = serialClose(pipefd[1], error_callback_); + int close_result1 = serialClose(pipefd[0], error_callback); + int close_result2 = serialClose(pipefd[1], error_callback); EXPECT_EQ(close_result1, static_cast(cpp_core::StatusCodes::kSuccess)); EXPECT_EQ(close_result2, static_cast(cpp_core::StatusCodes::kSuccess)); From d2bf98d2fc7fcc4090a1fe3e2a3c3147e12a2614 Mon Sep 17 00:00:00 2001 From: Katze719 Date: Wed, 28 Jan 2026 21:04:28 +0100 Subject: [PATCH 3/4] refactor: Update CMakeLists.txt to refine source file inclusion and add new unit tests - Excluded test files and helpers from library source files in CMakeLists.txt. - Added unit tests for serialClose, serialOpen, serialRead, and serialWrite functions. - Introduced error capture mechanism for better error handling in tests. - Implemented integration tests for serial communication with Arduino and pipe round trips. - Removed outdated test_serial_functions.cpp file. --- CMakeLists.txt | 19 +- src/serial_close.test.cpp | 85 +++ src/serial_open.test.cpp | 214 ++++++ src/serial_read.test.cpp | 131 ++++ src/serial_write.test.cpp | 170 +++++ src/test_helpers/error_capture.cpp | 12 + src/test_helpers/error_capture.hpp | 16 + tests/integration.test.cpp | 102 +++ ...al_arduino.cpp => serial_arduino.test.cpp} | 52 +- tests/test_serial_functions.cpp | 680 ------------------ 10 files changed, 767 insertions(+), 714 deletions(-) create mode 100644 src/serial_close.test.cpp create mode 100644 src/serial_open.test.cpp create mode 100644 src/serial_read.test.cpp create mode 100644 src/serial_write.test.cpp create mode 100644 src/test_helpers/error_capture.cpp create mode 100644 src/test_helpers/error_capture.hpp create mode 100644 tests/integration.test.cpp rename tests/{test_serial_arduino.cpp => serial_arduino.test.cpp} (57%) delete mode 100644 tests/test_serial_functions.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 60b49e3..b17a2a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,10 +57,10 @@ CPMAddPackage( "gtest_force_shared_crt ON" ) -file( - GLOB_RECURSE LIB_SOURCES - "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp" -) +# Library sources: src/*.cpp only, exclude *.test.cpp and test_helpers/ +file(GLOB_RECURSE LIB_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +list(FILTER LIB_SOURCES EXCLUDE REGEX ".*\\.test\\.cpp$") +list(FILTER LIB_SOURCES EXCLUDE REGEX ".*/test_helpers/.*") add_library(cpp_bindings_linux SHARED ${LIB_SOURCES}) @@ -88,11 +88,11 @@ target_link_libraries( target_compile_features(cpp_bindings_linux PUBLIC cxx_std_23) -# Collect all test source files -file( - GLOB_RECURSE TEST_SOURCES - "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp" -) +# Test sources: src/*.test.cpp, tests/*.test.cpp, src/test_helpers/*.cpp (helpers excluded from lib) +file(GLOB SRC_UNIT_TESTS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.test.cpp") +file(GLOB TESTS_INTEGRATION "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.test.cpp") +file(GLOB TEST_HELPER_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/test_helpers/*.cpp") +set(TEST_SOURCES ${SRC_UNIT_TESTS} ${TESTS_INTEGRATION} ${TEST_HELPER_SOURCES}) if(TEST_SOURCES) add_executable(cpp_bindings_linux_tests ${TEST_SOURCES}) @@ -101,6 +101,7 @@ if(TEST_SOURCES) cpp_bindings_linux_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_BINARY_DIR}/generated ) diff --git a/src/serial_close.test.cpp b/src/serial_close.test.cpp new file mode 100644 index 0000000..e34a8b8 --- /dev/null +++ b/src/serial_close.test.cpp @@ -0,0 +1,85 @@ +#include +#include + +#include + +#include + +#include "test_helpers/error_capture.hpp" + +// ============================================================================ +// Tests for serialClose +// ============================================================================ + +class SerialCloseTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; +}; + +TEST_F(SerialCloseTest, CloseInvalidHandleZero) +{ + int result = serialClose(0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandleNegative) +{ + int result = serialClose(-1, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandleNegativeLarge) +{ + int result = serialClose(-12345, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandleTooLarge) +{ + auto too_large_handle = static_cast(std::numeric_limits::max()) + 1; + int result = serialClose(too_large_handle, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandleIntMaxBoundary) +{ + auto handle = static_cast(std::numeric_limits::max()); + int result = serialClose(handle, error_callback); + + // Should fail because this fd doesn't exist, but not with InvalidHandleError + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialCloseTest, CloseNoErrorCallback) +{ + int result = serialClose(0, nullptr); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); +} + +TEST_F(SerialCloseTest, CloseInvalidHandle) +{ + // Test closing a real invalid fd (one that never existed) + // We should get an error but not crash + int result = serialClose(9999, error_callback); + + // This will fail because the fd doesn't exist + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kCloseHandleError)); +} diff --git a/src/serial_open.test.cpp b/src/serial_open.test.cpp new file mode 100644 index 0000000..6fdce3c --- /dev/null +++ b/src/serial_open.test.cpp @@ -0,0 +1,214 @@ +#include +#include + +#include +#include +#include + +#include +#include + +#include "test_helpers/error_capture.hpp" + +// ============================================================================ +// Tests for serialOpen +// ============================================================================ + +class SerialOpenTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; +}; + +TEST_F(SerialOpenTest, NullPortParameter) +{ + intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); + EXPECT_NE(error_capture.last_message.find("nullptr"), std::string::npos); +} + +TEST_F(SerialOpenTest, BaudrateTooLow) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 100, 8, 0, 1, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); + EXPECT_NE(error_capture.last_message.find("baudrate"), std::string::npos); +} + +TEST_F(SerialOpenTest, BaudrateTooLowBoundary) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 299, 8, 0, 1, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, BaudrateBoundaryValid) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 300, 8, 0, 1, error_callback); + + // /dev/null is not a real serial port, but should pass baudrate validation + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, DataBitsTooLow) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 4, 0, 1, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); + EXPECT_NE(error_capture.last_message.find("data bits"), std::string::npos); +} + +TEST_F(SerialOpenTest, DataBitsTooHigh) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 9, 0, 1, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidDataBits5) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 5, 0, 1, error_callback); + + // Should pass data bits validation + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidDataBits6) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 6, 0, 1, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidDataBits7) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 7, 0, 1, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidDataBits8) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, InvalidParity) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 5, 1, error_callback); + + // Invalid parity should return an error + EXPECT_LT(result, 0); +} + +TEST_F(SerialOpenTest, ValidParityNone) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidParityEven) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 1, 1, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidParityOdd) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 2, 1, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, InvalidStopBits) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 3, error_callback); + + // Invalid stop bits should return an error + EXPECT_LT(result, 0); +} + +TEST_F(SerialOpenTest, ValidStopBits0) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 0, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidStopBits1) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, ValidStopBits2) +{ + const char *port = "/dev/null"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 2, error_callback); + + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); +} + +TEST_F(SerialOpenTest, NonExistentPort) +{ + const char *port = "/dev/ttyNONEXISTENT99999"; + intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); +} + +TEST_F(SerialOpenTest, VariousBaudrates) +{ + const char *port = "/dev/null"; + + // Test common baudrates + const std::array baudrates = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800}; + + for (int baudrate : baudrates) + { + intptr_t result = + serialOpen(const_cast(static_cast(port)), baudrate, 8, 0, 1, error_callback); + EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)) + << "Baudrate " << baudrate << " should be valid"; + } +} + +TEST_F(SerialOpenTest, NoErrorCallbackNullPort) +{ + intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, nullptr); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); +} diff --git a/src/serial_read.test.cpp b/src/serial_read.test.cpp new file mode 100644 index 0000000..fbea49f --- /dev/null +++ b/src/serial_read.test.cpp @@ -0,0 +1,131 @@ +#include +#include + +#include +#include +#include +#include + +#include + +#include "test_helpers/error_capture.hpp" + +// ============================================================================ +// Tests for serialRead +// ============================================================================ + +class SerialReadTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; +}; + +TEST_F(SerialReadTest, ReadNullBuffer) +{ + int result = serialRead(1, nullptr, 10, 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); + EXPECT_NE(error_capture.last_message.find("buffer"), std::string::npos); +} + +TEST_F(SerialReadTest, ReadZeroBufferSize) +{ + std::array buffer{}; + int result = serialRead(1, buffer.data(), 0, 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); +} + +TEST_F(SerialReadTest, ReadNegativeBufferSize) +{ + std::array buffer{}; + int result = serialRead(1, buffer.data(), -1, 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); +} + +TEST_F(SerialReadTest, ReadInvalidHandleZero) +{ + std::array buffer{}; + int result = serialRead(0, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialReadTest, ReadInvalidHandleNegative) +{ + std::array buffer{}; + int result = serialRead(-1, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialReadTest, ReadInvalidHandleTooLarge) +{ + std::array buffer{}; + auto too_large = static_cast(std::numeric_limits::max()) + 1; + int result = serialRead(too_large, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialReadTest, ReadFromDevNull) +{ + int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + std::array buffer{}; + int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), 0, 0, error_callback); + + EXPECT_EQ(result, 0); + close(fd); +} + +TEST_F(SerialReadTest, ReadWithLargeBufferSize) +{ + int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + std::array buffer{}; + int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), 0, 0, error_callback); + + EXPECT_EQ(result, 0); + close(fd); +} + +TEST_F(SerialReadTest, ReadNoErrorCallback) +{ + std::array buffer{}; + int result = serialRead(0, buffer.data(), static_cast(buffer.size()), 100, 0, nullptr); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialReadTest, ReadWithVariousTimeouts) +{ + int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + std::array buffer{}; + + // Test various timeout values + for (int timeout : {0, 1, 10, 100, 1000}) + { + int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), timeout, 0, error_callback); + EXPECT_EQ(result, 0) << "Timeout " << timeout << " should return 0 for /dev/null"; + } + + close(fd); +} diff --git a/src/serial_write.test.cpp b/src/serial_write.test.cpp new file mode 100644 index 0000000..b380403 --- /dev/null +++ b/src/serial_write.test.cpp @@ -0,0 +1,170 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "test_helpers/error_capture.hpp" + +// ============================================================================ +// Tests for serialWrite +// ============================================================================ + +class SerialWriteTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; +}; + +TEST_F(SerialWriteTest, WriteNullBuffer) +{ + int result = serialWrite(1, nullptr, 10, 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); + EXPECT_NE(error_capture.last_message.find("buffer"), std::string::npos); +} + +TEST_F(SerialWriteTest, WriteZeroBufferSize) +{ + std::array buffer{}; + int result = serialWrite(1, buffer.data(), 0, 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); +} + +TEST_F(SerialWriteTest, WriteNegativeBufferSize) +{ + std::array buffer{}; + int result = serialWrite(1, buffer.data(), -1, 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); +} + +TEST_F(SerialWriteTest, WriteInvalidHandleZero) +{ + const char *buffer = "test"; + int result = serialWrite(0, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialWriteTest, WriteInvalidHandleNegative) +{ + const char *buffer = "test"; + int result = serialWrite(-1, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialWriteTest, WriteInvalidHandleTooLarge) +{ + const char *buffer = "test"; + auto too_large = static_cast(std::numeric_limits::max()) + 1; + int result = serialWrite(too_large, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); +} + +TEST_F(SerialWriteTest, WriteToDevNull) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *test_data = "Hello World"; + const int len = static_cast(strlen(test_data)); + int result = serialWrite(fd, test_data, len, 0, 0, error_callback); + + EXPECT_EQ(result, len); + close(fd); +} + +TEST_F(SerialWriteTest, WriteLargeBuffer) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + std::string large_data(4096, 'A'); + const int len = static_cast(large_data.size()); + int result = serialWrite(fd, large_data.c_str(), len, 0, 0, error_callback); + + EXPECT_EQ(result, len); + close(fd); +} + +TEST_F(SerialWriteTest, WriteMultipleSmallBuffers) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *data = "test"; + const int len = static_cast(strlen(data)); + for (int i = 0; i < 10; ++i) + { + int result = serialWrite(fd, data, len, 0, 0, error_callback); + EXPECT_EQ(result, len); + } + + close(fd); +} + +TEST_F(SerialWriteTest, WriteNoErrorCallback) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *test_data = "test"; + const int len = static_cast(strlen(test_data)); + int result = serialWrite(fd, test_data, len, 0, 0, nullptr); + + EXPECT_EQ(result, len); + close(fd); +} + +TEST_F(SerialWriteTest, WriteWithVariousTimeouts) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *test_data = "test"; + const int len = static_cast(strlen(test_data)); + + // Test various timeout values + for (int timeout : {0, 1, 10, 100, 1000}) + { + int result = serialWrite(fd, test_data, len, timeout, 0, error_callback); + EXPECT_EQ(result, len) << "Timeout " << timeout << " should succeed for /dev/null"; + } + + close(fd); +} + +TEST_F(SerialWriteTest, WriteEmptyStringToDevNull) +{ + int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); + ASSERT_GE(fd, 0); + + const char *empty = ""; + // This should fail because buffer_size is 0 + int result = serialWrite(fd, empty, 0, 0, 0, error_callback); + + EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); + close(fd); +} diff --git a/src/test_helpers/error_capture.cpp b/src/test_helpers/error_capture.cpp new file mode 100644 index 0000000..5b58f09 --- /dev/null +++ b/src/test_helpers/error_capture.cpp @@ -0,0 +1,12 @@ +#include "test_helpers/error_capture.hpp" + +void ErrorCapture::callback(int code, const char *message) +{ + if (instance != nullptr) + { + instance->last_code = code; + instance->last_message = message != nullptr ? message : ""; + } +} + +ErrorCapture *ErrorCapture::instance = nullptr; diff --git a/src/test_helpers/error_capture.hpp b/src/test_helpers/error_capture.hpp new file mode 100644 index 0000000..9749538 --- /dev/null +++ b/src/test_helpers/error_capture.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#include + +struct ErrorCapture +{ + int last_code = 0; + std::string last_message; + + static void callback(int code, const char *message); + + static ErrorCapture *instance; +}; diff --git a/tests/integration.test.cpp b/tests/integration.test.cpp new file mode 100644 index 0000000..79d56fc --- /dev/null +++ b/tests/integration.test.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "test_helpers/error_capture.hpp" + +// ============================================================================ +// Integration Tests +// ============================================================================ + +class SerialIntegrationTest : public ::testing::Test +{ + protected: + void SetUp() override + { + ErrorCapture::instance = &error_capture; + error_callback = &ErrorCapture::callback; + } + + void TearDown() override + { + ErrorCapture::instance = nullptr; + } + + ErrorCapture error_capture; + ErrorCallbackT error_callback = nullptr; +}; + +TEST_F(SerialIntegrationTest, ReadWritePipeRoundTrip) +{ + std::array pipefd{}; + ASSERT_EQ(pipe(pipefd.data()), 0); + + // Set non-blocking + fcntl(pipefd[0], F_SETFL, O_NONBLOCK); + fcntl(pipefd[1], F_SETFL, O_NONBLOCK); + + const char *test_message = "Hello"; + const int msg_len = static_cast(strlen(test_message)); + int write_result = serialWrite(pipefd[1], test_message, msg_len, 100, 0, error_callback); + EXPECT_EQ(write_result, msg_len); + + std::array read_buffer{}; + int read_result = + serialRead(pipefd[0], read_buffer.data(), static_cast(read_buffer.size()), 100, 0, error_callback); + EXPECT_EQ(read_result, msg_len); + EXPECT_EQ(std::string(read_buffer.data()), std::string(test_message)); + + close(pipefd[0]); + close(pipefd[1]); +} + +TEST_F(SerialIntegrationTest, MultipleWrites) +{ + std::array pipefd{}; + ASSERT_EQ(pipe(pipefd.data()), 0); + + fcntl(pipefd[0], F_SETFL, O_NONBLOCK); + fcntl(pipefd[1], F_SETFL, O_NONBLOCK); + + const char *msg1 = "Hello"; + const char *msg2 = "World"; + + serialWrite(pipefd[1], msg1, static_cast(strlen(msg1)), 100, 0, error_callback); + serialWrite(pipefd[1], msg2, static_cast(strlen(msg2)), 100, 0, error_callback); + + std::array read_buffer{}; + int read_result = + serialRead(pipefd[0], read_buffer.data(), static_cast(read_buffer.size()), 100, 0, error_callback); + EXPECT_GE(read_result, 0); + + close(pipefd[0]); + close(pipefd[1]); +} + +TEST_F(SerialIntegrationTest, CloseAfterOperations) +{ + std::array pipefd{}; + ASSERT_EQ(pipe(pipefd.data()), 0); + + const char *test_data = "test"; + serialWrite(pipefd[1], test_data, static_cast(strlen(test_data)), 100, 0, error_callback); + + std::array buffer{}; + serialRead(pipefd[0], buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); + + int close_result1 = serialClose(pipefd[0], error_callback); + int close_result2 = serialClose(pipefd[1], error_callback); + + EXPECT_EQ(close_result1, static_cast(cpp_core::StatusCodes::kSuccess)); + EXPECT_EQ(close_result2, static_cast(cpp_core::StatusCodes::kSuccess)); +} diff --git a/tests/test_serial_arduino.cpp b/tests/serial_arduino.test.cpp similarity index 57% rename from tests/test_serial_arduino.cpp rename to tests/serial_arduino.test.cpp index 6772c4a..994f175 100644 --- a/tests/test_serial_arduino.cpp +++ b/tests/serial_arduino.test.cpp @@ -1,4 +1,4 @@ -// Test for serial communication with Arduino echo script on /dev/ttyUSB0 +// Integration test: serial communication with Arduino echo script on /dev/ttyUSB0 #include #include @@ -8,18 +8,20 @@ #include #include +#include #include +#include class SerialArduinoTest : public ::testing::Test { protected: void SetUp() override { - const char *env_port = std::getenv("SERIAL_TEST_PORT"); + const char *env_port = std::getenv("SERIAL_TEST_PORT"); // NOLINT(concurrency-mt-unsafe) const char *port = env_port != nullptr ? env_port : "/dev/ttyUSB0"; - handle_ = serialOpen(const_cast(static_cast(port)), 115200, 8, 0, 0, nullptr); + handle = serialOpen(const_cast(static_cast(port)), 115200, 8, 0, 0, nullptr); - if (handle_ <= 0) + if (handle <= 0) { GTEST_SKIP() << "Could not open serial port '" << port << "'. Set SERIAL_TEST_PORT or connect Arduino on /dev/ttyUSB0."; @@ -30,19 +32,19 @@ class SerialArduinoTest : public ::testing::Test void TearDown() override { - if (handle_ > 0) + if (handle > 0) { - serialClose(handle_, nullptr); - handle_ = 0; + serialClose(handle, nullptr); + handle = 0; } } - intptr_t handle_ = 0; + intptr_t handle = 0; }; TEST_F(SerialArduinoTest, OpenClose) { - EXPECT_GT(handle_, 0) << "serialOpen should return a positive handle"; + EXPECT_GT(handle, 0) << "serialOpen should return a positive handle"; } TEST_F(SerialArduinoTest, WriteReadEcho) @@ -50,52 +52,52 @@ TEST_F(SerialArduinoTest, WriteReadEcho) const char *test_message = "Hello Arduino!\n"; int message_len = static_cast(strlen(test_message)); - int written = serialWrite(handle_, test_message, message_len, 1000, 1, nullptr); + int written = serialWrite(handle, test_message, message_len, 1000, 1, nullptr); EXPECT_EQ(written, message_len) << "Should write all bytes. Written: " << written << ", Expected: " << message_len; usleep(500000); - char read_buffer[256] = {0}; - int read_bytes = serialRead(handle_, read_buffer, sizeof(read_buffer) - 1, 2000, 1, nullptr); + std::array read_buffer{}; + int read_bytes = serialRead(handle, read_buffer.data(), static_cast(read_buffer.size()) - 1, 2000, 1, nullptr); EXPECT_GT(read_bytes, 0) << "Should read at least some bytes"; - EXPECT_LE(read_bytes, static_cast(sizeof(read_buffer) - 1)) << "Should not overflow buffer"; + EXPECT_LE(read_bytes, static_cast(read_buffer.size()) - 1) << "Should not overflow buffer"; - read_buffer[read_bytes] = '\0'; - EXPECT_STRNE(read_buffer, "") << "Should receive echo from Arduino"; + read_buffer[static_cast(read_bytes)] = '\0'; + EXPECT_STRNE(read_buffer.data(), "") << "Should receive echo from Arduino"; } TEST_F(SerialArduinoTest, MultipleEchoCycles) { - const char *messages[] = {"Test1\n", "Test2\n", "Test3\n"}; - const int num_messages = 3; + const std::array messages = {"Test1\n", "Test2\n", "Test3\n"}; - for (int i = 0; i < num_messages; ++i) + for (size_t i = 0; i < messages.size(); ++i) { int msg_len = static_cast(strlen(messages[i])); - int written = serialWrite(handle_, messages[i], msg_len, 1000, 1, nullptr); + int written = serialWrite(handle, messages[i], msg_len, 1000, 1, nullptr); EXPECT_EQ(written, msg_len) << "Cycle " << i << ": write failed"; usleep(500000); - char read_buffer[256] = {0}; - int read_bytes = serialRead(handle_, read_buffer, sizeof(read_buffer) - 1, 2000, 1, nullptr); + std::array read_buffer{}; + int read_bytes = + serialRead(handle, read_buffer.data(), static_cast(read_buffer.size()) - 1, 2000, 1, nullptr); EXPECT_GT(read_bytes, 0) << "Cycle " << i << ": read failed"; } } TEST_F(SerialArduinoTest, ReadTimeout) { - char buffer[256]; - int read_bytes = serialRead(handle_, buffer, sizeof(buffer), 100, 1, nullptr); + std::array buffer{}; + int read_bytes = serialRead(handle, buffer.data(), static_cast(buffer.size()), 100, 1, nullptr); EXPECT_GE(read_bytes, 0) << "Timeout should return 0, not error"; } TEST(SerialInvalidHandleTest, InvalidHandleRead) { - char buffer[256]; - int result = serialRead(-1, buffer, sizeof(buffer), 1000, 1, nullptr); + std::array buffer{}; + int result = serialRead(-1, buffer.data(), static_cast(buffer.size()), 1000, 1, nullptr); EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)) << "Should return error for invalid handle"; } diff --git a/tests/test_serial_functions.cpp b/tests/test_serial_functions.cpp deleted file mode 100644 index d11bce9..0000000 --- a/tests/test_serial_functions.cpp +++ /dev/null @@ -1,680 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -// Helper to capture error callback -struct ErrorCapture -{ - int last_code = 0; - std::string last_message; - - static void callback(int code, const char *message) - { - if (instance != nullptr) - { - instance->last_code = code; - instance->last_message = message != nullptr ? message : ""; - } - } - - static ErrorCapture *instance; -}; - -ErrorCapture *ErrorCapture::instance = nullptr; - -// ============================================================================ -// Tests for serialOpen -// ============================================================================ - -class SerialOpenTest : public ::testing::Test -{ - protected: - void SetUp() override - { - ErrorCapture::instance = &error_capture; - error_callback = &ErrorCapture::callback; - } - - void TearDown() override - { - ErrorCapture::instance = nullptr; - } - - ErrorCapture error_capture; - ErrorCallbackT error_callback = nullptr; -}; - -TEST_F(SerialOpenTest, NullPortParameter) -{ - intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); - EXPECT_NE(error_capture.last_message.find("nullptr"), std::string::npos); -} - -TEST_F(SerialOpenTest, BaudrateTooLow) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 100, 8, 0, 1, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); - EXPECT_NE(error_capture.last_message.find("baudrate"), std::string::npos); -} - -TEST_F(SerialOpenTest, BaudrateTooLowBoundary) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 299, 8, 0, 1, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, BaudrateBoundaryValid) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 300, 8, 0, 1, error_callback); - - // /dev/null is not a real serial port, but should pass baudrate validation - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, DataBitsTooLow) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 4, 0, 1, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); - EXPECT_NE(error_capture.last_message.find("data bits"), std::string::npos); -} - -TEST_F(SerialOpenTest, DataBitsTooHigh) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 9, 0, 1, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, ValidDataBits5) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 5, 0, 1, error_callback); - - // Should pass data bits validation - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, ValidDataBits6) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 6, 0, 1, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, ValidDataBits7) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 7, 0, 1, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, ValidDataBits8) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, InvalidParity) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 5, 1, error_callback); - - // Invalid parity should return an error - EXPECT_LT(result, 0); -} - -TEST_F(SerialOpenTest, ValidParityNone) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, ValidParityEven) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 1, 1, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, ValidParityOdd) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 2, 1, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, InvalidStopBits) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 3, error_callback); - - // Invalid stop bits should return an error - EXPECT_LT(result, 0); -} - -TEST_F(SerialOpenTest, ValidStopBits0) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 0, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, ValidStopBits1) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, ValidStopBits2) -{ - const char *port = "/dev/null"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 2, error_callback); - - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)); -} - -TEST_F(SerialOpenTest, NonExistentPort) -{ - const char *port = "/dev/ttyNONEXISTENT99999"; - intptr_t result = serialOpen(const_cast(static_cast(port)), 9600, 8, 0, 1, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); -} - -TEST_F(SerialOpenTest, VariousBaudrates) -{ - const char *port = "/dev/null"; - - // Test common baudrates - const std::array baudrates = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800}; - - for (int baudrate : baudrates) - { - intptr_t result = - serialOpen(const_cast(static_cast(port)), baudrate, 8, 0, 1, error_callback); - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kSetStateError)) - << "Baudrate " << baudrate << " should be valid"; - } -} - -TEST_F(SerialOpenTest, NoErrorCallbackNullPort) -{ - intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, nullptr); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kNotFoundError)); -} - -// ============================================================================ -// Tests for serialClose -// ============================================================================ - -class SerialCloseTest : public ::testing::Test -{ - protected: - void SetUp() override - { - ErrorCapture::instance = &error_capture; - error_callback = &ErrorCapture::callback; - } - - void TearDown() override - { - ErrorCapture::instance = nullptr; - } - - ErrorCapture error_capture; - ErrorCallbackT error_callback = nullptr; -}; - -TEST_F(SerialCloseTest, CloseInvalidHandleZero) -{ - int result = serialClose(0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); -} - -TEST_F(SerialCloseTest, CloseInvalidHandleNegative) -{ - int result = serialClose(-1, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); -} - -TEST_F(SerialCloseTest, CloseInvalidHandleNegativeLarge) -{ - int result = serialClose(-12345, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); -} - -TEST_F(SerialCloseTest, CloseInvalidHandleTooLarge) -{ - auto too_large_handle = static_cast(std::numeric_limits::max()) + 1; - int result = serialClose(too_large_handle, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialCloseTest, CloseInvalidHandleIntMaxBoundary) -{ - auto handle = static_cast(std::numeric_limits::max()); - int result = serialClose(handle, error_callback); - - // Should fail because this fd doesn't exist, but not with InvalidHandleError - EXPECT_NE(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialCloseTest, CloseNoErrorCallback) -{ - int result = serialClose(0, nullptr); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kSuccess)); -} - -TEST_F(SerialCloseTest, CloseInvalidHandle) -{ - // Test closing a real invalid fd (one that never existed) - // We should get an error but not crash - int result = serialClose(9999, error_callback); - - // This will fail because the fd doesn't exist - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kCloseHandleError)); -} - -// ============================================================================ -// Tests for serialRead -// ============================================================================ - -class SerialReadTest : public ::testing::Test -{ - protected: - void SetUp() override - { - ErrorCapture::instance = &error_capture; - error_callback = &ErrorCapture::callback; - } - - void TearDown() override - { - ErrorCapture::instance = nullptr; - } - - ErrorCapture error_capture; - ErrorCallbackT error_callback = nullptr; -}; - -TEST_F(SerialReadTest, ReadNullBuffer) -{ - int result = serialRead(1, nullptr, 10, 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); - EXPECT_NE(error_capture.last_message.find("buffer"), std::string::npos); -} - -TEST_F(SerialReadTest, ReadZeroBufferSize) -{ - std::array buffer{}; - int result = serialRead(1, buffer.data(), 0, 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); -} - -TEST_F(SerialReadTest, ReadNegativeBufferSize) -{ - std::array buffer{}; - int result = serialRead(1, buffer.data(), -1, 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); -} - -TEST_F(SerialReadTest, ReadInvalidHandleZero) -{ - std::array buffer{}; - int result = serialRead(0, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialReadTest, ReadInvalidHandleNegative) -{ - std::array buffer{}; - int result = serialRead(-1, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialReadTest, ReadInvalidHandleTooLarge) -{ - std::array buffer{}; - auto too_large = static_cast(std::numeric_limits::max()) + 1; - int result = serialRead(too_large, buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialReadTest, ReadFromDevNull) -{ - int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - std::array buffer{}; - int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), 0, 0, error_callback); - - EXPECT_EQ(result, 0); - close(fd); -} - -TEST_F(SerialReadTest, ReadWithLargeBufferSize) -{ - int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - std::array buffer{}; - int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), 0, 0, error_callback); - - EXPECT_EQ(result, 0); - close(fd); -} - -TEST_F(SerialReadTest, ReadNoErrorCallback) -{ - std::array buffer{}; - int result = serialRead(0, buffer.data(), static_cast(buffer.size()), 100, 0, nullptr); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialReadTest, ReadWithVariousTimeouts) -{ - int fd = open("/dev/null", O_RDONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - std::array buffer{}; - - // Test various timeout values - for (int timeout : {0, 1, 10, 100, 1000}) - { - int result = serialRead(fd, buffer.data(), static_cast(buffer.size()), timeout, 0, error_callback); - EXPECT_EQ(result, 0) << "Timeout " << timeout << " should return 0 for /dev/null"; - } - - close(fd); -} - -// ============================================================================ -// Tests for serialWrite -// ============================================================================ - -class SerialWriteTest : public ::testing::Test -{ - protected: - void SetUp() override - { - ErrorCapture::instance = &error_capture; - error_callback = &ErrorCapture::callback; - } - - void TearDown() override - { - ErrorCapture::instance = nullptr; - } - - ErrorCapture error_capture; - ErrorCallbackT error_callback = nullptr; -}; - -TEST_F(SerialWriteTest, WriteNullBuffer) -{ - int result = serialWrite(1, nullptr, 10, 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); - EXPECT_NE(error_capture.last_message.find("buffer"), std::string::npos); -} - -TEST_F(SerialWriteTest, WriteZeroBufferSize) -{ - std::array buffer{}; - int result = serialWrite(1, buffer.data(), 0, 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); -} - -TEST_F(SerialWriteTest, WriteNegativeBufferSize) -{ - std::array buffer{}; - int result = serialWrite(1, buffer.data(), -1, 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); -} - -TEST_F(SerialWriteTest, WriteInvalidHandleZero) -{ - const char *buffer = "test"; - int result = serialWrite(0, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialWriteTest, WriteInvalidHandleNegative) -{ - const char *buffer = "test"; - int result = serialWrite(-1, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialWriteTest, WriteInvalidHandleTooLarge) -{ - const char *buffer = "test"; - auto too_large = static_cast(std::numeric_limits::max()) + 1; - int result = serialWrite(too_large, buffer, static_cast(strlen(buffer)), 100, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kInvalidHandleError)); -} - -TEST_F(SerialWriteTest, WriteToDevNull) -{ - int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - const char *test_data = "Hello World"; - const int len = static_cast(strlen(test_data)); - int result = serialWrite(fd, test_data, len, 0, 0, error_callback); - - EXPECT_EQ(result, len); - close(fd); -} - -TEST_F(SerialWriteTest, WriteLargeBuffer) -{ - int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - std::string large_data(4096, 'A'); - const int len = static_cast(large_data.size()); - int result = serialWrite(fd, large_data.c_str(), len, 0, 0, error_callback); - - EXPECT_EQ(result, len); - close(fd); -} - -TEST_F(SerialWriteTest, WriteMultipleSmallBuffers) -{ - int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - const char *data = "test"; - const int len = static_cast(strlen(data)); - for (int i = 0; i < 10; ++i) - { - int result = serialWrite(fd, data, len, 0, 0, error_callback); - EXPECT_EQ(result, len); - } - - close(fd); -} - -TEST_F(SerialWriteTest, WriteNoErrorCallback) -{ - int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - const char *test_data = "test"; - const int len = static_cast(strlen(test_data)); - int result = serialWrite(fd, test_data, len, 0, 0, nullptr); - - EXPECT_EQ(result, len); - close(fd); -} - -TEST_F(SerialWriteTest, WriteWithVariousTimeouts) -{ - int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - const char *test_data = "test"; - const int len = static_cast(strlen(test_data)); - - // Test various timeout values - for (int timeout : {0, 1, 10, 100, 1000}) - { - int result = serialWrite(fd, test_data, len, timeout, 0, error_callback); - EXPECT_EQ(result, len) << "Timeout " << timeout << " should succeed for /dev/null"; - } - - close(fd); -} - -TEST_F(SerialWriteTest, WriteEmptyStringToDevNull) -{ - int fd = open("/dev/null", O_WRONLY | O_NONBLOCK); - ASSERT_GE(fd, 0); - - const char *empty = ""; - // This should fail because buffer_size is 0 - int result = serialWrite(fd, empty, 0, 0, 0, error_callback); - - EXPECT_EQ(result, static_cast(cpp_core::StatusCodes::kBufferError)); - close(fd); -} - -// ============================================================================ -// Integration Tests -// ============================================================================ - -class SerialIntegrationTest : public ::testing::Test -{ - protected: - void SetUp() override - { - ErrorCapture::instance = &error_capture; - error_callback = &ErrorCapture::callback; - } - - void TearDown() override - { - ErrorCapture::instance = nullptr; - } - - ErrorCapture error_capture; - ErrorCallbackT error_callback = nullptr; -}; - -TEST_F(SerialIntegrationTest, ReadWritePipeRoundTrip) -{ - std::array pipefd{}; - ASSERT_EQ(pipe(pipefd.data()), 0); - - // Set non-blocking - fcntl(pipefd[0], F_SETFL, O_NONBLOCK); - fcntl(pipefd[1], F_SETFL, O_NONBLOCK); - - const char *test_message = "Hello"; - const int msg_len = static_cast(strlen(test_message)); - int write_result = serialWrite(pipefd[1], test_message, msg_len, 100, 0, error_callback); - EXPECT_EQ(write_result, msg_len); - - std::array read_buffer{}; - int read_result = - serialRead(pipefd[0], read_buffer.data(), static_cast(read_buffer.size()), 100, 0, error_callback); - EXPECT_EQ(read_result, msg_len); - EXPECT_EQ(std::string(read_buffer.data()), std::string(test_message)); - - close(pipefd[0]); - close(pipefd[1]); -} - -TEST_F(SerialIntegrationTest, MultipleWrites) -{ - std::array pipefd{}; - ASSERT_EQ(pipe(pipefd.data()), 0); - - fcntl(pipefd[0], F_SETFL, O_NONBLOCK); - fcntl(pipefd[1], F_SETFL, O_NONBLOCK); - - const char *msg1 = "Hello"; - const char *msg2 = "World"; - - serialWrite(pipefd[1], msg1, static_cast(strlen(msg1)), 100, 0, error_callback); - serialWrite(pipefd[1], msg2, static_cast(strlen(msg2)), 100, 0, error_callback); - - std::array read_buffer{}; - int read_result = - serialRead(pipefd[0], read_buffer.data(), static_cast(read_buffer.size()), 100, 0, error_callback); - EXPECT_GE(read_result, 0); - - close(pipefd[0]); - close(pipefd[1]); -} - -TEST_F(SerialIntegrationTest, CloseAfterOperations) -{ - std::array pipefd{}; - ASSERT_EQ(pipe(pipefd.data()), 0); - - const char *test_data = "test"; - serialWrite(pipefd[1], test_data, static_cast(strlen(test_data)), 100, 0, error_callback); - - std::array buffer{}; - serialRead(pipefd[0], buffer.data(), static_cast(buffer.size()), 100, 0, error_callback); - - int close_result1 = serialClose(pipefd[0], error_callback); - int close_result2 = serialClose(pipefd[1], error_callback); - - EXPECT_EQ(close_result1, static_cast(cpp_core::StatusCodes::kSuccess)); - EXPECT_EQ(close_result2, static_cast(cpp_core::StatusCodes::kSuccess)); -} From ba763c9b6d5adf6cd7d7b3dbf19590c5de9083e3 Mon Sep 17 00:00:00 2001 From: Katze719 Date: Wed, 28 Jan 2026 21:33:54 +0100 Subject: [PATCH 4/4] refactor: Remove commented test section headers from serial test files - Cleaned up test files by removing unnecessary commented headers for serialClose, serialOpen, serialWrite, and integration tests. --- src/serial_close.test.cpp | 4 ---- src/serial_open.test.cpp | 5 ----- src/serial_read.test.cpp | 4 ---- src/serial_write.test.cpp | 4 ---- tests/integration.test.cpp | 4 ---- 5 files changed, 21 deletions(-) diff --git a/src/serial_close.test.cpp b/src/serial_close.test.cpp index e34a8b8..5b89b64 100644 --- a/src/serial_close.test.cpp +++ b/src/serial_close.test.cpp @@ -7,10 +7,6 @@ #include "test_helpers/error_capture.hpp" -// ============================================================================ -// Tests for serialClose -// ============================================================================ - class SerialCloseTest : public ::testing::Test { protected: diff --git a/src/serial_open.test.cpp b/src/serial_open.test.cpp index 6fdce3c..b818ee1 100644 --- a/src/serial_open.test.cpp +++ b/src/serial_open.test.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -10,10 +9,6 @@ #include "test_helpers/error_capture.hpp" -// ============================================================================ -// Tests for serialOpen -// ============================================================================ - class SerialOpenTest : public ::testing::Test { protected: diff --git a/src/serial_read.test.cpp b/src/serial_read.test.cpp index fbea49f..543b6a0 100644 --- a/src/serial_read.test.cpp +++ b/src/serial_read.test.cpp @@ -10,10 +10,6 @@ #include "test_helpers/error_capture.hpp" -// ============================================================================ -// Tests for serialRead -// ============================================================================ - class SerialReadTest : public ::testing::Test { protected: diff --git a/src/serial_write.test.cpp b/src/serial_write.test.cpp index b380403..015211f 100644 --- a/src/serial_write.test.cpp +++ b/src/serial_write.test.cpp @@ -12,10 +12,6 @@ #include "test_helpers/error_capture.hpp" -// ============================================================================ -// Tests for serialWrite -// ============================================================================ - class SerialWriteTest : public ::testing::Test { protected: diff --git a/tests/integration.test.cpp b/tests/integration.test.cpp index 79d56fc..99fb133 100644 --- a/tests/integration.test.cpp +++ b/tests/integration.test.cpp @@ -14,10 +14,6 @@ #include "test_helpers/error_capture.hpp" -// ============================================================================ -// Integration Tests -// ============================================================================ - class SerialIntegrationTest : public ::testing::Test { protected: