From fb3ce82f4fe56fc39cf450ad47c20364de9fb917 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 08:19:02 +0100 Subject: [PATCH 01/12] feat: S24.07 SolidSyslogPosixAddress pool class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First slice of S24.07. Adds the POSIX platform Address as a pool- allocated handle wrapping struct sockaddr_in, sized by the new SOLIDSYSLOG_ADDRESS_POOL_SIZE tunable (default 3 to fit the canonical BDD UDP + plain-TCP + TLS-stream wiring without an override). Pool exhaustion falls back to a TU-private singleton sized as a real SolidSyslogPosixAddress, so a Resolver overwrite into the fallback is bounded. A cross-platform Core/-side NullAddress would have to be either platform-blind (and undersized — UB on Resolver write) or platform-aware (and break the layering); the per-platform TU-private fallback avoids both. Multi-overflow integrators share the fallback storage and race; the POOL_EXHAUSTED error handler call at every exhaustion is the signal to bump the tunable. Pool plumbing duplicates the established 3-TU split (Class.c + ClassPrivate.h + ClassStatic.c) used by every other E11 pool-class, with the standard pool / lock / error / stale-destroy tests. AsSockaddrIn / AsConstSockaddrIn accessors are TU-private — exposed only via the Private.h header that library internals (Resolver / Datagram / Stream) will include in later slices. No callers yet — additive only. Co-Authored-By: Claude Opus 4.7 (1M context) --- Core/Interface/SolidSyslogTunablesDefaults.h | 23 ++ Core/Source/SolidSyslogErrorMessages.h | 4 + Platform/Posix/CMakeLists.txt | 2 + .../Posix/Interface/SolidSyslogPosixAddress.h | 15 ++ .../Posix/Source/SolidSyslogPosixAddress.c | 16 ++ .../Source/SolidSyslogPosixAddressPrivate.h | 27 +++ .../Source/SolidSyslogPosixAddressStatic.c | 75 +++++++ Tests/CMakeLists.txt | 2 + Tests/SolidSyslogPosixAddressTest.cpp | 210 ++++++++++++++++++ 9 files changed, 374 insertions(+) create mode 100644 Platform/Posix/Interface/SolidSyslogPosixAddress.h create mode 100644 Platform/Posix/Source/SolidSyslogPosixAddress.c create mode 100644 Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h create mode 100644 Platform/Posix/Source/SolidSyslogPosixAddressStatic.c create mode 100644 Tests/SolidSyslogPosixAddressTest.cpp diff --git a/Core/Interface/SolidSyslogTunablesDefaults.h b/Core/Interface/SolidSyslogTunablesDefaults.h index ebf4e2b7..f64aea99 100644 --- a/Core/Interface/SolidSyslogTunablesDefaults.h +++ b/Core/Interface/SolidSyslogTunablesDefaults.h @@ -670,4 +670,27 @@ #error "SOLIDSYSLOG_MBED_TLS_STREAM_POOL_SIZE must be >= 1" #endif +/* + * Number of SolidSyslog{Posix,Winsock,FreeRtos}Address instances the + * library's internal static pool can simultaneously hold. Each instance + * carries one platform sockaddr (struct sockaddr_in on POSIX/Windows, + * struct freertos_sockaddr on FreeRTOS) — ~16 bytes per slot. + * + * Default 3 — covers the canonical BDD multi-transport wiring (one + * Address per Sender: UDP + plain-TCP + TLS-stream). Single-transport + * integrators pay ~32 bytes of unused slots; multi-transport integrators + * are spared an override. Bump via SOLIDSYSLOG_USER_TUNABLES_FILE if + * more than three concurrent senders are needed. + * + * Floor: 1. Sub-floor values rejected at compile time. + */ +#ifndef SOLIDSYSLOG_ADDRESS_POOL_SIZE +/* NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -- macro form required for preprocessor visibility (floor #if) and C array-size const-expr. */ +#define SOLIDSYSLOG_ADDRESS_POOL_SIZE 3U +#endif + +#if SOLIDSYSLOG_ADDRESS_POOL_SIZE < 1 +#error "SOLIDSYSLOG_ADDRESS_POOL_SIZE must be >= 1" +#endif + #endif /* SOLIDSYSLOG_TUNABLES_DEFAULTS_H */ diff --git a/Core/Source/SolidSyslogErrorMessages.h b/Core/Source/SolidSyslogErrorMessages.h index 3d9004f5..d1589e04 100644 --- a/Core/Source/SolidSyslogErrorMessages.h +++ b/Core/Source/SolidSyslogErrorMessages.h @@ -69,6 +69,10 @@ "SolidSyslogPosixMutex_Create pool exhausted; returning fallback mutex" #define SOLIDSYSLOG_ERROR_MSG_POSIXMUTEX_UNKNOWN_DESTROY \ "SolidSyslogPosixMutex_Destroy called with a handle not issued by this pool" +#define SOLIDSYSLOG_ERROR_MSG_POSIXADDRESS_POOL_EXHAUSTED \ + "SolidSyslogPosixAddress_Create pool exhausted; returning fallback address" +#define SOLIDSYSLOG_ERROR_MSG_POSIXADDRESS_UNKNOWN_DESTROY \ + "SolidSyslogPosixAddress_Destroy called with a handle not issued by this pool" #define SOLIDSYSLOG_ERROR_MSG_POSIXDATAGRAM_POOL_EXHAUSTED \ "SolidSyslogPosixDatagram_Create pool exhausted; returning fallback datagram" #define SOLIDSYSLOG_ERROR_MSG_POSIXDATAGRAM_UNKNOWN_DESTROY \ diff --git a/Platform/Posix/CMakeLists.txt b/Platform/Posix/CMakeLists.txt index 5e673d3f..43739a37 100644 --- a/Platform/Posix/CMakeLists.txt +++ b/Platform/Posix/CMakeLists.txt @@ -9,6 +9,8 @@ target_sources(${PROJECT_NAME} PRIVATE Source/SolidSyslogPosixSysUpTime.c Source/SolidSyslogPosixSleep.c Source/SolidSyslogAddress.c + Source/SolidSyslogPosixAddress.c + Source/SolidSyslogPosixAddressStatic.c Source/SolidSyslogGetAddrInfoResolver.c Source/SolidSyslogGetAddrInfoResolverStatic.c Source/SolidSyslogPosixDatagram.c diff --git a/Platform/Posix/Interface/SolidSyslogPosixAddress.h b/Platform/Posix/Interface/SolidSyslogPosixAddress.h new file mode 100644 index 00000000..aa8ff75e --- /dev/null +++ b/Platform/Posix/Interface/SolidSyslogPosixAddress.h @@ -0,0 +1,15 @@ +#ifndef SOLIDSYSLOGPOSIXADDRESS_H +#define SOLIDSYSLOGPOSIXADDRESS_H + +#include "ExternC.h" + +EXTERN_C_BEGIN + + struct SolidSyslogAddress; + + struct SolidSyslogAddress* SolidSyslogPosixAddress_Create(void); + void SolidSyslogPosixAddress_Destroy(struct SolidSyslogAddress * base); + +EXTERN_C_END + +#endif /* SOLIDSYSLOGPOSIXADDRESS_H */ diff --git a/Platform/Posix/Source/SolidSyslogPosixAddress.c b/Platform/Posix/Source/SolidSyslogPosixAddress.c new file mode 100644 index 00000000..176f019b --- /dev/null +++ b/Platform/Posix/Source/SolidSyslogPosixAddress.c @@ -0,0 +1,16 @@ +#include "SolidSyslogPosixAddressPrivate.h" + +#include + +struct SolidSyslogAddress; + +void PosixAddress_Initialise(struct SolidSyslogAddress* base) +{ + struct SolidSyslogPosixAddress* self = (struct SolidSyslogPosixAddress*) base; + memset(&self->Sockaddr, 0, sizeof(self->Sockaddr)); +} + +void PosixAddress_Cleanup(struct SolidSyslogAddress* base) +{ + (void) base; +} diff --git a/Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h b/Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h new file mode 100644 index 00000000..30cf79fa --- /dev/null +++ b/Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h @@ -0,0 +1,27 @@ +#ifndef SOLIDSYSLOGPOSIXADDRESSPRIVATE_H +#define SOLIDSYSLOGPOSIXADDRESSPRIVATE_H + +#include +#include + +struct SolidSyslogAddress; + +struct SolidSyslogPosixAddress +{ + struct sockaddr_in Sockaddr; +}; + +void PosixAddress_Initialise(struct SolidSyslogAddress* base); +void PosixAddress_Cleanup(struct SolidSyslogAddress* base); + +static inline struct sockaddr_in* SolidSyslogPosixAddress_AsSockaddrIn(struct SolidSyslogAddress* base) +{ + return &((struct SolidSyslogPosixAddress*) base)->Sockaddr; +} + +static inline const struct sockaddr_in* SolidSyslogPosixAddress_AsConstSockaddrIn(const struct SolidSyslogAddress* base) +{ + return &((const struct SolidSyslogPosixAddress*) base)->Sockaddr; +} + +#endif /* SOLIDSYSLOGPOSIXADDRESSPRIVATE_H */ diff --git a/Platform/Posix/Source/SolidSyslogPosixAddressStatic.c b/Platform/Posix/Source/SolidSyslogPosixAddressStatic.c new file mode 100644 index 00000000..aabaeac2 --- /dev/null +++ b/Platform/Posix/Source/SolidSyslogPosixAddressStatic.c @@ -0,0 +1,75 @@ +#include "SolidSyslogPosixAddress.h" + +#include +#include + +#include "SolidSyslogError.h" +#include "SolidSyslogErrorMessages.h" +#include "SolidSyslogPoolAllocator.h" +#include "SolidSyslogPosixAddressPrivate.h" +#include "SolidSyslogPrival.h" +#include "SolidSyslogTunables.h" + +struct SolidSyslogAddress; + +static inline size_t PosixAddress_IndexFromHandle(const struct SolidSyslogAddress* base); +static inline void PosixAddress_CleanupAtIndex(size_t index, void* context); + +static bool PosixAddress_InUse[SOLIDSYSLOG_ADDRESS_POOL_SIZE]; +static struct SolidSyslogPosixAddress PosixAddress_Pool[SOLIDSYSLOG_ADDRESS_POOL_SIZE]; +static struct SolidSyslogPoolAllocator PosixAddress_Allocator = {PosixAddress_InUse, SOLIDSYSLOG_ADDRESS_POOL_SIZE}; + +/* TU-private fallback returned when the pool is exhausted. Sized as a real + * SolidSyslogPosixAddress so a Resolver overwrite at the exhausted-fallback + * call site is bounded — same sockaddr_in storage as any pooled slot. Not + * a per-Sender slot: multi-overflow integrators share this storage and + * race on it. Bumping SOLIDSYSLOG_ADDRESS_POOL_SIZE removes the race. */ +static struct SolidSyslogPosixAddress PosixAddress_Fallback; + +struct SolidSyslogAddress* SolidSyslogPosixAddress_Create(void) +{ + size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&PosixAddress_Allocator); + struct SolidSyslogAddress* handle = (struct SolidSyslogAddress*) &PosixAddress_Fallback; + if (SolidSyslogPoolAllocator_IndexIsValid(&PosixAddress_Allocator, index)) + { + handle = (struct SolidSyslogAddress*) &PosixAddress_Pool[index]; + PosixAddress_Initialise(handle); + } + else + { + SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_ERROR, SOLIDSYSLOG_ERROR_MSG_POSIXADDRESS_POOL_EXHAUSTED); + } + return handle; +} + +void SolidSyslogPosixAddress_Destroy(struct SolidSyslogAddress* base) +{ + size_t index = PosixAddress_IndexFromHandle(base); + bool released = + SolidSyslogPoolAllocator_IndexIsValid(&PosixAddress_Allocator, index) && + SolidSyslogPoolAllocator_FreeIfInUse(&PosixAddress_Allocator, index, PosixAddress_CleanupAtIndex, NULL); + if (!released) + { + SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_WARNING, SOLIDSYSLOG_ERROR_MSG_POSIXADDRESS_UNKNOWN_DESTROY); + } +} + +static inline size_t PosixAddress_IndexFromHandle(const struct SolidSyslogAddress* base) +{ + size_t result = SOLIDSYSLOG_ADDRESS_POOL_SIZE; + for (size_t poolIndex = 0; poolIndex < SOLIDSYSLOG_ADDRESS_POOL_SIZE; poolIndex++) + { + if (base == (const struct SolidSyslogAddress*) &PosixAddress_Pool[poolIndex]) + { + result = poolIndex; + break; + } + } + return result; +} + +static inline void PosixAddress_CleanupAtIndex(size_t index, void* context) +{ + (void) context; + PosixAddress_Cleanup((struct SolidSyslogAddress*) &PosixAddress_Pool[index]); +} diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 9917155a..f3cd1db5 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -117,6 +117,7 @@ if(SOLIDSYSLOG_POSIX) SolidSyslogStreamSenderTest.cpp SolidSyslogPosixFileTest.cpp SolidSyslogBlockStorePosixTest.cpp + SolidSyslogPosixAddressTest.cpp SolidSyslogGetAddrInfoResolverTest.cpp SolidSyslogPosixDatagramTest.cpp SolidSyslogPosixTcpStreamTest.cpp @@ -177,6 +178,7 @@ endif() if(SOLIDSYSLOG_POSIX) target_link_libraries(${PROJECT_NAME}Tests PRIVATE PosixFakes) + target_include_directories(${PROJECT_NAME}Tests PRIVATE ${CMAKE_SOURCE_DIR}/Platform/Posix/Source) endif() if(SOLIDSYSLOG_OPENSSL) diff --git a/Tests/SolidSyslogPosixAddressTest.cpp b/Tests/SolidSyslogPosixAddressTest.cpp new file mode 100644 index 00000000..27820f4f --- /dev/null +++ b/Tests/SolidSyslogPosixAddressTest.cpp @@ -0,0 +1,210 @@ +#include "TestUtils.h" +#include "CppUTest/TestHarness.h" + +using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-file scope only; brings NEVER/ONCE/TWICE/THRICE into scope for the CALLED_* + // macros + +#include +#include + +#include "ConfigLockFake.h" +#include "ErrorHandlerFake.h" +#include "SolidSyslogErrorMessages.h" +#include "SolidSyslogPosixAddress.h" +#include "SolidSyslogPosixAddressPrivate.h" +#include "SolidSyslogPrival.h" +#include "SolidSyslogTunables.h" + +// NOLINTBEGIN(cppcoreguidelines-macro-usage,cppcoreguidelines-avoid-do-while) -- macros preserve __FILE__/__LINE__ at the call site + +// Asserts handle is non-null and not one of the slots in pool. +#define CHECK_IS_FALLBACK(handle, pool) \ + do \ + { \ + CHECK_TEXT((handle) != nullptr, "Fallback handle was nullptr"); \ + for (auto* slot : (pool)) \ + { \ + CHECK_TEXT(slot != nullptr, "pool slot was nullptr (FillPool failed?)"); \ + CHECK_TEXT((handle) != slot, "Fallback handle collided with a pool slot"); \ + } \ + } while (0) + +// NOLINTEND(cppcoreguidelines-macro-usage,cppcoreguidelines-avoid-do-while) + +// clang-format off +TEST_GROUP(SolidSyslogPosixAddress) +{ + struct SolidSyslogAddress* address = nullptr; + + void setup() override + { + address = SolidSyslogPosixAddress_Create(); + } + + void teardown() override + { + SolidSyslogPosixAddress_Destroy(address); + } +}; + +// clang-format on + +TEST(SolidSyslogPosixAddress, CreateReturnsNonNull) +{ + CHECK(address != nullptr); +} + +TEST(SolidSyslogPosixAddress, AsSockaddrInRoundTripsBytes) +{ + struct sockaddr_in expected = {}; + expected.sin_family = AF_INET; + expected.sin_port = htons(514U); + expected.sin_addr.s_addr = htonl(0x7F000001U); + + *SolidSyslogPosixAddress_AsSockaddrIn(address) = expected; + + const struct sockaddr_in* actual = SolidSyslogPosixAddress_AsConstSockaddrIn(address); + MEMCMP_EQUAL(&expected, actual, sizeof(expected)); +} + +TEST(SolidSyslogPosixAddress, CreateZeroesTheSockaddrFromAnyPriorSlotContents) +{ + struct sockaddr_in dirty = {}; + dirty.sin_family = AF_INET; + dirty.sin_port = htons(9999U); + dirty.sin_addr.s_addr = htonl(0xDEADBEEFU); + *SolidSyslogPosixAddress_AsSockaddrIn(address) = dirty; + SolidSyslogPosixAddress_Destroy(address); + + address = SolidSyslogPosixAddress_Create(); + + struct sockaddr_in zeroes = {}; + MEMCMP_EQUAL(&zeroes, SolidSyslogPosixAddress_AsConstSockaddrIn(address), sizeof(zeroes)); +} + +// clang-format off +TEST_GROUP(SolidSyslogPosixAddressPool) +{ + // cppcheck-suppress constVariable -- assigned in test bodies; cppcheck does not model CppUTest lifecycle + struct SolidSyslogAddress* pooled[SOLIDSYSLOG_ADDRESS_POOL_SIZE] = {}; + struct SolidSyslogAddress* overflow = nullptr; + + void teardown() override + { + for (auto* handle : pooled) + { + if (handle != nullptr) + { + SolidSyslogPosixAddress_Destroy(handle); + } + } + // cppcheck-suppress knownConditionTrueFalse -- assigned in test bodies; cppcheck does not model CppUTest lifecycle + if (overflow != nullptr) + { + SolidSyslogPosixAddress_Destroy(overflow); + } + ConfigLockFake_Uninstall(); + ErrorHandlerFake_Uninstall(); + } + + void FillPool() + { + for (auto*& slot : pooled) + { + slot = SolidSyslogPosixAddress_Create(); + } + } +}; + +// clang-format on + +TEST(SolidSyslogPosixAddressPool, FillingPoolThenOverflowReturnsDistinctFallback) +{ + FillPool(); + + overflow = SolidSyslogPosixAddress_Create(); + + CHECK_IS_FALLBACK(overflow, pooled); +} + +TEST(SolidSyslogPosixAddressPool, ExhaustedCreateReportsError) +{ + ErrorHandlerFake_Install(nullptr); + FillPool(); + + overflow = SolidSyslogPosixAddress_Create(); + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_ERROR, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_POSIXADDRESS_POOL_EXHAUSTED, ErrorHandlerFake_LastMessage()); +} + +TEST(SolidSyslogPosixAddressPool, CreateAcquiresAndReleasesConfigLockOnFirstFreeSlot) +{ + ConfigLockFake_Install(); + + pooled[0] = SolidSyslogPosixAddress_Create(); + + CALLED_FAKE(ConfigLockFake_Lock, ONCE); + CALLED_FAKE(ConfigLockFake_Unlock, ONCE); +} + +TEST(SolidSyslogPosixAddressPool, CreateLocksOncePerSlotProbedWhenPoolIsFull) +{ + FillPool(); + ConfigLockFake_Install(); + + overflow = SolidSyslogPosixAddress_Create(); + + LONGS_EQUAL(SOLIDSYSLOG_ADDRESS_POOL_SIZE, ConfigLockFake_LockCallCount()); + LONGS_EQUAL(SOLIDSYSLOG_ADDRESS_POOL_SIZE, ConfigLockFake_UnlockCallCount()); +} + +TEST(SolidSyslogPosixAddressPool, DestroyOfPooledHandleLocksOnce) +{ + pooled[0] = SolidSyslogPosixAddress_Create(); + ConfigLockFake_Install(); + + SolidSyslogPosixAddress_Destroy(pooled[0]); + pooled[0] = nullptr; + + CALLED_FAKE(ConfigLockFake_Lock, ONCE); + CALLED_FAKE(ConfigLockFake_Unlock, ONCE); +} + +TEST(SolidSyslogPosixAddressPool, DestroyOfUnknownHandleDoesNotLock) +{ + ConfigLockFake_Install(); + char stranger = 0; + + SolidSyslogPosixAddress_Destroy((struct SolidSyslogAddress*) &stranger); + + CALLED_FAKE(ConfigLockFake_Lock, NEVER); + CALLED_FAKE(ConfigLockFake_Unlock, NEVER); +} + +TEST(SolidSyslogPosixAddressPool, DestroyOfUnknownHandleReportsWarning) +{ + ErrorHandlerFake_Install(nullptr); + char stranger = 0; + + SolidSyslogPosixAddress_Destroy((struct SolidSyslogAddress*) &stranger); + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_WARNING, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_POSIXADDRESS_UNKNOWN_DESTROY, ErrorHandlerFake_LastMessage()); +} + +TEST(SolidSyslogPosixAddressPool, DestroyOfStaleHandleReportsWarning) +{ + pooled[0] = SolidSyslogPosixAddress_Create(); + SolidSyslogPosixAddress_Destroy(pooled[0]); + ErrorHandlerFake_Install(nullptr); + + SolidSyslogPosixAddress_Destroy(pooled[0]); + pooled[0] = nullptr; + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_WARNING, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_POSIXADDRESS_UNKNOWN_DESTROY, ErrorHandlerFake_LastMessage()); +} From 0ff714b23d0f8824826ce8e2e9a05d1d79a74344 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 08:35:53 +0100 Subject: [PATCH 02/12] refactor: S24.07 PosixAddress pool default 1 + HandleFromIndex helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review fixes on the PosixAddress slice: - SOLIDSYSLOG_ADDRESS_POOL_SIZE defaults to 1; BDD-target wirings override via SOLIDSYSLOG_USER_TUNABLES_FILE in their respective build harnesses. - Pool-slot impl-to-base cast moves into a PosixAddress_HandleFromIndex helper; the three call sites (Create success, IndexFromHandle, CleanupAtIndex) now route through one place. Fallback cast stays inline — it points to a separate static, one occurrence. Co-Authored-By: Claude Opus 4.7 (1M context) --- Core/Interface/SolidSyslogTunablesDefaults.h | 11 +++++------ .../Posix/Source/SolidSyslogPosixAddressStatic.c | 12 +++++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Core/Interface/SolidSyslogTunablesDefaults.h b/Core/Interface/SolidSyslogTunablesDefaults.h index f64aea99..69b9fa68 100644 --- a/Core/Interface/SolidSyslogTunablesDefaults.h +++ b/Core/Interface/SolidSyslogTunablesDefaults.h @@ -676,17 +676,16 @@ * carries one platform sockaddr (struct sockaddr_in on POSIX/Windows, * struct freertos_sockaddr on FreeRTOS) — ~16 bytes per slot. * - * Default 3 — covers the canonical BDD multi-transport wiring (one - * Address per Sender: UDP + plain-TCP + TLS-stream). Single-transport - * integrators pay ~32 bytes of unused slots; multi-transport integrators - * are spared an override. Bump via SOLIDSYSLOG_USER_TUNABLES_FILE if - * more than three concurrent senders are needed. + * Default 1 — typical integrator wires one Sender. Multi-transport + * integrators (e.g. the BDD targets wiring UDP + plain-TCP + TLS-stream) + * override this via SOLIDSYSLOG_USER_TUNABLES_FILE; the BDD wirings are + * deliberately the unusual case rather than the default. * * Floor: 1. Sub-floor values rejected at compile time. */ #ifndef SOLIDSYSLOG_ADDRESS_POOL_SIZE /* NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -- macro form required for preprocessor visibility (floor #if) and C array-size const-expr. */ -#define SOLIDSYSLOG_ADDRESS_POOL_SIZE 3U +#define SOLIDSYSLOG_ADDRESS_POOL_SIZE 1U #endif #if SOLIDSYSLOG_ADDRESS_POOL_SIZE < 1 diff --git a/Platform/Posix/Source/SolidSyslogPosixAddressStatic.c b/Platform/Posix/Source/SolidSyslogPosixAddressStatic.c index aabaeac2..935bcc50 100644 --- a/Platform/Posix/Source/SolidSyslogPosixAddressStatic.c +++ b/Platform/Posix/Source/SolidSyslogPosixAddressStatic.c @@ -12,6 +12,7 @@ struct SolidSyslogAddress; +static inline struct SolidSyslogAddress* PosixAddress_HandleFromIndex(size_t index); static inline size_t PosixAddress_IndexFromHandle(const struct SolidSyslogAddress* base); static inline void PosixAddress_CleanupAtIndex(size_t index, void* context); @@ -32,7 +33,7 @@ struct SolidSyslogAddress* SolidSyslogPosixAddress_Create(void) struct SolidSyslogAddress* handle = (struct SolidSyslogAddress*) &PosixAddress_Fallback; if (SolidSyslogPoolAllocator_IndexIsValid(&PosixAddress_Allocator, index)) { - handle = (struct SolidSyslogAddress*) &PosixAddress_Pool[index]; + handle = PosixAddress_HandleFromIndex(index); PosixAddress_Initialise(handle); } else @@ -54,12 +55,17 @@ void SolidSyslogPosixAddress_Destroy(struct SolidSyslogAddress* base) } } +static inline struct SolidSyslogAddress* PosixAddress_HandleFromIndex(size_t index) +{ + return (struct SolidSyslogAddress*) &PosixAddress_Pool[index]; +} + static inline size_t PosixAddress_IndexFromHandle(const struct SolidSyslogAddress* base) { size_t result = SOLIDSYSLOG_ADDRESS_POOL_SIZE; for (size_t poolIndex = 0; poolIndex < SOLIDSYSLOG_ADDRESS_POOL_SIZE; poolIndex++) { - if (base == (const struct SolidSyslogAddress*) &PosixAddress_Pool[poolIndex]) + if (base == PosixAddress_HandleFromIndex(poolIndex)) { result = poolIndex; break; @@ -71,5 +77,5 @@ static inline size_t PosixAddress_IndexFromHandle(const struct SolidSyslogAddres static inline void PosixAddress_CleanupAtIndex(size_t index, void* context) { (void) context; - PosixAddress_Cleanup((struct SolidSyslogAddress*) &PosixAddress_Pool[index]); + PosixAddress_Cleanup(PosixAddress_HandleFromIndex(index)); } From ccda60bfcc2ac6a9f978d71d4db016816246f61e Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 08:51:40 +0100 Subject: [PATCH 03/12] feat: S24.07 SolidSyslogWinsockAddress pool class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Duplicate-and-rename of the PosixAddress slice for the Winsock target. Same 3-TU split, same TU-private fallback shape, same set of pool plumbing tests. Storage struct wraps the Winsock sockaddr_in from ; AsSockaddrIn / AsConstSockaddrIn accessors are TU-private via SolidSyslogWinsockAddressPrivate.h. Reuses the shared SOLIDSYSLOG_ADDRESS_POOL_SIZE tunable — one pool size across all three platforms. Verified locally on the cpputest gcc image (Posix-side build green, new Winsock sources excluded from the link as expected). Windows build verification deferred to CI (build-windows-msvc, integration-windows-openssl, bdd-windows-otel). Co-Authored-By: Claude Opus 4.7 (1M context) --- Core/Source/SolidSyslogErrorMessages.h | 4 + Platform/Windows/CMakeLists.txt | 2 + .../Interface/SolidSyslogWinsockAddress.h | 15 ++ .../Source/SolidSyslogWinsockAddress.c | 16 ++ .../Source/SolidSyslogWinsockAddressPrivate.h | 29 +++ .../Source/SolidSyslogWinsockAddressStatic.c | 81 +++++++ Tests/CMakeLists.txt | 1 + Tests/SolidSyslogWinsockAddressTest.cpp | 210 ++++++++++++++++++ 8 files changed, 358 insertions(+) create mode 100644 Platform/Windows/Interface/SolidSyslogWinsockAddress.h create mode 100644 Platform/Windows/Source/SolidSyslogWinsockAddress.c create mode 100644 Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h create mode 100644 Platform/Windows/Source/SolidSyslogWinsockAddressStatic.c create mode 100644 Tests/SolidSyslogWinsockAddressTest.cpp diff --git a/Core/Source/SolidSyslogErrorMessages.h b/Core/Source/SolidSyslogErrorMessages.h index d1589e04..27938036 100644 --- a/Core/Source/SolidSyslogErrorMessages.h +++ b/Core/Source/SolidSyslogErrorMessages.h @@ -97,6 +97,10 @@ "SolidSyslogWindowsMutex_Create pool exhausted; returning fallback mutex" #define SOLIDSYSLOG_ERROR_MSG_WINDOWSMUTEX_UNKNOWN_DESTROY \ "SolidSyslogWindowsMutex_Destroy called with a handle not issued by this pool" +#define SOLIDSYSLOG_ERROR_MSG_WINSOCKADDRESS_POOL_EXHAUSTED \ + "SolidSyslogWinsockAddress_Create pool exhausted; returning fallback address" +#define SOLIDSYSLOG_ERROR_MSG_WINSOCKADDRESS_UNKNOWN_DESTROY \ + "SolidSyslogWinsockAddress_Destroy called with a handle not issued by this pool" #define SOLIDSYSLOG_ERROR_MSG_WINSOCKDATAGRAM_POOL_EXHAUSTED \ "SolidSyslogWinsockDatagram_Create pool exhausted; returning fallback datagram" #define SOLIDSYSLOG_ERROR_MSG_WINSOCKDATAGRAM_UNKNOWN_DESTROY \ diff --git a/Platform/Windows/CMakeLists.txt b/Platform/Windows/CMakeLists.txt index cd66e5ad..a417ca10 100644 --- a/Platform/Windows/CMakeLists.txt +++ b/Platform/Windows/CMakeLists.txt @@ -30,6 +30,8 @@ endif() if(SOLIDSYSLOG_WINSOCK) target_sources(${PROJECT_NAME} PRIVATE Source/SolidSyslogAddress.c + Source/SolidSyslogWinsockAddress.c + Source/SolidSyslogWinsockAddressStatic.c Source/SolidSyslogWinsockResolver.c Source/SolidSyslogWinsockResolverStatic.c Source/SolidSyslogWinsockDatagram.c diff --git a/Platform/Windows/Interface/SolidSyslogWinsockAddress.h b/Platform/Windows/Interface/SolidSyslogWinsockAddress.h new file mode 100644 index 00000000..583de3ea --- /dev/null +++ b/Platform/Windows/Interface/SolidSyslogWinsockAddress.h @@ -0,0 +1,15 @@ +#ifndef SOLIDSYSLOGWINSOCKADDRESS_H +#define SOLIDSYSLOGWINSOCKADDRESS_H + +#include "ExternC.h" + +EXTERN_C_BEGIN + + struct SolidSyslogAddress; + + struct SolidSyslogAddress* SolidSyslogWinsockAddress_Create(void); + void SolidSyslogWinsockAddress_Destroy(struct SolidSyslogAddress * base); + +EXTERN_C_END + +#endif /* SOLIDSYSLOGWINSOCKADDRESS_H */ diff --git a/Platform/Windows/Source/SolidSyslogWinsockAddress.c b/Platform/Windows/Source/SolidSyslogWinsockAddress.c new file mode 100644 index 00000000..6b1b700e --- /dev/null +++ b/Platform/Windows/Source/SolidSyslogWinsockAddress.c @@ -0,0 +1,16 @@ +#include "SolidSyslogWinsockAddressPrivate.h" + +#include + +struct SolidSyslogAddress; + +void WinsockAddress_Initialise(struct SolidSyslogAddress* base) +{ + struct SolidSyslogWinsockAddress* self = (struct SolidSyslogWinsockAddress*) base; + memset(&self->Sockaddr, 0, sizeof(self->Sockaddr)); +} + +void WinsockAddress_Cleanup(struct SolidSyslogAddress* base) +{ + (void) base; +} diff --git a/Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h b/Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h new file mode 100644 index 00000000..8df1e233 --- /dev/null +++ b/Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h @@ -0,0 +1,29 @@ +#ifndef SOLIDSYSLOGWINSOCKADDRESSPRIVATE_H +#define SOLIDSYSLOGWINSOCKADDRESSPRIVATE_H + +#include +#include + +struct SolidSyslogAddress; + +struct SolidSyslogWinsockAddress +{ + struct sockaddr_in Sockaddr; +}; + +void WinsockAddress_Initialise(struct SolidSyslogAddress* base); +void WinsockAddress_Cleanup(struct SolidSyslogAddress* base); + +static inline struct sockaddr_in* SolidSyslogWinsockAddress_AsSockaddrIn(struct SolidSyslogAddress* base) +{ + return &((struct SolidSyslogWinsockAddress*) base)->Sockaddr; +} + +static inline const struct sockaddr_in* SolidSyslogWinsockAddress_AsConstSockaddrIn( + const struct SolidSyslogAddress* base +) +{ + return &((const struct SolidSyslogWinsockAddress*) base)->Sockaddr; +} + +#endif /* SOLIDSYSLOGWINSOCKADDRESSPRIVATE_H */ diff --git a/Platform/Windows/Source/SolidSyslogWinsockAddressStatic.c b/Platform/Windows/Source/SolidSyslogWinsockAddressStatic.c new file mode 100644 index 00000000..95fc4682 --- /dev/null +++ b/Platform/Windows/Source/SolidSyslogWinsockAddressStatic.c @@ -0,0 +1,81 @@ +#include "SolidSyslogWinsockAddress.h" + +#include +#include + +#include "SolidSyslogError.h" +#include "SolidSyslogErrorMessages.h" +#include "SolidSyslogPoolAllocator.h" +#include "SolidSyslogPrival.h" +#include "SolidSyslogTunables.h" +#include "SolidSyslogWinsockAddressPrivate.h" + +struct SolidSyslogAddress; + +static inline struct SolidSyslogAddress* WinsockAddress_HandleFromIndex(size_t index); +static inline size_t WinsockAddress_IndexFromHandle(const struct SolidSyslogAddress* base); +static inline void WinsockAddress_CleanupAtIndex(size_t index, void* context); + +static bool WinsockAddress_InUse[SOLIDSYSLOG_ADDRESS_POOL_SIZE]; +static struct SolidSyslogWinsockAddress WinsockAddress_Pool[SOLIDSYSLOG_ADDRESS_POOL_SIZE]; +static struct SolidSyslogPoolAllocator WinsockAddress_Allocator = {WinsockAddress_InUse, SOLIDSYSLOG_ADDRESS_POOL_SIZE}; + +/* TU-private fallback returned when the pool is exhausted. Sized as a real + * SolidSyslogWinsockAddress so a Resolver overwrite at the exhausted-fallback + * call site is bounded — same sockaddr_in storage as any pooled slot. Not + * a per-Sender slot: multi-overflow integrators share this storage and + * race on it. Bumping SOLIDSYSLOG_ADDRESS_POOL_SIZE removes the race. */ +static struct SolidSyslogWinsockAddress WinsockAddress_Fallback; + +struct SolidSyslogAddress* SolidSyslogWinsockAddress_Create(void) +{ + size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&WinsockAddress_Allocator); + struct SolidSyslogAddress* handle = (struct SolidSyslogAddress*) &WinsockAddress_Fallback; + if (SolidSyslogPoolAllocator_IndexIsValid(&WinsockAddress_Allocator, index)) + { + handle = WinsockAddress_HandleFromIndex(index); + WinsockAddress_Initialise(handle); + } + else + { + SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_ERROR, SOLIDSYSLOG_ERROR_MSG_WINSOCKADDRESS_POOL_EXHAUSTED); + } + return handle; +} + +void SolidSyslogWinsockAddress_Destroy(struct SolidSyslogAddress* base) +{ + size_t index = WinsockAddress_IndexFromHandle(base); + bool released = + SolidSyslogPoolAllocator_IndexIsValid(&WinsockAddress_Allocator, index) && + SolidSyslogPoolAllocator_FreeIfInUse(&WinsockAddress_Allocator, index, WinsockAddress_CleanupAtIndex, NULL); + if (!released) + { + SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_WARNING, SOLIDSYSLOG_ERROR_MSG_WINSOCKADDRESS_UNKNOWN_DESTROY); + } +} + +static inline struct SolidSyslogAddress* WinsockAddress_HandleFromIndex(size_t index) +{ + return (struct SolidSyslogAddress*) &WinsockAddress_Pool[index]; +} + +static inline size_t WinsockAddress_IndexFromHandle(const struct SolidSyslogAddress* base) +{ + size_t result = SOLIDSYSLOG_ADDRESS_POOL_SIZE; + for (size_t poolIndex = 0; poolIndex < SOLIDSYSLOG_ADDRESS_POOL_SIZE; poolIndex++) + { + if (base == WinsockAddress_HandleFromIndex(poolIndex)) + { + result = poolIndex; + break; + } + } + return result; +} + +static inline void WinsockAddress_CleanupAtIndex(size_t index, void* context) +{ + (void) context; + WinsockAddress_Cleanup(WinsockAddress_HandleFromIndex(index)); +} diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index f3cd1db5..128550db 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -152,6 +152,7 @@ endif() if(SOLIDSYSLOG_WINSOCK) list(APPEND TEST_SOURCES WinsockFakeTest.cpp + SolidSyslogWinsockAddressTest.cpp SolidSyslogWinsockResolverTest.cpp SolidSyslogWinsockDatagramTest.cpp SolidSyslogWinsockTcpStreamTest.cpp diff --git a/Tests/SolidSyslogWinsockAddressTest.cpp b/Tests/SolidSyslogWinsockAddressTest.cpp new file mode 100644 index 00000000..a1c8ff6b --- /dev/null +++ b/Tests/SolidSyslogWinsockAddressTest.cpp @@ -0,0 +1,210 @@ +#include "TestUtils.h" +#include "CppUTest/TestHarness.h" + +using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-file scope only; brings NEVER/ONCE/TWICE/THRICE into scope for the CALLED_* + // macros + +#include +#include + +#include "ConfigLockFake.h" +#include "ErrorHandlerFake.h" +#include "SolidSyslogErrorMessages.h" +#include "SolidSyslogPrival.h" +#include "SolidSyslogTunables.h" +#include "SolidSyslogWinsockAddress.h" +#include "SolidSyslogWinsockAddressPrivate.h" + +// NOLINTBEGIN(cppcoreguidelines-macro-usage,cppcoreguidelines-avoid-do-while) -- macros preserve __FILE__/__LINE__ at the call site + +// Asserts handle is non-null and not one of the slots in pool. +#define CHECK_IS_FALLBACK(handle, pool) \ + do \ + { \ + CHECK_TEXT((handle) != nullptr, "Fallback handle was nullptr"); \ + for (auto* slot : (pool)) \ + { \ + CHECK_TEXT(slot != nullptr, "pool slot was nullptr (FillPool failed?)"); \ + CHECK_TEXT((handle) != slot, "Fallback handle collided with a pool slot"); \ + } \ + } while (0) + +// NOLINTEND(cppcoreguidelines-macro-usage,cppcoreguidelines-avoid-do-while) + +// clang-format off +TEST_GROUP(SolidSyslogWinsockAddress) +{ + struct SolidSyslogAddress* address = nullptr; + + void setup() override + { + address = SolidSyslogWinsockAddress_Create(); + } + + void teardown() override + { + SolidSyslogWinsockAddress_Destroy(address); + } +}; + +// clang-format on + +TEST(SolidSyslogWinsockAddress, CreateReturnsNonNull) +{ + CHECK(address != nullptr); +} + +TEST(SolidSyslogWinsockAddress, AsSockaddrInRoundTripsBytes) +{ + struct sockaddr_in expected = {}; + expected.sin_family = AF_INET; + expected.sin_port = htons(514U); + expected.sin_addr.s_addr = htonl(0x7F000001U); + + *SolidSyslogWinsockAddress_AsSockaddrIn(address) = expected; + + const struct sockaddr_in* actual = SolidSyslogWinsockAddress_AsConstSockaddrIn(address); + MEMCMP_EQUAL(&expected, actual, sizeof(expected)); +} + +TEST(SolidSyslogWinsockAddress, CreateZeroesTheSockaddrFromAnyPriorSlotContents) +{ + struct sockaddr_in dirty = {}; + dirty.sin_family = AF_INET; + dirty.sin_port = htons(9999U); + dirty.sin_addr.s_addr = htonl(0xDEADBEEFU); + *SolidSyslogWinsockAddress_AsSockaddrIn(address) = dirty; + SolidSyslogWinsockAddress_Destroy(address); + + address = SolidSyslogWinsockAddress_Create(); + + struct sockaddr_in zeroes = {}; + MEMCMP_EQUAL(&zeroes, SolidSyslogWinsockAddress_AsConstSockaddrIn(address), sizeof(zeroes)); +} + +// clang-format off +TEST_GROUP(SolidSyslogWinsockAddressPool) +{ + // cppcheck-suppress constVariable -- assigned in test bodies; cppcheck does not model CppUTest lifecycle + struct SolidSyslogAddress* pooled[SOLIDSYSLOG_ADDRESS_POOL_SIZE] = {}; + struct SolidSyslogAddress* overflow = nullptr; + + void teardown() override + { + for (auto* handle : pooled) + { + if (handle != nullptr) + { + SolidSyslogWinsockAddress_Destroy(handle); + } + } + // cppcheck-suppress knownConditionTrueFalse -- assigned in test bodies; cppcheck does not model CppUTest lifecycle + if (overflow != nullptr) + { + SolidSyslogWinsockAddress_Destroy(overflow); + } + ConfigLockFake_Uninstall(); + ErrorHandlerFake_Uninstall(); + } + + void FillPool() + { + for (auto*& slot : pooled) + { + slot = SolidSyslogWinsockAddress_Create(); + } + } +}; + +// clang-format on + +TEST(SolidSyslogWinsockAddressPool, FillingPoolThenOverflowReturnsDistinctFallback) +{ + FillPool(); + + overflow = SolidSyslogWinsockAddress_Create(); + + CHECK_IS_FALLBACK(overflow, pooled); +} + +TEST(SolidSyslogWinsockAddressPool, ExhaustedCreateReportsError) +{ + ErrorHandlerFake_Install(nullptr); + FillPool(); + + overflow = SolidSyslogWinsockAddress_Create(); + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_ERROR, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_WINSOCKADDRESS_POOL_EXHAUSTED, ErrorHandlerFake_LastMessage()); +} + +TEST(SolidSyslogWinsockAddressPool, CreateAcquiresAndReleasesConfigLockOnFirstFreeSlot) +{ + ConfigLockFake_Install(); + + pooled[0] = SolidSyslogWinsockAddress_Create(); + + CALLED_FAKE(ConfigLockFake_Lock, ONCE); + CALLED_FAKE(ConfigLockFake_Unlock, ONCE); +} + +TEST(SolidSyslogWinsockAddressPool, CreateLocksOncePerSlotProbedWhenPoolIsFull) +{ + FillPool(); + ConfigLockFake_Install(); + + overflow = SolidSyslogWinsockAddress_Create(); + + LONGS_EQUAL(SOLIDSYSLOG_ADDRESS_POOL_SIZE, ConfigLockFake_LockCallCount()); + LONGS_EQUAL(SOLIDSYSLOG_ADDRESS_POOL_SIZE, ConfigLockFake_UnlockCallCount()); +} + +TEST(SolidSyslogWinsockAddressPool, DestroyOfPooledHandleLocksOnce) +{ + pooled[0] = SolidSyslogWinsockAddress_Create(); + ConfigLockFake_Install(); + + SolidSyslogWinsockAddress_Destroy(pooled[0]); + pooled[0] = nullptr; + + CALLED_FAKE(ConfigLockFake_Lock, ONCE); + CALLED_FAKE(ConfigLockFake_Unlock, ONCE); +} + +TEST(SolidSyslogWinsockAddressPool, DestroyOfUnknownHandleDoesNotLock) +{ + ConfigLockFake_Install(); + char stranger = 0; + + SolidSyslogWinsockAddress_Destroy((struct SolidSyslogAddress*) &stranger); + + CALLED_FAKE(ConfigLockFake_Lock, NEVER); + CALLED_FAKE(ConfigLockFake_Unlock, NEVER); +} + +TEST(SolidSyslogWinsockAddressPool, DestroyOfUnknownHandleReportsWarning) +{ + ErrorHandlerFake_Install(nullptr); + char stranger = 0; + + SolidSyslogWinsockAddress_Destroy((struct SolidSyslogAddress*) &stranger); + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_WARNING, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_WINSOCKADDRESS_UNKNOWN_DESTROY, ErrorHandlerFake_LastMessage()); +} + +TEST(SolidSyslogWinsockAddressPool, DestroyOfStaleHandleReportsWarning) +{ + pooled[0] = SolidSyslogWinsockAddress_Create(); + SolidSyslogWinsockAddress_Destroy(pooled[0]); + ErrorHandlerFake_Install(nullptr); + + SolidSyslogWinsockAddress_Destroy(pooled[0]); + pooled[0] = nullptr; + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_WARNING, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_WINSOCKADDRESS_UNKNOWN_DESTROY, ErrorHandlerFake_LastMessage()); +} From 97c5dfbce8f4d6cd29ad34c8bca2403447c3dbff Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 08:55:24 +0100 Subject: [PATCH 04/12] feat: S24.07 SolidSyslogFreeRtosAddress pool class Duplicate-and-rename of the PosixAddress slice for the FreeRTOS target. Same 3-TU split, same TU-private fallback shape, same set of pool plumbing tests. Storage struct wraps struct freertos_sockaddr from ; AsFreertosSockaddr / AsConstFreertosSockaddr accessors are TU-private via SolidSyslogFreeRtosAddressPrivate.h. Reuses the shared SOLIDSYSLOG_ADDRESS_POOL_SIZE tunable. Verified locally in the cpputest-freertos host image: SolidSyslogFreeRtosAddressTest 11/11 green; the four other FreeRTOS host tests (Datagram, Mutex, StaticResolver, SysUpTime, TcpStream) all still green; SolidSyslogTests 1291/1293; MbedTlsStream tests 42/42. Co-Authored-By: Claude Opus 4.7 (1M context) --- Core/Source/SolidSyslogErrorMessages.h | 4 + .../Interface/SolidSyslogFreeRtosAddress.h | 15 ++ .../Source/SolidSyslogFreeRtosAddress.c | 16 ++ .../SolidSyslogFreeRtosAddressPrivate.h | 29 +++ .../Source/SolidSyslogFreeRtosAddressStatic.c | 84 +++++++ Tests/FreeRtos/CMakeLists.txt | 28 +++ .../SolidSyslogFreeRtosAddressTest.cpp | 213 ++++++++++++++++++ 7 files changed, 389 insertions(+) create mode 100644 Platform/FreeRtos/Interface/SolidSyslogFreeRtosAddress.h create mode 100644 Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c create mode 100644 Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h create mode 100644 Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c create mode 100644 Tests/FreeRtos/SolidSyslogFreeRtosAddressTest.cpp diff --git a/Core/Source/SolidSyslogErrorMessages.h b/Core/Source/SolidSyslogErrorMessages.h index 27938036..234fc90c 100644 --- a/Core/Source/SolidSyslogErrorMessages.h +++ b/Core/Source/SolidSyslogErrorMessages.h @@ -121,6 +121,10 @@ "SolidSyslogFreeRtosMutex_Create pool exhausted; returning fallback mutex" #define SOLIDSYSLOG_ERROR_MSG_FREERTOSMUTEX_UNKNOWN_DESTROY \ "SolidSyslogFreeRtosMutex_Destroy called with a handle not issued by this pool" +#define SOLIDSYSLOG_ERROR_MSG_FREERTOSADDRESS_POOL_EXHAUSTED \ + "SolidSyslogFreeRtosAddress_Create pool exhausted; returning fallback address" +#define SOLIDSYSLOG_ERROR_MSG_FREERTOSADDRESS_UNKNOWN_DESTROY \ + "SolidSyslogFreeRtosAddress_Destroy called with a handle not issued by this pool" #define SOLIDSYSLOG_ERROR_MSG_FREERTOSDATAGRAM_POOL_EXHAUSTED \ "SolidSyslogFreeRtosDatagram_Create pool exhausted; returning fallback datagram" #define SOLIDSYSLOG_ERROR_MSG_FREERTOSDATAGRAM_UNKNOWN_DESTROY \ diff --git a/Platform/FreeRtos/Interface/SolidSyslogFreeRtosAddress.h b/Platform/FreeRtos/Interface/SolidSyslogFreeRtosAddress.h new file mode 100644 index 00000000..8dd35894 --- /dev/null +++ b/Platform/FreeRtos/Interface/SolidSyslogFreeRtosAddress.h @@ -0,0 +1,15 @@ +#ifndef SOLIDSYSLOGFREERTOSADDRESS_H +#define SOLIDSYSLOGFREERTOSADDRESS_H + +#include "ExternC.h" + +EXTERN_C_BEGIN + + struct SolidSyslogAddress; + + struct SolidSyslogAddress* SolidSyslogFreeRtosAddress_Create(void); + void SolidSyslogFreeRtosAddress_Destroy(struct SolidSyslogAddress * base); + +EXTERN_C_END + +#endif /* SOLIDSYSLOGFREERTOSADDRESS_H */ diff --git a/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c b/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c new file mode 100644 index 00000000..f09c7bac --- /dev/null +++ b/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c @@ -0,0 +1,16 @@ +#include "SolidSyslogFreeRtosAddressPrivate.h" + +#include + +struct SolidSyslogAddress; + +void FreeRtosAddress_Initialise(struct SolidSyslogAddress* base) +{ + struct SolidSyslogFreeRtosAddress* self = (struct SolidSyslogFreeRtosAddress*) base; + memset(&self->Sockaddr, 0, sizeof(self->Sockaddr)); +} + +void FreeRtosAddress_Cleanup(struct SolidSyslogAddress* base) +{ + (void) base; +} diff --git a/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h b/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h new file mode 100644 index 00000000..3a3df552 --- /dev/null +++ b/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h @@ -0,0 +1,29 @@ +#ifndef SOLIDSYSLOGFREERTOSADDRESSPRIVATE_H +#define SOLIDSYSLOGFREERTOSADDRESSPRIVATE_H + +#include "FreeRTOS.h" +#include "FreeRTOS_Sockets.h" + +struct SolidSyslogAddress; + +struct SolidSyslogFreeRtosAddress +{ + struct freertos_sockaddr Sockaddr; +}; + +void FreeRtosAddress_Initialise(struct SolidSyslogAddress* base); +void FreeRtosAddress_Cleanup(struct SolidSyslogAddress* base); + +static inline struct freertos_sockaddr* SolidSyslogFreeRtosAddress_AsFreertosSockaddr(struct SolidSyslogAddress* base) +{ + return &((struct SolidSyslogFreeRtosAddress*) base)->Sockaddr; +} + +static inline const struct freertos_sockaddr* SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr( + const struct SolidSyslogAddress* base +) +{ + return &((const struct SolidSyslogFreeRtosAddress*) base)->Sockaddr; +} + +#endif /* SOLIDSYSLOGFREERTOSADDRESSPRIVATE_H */ diff --git a/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c b/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c new file mode 100644 index 00000000..d5b16060 --- /dev/null +++ b/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c @@ -0,0 +1,84 @@ +#include "SolidSyslogFreeRtosAddress.h" + +#include +#include + +#include "SolidSyslogError.h" +#include "SolidSyslogErrorMessages.h" +#include "SolidSyslogFreeRtosAddressPrivate.h" +#include "SolidSyslogPoolAllocator.h" +#include "SolidSyslogPrival.h" +#include "SolidSyslogTunables.h" + +struct SolidSyslogAddress; + +static inline struct SolidSyslogAddress* FreeRtosAddress_HandleFromIndex(size_t index); +static inline size_t FreeRtosAddress_IndexFromHandle(const struct SolidSyslogAddress* base); +static inline void FreeRtosAddress_CleanupAtIndex(size_t index, void* context); + +static bool FreeRtosAddress_InUse[SOLIDSYSLOG_ADDRESS_POOL_SIZE]; +static struct SolidSyslogFreeRtosAddress FreeRtosAddress_Pool[SOLIDSYSLOG_ADDRESS_POOL_SIZE]; +static struct SolidSyslogPoolAllocator FreeRtosAddress_Allocator = { + FreeRtosAddress_InUse, + SOLIDSYSLOG_ADDRESS_POOL_SIZE +}; + +/* TU-private fallback returned when the pool is exhausted. Sized as a real + * SolidSyslogFreeRtosAddress so a Resolver overwrite at the exhausted-fallback + * call site is bounded — same freertos_sockaddr storage as any pooled slot. + * Not a per-Sender slot: multi-overflow integrators share this storage and + * race on it. Bumping SOLIDSYSLOG_ADDRESS_POOL_SIZE removes the race. */ +static struct SolidSyslogFreeRtosAddress FreeRtosAddress_Fallback; + +struct SolidSyslogAddress* SolidSyslogFreeRtosAddress_Create(void) +{ + size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&FreeRtosAddress_Allocator); + struct SolidSyslogAddress* handle = (struct SolidSyslogAddress*) &FreeRtosAddress_Fallback; + if (SolidSyslogPoolAllocator_IndexIsValid(&FreeRtosAddress_Allocator, index)) + { + handle = FreeRtosAddress_HandleFromIndex(index); + FreeRtosAddress_Initialise(handle); + } + else + { + SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_ERROR, SOLIDSYSLOG_ERROR_MSG_FREERTOSADDRESS_POOL_EXHAUSTED); + } + return handle; +} + +void SolidSyslogFreeRtosAddress_Destroy(struct SolidSyslogAddress* base) +{ + size_t index = FreeRtosAddress_IndexFromHandle(base); + bool released = + SolidSyslogPoolAllocator_IndexIsValid(&FreeRtosAddress_Allocator, index) && + SolidSyslogPoolAllocator_FreeIfInUse(&FreeRtosAddress_Allocator, index, FreeRtosAddress_CleanupAtIndex, NULL); + if (!released) + { + SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_WARNING, SOLIDSYSLOG_ERROR_MSG_FREERTOSADDRESS_UNKNOWN_DESTROY); + } +} + +static inline struct SolidSyslogAddress* FreeRtosAddress_HandleFromIndex(size_t index) +{ + return (struct SolidSyslogAddress*) &FreeRtosAddress_Pool[index]; +} + +static inline size_t FreeRtosAddress_IndexFromHandle(const struct SolidSyslogAddress* base) +{ + size_t result = SOLIDSYSLOG_ADDRESS_POOL_SIZE; + for (size_t poolIndex = 0; poolIndex < SOLIDSYSLOG_ADDRESS_POOL_SIZE; poolIndex++) + { + if (base == FreeRtosAddress_HandleFromIndex(poolIndex)) + { + result = poolIndex; + break; + } + } + return result; +} + +static inline void FreeRtosAddress_CleanupAtIndex(size_t index, void* context) +{ + (void) context; + FreeRtosAddress_Cleanup(FreeRtosAddress_HandleFromIndex(index)); +} diff --git a/Tests/FreeRtos/CMakeLists.txt b/Tests/FreeRtos/CMakeLists.txt index 9e3b2e57..f4071d02 100644 --- a/Tests/FreeRtos/CMakeLists.txt +++ b/Tests/FreeRtos/CMakeLists.txt @@ -98,6 +98,34 @@ else() ) add_test(NAME SolidSyslogFreeRtosStaticResolverTest COMMAND SolidSyslogFreeRtosStaticResolverTest) + + add_executable(SolidSyslogFreeRtosAddressTest + SolidSyslogFreeRtosAddressTest.cpp + main.cpp + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c + ) + + target_link_libraries(SolidSyslogFreeRtosAddressTest PRIVATE + ${PROJECT_NAME} + ConfigLockFake + ErrorHandlerFake + CppUTest + CppUTestExt + ) + + target_include_directories(SolidSyslogFreeRtosAddressTest PRIVATE + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Interface + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source + ${CMAKE_SOURCE_DIR}/Core/Interface + ${CMAKE_SOURCE_DIR}/Core/Source + ${CMAKE_SOURCE_DIR}/Tests/Support + ${CMAKE_SOURCE_DIR}/Tests/Support/FreeRtosFakes/Interface + $ENV{FREERTOS_KERNEL_PATH}/include + $ENV{FREERTOS_PLUS_TCP_PATH}/source/include + ) + + add_test(NAME SolidSyslogFreeRtosAddressTest COMMAND SolidSyslogFreeRtosAddressTest) endif() # SolidSyslogFreeRtosMutex — kernel-only adapter wrapping a FreeRTOS static diff --git a/Tests/FreeRtos/SolidSyslogFreeRtosAddressTest.cpp b/Tests/FreeRtos/SolidSyslogFreeRtosAddressTest.cpp new file mode 100644 index 00000000..88d5376c --- /dev/null +++ b/Tests/FreeRtos/SolidSyslogFreeRtosAddressTest.cpp @@ -0,0 +1,213 @@ +#include "TestUtils.h" +#include "CppUTest/TestHarness.h" + +using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-file scope only; brings NEVER/ONCE/TWICE/THRICE into scope for the CALLED_* + // macros + +#include + +#include "ConfigLockFake.h" +#include "ErrorHandlerFake.h" +#include "SolidSyslogErrorMessages.h" +#include "SolidSyslogFreeRtosAddress.h" +#include "SolidSyslogFreeRtosAddressPrivate.h" +#include "SolidSyslogPrival.h" +#include "SolidSyslogTunables.h" + +#include "FreeRTOS.h" +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" + +// NOLINTBEGIN(cppcoreguidelines-macro-usage,cppcoreguidelines-avoid-do-while) -- macros preserve __FILE__/__LINE__ at the call site + +// Asserts handle is non-null and not one of the slots in pool. +#define CHECK_IS_FALLBACK(handle, pool) \ + do \ + { \ + CHECK_TEXT((handle) != nullptr, "Fallback handle was nullptr"); \ + for (auto* slot : (pool)) \ + { \ + CHECK_TEXT(slot != nullptr, "pool slot was nullptr (FillPool failed?)"); \ + CHECK_TEXT((handle) != slot, "Fallback handle collided with a pool slot"); \ + } \ + } while (0) + +// NOLINTEND(cppcoreguidelines-macro-usage,cppcoreguidelines-avoid-do-while) + +// clang-format off +TEST_GROUP(SolidSyslogFreeRtosAddress) +{ + struct SolidSyslogAddress* address = nullptr; + + void setup() override + { + address = SolidSyslogFreeRtosAddress_Create(); + } + + void teardown() override + { + SolidSyslogFreeRtosAddress_Destroy(address); + } +}; + +// clang-format on + +TEST(SolidSyslogFreeRtosAddress, CreateReturnsNonNull) +{ + CHECK(address != nullptr); +} + +TEST(SolidSyslogFreeRtosAddress, AsFreertosSockaddrRoundTripsBytes) +{ + struct freertos_sockaddr expected = {}; + expected.sin_family = FREERTOS_AF_INET; + expected.sin_port = FreeRTOS_htons(514U); + expected.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick(127, 0, 0, 1); + + *SolidSyslogFreeRtosAddress_AsFreertosSockaddr(address) = expected; + + const struct freertos_sockaddr* actual = SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(address); + MEMCMP_EQUAL(&expected, actual, sizeof(expected)); +} + +TEST(SolidSyslogFreeRtosAddress, CreateZeroesTheSockaddrFromAnyPriorSlotContents) +{ + struct freertos_sockaddr dirty = {}; + dirty.sin_family = FREERTOS_AF_INET; + dirty.sin_port = FreeRTOS_htons(9999U); + dirty.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick(1, 2, 3, 4); + *SolidSyslogFreeRtosAddress_AsFreertosSockaddr(address) = dirty; + SolidSyslogFreeRtosAddress_Destroy(address); + + address = SolidSyslogFreeRtosAddress_Create(); + + struct freertos_sockaddr zeroes = {}; + MEMCMP_EQUAL(&zeroes, SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(address), sizeof(zeroes)); +} + +// clang-format off +TEST_GROUP(SolidSyslogFreeRtosAddressPool) +{ + // cppcheck-suppress constVariable -- assigned in test bodies; cppcheck does not model CppUTest lifecycle + struct SolidSyslogAddress* pooled[SOLIDSYSLOG_ADDRESS_POOL_SIZE] = {}; + struct SolidSyslogAddress* overflow = nullptr; + + void teardown() override + { + for (auto* handle : pooled) + { + if (handle != nullptr) + { + SolidSyslogFreeRtosAddress_Destroy(handle); + } + } + // cppcheck-suppress knownConditionTrueFalse -- assigned in test bodies; cppcheck does not model CppUTest lifecycle + if (overflow != nullptr) + { + SolidSyslogFreeRtosAddress_Destroy(overflow); + } + ConfigLockFake_Uninstall(); + ErrorHandlerFake_Uninstall(); + } + + void FillPool() + { + for (auto*& slot : pooled) + { + slot = SolidSyslogFreeRtosAddress_Create(); + } + } +}; + +// clang-format on + +TEST(SolidSyslogFreeRtosAddressPool, FillingPoolThenOverflowReturnsDistinctFallback) +{ + FillPool(); + + overflow = SolidSyslogFreeRtosAddress_Create(); + + CHECK_IS_FALLBACK(overflow, pooled); +} + +TEST(SolidSyslogFreeRtosAddressPool, ExhaustedCreateReportsError) +{ + ErrorHandlerFake_Install(nullptr); + FillPool(); + + overflow = SolidSyslogFreeRtosAddress_Create(); + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_ERROR, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_FREERTOSADDRESS_POOL_EXHAUSTED, ErrorHandlerFake_LastMessage()); +} + +TEST(SolidSyslogFreeRtosAddressPool, CreateAcquiresAndReleasesConfigLockOnFirstFreeSlot) +{ + ConfigLockFake_Install(); + + pooled[0] = SolidSyslogFreeRtosAddress_Create(); + + CALLED_FAKE(ConfigLockFake_Lock, ONCE); + CALLED_FAKE(ConfigLockFake_Unlock, ONCE); +} + +TEST(SolidSyslogFreeRtosAddressPool, CreateLocksOncePerSlotProbedWhenPoolIsFull) +{ + FillPool(); + ConfigLockFake_Install(); + + overflow = SolidSyslogFreeRtosAddress_Create(); + + LONGS_EQUAL(SOLIDSYSLOG_ADDRESS_POOL_SIZE, ConfigLockFake_LockCallCount()); + LONGS_EQUAL(SOLIDSYSLOG_ADDRESS_POOL_SIZE, ConfigLockFake_UnlockCallCount()); +} + +TEST(SolidSyslogFreeRtosAddressPool, DestroyOfPooledHandleLocksOnce) +{ + pooled[0] = SolidSyslogFreeRtosAddress_Create(); + ConfigLockFake_Install(); + + SolidSyslogFreeRtosAddress_Destroy(pooled[0]); + pooled[0] = nullptr; + + CALLED_FAKE(ConfigLockFake_Lock, ONCE); + CALLED_FAKE(ConfigLockFake_Unlock, ONCE); +} + +TEST(SolidSyslogFreeRtosAddressPool, DestroyOfUnknownHandleDoesNotLock) +{ + ConfigLockFake_Install(); + char stranger = 0; + + SolidSyslogFreeRtosAddress_Destroy((struct SolidSyslogAddress*) &stranger); + + CALLED_FAKE(ConfigLockFake_Lock, NEVER); + CALLED_FAKE(ConfigLockFake_Unlock, NEVER); +} + +TEST(SolidSyslogFreeRtosAddressPool, DestroyOfUnknownHandleReportsWarning) +{ + ErrorHandlerFake_Install(nullptr); + char stranger = 0; + + SolidSyslogFreeRtosAddress_Destroy((struct SolidSyslogAddress*) &stranger); + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_WARNING, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_FREERTOSADDRESS_UNKNOWN_DESTROY, ErrorHandlerFake_LastMessage()); +} + +TEST(SolidSyslogFreeRtosAddressPool, DestroyOfStaleHandleReportsWarning) +{ + pooled[0] = SolidSyslogFreeRtosAddress_Create(); + SolidSyslogFreeRtosAddress_Destroy(pooled[0]); + ErrorHandlerFake_Install(nullptr); + + SolidSyslogFreeRtosAddress_Destroy(pooled[0]); + pooled[0] = nullptr; + + CALLED_FAKE(ErrorHandlerFake_Handle, ONCE); + LONGS_EQUAL(SOLIDSYSLOG_SEVERITY_WARNING, ErrorHandlerFake_LastSeverity()); + STRCMP_EQUAL(SOLIDSYSLOG_ERROR_MSG_FREERTOSADDRESS_UNKNOWN_DESTROY, ErrorHandlerFake_LastMessage()); +} From e02afa0d73cccec64098825d19f07ee8fc188e53 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 08:59:53 +0100 Subject: [PATCH 05/12] refactor: S24.07 SOLIDSYSLOG_ADDRESS_POOL_SIZE default to 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Matches the canonical BDD multi-transport wiring (one Address per Sender across UDP + plain-TCP + TLS-stream). Same trade-off applied by SOLIDSYSLOG_POSIX_TCP_STREAM_POOL_SIZE and SOLIDSYSLOG_STREAM_SENDER_POOL_SIZE — single-transport integrators pay a small unused-slot cost, multi-transport integrators get the canonical wiring without an override. Co-Authored-By: Claude Opus 4.7 (1M context) --- Core/Interface/SolidSyslogTunablesDefaults.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Core/Interface/SolidSyslogTunablesDefaults.h b/Core/Interface/SolidSyslogTunablesDefaults.h index 69b9fa68..6329764c 100644 --- a/Core/Interface/SolidSyslogTunablesDefaults.h +++ b/Core/Interface/SolidSyslogTunablesDefaults.h @@ -676,16 +676,20 @@ * carries one platform sockaddr (struct sockaddr_in on POSIX/Windows, * struct freertos_sockaddr on FreeRTOS) — ~16 bytes per slot. * - * Default 1 — typical integrator wires one Sender. Multi-transport - * integrators (e.g. the BDD targets wiring UDP + plain-TCP + TLS-stream) - * override this via SOLIDSYSLOG_USER_TUNABLES_FILE; the BDD wirings are - * deliberately the unusual case rather than the default. + * Default 3 — matches the canonical BDD multi-transport wiring + * (UDP + plain-TCP + TLS-stream, one Address per Sender) so common + * integrators are spared an override. Same trade-off as + * SOLIDSYSLOG_POSIX_TCP_STREAM_POOL_SIZE / _STREAM_SENDER_POOL_SIZE: + * single-transport integrators pay ~32 bytes of unused slots per platform; + * multi-transport integrators get the canonical wiring out of the box. + * Bump via SOLIDSYSLOG_USER_TUNABLES_FILE if more than three concurrent + * senders are needed. * * Floor: 1. Sub-floor values rejected at compile time. */ #ifndef SOLIDSYSLOG_ADDRESS_POOL_SIZE /* NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -- macro form required for preprocessor visibility (floor #if) and C array-size const-expr. */ -#define SOLIDSYSLOG_ADDRESS_POOL_SIZE 1U +#define SOLIDSYSLOG_ADDRESS_POOL_SIZE 3U #endif #if SOLIDSYSLOG_ADDRESS_POOL_SIZE < 1 From 69f69f4fdcf4f1c56d4fa29ab896ffd9095c7bae Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 09:05:10 +0100 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20S24.07=20UdpSenderConfig.Address?= =?UTF-8?q?=20=E2=80=94=20thread=20Address=20through?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a required Address field to SolidSyslogUdpSenderConfig and drops the inline 128-byte SolidSyslogAddressStorage that every UdpSender slot carried under the old caller-supplied-storage pattern. UdpSender now reads the destination slot via self->Config.Address; the platform Address pool owns the storage. Bad-setup contract: Create rejects a NULL Address handle with SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_ADDRESS and the resulting sender resolves to SolidSyslogNullSender, matching the existing NULL-Resolver / NULL-Datagram / NULL-Endpoint shape. Threads the new field through every UdpSender consumer: SolidSyslogUdpSenderTest (and the Retry / Reconnect / Endpoint test groups it backs), BddTargetServiceThreadTest, and the three BDD-target main.c files (Linux / Windows / FreeRtos) — each wires an Address handle from its platform's pool and destroys it after the Sender. Co-Authored-By: Claude Opus 4.7 (1M context) --- Bdd/Targets/FreeRtos/main.c | 5 +++++ Bdd/Targets/Linux/main.c | 5 +++++ Bdd/Targets/Windows/BddTargetWindows.c | 5 +++++ Core/Interface/SolidSyslogUdpSender.h | 1 + Core/Source/SolidSyslogErrorMessages.h | 1 + Core/Source/SolidSyslogUdpSender.c | 3 +-- Core/Source/SolidSyslogUdpSenderPrivate.h | 2 -- Core/Source/SolidSyslogUdpSenderStatic.c | 4 ++++ .../Bdd/Targets/BddTargetServiceThreadTest.cpp | 6 +++++- Tests/SolidSyslogUdpSenderTest.cpp | 17 +++++++++++++++-- 10 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Bdd/Targets/FreeRtos/main.c b/Bdd/Targets/FreeRtos/main.c index c0425974..00936016 100644 --- a/Bdd/Targets/FreeRtos/main.c +++ b/Bdd/Targets/FreeRtos/main.c @@ -42,6 +42,7 @@ #include "SolidSyslogFatFsFile.h" #include "SolidSyslogFileBlockDevice.h" #include "SolidSyslogFormatter.h" +#include "SolidSyslogFreeRtosAddress.h" #include "SolidSyslogFreeRtosDatagram.h" #include "SolidSyslogFreeRtosMutex.h" #include "SolidSyslogFreeRtosStaticResolver.h" @@ -238,6 +239,7 @@ static struct SolidSyslogStructuredData* originSd = NULL; * TeardownAll then SemihostingExit). */ static struct SolidSyslogResolver* resolver = NULL; static struct SolidSyslogDatagram* datagram = NULL; +static struct SolidSyslogAddress* udpAddress = NULL; static struct SolidSyslogStream* tcpStream = NULL; static struct SolidSyslogSender* tcpSender = NULL; static struct SolidSyslogSender* tlsSender = NULL; @@ -702,6 +704,7 @@ static void TeardownAll(void) SolidSyslogStreamSender_Destroy(tcpSender); SolidSyslogFreeRtosTcpStream_Destroy(tcpStream); SolidSyslogUdpSender_Destroy(udpSender); + SolidSyslogFreeRtosAddress_Destroy(udpAddress); SolidSyslogFreeRtosDatagram_Destroy(datagram); SolidSyslogFreeRtosStaticResolver_Destroy(resolver); } @@ -805,10 +808,12 @@ static void InteractiveTask(void* argument) resolver = SolidSyslogFreeRtosStaticResolver_Create(TEST_DESTINATION_IPV4); datagram = SolidSyslogFreeRtosDatagram_Create(); + udpAddress = SolidSyslogFreeRtosAddress_Create(); struct SolidSyslogUdpSenderConfig udpConfig = { .Resolver = resolver, .Datagram = datagram, + .Address = udpAddress, .Endpoint = GetEndpoint, .EndpointVersion = GetEndpointVersion, }; diff --git a/Bdd/Targets/Linux/main.c b/Bdd/Targets/Linux/main.c index fbbd8f6a..c2d3cf15 100644 --- a/Bdd/Targets/Linux/main.c +++ b/Bdd/Targets/Linux/main.c @@ -38,6 +38,7 @@ #include "SolidSyslogPosixSleep.h" #include "SolidSyslogPosixSysUpTime.h" #include "SolidSyslogGetAddrInfoResolver.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogPosixDatagram.h" #include "SolidSyslogPosixTcpStream.h" #include "SolidSyslogSwitchingSender.h" @@ -56,6 +57,7 @@ static struct SolidSyslogSender* plainTcpSender; static struct SolidSyslogSender* udpSender; static struct SolidSyslogSender* switchingSender; static struct SolidSyslogDatagram* udpDatagram; +static struct SolidSyslogAddress* udpAddress; static struct SolidSyslogResolver* sharedResolver; static void GetTimeQuality(struct SolidSyslogTimeQuality* timeQuality) @@ -83,9 +85,11 @@ static struct SolidSyslogSender* CreateSender(const struct BddTargetOptions* opt struct SolidSyslogResolver* resolver = sharedResolver; udpDatagram = SolidSyslogPosixDatagram_Create(); + udpAddress = SolidSyslogPosixAddress_Create(); static struct SolidSyslogUdpSenderConfig udpConfig = {0}; udpConfig.Resolver = resolver; udpConfig.Datagram = udpDatagram; + udpConfig.Address = udpAddress; udpConfig.Endpoint = BddTargetUdpConfig_GetEndpoint; udpConfig.EndpointVersion = BddTargetUdpConfig_GetEndpointVersion; udpSender = SolidSyslogUdpSender_Create(&udpConfig); @@ -191,6 +195,7 @@ static void DestroySender(void) SolidSyslogStreamSender_Destroy(plainTcpSender); SolidSyslogPosixTcpStream_Destroy(plainTcpStream); SolidSyslogUdpSender_Destroy(udpSender); + SolidSyslogPosixAddress_Destroy(udpAddress); SolidSyslogPosixDatagram_Destroy(udpDatagram); SolidSyslogGetAddrInfoResolver_Destroy(sharedResolver); } diff --git a/Bdd/Targets/Windows/BddTargetWindows.c b/Bdd/Targets/Windows/BddTargetWindows.c index a9f5e21d..537b28a0 100644 --- a/Bdd/Targets/Windows/BddTargetWindows.c +++ b/Bdd/Targets/Windows/BddTargetWindows.c @@ -34,6 +34,7 @@ #include "SolidSyslogWindowsProcessId.h" #include "SolidSyslogWindowsSleep.h" #include "SolidSyslogWindowsSysUpTime.h" +#include "SolidSyslogWinsockAddress.h" #include "SolidSyslogWinsockDatagram.h" #include "SolidSyslogWinsockResolver.h" #include "SolidSyslogWinsockTcpStream.h" @@ -74,6 +75,7 @@ static struct SolidSyslogResolver* resolver; static struct SolidSyslogStream* plainTcpStream; static struct SolidSyslogSender* plainTcpSender; static struct SolidSyslogDatagram* udpDatagram; +static struct SolidSyslogAddress* udpAddress; static struct SolidSyslogSender* udpSender; static struct SolidSyslogSender* switchingSender; @@ -181,9 +183,11 @@ static struct SolidSyslogSender* CreateSender(const struct BddTargetWindowsOptio resolver = SolidSyslogWinsockResolver_Create(); udpDatagram = SolidSyslogWinsockDatagram_Create(); + udpAddress = SolidSyslogWinsockAddress_Create(); static struct SolidSyslogUdpSenderConfig udpConfig = {0}; udpConfig.Resolver = resolver; udpConfig.Datagram = udpDatagram; + udpConfig.Address = udpAddress; udpConfig.Endpoint = GetEndpoint; udpConfig.EndpointVersion = GetEndpointVersion; udpSender = SolidSyslogUdpSender_Create(&udpConfig); @@ -220,6 +224,7 @@ static void DestroySender(void) SolidSyslogStreamSender_Destroy(plainTcpSender); SolidSyslogWinsockTcpStream_Destroy(plainTcpStream); SolidSyslogUdpSender_Destroy(udpSender); + SolidSyslogWinsockAddress_Destroy(udpAddress); SolidSyslogWinsockDatagram_Destroy(udpDatagram); SolidSyslogWinsockResolver_Destroy(resolver); } diff --git a/Core/Interface/SolidSyslogUdpSender.h b/Core/Interface/SolidSyslogUdpSender.h index c9520f62..5174fd61 100644 --- a/Core/Interface/SolidSyslogUdpSender.h +++ b/Core/Interface/SolidSyslogUdpSender.h @@ -12,6 +12,7 @@ EXTERN_C_BEGIN { struct SolidSyslogResolver* Resolver; struct SolidSyslogDatagram* Datagram; + struct SolidSyslogAddress* Address; SolidSyslogEndpointFunction Endpoint; /* fills host/port; called only on (re)connect */ SolidSyslogEndpointVersionFunction EndpointVersion; /* polled cheaply on every Send for stale check */ }; diff --git a/Core/Source/SolidSyslogErrorMessages.h b/Core/Source/SolidSyslogErrorMessages.h index 234fc90c..31027aa8 100644 --- a/Core/Source/SolidSyslogErrorMessages.h +++ b/Core/Source/SolidSyslogErrorMessages.h @@ -17,6 +17,7 @@ #define SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_CONFIG "SolidSyslogUdpSender_Create called with NULL config" #define SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_RESOLVER "SolidSyslogUdpSender_Create config.Resolver is NULL" #define SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_DATAGRAM "SolidSyslogUdpSender_Create config.Datagram is NULL" +#define SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_ADDRESS "SolidSyslogUdpSender_Create config.Address is NULL" #define SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_ENDPOINT "SolidSyslogUdpSender_Create config.Endpoint is NULL" #define SOLIDSYSLOG_ERROR_MSG_UDPSENDER_SEND_NULL_BUFFER "SolidSyslogUdpSender_Send called with NULL buffer" #define SOLIDSYSLOG_ERROR_MSG_UDPSENDER_POOL_EXHAUSTED \ diff --git a/Core/Source/SolidSyslogUdpSender.c b/Core/Source/SolidSyslogUdpSender.c index c24ea00f..882fbd31 100644 --- a/Core/Source/SolidSyslogUdpSender.c +++ b/Core/Source/SolidSyslogUdpSender.c @@ -2,7 +2,6 @@ #include #include -#include "SolidSyslogAddress.h" #include "SolidSyslogDatagram.h" #include "SolidSyslogEndpoint.h" #include "SolidSyslogError.h" @@ -171,7 +170,7 @@ static bool UdpSender_ResolveDestination(struct SolidSyslogUdpSender* self, cons static inline struct SolidSyslogAddress* UdpSender_Address(struct SolidSyslogUdpSender* self) { - return SolidSyslogAddress_FromStorage(&self->AddrStorage); + return self->Config.Address; } static inline void UdpSender_CloseSocket(struct SolidSyslogUdpSender* self) diff --git a/Core/Source/SolidSyslogUdpSenderPrivate.h b/Core/Source/SolidSyslogUdpSenderPrivate.h index 892db5c2..84bc4418 100644 --- a/Core/Source/SolidSyslogUdpSenderPrivate.h +++ b/Core/Source/SolidSyslogUdpSenderPrivate.h @@ -4,7 +4,6 @@ #include #include -#include "SolidSyslogAddress.h" #include "SolidSyslogSenderDefinition.h" #include "SolidSyslogUdpSender.h" @@ -12,7 +11,6 @@ struct SolidSyslogUdpSender { struct SolidSyslogSender Base; struct SolidSyslogUdpSenderConfig Config; - SolidSyslogAddressStorage AddrStorage; bool Connected; uint32_t LastEndpointVersion; }; diff --git a/Core/Source/SolidSyslogUdpSenderStatic.c b/Core/Source/SolidSyslogUdpSenderStatic.c index 3ddea751..49220528 100644 --- a/Core/Source/SolidSyslogUdpSenderStatic.c +++ b/Core/Source/SolidSyslogUdpSenderStatic.c @@ -66,6 +66,10 @@ static bool UdpSender_IsValidConfig(const struct SolidSyslogUdpSenderConfig* con { SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_ERROR, SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_DATAGRAM); } + else if (config->Address == NULL) + { + SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_ERROR, SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_ADDRESS); + } else if (config->Endpoint == NULL) { SolidSyslog_Error(SOLIDSYSLOG_SEVERITY_ERROR, SOLIDSYSLOG_ERROR_MSG_UDPSENDER_CREATE_NULL_ENDPOINT); diff --git a/Tests/Bdd/Targets/BddTargetServiceThreadTest.cpp b/Tests/Bdd/Targets/BddTargetServiceThreadTest.cpp index 5d353826..a7ff301e 100644 --- a/Tests/Bdd/Targets/BddTargetServiceThreadTest.cpp +++ b/Tests/Bdd/Targets/BddTargetServiceThreadTest.cpp @@ -8,6 +8,7 @@ #include "SolidSyslogFormatter.h" #include "SolidSyslogPosixMessageQueueBuffer.h" #include "SolidSyslogGetAddrInfoResolver.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogPosixDatagram.h" #include "SolidSyslogUdpSender.h" #include "SolidSyslogNullStore.h" @@ -55,6 +56,7 @@ TEST_GROUP(BddTargetServiceThread) struct SolidSyslogStore* store = nullptr; struct SolidSyslogDatagram* datagram = nullptr; struct SolidSyslogResolver* resolver = nullptr; + struct SolidSyslogAddress* address = nullptr; // cppcheck-suppress variableScope -- member of TEST_GROUP; scope managed by CppUTest macro volatile bool shutdown; @@ -70,7 +72,8 @@ TEST_GROUP(BddTargetServiceThread) resolver = SolidSyslogGetAddrInfoResolver_Create(); datagram = SolidSyslogPosixDatagram_Create(); - SolidSyslogUdpSenderConfig udpConfig = {resolver, datagram, BddTargetEndpoint, BddTargetEndpointVersion}; + address = SolidSyslogPosixAddress_Create(); + SolidSyslogUdpSenderConfig udpConfig = {resolver, datagram, address, BddTargetEndpoint, BddTargetEndpointVersion}; sender = SolidSyslogUdpSender_Create(&udpConfig); buffer = SolidSyslogPosixMessageQueueBuffer_Create(SOLIDSYSLOG_MAX_MESSAGE_SIZE, 10); store = SolidSyslogNullStore_Get(); @@ -85,6 +88,7 @@ TEST_GROUP(BddTargetServiceThread) SolidSyslog_Destroy(solidSyslog); SolidSyslogPosixMessageQueueBuffer_Destroy(buffer); SolidSyslogUdpSender_Destroy(sender); + SolidSyslogPosixAddress_Destroy(address); SolidSyslogPosixDatagram_Destroy(datagram); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } diff --git a/Tests/SolidSyslogUdpSenderTest.cpp b/Tests/SolidSyslogUdpSenderTest.cpp index 3ab3143e..b89239cf 100644 --- a/Tests/SolidSyslogUdpSenderTest.cpp +++ b/Tests/SolidSyslogUdpSenderTest.cpp @@ -9,6 +9,7 @@ #include "SolidSyslogEndpoint.h" #include "SolidSyslogFormatter.h" #include "SolidSyslogGetAddrInfoResolver.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogPosixDatagram.h" #include "SolidSyslogTunables.h" #include "SolidSyslogUdpSender.h" @@ -95,6 +96,7 @@ TEST_BASE(UdpSenderTestBase) { struct SolidSyslogResolver* resolver = nullptr; struct SolidSyslogDatagram* datagram = nullptr; + struct SolidSyslogAddress* address = nullptr; SolidSyslogUdpSenderConfig config{}; struct SolidSyslogSender* sender = nullptr; @@ -113,7 +115,8 @@ TEST_BASE(UdpSenderTestBase) resetEndpointStubs(); resolver = SolidSyslogGetAddrInfoResolver_Create(); datagram = SolidSyslogPosixDatagram_Create(); - config = {resolver, datagram, TestEndpoint, TestEndpointVersion}; + address = SolidSyslogPosixAddress_Create(); + config = {resolver, datagram, address, TestEndpoint, TestEndpointVersion}; } void setupFakesWithDatagramFake() @@ -122,17 +125,20 @@ TEST_BASE(UdpSenderTestBase) resetEndpointStubs(); resolver = SolidSyslogGetAddrInfoResolver_Create(); datagram = DatagramFake_Create(); - config = {resolver, datagram, TestEndpoint, TestEndpointVersion}; + address = SolidSyslogPosixAddress_Create(); + config = {resolver, datagram, address, TestEndpoint, TestEndpointVersion}; } void teardownFakesWithPosixDatagram() const { + SolidSyslogPosixAddress_Destroy(address); SolidSyslogPosixDatagram_Destroy(datagram); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } void teardownFakesWithDatagramFake() const { + SolidSyslogPosixAddress_Destroy(address); DatagramFake_Destroy(datagram); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } @@ -777,6 +783,13 @@ TEST(SolidSyslogUdpSenderBadSetup, CreateWithNullEndpointReportsError) CHECK_REPORTED_ERROR("SolidSyslogUdpSender_Create config.Endpoint is NULL"); } +TEST(SolidSyslogUdpSenderBadSetup, CreateWithNullAddressReportsError) +{ + config.Address = nullptr; + SolidSyslogUdpSender_Create(&config); + CHECK_REPORTED_ERROR("SolidSyslogUdpSender_Create config.Address is NULL"); +} + TEST(SolidSyslogUdpSenderBadSetup, NullEndpointVersionIsOptional) { config.EndpointVersion = nullptr; From 7efdf00297cda40cb7b81cc2482837cb428cb0d2 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 09:11:30 +0100 Subject: [PATCH 07/12] =?UTF-8?q?feat:=20S24.07=20StreamSenderConfig.Addre?= =?UTF-8?q?ss=20=E2=80=94=20thread=20Address=20through?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a required Address field to SolidSyslogStreamSenderConfig and drops the per-Connect stack-allocated SolidSyslogAddressStorage that StreamSender_Connect used to set up its resolution target. The platform Address pool now owns the storage; StreamSender_Connect just reads self->Config.Address directly. Threads the new field through every StreamSender consumer: SolidSyslogStreamSenderTest (five TEST_GROUPs, each wiring its own PosixAddress), the three BDD-target main.c files (Linux PosixAddress + Windows WinsockAddress + FreeRtos FreeRtosAddress for their plain- TCP StreamSenders), and the three TLS-sender glue files in Bdd/Targets/Common/ (each TLS StreamSender now creates and owns its own platform Address — one per Sender, no sharing). Each BDD wiring now consumes three Address pool slots (UDP + plain-TCP + TLS), exactly fitting the SOLIDSYSLOG_ADDRESS_POOL_SIZE=3 default. StreamSender keeps its existing permissive bad-setup posture (no NULL-field validation) — tightening it is out of scope for S24.07. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../BddTargetTlsSender_MbedTls_FreeRtosTcp.c | 6 ++++ .../BddTargetTlsSender_OpenSsl_PosixTcp.c | 6 ++++ .../BddTargetTlsSender_OpenSsl_WinsockTcp.c | 6 ++++ Bdd/Targets/FreeRtos/main.c | 4 +++ Bdd/Targets/Linux/main.c | 4 +++ Bdd/Targets/Windows/BddTargetWindows.c | 4 +++ Core/Interface/SolidSyslogStreamSender.h | 1 + Core/Source/SolidSyslogStreamSender.c | 5 ++-- Tests/SolidSyslogStreamSenderTest.cpp | 28 +++++++++++++++---- 9 files changed, 55 insertions(+), 9 deletions(-) diff --git a/Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c b/Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c index 4564b569..ee011ff9 100644 --- a/Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c +++ b/Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c @@ -25,6 +25,7 @@ #include "BddTargetMtlsConfig.h" #include "BddTargetSwitchConfig.h" #include "BddTargetTlsConfig.h" +#include "SolidSyslogFreeRtosAddress.h" #include "SolidSyslogFreeRtosTcpStream.h" #include "SolidSyslogMbedTlsStream.h" #include "SolidSyslogNullSender.h" @@ -55,6 +56,7 @@ struct SolidSyslogResolver; static struct SolidSyslogStream* underlyingStream; static struct SolidSyslogStream* tlsStream; +static struct SolidSyslogAddress* address; static struct SolidSyslogSender* sender; /* Entropy + CTR_DRBG live for the lifetime of the BDD target; one-shot init @@ -376,10 +378,13 @@ struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* tlsStreamConfig.ClientKey = &clientKey; tlsStream = SolidSyslogMbedTlsStream_Create(&tlsStreamConfig); + address = SolidSyslogFreeRtosAddress_Create(); + static struct SolidSyslogStreamSenderConfig senderConfig; senderConfig = (struct SolidSyslogStreamSenderConfig) {0}; senderConfig.Resolver = resolver; senderConfig.Stream = tlsStream; + senderConfig.Address = address; senderConfig.Endpoint = DispatchEndpoint; senderConfig.EndpointVersion = DispatchEndpointVersion; sender = SolidSyslogStreamSender_Create(&senderConfig); @@ -398,6 +403,7 @@ void BddTargetTlsSender_Destroy(void) return; } SolidSyslogStreamSender_Destroy(sender); + SolidSyslogFreeRtosAddress_Destroy(address); SolidSyslogMbedTlsStream_Destroy(tlsStream); SolidSyslogFreeRtosTcpStream_Destroy(underlyingStream); diff --git a/Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_PosixTcp.c b/Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_PosixTcp.c index c51785a0..027a73ac 100644 --- a/Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_PosixTcp.c +++ b/Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_PosixTcp.c @@ -3,6 +3,7 @@ #include "BddTargetMtlsConfig.h" #include "BddTargetTlsConfig.h" #include "BddTargetTlsSender.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogPosixSleep.h" #include "SolidSyslogPosixTcpStream.h" #include "SolidSyslogStreamSender.h" @@ -13,6 +14,7 @@ struct SolidSyslogResolver; static struct SolidSyslogStream* underlyingStream; static struct SolidSyslogStream* tlsStream; +static struct SolidSyslogAddress* address; static struct SolidSyslogSender* sender; struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* resolver, bool mtls) @@ -37,10 +39,13 @@ struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* } tlsStream = SolidSyslogTlsStream_Create(&tlsStreamConfig); + address = SolidSyslogPosixAddress_Create(); + static struct SolidSyslogStreamSenderConfig senderConfig; senderConfig = (struct SolidSyslogStreamSenderConfig) {0}; senderConfig.Resolver = resolver; senderConfig.Stream = tlsStream; + senderConfig.Address = address; senderConfig.Endpoint = mtls ? BddTargetMtlsConfig_GetEndpoint : BddTargetTlsConfig_GetEndpoint; senderConfig.EndpointVersion = mtls ? BddTargetMtlsConfig_GetEndpointVersion : BddTargetTlsConfig_GetEndpointVersion; @@ -52,6 +57,7 @@ struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* void BddTargetTlsSender_Destroy(void) { SolidSyslogStreamSender_Destroy(sender); + SolidSyslogPosixAddress_Destroy(address); SolidSyslogTlsStream_Destroy(tlsStream); SolidSyslogPosixTcpStream_Destroy(underlyingStream); } diff --git a/Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_WinsockTcp.c b/Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_WinsockTcp.c index 68aad843..fa588b24 100644 --- a/Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_WinsockTcp.c +++ b/Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_WinsockTcp.c @@ -6,6 +6,7 @@ #include "SolidSyslogStreamSender.h" #include "SolidSyslogTlsStream.h" #include "SolidSyslogWindowsSleep.h" +#include "SolidSyslogWinsockAddress.h" #include "SolidSyslogWinsockTcpStream.h" struct SolidSyslogResolver; @@ -13,6 +14,7 @@ struct SolidSyslogResolver; static struct SolidSyslogStream* underlyingStream; static struct SolidSyslogStream* tlsStream; +static struct SolidSyslogAddress* address; static struct SolidSyslogSender* sender; struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* resolver, bool mtls) @@ -37,10 +39,13 @@ struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* } tlsStream = SolidSyslogTlsStream_Create(&tlsStreamConfig); + address = SolidSyslogWinsockAddress_Create(); + static struct SolidSyslogStreamSenderConfig senderConfig; senderConfig = (struct SolidSyslogStreamSenderConfig) {0}; senderConfig.Resolver = resolver; senderConfig.Stream = tlsStream; + senderConfig.Address = address; senderConfig.Endpoint = mtls ? BddTargetMtlsConfig_GetEndpoint : BddTargetTlsConfig_GetEndpoint; senderConfig.EndpointVersion = mtls ? BddTargetMtlsConfig_GetEndpointVersion : BddTargetTlsConfig_GetEndpointVersion; @@ -52,6 +57,7 @@ struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* void BddTargetTlsSender_Destroy(void) { SolidSyslogStreamSender_Destroy(sender); + SolidSyslogWinsockAddress_Destroy(address); SolidSyslogTlsStream_Destroy(tlsStream); SolidSyslogWinsockTcpStream_Destroy(underlyingStream); } diff --git a/Bdd/Targets/FreeRtos/main.c b/Bdd/Targets/FreeRtos/main.c index 00936016..df6e4477 100644 --- a/Bdd/Targets/FreeRtos/main.c +++ b/Bdd/Targets/FreeRtos/main.c @@ -241,6 +241,7 @@ static struct SolidSyslogResolver* resolver = NULL; static struct SolidSyslogDatagram* datagram = NULL; static struct SolidSyslogAddress* udpAddress = NULL; static struct SolidSyslogStream* tcpStream = NULL; +static struct SolidSyslogAddress* tcpAddress = NULL; static struct SolidSyslogSender* tcpSender = NULL; static struct SolidSyslogSender* tlsSender = NULL; static struct SolidSyslogSender* udpSender = NULL; @@ -702,6 +703,7 @@ static void TeardownAll(void) BddTargetTlsSender_Destroy(); tlsSender = NULL; SolidSyslogStreamSender_Destroy(tcpSender); + SolidSyslogFreeRtosAddress_Destroy(tcpAddress); SolidSyslogFreeRtosTcpStream_Destroy(tcpStream); SolidSyslogUdpSender_Destroy(udpSender); SolidSyslogFreeRtosAddress_Destroy(udpAddress); @@ -824,9 +826,11 @@ static void InteractiveTask(void* argument) * same host:port for both transports — the syslog-ng config in * Bdd/syslog-ng/syslog-ng.conf has a TCP listener on 5514 alongside UDP. */ tcpStream = SolidSyslogFreeRtosTcpStream_Create(); + tcpAddress = SolidSyslogFreeRtosAddress_Create(); struct SolidSyslogStreamSenderConfig tcpConfig = { .Resolver = resolver, .Stream = tcpStream, + .Address = tcpAddress, .Endpoint = GetEndpoint, .EndpointVersion = GetEndpointVersion, }; diff --git a/Bdd/Targets/Linux/main.c b/Bdd/Targets/Linux/main.c index c2d3cf15..9c1e840f 100644 --- a/Bdd/Targets/Linux/main.c +++ b/Bdd/Targets/Linux/main.c @@ -53,6 +53,7 @@ static const char* const THRESHOLD_MARKER_PATH = "/tmp/solidsyslog_threshold_mar static struct SolidSyslogFile* storeFile; static struct SolidSyslogBlockDevice* storeBlockDevice; static struct SolidSyslogStream* plainTcpStream; +static struct SolidSyslogAddress* plainTcpAddress; static struct SolidSyslogSender* plainTcpSender; static struct SolidSyslogSender* udpSender; static struct SolidSyslogSender* switchingSender; @@ -95,9 +96,11 @@ static struct SolidSyslogSender* CreateSender(const struct BddTargetOptions* opt udpSender = SolidSyslogUdpSender_Create(&udpConfig); plainTcpStream = SolidSyslogPosixTcpStream_Create(); + plainTcpAddress = SolidSyslogPosixAddress_Create(); static struct SolidSyslogStreamSenderConfig tcpConfig = {0}; tcpConfig.Resolver = resolver; tcpConfig.Stream = plainTcpStream; + tcpConfig.Address = plainTcpAddress; tcpConfig.Endpoint = BddTargetTcpConfig_GetEndpoint; tcpConfig.EndpointVersion = BddTargetTcpConfig_GetEndpointVersion; plainTcpSender = SolidSyslogStreamSender_Create(&tcpConfig); @@ -193,6 +196,7 @@ static void DestroySender(void) SolidSyslogSwitchingSender_Destroy(switchingSender); BddTargetTlsSender_Destroy(); SolidSyslogStreamSender_Destroy(plainTcpSender); + SolidSyslogPosixAddress_Destroy(plainTcpAddress); SolidSyslogPosixTcpStream_Destroy(plainTcpStream); SolidSyslogUdpSender_Destroy(udpSender); SolidSyslogPosixAddress_Destroy(udpAddress); diff --git a/Bdd/Targets/Windows/BddTargetWindows.c b/Bdd/Targets/Windows/BddTargetWindows.c index 537b28a0..ef646c54 100644 --- a/Bdd/Targets/Windows/BddTargetWindows.c +++ b/Bdd/Targets/Windows/BddTargetWindows.c @@ -73,6 +73,7 @@ static struct SolidSyslog* solidSyslog; teardown can reach them after the SwitchingSender wraps them all. */ static struct SolidSyslogResolver* resolver; static struct SolidSyslogStream* plainTcpStream; +static struct SolidSyslogAddress* plainTcpAddress; static struct SolidSyslogSender* plainTcpSender; static struct SolidSyslogDatagram* udpDatagram; static struct SolidSyslogAddress* udpAddress; @@ -193,9 +194,11 @@ static struct SolidSyslogSender* CreateSender(const struct BddTargetWindowsOptio udpSender = SolidSyslogUdpSender_Create(&udpConfig); plainTcpStream = SolidSyslogWinsockTcpStream_Create(); + plainTcpAddress = SolidSyslogWinsockAddress_Create(); static struct SolidSyslogStreamSenderConfig tcpConfig = {0}; tcpConfig.Resolver = resolver; tcpConfig.Stream = plainTcpStream; + tcpConfig.Address = plainTcpAddress; tcpConfig.Endpoint = GetEndpoint; tcpConfig.EndpointVersion = GetEndpointVersion; plainTcpSender = SolidSyslogStreamSender_Create(&tcpConfig); @@ -222,6 +225,7 @@ static void DestroySender(void) SolidSyslogSwitchingSender_Destroy(switchingSender); BddTargetTlsSender_Destroy(); SolidSyslogStreamSender_Destroy(plainTcpSender); + SolidSyslogWinsockAddress_Destroy(plainTcpAddress); SolidSyslogWinsockTcpStream_Destroy(plainTcpStream); SolidSyslogUdpSender_Destroy(udpSender); SolidSyslogWinsockAddress_Destroy(udpAddress); diff --git a/Core/Interface/SolidSyslogStreamSender.h b/Core/Interface/SolidSyslogStreamSender.h index 20154b4c..670708ba 100644 --- a/Core/Interface/SolidSyslogStreamSender.h +++ b/Core/Interface/SolidSyslogStreamSender.h @@ -12,6 +12,7 @@ EXTERN_C_BEGIN { struct SolidSyslogResolver* Resolver; struct SolidSyslogStream* Stream; + struct SolidSyslogAddress* Address; SolidSyslogEndpointFunction Endpoint; /* fills host/port; called only on (re)connect */ SolidSyslogEndpointVersionFunction EndpointVersion; /* polled cheaply on every Send for stale check */ }; diff --git a/Core/Source/SolidSyslogStreamSender.c b/Core/Source/SolidSyslogStreamSender.c index eb985c56..ead6ac36 100644 --- a/Core/Source/SolidSyslogStreamSender.c +++ b/Core/Source/SolidSyslogStreamSender.c @@ -2,7 +2,6 @@ #include #include -#include "SolidSyslogAddress.h" #include "SolidSyslogEndpoint.h" #include "SolidSyslogFormatter.h" #include "SolidSyslogNullSender.h" @@ -53,6 +52,7 @@ void StreamSender_Initialise(struct SolidSyslogSender* base, const struct SolidS self->Base.Disconnect = StreamSender_Disconnect; self->Config.Resolver = config->Resolver; self->Config.Stream = config->Stream; + self->Config.Address = config->Address; self->Config.Endpoint = (config->Endpoint != NULL) ? config->Endpoint : StreamSender_NilEndpoint; self->Config.EndpointVersion = (config->EndpointVersion != NULL) ? config->EndpointVersion : StreamSender_NilEndpointVersion; @@ -105,8 +105,7 @@ static inline bool StreamSender_Connected(struct SolidSyslogStreamSender* self) static bool StreamSender_Connect(struct SolidSyslogStreamSender* self) { - SolidSyslogAddressStorage addrStorage = {0}; - struct SolidSyslogAddress* addr = SolidSyslogAddress_FromStorage(&addrStorage); + struct SolidSyslogAddress* addr = self->Config.Address; if (StreamSender_ResolveDestination(self, addr)) { diff --git a/Tests/SolidSyslogStreamSenderTest.cpp b/Tests/SolidSyslogStreamSenderTest.cpp index 57feb9ad..d53494fd 100644 --- a/Tests/SolidSyslogStreamSenderTest.cpp +++ b/Tests/SolidSyslogStreamSenderTest.cpp @@ -7,6 +7,7 @@ #include "SolidSyslogEndpoint.h" #include "SolidSyslogFormatter.h" #include "SolidSyslogGetAddrInfoResolver.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogPosixTcpStream.h" #include "SolidSyslogSender.h" #include "SolidSyslogStreamSender.h" @@ -88,6 +89,7 @@ TEST_GROUP(SolidSyslogStreamSender) { struct SolidSyslogResolver* resolver = nullptr; struct SolidSyslogStream* stream = nullptr; + struct SolidSyslogAddress* address = nullptr; struct SolidSyslogStreamSenderConfig config; // cppcheck-suppress constVariablePointer -- Send requires non-const self; false positive from macro expansion // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros @@ -101,7 +103,8 @@ TEST_GROUP(SolidSyslogStreamSender) endpointGetPort = GetPort; resolver = SolidSyslogGetAddrInfoResolver_Create(); stream = SolidSyslogPosixTcpStream_Create(); - config = {resolver, stream, TestEndpoint, TestEndpointVersion}; + address = SolidSyslogPosixAddress_Create(); + config = {resolver, stream, address, TestEndpoint, TestEndpointVersion}; // cppcheck-suppress unreadVariable -- read by teardown and tests; cppcheck does not model CppUTest lifecycle sender = SolidSyslogStreamSender_Create(&config); } @@ -109,6 +112,7 @@ TEST_GROUP(SolidSyslogStreamSender) void teardown() override { SolidSyslogStreamSender_Destroy(sender); + SolidSyslogPosixAddress_Destroy(address); SolidSyslogPosixTcpStream_Destroy(stream); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } @@ -150,6 +154,7 @@ TEST_GROUP(SolidSyslogStreamSenderDestroy) { struct SolidSyslogResolver* resolver = nullptr; struct SolidSyslogStream* stream = nullptr; + struct SolidSyslogAddress* address = nullptr; struct SolidSyslogStreamSenderConfig config; void setup() override @@ -160,12 +165,14 @@ TEST_GROUP(SolidSyslogStreamSenderDestroy) endpointGetPort = GetPort; resolver = SolidSyslogGetAddrInfoResolver_Create(); stream = SolidSyslogPosixTcpStream_Create(); + address = SolidSyslogPosixAddress_Create(); // cppcheck-suppress unreadVariable -- used in test bodies; cppcheck does not model CppUTest macros - config = {resolver, stream, TestEndpoint, TestEndpointVersion}; + config = {resolver, stream, address, TestEndpoint, TestEndpointVersion}; } void teardown() override { + SolidSyslogPosixAddress_Destroy(address); SolidSyslogPosixTcpStream_Destroy(stream); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } @@ -337,6 +344,7 @@ TEST_GROUP(SolidSyslogStreamSenderConfig) int (*getPortFn)(void) = GetPort; // NOLINT(modernize-redundant-void-arg) -- C idiom struct SolidSyslogStream* stream = nullptr; struct SolidSyslogResolver* resolver = nullptr; + struct SolidSyslogAddress* address = nullptr; // cppcheck-suppress constVariablePointer -- Send requires non-const self; false positive from macro expansion // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros struct SolidSyslogSender* sender = nullptr; @@ -354,6 +362,7 @@ TEST_GROUP(SolidSyslogStreamSenderConfig) void teardown() override { SolidSyslogStreamSender_Destroy(sender); + SolidSyslogPosixAddress_Destroy(address); SolidSyslogPosixTcpStream_Destroy(stream); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } @@ -364,7 +373,8 @@ TEST_GROUP(SolidSyslogStreamSenderConfig) endpointGetPort = getPortFn; resolver = SolidSyslogGetAddrInfoResolver_Create(); stream = SolidSyslogPosixTcpStream_Create(); - struct SolidSyslogStreamSenderConfig config = {resolver, stream, TestEndpoint, TestEndpointVersion}; + address = SolidSyslogPosixAddress_Create(); + struct SolidSyslogStreamSenderConfig config = {resolver, stream, address, TestEndpoint, TestEndpointVersion}; // cppcheck-suppress unreadVariable -- read by teardown and tests; cppcheck does not model CppUTest lifecycle sender = SolidSyslogStreamSender_Create(&config); } @@ -442,6 +452,7 @@ TEST_GROUP(SolidSyslogStreamSenderFailure) { struct SolidSyslogResolver* resolver = nullptr; struct SolidSyslogStream* stream = nullptr; + struct SolidSyslogAddress* address = nullptr; struct SolidSyslogStreamSenderConfig config; // cppcheck-suppress constVariablePointer -- Send requires non-const self; false positive from macro expansion // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros @@ -455,7 +466,8 @@ TEST_GROUP(SolidSyslogStreamSenderFailure) endpointGetPort = GetPort; resolver = SolidSyslogGetAddrInfoResolver_Create(); stream = SolidSyslogPosixTcpStream_Create(); - config = {resolver, stream, TestEndpoint, TestEndpointVersion}; + address = SolidSyslogPosixAddress_Create(); + config = {resolver, stream, address, TestEndpoint, TestEndpointVersion}; // cppcheck-suppress unreadVariable -- read by teardown and tests; cppcheck does not model CppUTest lifecycle sender = SolidSyslogStreamSender_Create(&config); } @@ -463,6 +475,7 @@ TEST_GROUP(SolidSyslogStreamSenderFailure) void teardown() override { SolidSyslogStreamSender_Destroy(sender); + SolidSyslogPosixAddress_Destroy(address); SolidSyslogPosixTcpStream_Destroy(stream); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } @@ -628,7 +641,7 @@ TEST(SolidSyslogStreamSenderFailure, NoEndpointConfiguredConnectsToPortZero) * with pool semantics a second live Create on a SIZE=1 pool would otherwise overflow * to NullSender. Reassigning to `sender` lets teardown release the no-endpoint sender. */ SolidSyslogStreamSender_Destroy(sender); - struct SolidSyslogStreamSenderConfig configNoEndpoint = {resolver, stream, nullptr, nullptr}; + struct SolidSyslogStreamSenderConfig configNoEndpoint = {resolver, stream, address, nullptr, nullptr}; sender = SolidSyslogStreamSender_Create(&configNoEndpoint); SolidSyslogSender_Send(sender, TEST_MESSAGE, TEST_MESSAGE_LEN); CALLED_FAKE(SocketFake_Connect, ONCE); @@ -645,6 +658,7 @@ TEST_GROUP(SolidSyslogStreamSenderPool) { struct SolidSyslogResolver* resolver = nullptr; struct SolidSyslogStream* stream = nullptr; + struct SolidSyslogAddress* address = nullptr; struct SolidSyslogStreamSenderConfig config; struct SolidSyslogSender* pooled[SOLIDSYSLOG_STREAM_SENDER_POOL_SIZE] = {}; struct SolidSyslogSender* overflow = nullptr; @@ -657,8 +671,9 @@ TEST_GROUP(SolidSyslogStreamSenderPool) endpointGetPort = GetPort; resolver = SolidSyslogGetAddrInfoResolver_Create(); stream = SolidSyslogPosixTcpStream_Create(); + address = SolidSyslogPosixAddress_Create(); // cppcheck-suppress unreadVariable -- read by MakeSender; cppcheck does not model CppUTest macros - config = {resolver, stream, TestEndpoint, TestEndpointVersion}; + config = {resolver, stream, address, TestEndpoint, TestEndpointVersion}; } void teardown() override @@ -674,6 +689,7 @@ TEST_GROUP(SolidSyslogStreamSenderPool) { SolidSyslogStreamSender_Destroy(overflow); } + SolidSyslogPosixAddress_Destroy(address); SolidSyslogPosixTcpStream_Destroy(stream); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } From d98770ea3ac8b496c635ba44969b5ac22a35769c Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 09:14:06 +0100 Subject: [PATCH 08/12] refactor: S24.07 internal accessors via *AddressPrivate.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Library-internal consumers of the platform sockaddr (Resolver, Datagram, Stream impls on POSIX / Winsock / FreeRTOS) move from the old shared SolidSyslogAddressInternal.h accessor names (SolidSyslogAddress_AsSockaddrIn / _AsConstSockaddrIn / _AsFreertosSockaddr / _AsConstFreertosSockaddr) onto the platform-specific accessors that live alongside each platform pool class (SolidSyslogPosixAddress_AsSockaddrIn etc., declared in SolidSyslog{Posix,Winsock,FreeRtos}AddressPrivate.h). 11 files migrated, one site per file. The three legacy SolidSyslogAddressInternal.h headers are now unreferenced — they get deleted alongside the rest of the legacy Address surface in the closing slice. Verified locally in the cpputest-freertos host image: SolidSyslogTests 1292/1294; BddTargetTests 48/48; all five FreeRTOS host tests green (Address 11, Datagram 30, Mutex 13, StaticResolver 18, SysUpTime 4, TcpStream 46). Co-Authored-By: Claude Opus 4.7 (1M context) --- Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagram.c | 4 ++-- .../FreeRtos/Source/SolidSyslogFreeRtosStaticResolver.c | 4 ++-- Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c | 4 ++-- Platform/Posix/Source/SolidSyslogGetAddrInfoResolver.c | 4 ++-- Platform/Posix/Source/SolidSyslogPosixDatagram.c | 6 +++--- Platform/Posix/Source/SolidSyslogPosixTcpStream.c | 4 ++-- Platform/Windows/Source/SolidSyslogWinsockDatagram.c | 6 +++--- Platform/Windows/Source/SolidSyslogWinsockResolver.c | 4 ++-- Platform/Windows/Source/SolidSyslogWinsockTcpStream.c | 4 ++-- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagram.c b/Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagram.c index 48c87b0c..d3796b22 100644 --- a/Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagram.c +++ b/Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagram.c @@ -12,8 +12,8 @@ #include "FreeRTOS_Sockets.h" #include "task.h" -#include "SolidSyslogAddressInternal.h" #include "SolidSyslogDatagramDefinition.h" +#include "SolidSyslogFreeRtosAddressPrivate.h" #include "SolidSyslogFreeRtosDatagramPrivate.h" #include "SolidSyslogNullDatagram.h" #include "SolidSyslogUdpPayload.h" @@ -83,7 +83,7 @@ static enum SolidSyslogDatagramSendResult FreeRtosDatagram_SendTo( enum SolidSyslogDatagramSendResult result = SOLIDSYSLOG_DATAGRAM_SEND_RESULT_FAILED; if (FreeRtosDatagram_IsOpen(self)) { - const struct freertos_sockaddr* dest = SolidSyslogAddress_AsConstFreertosSockaddr(addr); + const struct freertos_sockaddr* dest = SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr); FreeRtosDatagram_PrimeArpIfMissing(dest->sin_address.ulIP_IPv4); int32_t sent = FreeRTOS_sendto(self->Socket, buffer, size, 0, dest, sizeof(*dest)); if (sent > 0) diff --git a/Platform/FreeRtos/Source/SolidSyslogFreeRtosStaticResolver.c b/Platform/FreeRtos/Source/SolidSyslogFreeRtosStaticResolver.c index c535c1f3..d041b04b 100644 --- a/Platform/FreeRtos/Source/SolidSyslogFreeRtosStaticResolver.c +++ b/Platform/FreeRtos/Source/SolidSyslogFreeRtosStaticResolver.c @@ -8,7 +8,7 @@ #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" -#include "SolidSyslogAddressInternal.h" +#include "SolidSyslogFreeRtosAddressPrivate.h" #include "SolidSyslogFreeRtosStaticResolverPrivate.h" #include "SolidSyslogNullResolver.h" #include "SolidSyslogResolverDefinition.h" @@ -61,7 +61,7 @@ static bool FreeRtosStaticResolver_Resolve( (void) transport; (void) host; struct SolidSyslogFreeRtosStaticResolver* self = FreeRtosStaticResolver_SelfFromBase(base); - struct freertos_sockaddr* sockaddr = SolidSyslogAddress_AsFreertosSockaddr(result); + struct freertos_sockaddr* sockaddr = SolidSyslogFreeRtosAddress_AsFreertosSockaddr(result); sockaddr->sin_family = FREERTOS_AF_INET; sockaddr->sin_port = (uint16_t) FreeRTOS_htons(port); sockaddr->sin_address.ulIP_IPv4 = diff --git a/Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c b/Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c index 8d005acd..8affef6c 100644 --- a/Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c +++ b/Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c @@ -13,7 +13,7 @@ #include "FreeRTOS_Sockets.h" #include "task.h" -#include "SolidSyslogAddressInternal.h" +#include "SolidSyslogFreeRtosAddressPrivate.h" #include "SolidSyslogFreeRtosTcpStreamPrivate.h" #include "SolidSyslogNullStream.h" #include "SolidSyslogStream.h" @@ -161,7 +161,7 @@ static bool FreeRtosTcpStream_TryConnect( const struct SolidSyslogAddress* addr ) { - const struct freertos_sockaddr* dest = SolidSyslogAddress_AsConstFreertosSockaddr(addr); + const struct freertos_sockaddr* dest = SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr); FreeRtosTcpStream_PrimeArpIfMissing(dest->sin_address.ulIP_IPv4); FreeRtosTcpStream_SetSendTimeout(self->Socket, CONNECT_TIMEOUT_TICKS); FreeRtosTcpStream_SetRecvTimeout(self->Socket, CONNECT_TIMEOUT_TICKS); diff --git a/Platform/Posix/Source/SolidSyslogGetAddrInfoResolver.c b/Platform/Posix/Source/SolidSyslogGetAddrInfoResolver.c index 79c132b8..3e2d195c 100644 --- a/Platform/Posix/Source/SolidSyslogGetAddrInfoResolver.c +++ b/Platform/Posix/Source/SolidSyslogGetAddrInfoResolver.c @@ -8,7 +8,7 @@ #include #include -#include "SolidSyslogAddressInternal.h" +#include "SolidSyslogPosixAddressPrivate.h" #include "SolidSyslogGetAddrInfoResolverPrivate.h" #include "SolidSyslogNullResolver.h" #include "SolidSyslogResolverDefinition.h" @@ -61,7 +61,7 @@ static bool GetAddrInfoResolver_Resolve( if (getaddrinfo(host, NULL, &hints, &info) == GETADDRINFO_SUCCESS) { - struct sockaddr_in* sin = SolidSyslogAddress_AsSockaddrIn(result); + struct sockaddr_in* sin = SolidSyslogPosixAddress_AsSockaddrIn(result); *sin = *(struct sockaddr_in*) info->ai_addr; sin->sin_port = htons(port); freeaddrinfo(info); diff --git a/Platform/Posix/Source/SolidSyslogPosixDatagram.c b/Platform/Posix/Source/SolidSyslogPosixDatagram.c index 6a8253be..4191c9a3 100644 --- a/Platform/Posix/Source/SolidSyslogPosixDatagram.c +++ b/Platform/Posix/Source/SolidSyslogPosixDatagram.c @@ -8,10 +8,10 @@ #include #include -#include "SolidSyslogAddressInternal.h" #include "SolidSyslogDatagram.h" #include "SolidSyslogDatagramDefinition.h" #include "SolidSyslogNullDatagram.h" +#include "SolidSyslogPosixAddressPrivate.h" #include "SolidSyslogPosixDatagramPrivate.h" #include "SolidSyslogUdpPayload.h" @@ -93,7 +93,7 @@ static enum SolidSyslogDatagramSendResult PosixDatagram_SendTo( enum SolidSyslogDatagramSendResult result = SOLIDSYSLOG_DATAGRAM_SEND_RESULT_FAILED; if (PosixDatagram_ConnectIfNeeded(self, addr)) { - const struct sockaddr_in* sin = SolidSyslogAddress_AsConstSockaddrIn(addr); + const struct sockaddr_in* sin = SolidSyslogPosixAddress_AsConstSockaddrIn(addr); ssize_t sent = sendto(self->Fd, buffer, size, 0, (const struct sockaddr*) sin, sizeof(*sin)); if (sent >= 0) { @@ -118,7 +118,7 @@ static inline bool PosixDatagram_ConnectIfNeeded( { if (!self->Connected) { - const struct sockaddr_in* sin = SolidSyslogAddress_AsConstSockaddrIn(addr); + const struct sockaddr_in* sin = SolidSyslogPosixAddress_AsConstSockaddrIn(addr); if (connect(self->Fd, (const struct sockaddr*) sin, sizeof(*sin)) == 0) { const int pmtu = IP_PMTUDISC_DO; diff --git a/Platform/Posix/Source/SolidSyslogPosixTcpStream.c b/Platform/Posix/Source/SolidSyslogPosixTcpStream.c index 8bd40368..ddb9e963 100644 --- a/Platform/Posix/Source/SolidSyslogPosixTcpStream.c +++ b/Platform/Posix/Source/SolidSyslogPosixTcpStream.c @@ -12,8 +12,8 @@ #include #include -#include "SolidSyslogAddressInternal.h" #include "SolidSyslogNullStream.h" +#include "SolidSyslogPosixAddressPrivate.h" #include "SolidSyslogPosixTcpStreamPrivate.h" #include "SolidSyslogStream.h" #include "SolidSyslogStreamDefinition.h" @@ -91,7 +91,7 @@ static inline struct SolidSyslogPosixTcpStream* PosixTcpStream_SelfFromBase(stru static bool PosixTcpStream_Open(struct SolidSyslogStream* base, const struct SolidSyslogAddress* addr) { struct SolidSyslogPosixTcpStream* self = PosixTcpStream_SelfFromBase(base); - const struct sockaddr_in* sin = SolidSyslogAddress_AsConstSockaddrIn(addr); + const struct sockaddr_in* sin = SolidSyslogPosixAddress_AsConstSockaddrIn(addr); bool connected = false; self->Fd = PosixTcpStream_OpenAndConfigureSocket(); diff --git a/Platform/Windows/Source/SolidSyslogWinsockDatagram.c b/Platform/Windows/Source/SolidSyslogWinsockDatagram.c index 96b4a0cf..79c2cc80 100644 --- a/Platform/Windows/Source/SolidSyslogWinsockDatagram.c +++ b/Platform/Windows/Source/SolidSyslogWinsockDatagram.c @@ -4,10 +4,10 @@ #include #include -#include "SolidSyslogAddressInternal.h" #include "SolidSyslogDatagramDefinition.h" #include "SolidSyslogNullDatagram.h" #include "SolidSyslogUdpPayload.h" +#include "SolidSyslogWinsockAddressPrivate.h" #include "SolidSyslogWinsockDatagramInternal.h" #include "SolidSyslogWinsockDatagramPrivate.h" @@ -132,7 +132,7 @@ static enum SolidSyslogDatagramSendResult WinsockDatagram_SendTo( enum SolidSyslogDatagramSendResult result = SOLIDSYSLOG_DATAGRAM_SEND_RESULT_FAILED; if (WinsockDatagram_ConnectIfNeeded(self, addr)) { - const struct sockaddr_in* sin = SolidSyslogAddress_AsConstSockaddrIn(addr); + const struct sockaddr_in* sin = SolidSyslogWinsockAddress_AsConstSockaddrIn(addr); int sent = Winsock_sendto( self->Fd, (const char*) buffer, @@ -164,7 +164,7 @@ static inline bool WinsockDatagram_ConnectIfNeeded( { if (!self->Connected) { - const struct sockaddr_in* sin = SolidSyslogAddress_AsConstSockaddrIn(addr); + const struct sockaddr_in* sin = SolidSyslogWinsockAddress_AsConstSockaddrIn(addr); if (Winsock_connect(self->Fd, (const struct sockaddr*) sin, (int) sizeof(*sin)) != SOCKET_ERROR) { const int pmtu = IP_PMTUDISC_DO; diff --git a/Platform/Windows/Source/SolidSyslogWinsockResolver.c b/Platform/Windows/Source/SolidSyslogWinsockResolver.c index 2bc1a7a1..b1da89fa 100644 --- a/Platform/Windows/Source/SolidSyslogWinsockResolver.c +++ b/Platform/Windows/Source/SolidSyslogWinsockResolver.c @@ -4,7 +4,7 @@ #include #include -#include "SolidSyslogAddressInternal.h" +#include "SolidSyslogWinsockAddressPrivate.h" #include "SolidSyslogNullResolver.h" #include "SolidSyslogResolverDefinition.h" #include "SolidSyslogTransport.h" @@ -78,7 +78,7 @@ static bool WinsockResolver_Resolve( if (Winsock_getaddrinfo(host, NULL, &hints, &info) == GETADDRINFO_SUCCESS) { - struct sockaddr_in* sin = SolidSyslogAddress_AsSockaddrIn(result); + struct sockaddr_in* sin = SolidSyslogWinsockAddress_AsSockaddrIn(result); *sin = *(struct sockaddr_in*) info->ai_addr; sin->sin_port = htons(port); Winsock_freeaddrinfo(info); diff --git a/Platform/Windows/Source/SolidSyslogWinsockTcpStream.c b/Platform/Windows/Source/SolidSyslogWinsockTcpStream.c index b54f1817..6a3fe8fc 100644 --- a/Platform/Windows/Source/SolidSyslogWinsockTcpStream.c +++ b/Platform/Windows/Source/SolidSyslogWinsockTcpStream.c @@ -10,9 +10,9 @@ #include #include -#include "SolidSyslogAddressInternal.h" #include "SolidSyslogNullStream.h" #include "SolidSyslogStreamDefinition.h" +#include "SolidSyslogWinsockAddressPrivate.h" #include "SolidSyslogWinsockTcpStreamInternal.h" #include "SolidSyslogWinsockTcpStreamPrivate.h" @@ -171,7 +171,7 @@ static inline struct SolidSyslogWinsockTcpStream* WinsockTcpStream_SelfFromBase( static bool WinsockTcpStream_Open(struct SolidSyslogStream* base, const struct SolidSyslogAddress* addr) { struct SolidSyslogWinsockTcpStream* self = WinsockTcpStream_SelfFromBase(base); - const struct sockaddr_in* sin = SolidSyslogAddress_AsConstSockaddrIn(addr); + const struct sockaddr_in* sin = SolidSyslogWinsockAddress_AsConstSockaddrIn(addr); bool connected = false; self->Fd = WinsockTcpStream_OpenAndConfigureSocket(); From 63ab73fd589bde6e7ab0603e21b877500a403f61 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 09:56:51 +0100 Subject: [PATCH 09/12] refactor!: S24.07 delete legacy caller-supplied Address API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes out S24.07. Removes the caller-supplied SolidSyslogAddressStorage API now that every site has been migrated onto the per-platform pool classes: - Slims Core/Interface/SolidSyslogAddress.h to the opaque forward declaration only — SolidSyslogAddressStorage, SOLIDSYSLOG_ADDRESS_SIZE, and SolidSyslogAddress_FromStorage are gone. - Deletes the three identical Platform/{Posix,Windows,FreeRtos}/Source/ SolidSyslogAddress.c factory files plus their CMake entries. - Deletes the three Platform/{Posix,Windows,FreeRtos}/Source/ SolidSyslogAddressInternal.h headers (the AsSockaddrIn / AsFreertosSockaddr accessors moved to SolidSyslog{Posix,Winsock,FreeRtos}AddressPrivate.h in the previous slice). - Deletes Tests/SolidSyslogAddressTest.cpp — the only test it carried was for _FromStorage, which no longer exists. Pool-class behaviour is covered by the three new per-platform Address tests. - Migrates 13 test fixtures off SolidSyslogAddressStorage onto SolidSyslog{Posix,Winsock,FreeRtos}Address_Create — covers the POSIX / Winsock / FreeRTOS datagram + stream + resolver tests, the TLS unit + integration tests on both the OpenSSL and Mbed TLS reference adapters, and StreamFakeTest. - Adds Platform/FreeRtos/Source to the three FreeRTOS host test executables' include paths so they can reach the new SolidSyslogFreeRtosAddressPrivate.h accessors. - Compiles SolidSyslogFreeRtosAddress{.c,Static.c} into the FreeRtosDatagramTest / FreeRtosTcpStreamTest / FreeRtosStaticResolverTest executables (they don't link libSolidSyslog at FREERTOS_PATH-build time). Verified locally in the cpputest-freertos host image: SolidSyslogTests 1290/1292; BddTargetTests 48/48; all six FreeRTOS host tests green; MbedTlsStreamTest 42/42; OpenSslIntegrationTests 9/9; MbedTlsIntegrationTests 7/7. BREAKING CHANGE: SolidSyslogAddressStorage and SolidSyslogAddress_FromStorage are removed. Integrators must allocate destination addresses through the platform pool — SolidSyslog{Posix,Winsock,FreeRtos}Address_Create — and wire the returned handle into UdpSenderConfig.Address / StreamSenderConfig.Address. Co-Authored-By: Claude Opus 4.7 (1M context) --- Core/Interface/SolidSyslogAddress.h | 14 --------- Platform/FreeRtos/Source/SolidSyslogAddress.c | 6 ---- .../Source/SolidSyslogAddressInternal.h | 29 ------------------- Platform/Posix/CMakeLists.txt | 1 - Platform/Posix/Source/SolidSyslogAddress.c | 6 ---- .../Posix/Source/SolidSyslogAddressInternal.h | 27 ----------------- Platform/Windows/CMakeLists.txt | 1 - Platform/Windows/Source/SolidSyslogAddress.c | 6 ---- .../Source/SolidSyslogAddressInternal.h | 27 ----------------- Tests/CMakeLists.txt | 4 --- Tests/FreeRtos/CMakeLists.txt | 8 +++++ .../SolidSyslogFreeRtosDatagramTest.cpp | 25 +++++++--------- .../SolidSyslogFreeRtosStaticResolverTest.cpp | 19 ++++++------ .../SolidSyslogFreeRtosTcpStreamTest.cpp | 26 ++++++++--------- .../MbedTls/SolidSyslogMbedTlsStreamTest.cpp | 14 ++++----- ...olidSyslogMbedTlsStreamIntegrationTest.cpp | 23 +++++++-------- .../SolidSyslogTlsStreamIntegrationTest.cpp | 6 ++-- Tests/SolidSyslogAddressTest.cpp | 22 -------------- Tests/SolidSyslogGetAddrInfoResolverTest.cpp | 26 +++++++---------- Tests/SolidSyslogPosixDatagramTest.cpp | 15 ++++------ Tests/SolidSyslogPosixTcpStreamTest.cpp | 19 +++++------- Tests/SolidSyslogTlsStreamTest.cpp | 14 ++++----- Tests/SolidSyslogWinsockDatagramTest.cpp | 29 ++++++++----------- Tests/SolidSyslogWinsockResolverTest.cpp | 20 ++++++------- Tests/SolidSyslogWinsockTcpStreamTest.cpp | 19 +++++------- Tests/StreamFakeTest.cpp | 18 ++++++------ 26 files changed, 130 insertions(+), 294 deletions(-) delete mode 100644 Platform/FreeRtos/Source/SolidSyslogAddress.c delete mode 100644 Platform/FreeRtos/Source/SolidSyslogAddressInternal.h delete mode 100644 Platform/Posix/Source/SolidSyslogAddress.c delete mode 100644 Platform/Posix/Source/SolidSyslogAddressInternal.h delete mode 100644 Platform/Windows/Source/SolidSyslogAddress.c delete mode 100644 Platform/Windows/Source/SolidSyslogAddressInternal.h delete mode 100644 Tests/SolidSyslogAddressTest.cpp diff --git a/Core/Interface/SolidSyslogAddress.h b/Core/Interface/SolidSyslogAddress.h index 2d9042f8..d76b2f43 100644 --- a/Core/Interface/SolidSyslogAddress.h +++ b/Core/Interface/SolidSyslogAddress.h @@ -2,25 +2,11 @@ #define SOLIDSYSLOGADDRESS_H #include "ExternC.h" -#include EXTERN_C_BEGIN - enum - { - SOLIDSYSLOG_ADDRESS_SIZE = - 128 /* bytes; sized to cover struct sockaddr_storage for cross-platform parity (glibc, Winsock) */ - }; - - typedef struct - { - intptr_t slots[SOLIDSYSLOG_ADDRESS_SIZE / sizeof(intptr_t)]; - } SolidSyslogAddressStorage; - struct SolidSyslogAddress; - struct SolidSyslogAddress* SolidSyslogAddress_FromStorage(SolidSyslogAddressStorage * storage); - EXTERN_C_END #endif /* SOLIDSYSLOGADDRESS_H */ diff --git a/Platform/FreeRtos/Source/SolidSyslogAddress.c b/Platform/FreeRtos/Source/SolidSyslogAddress.c deleted file mode 100644 index 86c56276..00000000 --- a/Platform/FreeRtos/Source/SolidSyslogAddress.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "SolidSyslogAddress.h" - -struct SolidSyslogAddress* SolidSyslogAddress_FromStorage(SolidSyslogAddressStorage* storage) -{ - return (struct SolidSyslogAddress*) storage; -} diff --git a/Platform/FreeRtos/Source/SolidSyslogAddressInternal.h b/Platform/FreeRtos/Source/SolidSyslogAddressInternal.h deleted file mode 100644 index 24f04f20..00000000 --- a/Platform/FreeRtos/Source/SolidSyslogAddressInternal.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef SOLIDSYSLOGADDRESSINTERNAL_H -#define SOLIDSYSLOGADDRESSINTERNAL_H - -#include "SolidSyslogAddress.h" -#include "SolidSyslogMacros.h" - -#include "FreeRTOS.h" -#include "FreeRTOS_Sockets.h" - -SOLIDSYSLOG_STATIC_ASSERT( - sizeof(struct freertos_sockaddr) <= SOLIDSYSLOG_ADDRESS_SIZE, - SolidSyslogAddressStorage_too_small_for_freertos_sockaddr -); - -static inline const struct freertos_sockaddr* SolidSyslogAddress_AsConstFreertosSockaddr( - const struct SolidSyslogAddress* address -) -{ - const uint8_t* bytes = (const uint8_t*) address; - return (const struct freertos_sockaddr*) bytes; -} - -static inline struct freertos_sockaddr* SolidSyslogAddress_AsFreertosSockaddr(struct SolidSyslogAddress* address) -{ - uint8_t* bytes = (uint8_t*) address; - return (struct freertos_sockaddr*) bytes; -} - -#endif /* SOLIDSYSLOGADDRESSINTERNAL_H */ diff --git a/Platform/Posix/CMakeLists.txt b/Platform/Posix/CMakeLists.txt index 43739a37..505ff1e5 100644 --- a/Platform/Posix/CMakeLists.txt +++ b/Platform/Posix/CMakeLists.txt @@ -8,7 +8,6 @@ target_sources(${PROJECT_NAME} PRIVATE Source/SolidSyslogPosixProcessId.c Source/SolidSyslogPosixSysUpTime.c Source/SolidSyslogPosixSleep.c - Source/SolidSyslogAddress.c Source/SolidSyslogPosixAddress.c Source/SolidSyslogPosixAddressStatic.c Source/SolidSyslogGetAddrInfoResolver.c diff --git a/Platform/Posix/Source/SolidSyslogAddress.c b/Platform/Posix/Source/SolidSyslogAddress.c deleted file mode 100644 index 86c56276..00000000 --- a/Platform/Posix/Source/SolidSyslogAddress.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "SolidSyslogAddress.h" - -struct SolidSyslogAddress* SolidSyslogAddress_FromStorage(SolidSyslogAddressStorage* storage) -{ - return (struct SolidSyslogAddress*) storage; -} diff --git a/Platform/Posix/Source/SolidSyslogAddressInternal.h b/Platform/Posix/Source/SolidSyslogAddressInternal.h deleted file mode 100644 index 13d33ac3..00000000 --- a/Platform/Posix/Source/SolidSyslogAddressInternal.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SOLIDSYSLOGADDRESSINTERNAL_H -#define SOLIDSYSLOGADDRESSINTERNAL_H - -#include "SolidSyslogAddress.h" -#include "SolidSyslogMacros.h" - -#include -#include - -SOLIDSYSLOG_STATIC_ASSERT( - sizeof(struct sockaddr_in) <= SOLIDSYSLOG_ADDRESS_SIZE, - SolidSyslogAddressStorage_too_small_for_sockaddr_in -); - -static inline struct sockaddr_in* SolidSyslogAddress_AsSockaddrIn(struct SolidSyslogAddress* address) -{ - uint8_t* bytes = (uint8_t*) address; - return (struct sockaddr_in*) bytes; -} - -static inline const struct sockaddr_in* SolidSyslogAddress_AsConstSockaddrIn(const struct SolidSyslogAddress* address) -{ - const uint8_t* bytes = (const uint8_t*) address; - return (const struct sockaddr_in*) bytes; -} - -#endif /* SOLIDSYSLOGADDRESSINTERNAL_H */ diff --git a/Platform/Windows/CMakeLists.txt b/Platform/Windows/CMakeLists.txt index a417ca10..ca6107eb 100644 --- a/Platform/Windows/CMakeLists.txt +++ b/Platform/Windows/CMakeLists.txt @@ -29,7 +29,6 @@ endif() if(SOLIDSYSLOG_WINSOCK) target_sources(${PROJECT_NAME} PRIVATE - Source/SolidSyslogAddress.c Source/SolidSyslogWinsockAddress.c Source/SolidSyslogWinsockAddressStatic.c Source/SolidSyslogWinsockResolver.c diff --git a/Platform/Windows/Source/SolidSyslogAddress.c b/Platform/Windows/Source/SolidSyslogAddress.c deleted file mode 100644 index 86c56276..00000000 --- a/Platform/Windows/Source/SolidSyslogAddress.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "SolidSyslogAddress.h" - -struct SolidSyslogAddress* SolidSyslogAddress_FromStorage(SolidSyslogAddressStorage* storage) -{ - return (struct SolidSyslogAddress*) storage; -} diff --git a/Platform/Windows/Source/SolidSyslogAddressInternal.h b/Platform/Windows/Source/SolidSyslogAddressInternal.h deleted file mode 100644 index d647c393..00000000 --- a/Platform/Windows/Source/SolidSyslogAddressInternal.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SOLIDSYSLOGADDRESSINTERNAL_H -#define SOLIDSYSLOGADDRESSINTERNAL_H - -#include "SolidSyslogAddress.h" -#include "SolidSyslogMacros.h" - -#include -#include - -SOLIDSYSLOG_STATIC_ASSERT( - sizeof(struct sockaddr_in) <= SOLIDSYSLOG_ADDRESS_SIZE, - SolidSyslogAddressStorage_too_small_for_sockaddr_in -); - -static inline struct sockaddr_in* SolidSyslogAddress_AsSockaddrIn(struct SolidSyslogAddress* address) -{ - uint8_t* bytes = (uint8_t*) address; - return (struct sockaddr_in*) bytes; -} - -static inline const struct sockaddr_in* SolidSyslogAddress_AsConstSockaddrIn(const struct SolidSyslogAddress* address) -{ - const uint8_t* bytes = (const uint8_t*) address; - return (const struct sockaddr_in*) bytes; -} - -#endif /* SOLIDSYSLOGADDRESSINTERNAL_H */ diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 128550db..10ddd24c 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -133,10 +133,6 @@ if(SOLIDSYSLOG_OPENSSL) ) endif() -if(SOLIDSYSLOG_POSIX OR SOLIDSYSLOG_WINSOCK) - list(APPEND TEST_SOURCES SolidSyslogAddressTest.cpp) -endif() - if(HAVE_WINDOWS_PLATFORM) list(APPEND TEST_SOURCES SolidSyslogWindowsClockTest.cpp diff --git a/Tests/FreeRtos/CMakeLists.txt b/Tests/FreeRtos/CMakeLists.txt index f4071d02..78141319 100644 --- a/Tests/FreeRtos/CMakeLists.txt +++ b/Tests/FreeRtos/CMakeLists.txt @@ -14,6 +14,8 @@ else() add_executable(SolidSyslogFreeRtosDatagramTest SolidSyslogFreeRtosDatagramTest.cpp main.cpp + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagram.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagramStatic.c ${CMAKE_SOURCE_DIR}/Tests/Support/FreeRtosFakes/Source/FreeRtosSocketsFake.c @@ -31,6 +33,7 @@ else() target_include_directories(SolidSyslogFreeRtosDatagramTest PRIVATE ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Interface + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source ${CMAKE_SOURCE_DIR}/Core/Interface ${CMAKE_SOURCE_DIR}/Core/Source ${CMAKE_SOURCE_DIR}/Tests/Support @@ -44,6 +47,8 @@ else() add_executable(SolidSyslogFreeRtosTcpStreamTest SolidSyslogFreeRtosTcpStreamTest.cpp main.cpp + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStreamStatic.c ${CMAKE_SOURCE_DIR}/Tests/Support/FreeRtosFakes/Source/FreeRtosSocketsFake.c @@ -75,6 +80,8 @@ else() add_executable(SolidSyslogFreeRtosStaticResolverTest SolidSyslogFreeRtosStaticResolverTest.cpp main.cpp + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosStaticResolver.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosStaticResolverStatic.c ) @@ -89,6 +96,7 @@ else() target_include_directories(SolidSyslogFreeRtosStaticResolverTest PRIVATE ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Interface + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source ${CMAKE_SOURCE_DIR}/Core/Interface ${CMAKE_SOURCE_DIR}/Core/Source ${CMAKE_SOURCE_DIR}/Tests/Support diff --git a/Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp b/Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp index 965f049a..28d72e5d 100644 --- a/Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp +++ b/Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp @@ -6,10 +6,11 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" #include "SolidSyslogDatagram.h" #include "SolidSyslogDatagramDefinition.h" #include "SolidSyslogErrorMessages.h" +#include "SolidSyslogFreeRtosAddress.h" +#include "SolidSyslogFreeRtosAddressPrivate.h" #include "SolidSyslogFreeRtosDatagram.h" #include "SolidSyslogPrival.h" #include "SolidSyslogTunables.h" @@ -44,7 +45,6 @@ static const uint16_t TEST_PORT = 514; TEST_GROUP(SolidSyslogFreeRtosDatagram) { struct SolidSyslogDatagram* datagram = nullptr; - SolidSyslogAddressStorage addrStorage{}; struct SolidSyslogAddress* addr = nullptr; void setup() override @@ -53,18 +53,16 @@ TEST_GROUP(SolidSyslogFreeRtosDatagram) FreeRtosArpFake_Reset(); FreeRtosTaskFake_Reset(); datagram = SolidSyslogFreeRtosDatagram_Create(); - - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing into platform layout, storage is intptr_t-aligned - auto* sin = reinterpret_cast(&addrStorage); + addr = SolidSyslogFreeRtosAddress_Create(); + struct freertos_sockaddr* sin = SolidSyslogFreeRtosAddress_AsFreertosSockaddr(addr); sin->sin_family = FREERTOS_AF_INET; sin->sin_port = FreeRTOS_htons(TEST_PORT); sin->sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick(127, 0, 0, 1); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- platform-layout cast, see above - addr = reinterpret_cast(&addrStorage); } void teardown() override { + SolidSyslogFreeRtosAddress_Destroy(addr); SolidSyslogFreeRtosDatagram_Destroy(datagram); } @@ -189,11 +187,7 @@ TEST(SolidSyslogFreeRtosDatagram, SendToSendsBufferToDestinationAfterOpen) POINTERS_EQUAL(TEST_MESSAGE, FreeRtosSocketsFake_LastSendtoBuffer()); LONGS_EQUAL(TEST_MESSAGE_LEN, FreeRtosSocketsFake_LastSendtoLength()); LONGS_EQUAL(0, FreeRtosSocketsFake_LastSendtoFlags()); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- platform-layout cast, see setup - POINTERS_EQUAL( - reinterpret_cast(addr), - FreeRtosSocketsFake_LastSendtoDestination() - ); + POINTERS_EQUAL(SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr), FreeRtosSocketsFake_LastSendtoDestination()); LONGS_EQUAL(sizeof(struct freertos_sockaddr), FreeRtosSocketsFake_LastSendtoDestinationLength()); } @@ -327,16 +321,17 @@ TEST(SolidSyslogFreeRtosDatagramPool, FallbackVtableMethodsAreNoOps) { FillPool(); overflow = SolidSyslogFreeRtosDatagram_Create(); - SolidSyslogAddressStorage addrStorage{}; - struct SolidSyslogAddress* addr = SolidSyslogAddress_FromStorage(&addrStorage); + struct SolidSyslogAddress* localAddr = SolidSyslogFreeRtosAddress_Create(); FreeRtosSocketsFake_Reset(); /* NullDatagram's Open returns true so caller success paths are not * tripped; no underlying FreeRTOS_socket is created. */ CHECK_TRUE(SolidSyslogDatagram_Open(overflow)); - SolidSyslogDatagram_SendTo(overflow, "x", 1, addr); + SolidSyslogDatagram_SendTo(overflow, "x", 1, localAddr); SolidSyslogDatagram_Close(overflow); + SolidSyslogFreeRtosAddress_Destroy(localAddr); + CALLED_FAKE(FreeRtosSocketsFake_Socket, NEVER); CALLED_FAKE(FreeRtosSocketsFake_Sendto, NEVER); CALLED_FAKE(FreeRtosSocketsFake_Closesocket, NEVER); diff --git a/Tests/FreeRtos/SolidSyslogFreeRtosStaticResolverTest.cpp b/Tests/FreeRtos/SolidSyslogFreeRtosStaticResolverTest.cpp index 1b4d3ef2..93129539 100644 --- a/Tests/FreeRtos/SolidSyslogFreeRtosStaticResolverTest.cpp +++ b/Tests/FreeRtos/SolidSyslogFreeRtosStaticResolverTest.cpp @@ -6,7 +6,8 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" +#include "SolidSyslogFreeRtosAddress.h" +#include "SolidSyslogFreeRtosAddressPrivate.h" #include "SolidSyslogErrorMessages.h" #include "SolidSyslogFreeRtosStaticResolver.h" #include "SolidSyslogPrival.h" @@ -44,17 +45,17 @@ static const char* IGNORED_HOST = "ignored.example.com"; TEST_GROUP(SolidSyslogFreeRtosStaticResolver) { struct SolidSyslogResolver* resolver = nullptr; - SolidSyslogAddressStorage addrStorage{}; struct SolidSyslogAddress* addr = nullptr; void setup() override { resolver = SolidSyslogFreeRtosStaticResolver_Create(TEST_OCTETS); - addr = SolidSyslogAddress_FromStorage(&addrStorage); + addr = SolidSyslogFreeRtosAddress_Create(); } void teardown() override { + SolidSyslogFreeRtosAddress_Destroy(addr); SolidSyslogFreeRtosStaticResolver_Destroy(resolver); } @@ -72,8 +73,7 @@ TEST_GROUP(SolidSyslogFreeRtosStaticResolver) // NOLINTNEXTLINE(modernize-use-nodiscard) -- used through accessor syntax in tests const struct freertos_sockaddr* Result() const { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- platform-layout cast, storage is intptr_t-aligned - return reinterpret_cast(&addrStorage); + return SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr); } }; @@ -112,7 +112,7 @@ TEST(SolidSyslogFreeRtosStaticResolver, ResolveProducesSameIpv4ForAnyHostString) Resolve("first.Host"); uint32_t firstIpv4 = Result()->sin_address.ulIP_IPv4; - addrStorage = {}; + *SolidSyslogFreeRtosAddress_AsFreertosSockaddr(addr) = {}; Resolve("totally.different.second.host"); LONGS_EQUAL(firstIpv4, Result()->sin_address.ulIP_IPv4); @@ -123,7 +123,7 @@ TEST(SolidSyslogFreeRtosStaticResolver, ResolveProducesSameIpv4ForUdpAndTcpTrans Resolve(IGNORED_HOST, TEST_PORT, SOLIDSYSLOG_TRANSPORT_UDP); uint32_t udpIpv4 = Result()->sin_address.ulIP_IPv4; - addrStorage = {}; + *SolidSyslogFreeRtosAddress_AsFreertosSockaddr(addr) = {}; Resolve(IGNORED_HOST, TEST_PORT, SOLIDSYSLOG_TRANSPORT_TCP); LONGS_EQUAL(udpIpv4, Result()->sin_address.ulIP_IPv4); @@ -206,10 +206,11 @@ TEST(SolidSyslogFreeRtosStaticResolverPool, FallbackResolveReturnsFalse) { FillPool(); overflow = SolidSyslogFreeRtosStaticResolver_Create(TEST_OCTETS); - SolidSyslogAddressStorage addrStorage{}; - struct SolidSyslogAddress* addr = SolidSyslogAddress_FromStorage(&addrStorage); + struct SolidSyslogAddress* addr = SolidSyslogFreeRtosAddress_Create(); CHECK_FALSE(SolidSyslogResolver_Resolve(overflow, SOLIDSYSLOG_TRANSPORT_UDP, "host", 514, addr)); + + SolidSyslogFreeRtosAddress_Destroy(addr); } TEST(SolidSyslogFreeRtosStaticResolverPool, CreateAcquiresAndReleasesConfigLockOnFirstFreeSlot) diff --git a/Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp b/Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp index 33104b37..c6268cdb 100644 --- a/Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp +++ b/Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp @@ -6,8 +6,9 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" #include "SolidSyslogErrorMessages.h" +#include "SolidSyslogFreeRtosAddress.h" +#include "SolidSyslogFreeRtosAddressPrivate.h" #include "SolidSyslogFreeRtosTcpStream.h" #include "SolidSyslogPrival.h" #include "SolidSyslogStream.h" @@ -48,7 +49,6 @@ static const BaseType_t TEST_READ_BYTES = 7; TEST_GROUP(SolidSyslogFreeRtosTcpStream) { struct SolidSyslogStream* stream = nullptr; - SolidSyslogAddressStorage addrStorage{}; struct SolidSyslogAddress* addr = nullptr; char readBuffer[16] = {0}; @@ -57,19 +57,17 @@ TEST_GROUP(SolidSyslogFreeRtosTcpStream) FreeRtosSocketsFake_Reset(); FreeRtosArpFake_Reset(); FreeRtosTaskFake_Reset(); - stream = SolidSyslogFreeRtosTcpStream_Create(); - - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing into platform layout, storage is intptr_t-aligned - auto* sin = reinterpret_cast(&addrStorage); - sin->sin_family = FREERTOS_AF_INET; - sin->sin_port = FreeRTOS_htons(TEST_PORT); - sin->sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick(10, 0, 2, 2); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- platform-layout cast, see above - addr = reinterpret_cast(&addrStorage); + stream = SolidSyslogFreeRtosTcpStream_Create(); + addr = SolidSyslogFreeRtosAddress_Create(); + struct freertos_sockaddr* sin = SolidSyslogFreeRtosAddress_AsFreertosSockaddr(addr); + sin->sin_family = FREERTOS_AF_INET; + sin->sin_port = FreeRTOS_htons(TEST_PORT); + sin->sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick(10, 0, 2, 2); } void teardown() override { + SolidSyslogFreeRtosAddress_Destroy(addr); if (stream != nullptr) { SolidSyslogFreeRtosTcpStream_Destroy(stream); @@ -433,17 +431,17 @@ TEST(SolidSyslogFreeRtosTcpStreamPool, FallbackVtableMethodsAreNoOps) { FillPool(); overflow = SolidSyslogFreeRtosTcpStream_Create(); - SolidSyslogAddressStorage addrStorage{}; - struct SolidSyslogAddress* addr = SolidSyslogAddress_FromStorage(&addrStorage); + struct SolidSyslogAddress* localAddr = SolidSyslogFreeRtosAddress_Create(); char buf[8] = {0}; FreeRtosSocketsFake_Reset(); /* NullStream's Open/Send/Read return safe values so the Service algorithm * does not tear the (non-existent) connection down on the fallback. */ - CHECK_TRUE(SolidSyslogStream_Open(overflow, addr)); + CHECK_TRUE(SolidSyslogStream_Open(overflow, localAddr)); CHECK_TRUE(SolidSyslogStream_Send(overflow, buf, sizeof(buf))); LONGS_EQUAL(0, SolidSyslogStream_Read(overflow, buf, sizeof(buf))); SolidSyslogStream_Close(overflow); + SolidSyslogFreeRtosAddress_Destroy(localAddr); CALLED_FAKE(FreeRtosSocketsFake_Socket, NEVER); CALLED_FAKE(FreeRtosSocketsFake_Connect, NEVER); diff --git a/Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp b/Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp index 7eb61efc..53a84496 100644 --- a/Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp +++ b/Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp @@ -6,8 +6,8 @@ extern "C" #include #include "MbedTlsFake.h" -#include "SolidSyslogAddress.h" #include "SolidSyslogMbedTlsStream.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogStream.h" #include "SolidSyslogStreamDefinition.h" #include "StreamFake.h" @@ -29,11 +29,10 @@ static void NoOpSleep(int milliseconds) // clang-format off TEST_GROUP(SolidSyslogMbedTlsStream) { - struct SolidSyslogStream* transport = nullptr; - struct SolidSyslogStream* handle = nullptr; - struct SolidSyslogMbedTlsStreamConfig config = {}; - SolidSyslogAddressStorage addrStorage = {}; - struct SolidSyslogAddress* addr = nullptr; + struct SolidSyslogStream* transport = nullptr; + struct SolidSyslogStream* handle = nullptr; + struct SolidSyslogMbedTlsStreamConfig config = {}; + struct SolidSyslogAddress* addr = nullptr; void setup() override { @@ -45,12 +44,13 @@ TEST_GROUP(SolidSyslogMbedTlsStream) config.Sleep = NoOpSleep; handle = SolidSyslogMbedTlsStream_Create(&config); // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros - addr = SolidSyslogAddress_FromStorage(&addrStorage); + addr = SolidSyslogPosixAddress_Create(); } void teardown() override { SolidSyslogMbedTlsStream_Destroy(handle); + SolidSyslogPosixAddress_Destroy(addr); StreamFake_Destroy(transport); } diff --git a/Tests/MbedTlsIntegration/SolidSyslogMbedTlsStreamIntegrationTest.cpp b/Tests/MbedTlsIntegration/SolidSyslogMbedTlsStreamIntegrationTest.cpp index ff681f3a..15130c4f 100644 --- a/Tests/MbedTlsIntegration/SolidSyslogMbedTlsStreamIntegrationTest.cpp +++ b/Tests/MbedTlsIntegration/SolidSyslogMbedTlsStreamIntegrationTest.cpp @@ -13,8 +13,8 @@ extern "C" #include "MbedTlsTestCert.h" #include "MbedTlsTestServer.h" #include "SocketStream.h" -#include "SolidSyslogAddress.h" #include "SolidSyslogMbedTlsStream.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogStream.h" } @@ -41,9 +41,11 @@ TEST_GROUP(SolidSyslogMbedTlsStreamIntegration) struct MbedTlsTestServer* server = nullptr; struct SolidSyslogStream* clientTransport = nullptr; struct SolidSyslogStream* tlsStream = nullptr; + struct SolidSyslogAddress* addr = nullptr; void setup() override { + addr = SolidSyslogPosixAddress_Create(); mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&rng); const unsigned char pers[] = "mbedtls-integration-test"; @@ -91,6 +93,7 @@ TEST_GROUP(SolidSyslogMbedTlsStreamIntegration) MbedTlsTestCert_Destroy(&trustedCa); mbedtls_ctr_drbg_free(&rng); mbedtls_entropy_free(&entropy); + SolidSyslogPosixAddress_Destroy(addr); } struct SolidSyslogStream* StartServerWithCert(const struct MbedTlsTestCert* cert) @@ -157,8 +160,7 @@ TEST(SolidSyslogMbedTlsStreamIntegration, HandshakeSucceedsWhenServerCertSignedB struct SolidSyslogMbedTlsStreamConfig config = BuildBaseConfig(transport); tlsStream = SolidSyslogMbedTlsStream_Create(&config); - SolidSyslogAddressStorage storage = {}; - bool opened = SolidSyslogStream_Open(tlsStream, SolidSyslogAddress_FromStorage(&storage)); + bool opened = SolidSyslogStream_Open(tlsStream, addr); CHECK_TRUE_TEXT(opened, "client-side Open (incl. handshake) should succeed against a trusted server"); CHECK_TRUE_TEXT( @@ -182,8 +184,7 @@ TEST(SolidSyslogMbedTlsStreamIntegration, HandshakeFailsWhenServerCertSignedByUn config.CaChain = &untrustedCa.Cert; tlsStream = SolidSyslogMbedTlsStream_Create(&config); - SolidSyslogAddressStorage storage = {}; - bool opened = SolidSyslogStream_Open(tlsStream, SolidSyslogAddress_FromStorage(&storage)); + bool opened = SolidSyslogStream_Open(tlsStream, addr); CHECK_FALSE_TEXT(opened, "client-side handshake must fail when the server cert chains to an untrusted CA"); @@ -197,8 +198,7 @@ TEST(SolidSyslogMbedTlsStreamIntegration, HandshakeFailsWhenServerNameDoesNotMat config.ServerName = "wrong-host.example.com"; /* server cert has SAN syslog.example.com */ tlsStream = SolidSyslogMbedTlsStream_Create(&config); - SolidSyslogAddressStorage storage = {}; - bool opened = SolidSyslogStream_Open(tlsStream, SolidSyslogAddress_FromStorage(&storage)); + bool opened = SolidSyslogStream_Open(tlsStream, addr); CHECK_FALSE_TEXT(opened, "client-side handshake must fail when ServerName does not match the cert's SAN"); } @@ -221,8 +221,7 @@ TEST(SolidSyslogMbedTlsStreamIntegration, MutualTlsHandshakeSucceedsWithClientCe config.ClientKey = &clientCert.Key; tlsStream = SolidSyslogMbedTlsStream_Create(&config); - SolidSyslogAddressStorage storage = {}; - bool opened = SolidSyslogStream_Open(tlsStream, SolidSyslogAddress_FromStorage(&storage)); + bool opened = SolidSyslogStream_Open(tlsStream, addr); CHECK_TRUE_TEXT(opened, "client-side mTLS Open should succeed against a server trusting the client CA"); CHECK_TRUE_TEXT( @@ -249,8 +248,7 @@ TEST(SolidSyslogMbedTlsStreamIntegration, MutualTlsHandshakeRejectedWhenClientSe struct SolidSyslogMbedTlsStreamConfig config = BuildBaseConfig(transport); tlsStream = SolidSyslogMbedTlsStream_Create(&config); - SolidSyslogAddressStorage storage = {}; - bool opened = SolidSyslogStream_Open(tlsStream, SolidSyslogAddress_FromStorage(&storage)); + bool opened = SolidSyslogStream_Open(tlsStream, addr); CHECK_FALSE_TEXT(opened, "mTLS handshake must fail when the client does not present a cert"); @@ -284,8 +282,7 @@ TEST(SolidSyslogMbedTlsStreamIntegration, MutualTlsHandshakeRejectedWhenClientCe config.ClientKey = &clientCert.Key; tlsStream = SolidSyslogMbedTlsStream_Create(&config); - SolidSyslogAddressStorage storage = {}; - bool opened = SolidSyslogStream_Open(tlsStream, SolidSyslogAddress_FromStorage(&storage)); + bool opened = SolidSyslogStream_Open(tlsStream, addr); CHECK_FALSE_TEXT(opened, "mTLS handshake must fail when the client cert chains to an untrusted CA"); diff --git a/Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp b/Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp index 31f32e39..1ad7de2e 100644 --- a/Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp +++ b/Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp @@ -8,7 +8,7 @@ #include #include "BioPairStream.h" -#include "SolidSyslogAddress.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogStream.h" #include "SolidSyslogTlsStream.h" #include "TlsTestCert.h" @@ -35,7 +35,6 @@ TEST_GROUP(TlsStreamIntegration) struct SolidSyslogTlsStreamConfig tlsConfig = {}; struct SolidSyslogStream* tlsStream = nullptr; - SolidSyslogAddressStorage addrStorage = {}; struct SolidSyslogAddress* addr = nullptr; char caPath[256] = {}; char clientCertPath[256] = {}; @@ -43,11 +42,12 @@ TEST_GROUP(TlsStreamIntegration) void setup() override { - addr = SolidSyslogAddress_FromStorage(&addrStorage); + addr = SolidSyslogPosixAddress_Create(); } void teardown() override { + if (addr != nullptr) { SolidSyslogPosixAddress_Destroy(addr); } if (tlsStream != nullptr) { SolidSyslogTlsStream_Destroy(tlsStream); } if (transport != nullptr) { BioPairStream_Destroy(transport); } if (server != nullptr) { TlsTestServer_Destroy(server); } diff --git a/Tests/SolidSyslogAddressTest.cpp b/Tests/SolidSyslogAddressTest.cpp deleted file mode 100644 index 104bd01e..00000000 --- a/Tests/SolidSyslogAddressTest.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "SolidSyslogAddress.h" -#include "CppUTest/TestHarness.h" - -// clang-format off -TEST_GROUP(SolidSyslogAddress) -{ - SolidSyslogAddressStorage storage{}; -}; - -// clang-format on - -TEST(SolidSyslogAddress, FromStorageReturnsNonNull) -{ - CHECK_TRUE(SolidSyslogAddress_FromStorage(&storage) != nullptr); -} - -TEST(SolidSyslogAddress, FromStorageReturnsSamePointerOnSuccessiveCalls) -{ - struct SolidSyslogAddress* first = SolidSyslogAddress_FromStorage(&storage); - struct SolidSyslogAddress* second = SolidSyslogAddress_FromStorage(&storage); - POINTERS_EQUAL(first, second); -} diff --git a/Tests/SolidSyslogGetAddrInfoResolverTest.cpp b/Tests/SolidSyslogGetAddrInfoResolverTest.cpp index 4b453aaf..70194e78 100644 --- a/Tests/SolidSyslogGetAddrInfoResolverTest.cpp +++ b/Tests/SolidSyslogGetAddrInfoResolverTest.cpp @@ -5,9 +5,10 @@ #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" #include "SolidSyslogErrorMessages.h" #include "SolidSyslogGetAddrInfoResolver.h" +#include "SolidSyslogPosixAddress.h" +#include "SolidSyslogPosixAddressPrivate.h" #include "SolidSyslogPrival.h" #include "SolidSyslogResolver.h" #include "SolidSyslogResolverDefinition.h" @@ -31,32 +32,30 @@ static const uint16_t TEST_ALTERNATE_PORT = 9999; TEST_GROUP(SolidSyslogGetAddrInfoResolver) { struct SolidSyslogResolver* resolver = nullptr; - SolidSyslogAddressStorage resultStorage{}; + struct SolidSyslogAddress* result = nullptr; void setup() override { SocketFake_Reset(); resolver = SolidSyslogGetAddrInfoResolver_Create(); + result = SolidSyslogPosixAddress_Create(); } void teardown() override { + SolidSyslogPosixAddress_Destroy(result); SolidSyslogGetAddrInfoResolver_Destroy(resolver); } bool Resolve(const char* host, uint16_t port, enum SolidSyslogTransport transport = SOLIDSYSLOG_TRANSPORT_UDP) { - struct SolidSyslogAddress* address = SolidSyslogAddress_FromStorage(&resultStorage); - return SolidSyslogResolver_Resolve(resolver, transport, host, port, address); + return SolidSyslogResolver_Resolve(resolver, transport, host, port, result); } // NOLINTNEXTLINE(modernize-use-nodiscard) -- used through accessor syntax in tests const struct sockaddr_in* Result() const { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing, legal and necessary - const auto* bytes = reinterpret_cast(&resultStorage); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- reinterpret to platform layout, storage is intptr_t-aligned - return reinterpret_cast(bytes); + return SolidSyslogPosixAddress_AsConstSockaddrIn(result); } }; @@ -205,14 +204,9 @@ TEST(SolidSyslogGetAddrInfoResolverPool, FallbackResolveReturnsFalse) FillPool(); overflow = SolidSyslogGetAddrInfoResolver_Create(); - SolidSyslogAddressStorage resultStorage{}; - CHECK_FALSE(SolidSyslogResolver_Resolve( - overflow, - SOLIDSYSLOG_TRANSPORT_UDP, - TEST_HOST, - TEST_PORT, - SolidSyslogAddress_FromStorage(&resultStorage) - )); + struct SolidSyslogAddress* fallbackResult = SolidSyslogPosixAddress_Create(); + CHECK_FALSE(SolidSyslogResolver_Resolve(overflow, SOLIDSYSLOG_TRANSPORT_UDP, TEST_HOST, TEST_PORT, fallbackResult)); + SolidSyslogPosixAddress_Destroy(fallbackResult); } TEST(SolidSyslogGetAddrInfoResolverPool, CreateAcquiresAndReleasesConfigLockOnFirstFreeSlot) diff --git a/Tests/SolidSyslogPosixDatagramTest.cpp b/Tests/SolidSyslogPosixDatagramTest.cpp index c1eaa50a..19663e38 100644 --- a/Tests/SolidSyslogPosixDatagramTest.cpp +++ b/Tests/SolidSyslogPosixDatagramTest.cpp @@ -5,10 +5,11 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f // macros #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" #include "SolidSyslogDatagram.h" #include "SolidSyslogDatagramDefinition.h" #include "SolidSyslogErrorMessages.h" +#include "SolidSyslogPosixAddress.h" +#include "SolidSyslogPosixAddressPrivate.h" #include "SolidSyslogPosixDatagram.h" #include "SolidSyslogPrival.h" #include "SolidSyslogTunables.h" @@ -44,7 +45,6 @@ TEST_GROUP(SolidSyslogPosixDatagram) { // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros struct SolidSyslogDatagram* datagram = nullptr; - SolidSyslogAddressStorage addrStorage{}; // cppcheck-suppress unreadVariable -- assigned in setup; cppcheck does not model CppUTest macros struct SolidSyslogAddress* addr = nullptr; @@ -52,20 +52,17 @@ TEST_GROUP(SolidSyslogPosixDatagram) { SocketFake_Reset(); // cppcheck-suppress unreadVariable -- used in tests; cppcheck does not model CppUTest macros - datagram = SolidSyslogPosixDatagram_Create(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing, legal and necessary - auto* bytes = reinterpret_cast(&addrStorage); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- reinterpret to platform layout, storage is intptr_t-aligned - auto* sin = reinterpret_cast(bytes); + datagram = SolidSyslogPosixDatagram_Create(); + addr = SolidSyslogPosixAddress_Create(); + struct sockaddr_in* sin = SolidSyslogPosixAddress_AsSockaddrIn(addr); sin->sin_family = AF_INET; sin->sin_port = htons(TEST_PORT); inet_pton(AF_INET, TEST_ADDRESS, &sin->sin_addr); - // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros - addr = SolidSyslogAddress_FromStorage(&addrStorage); } void teardown() override { + SolidSyslogPosixAddress_Destroy(addr); SolidSyslogPosixDatagram_Destroy(datagram); } }; diff --git a/Tests/SolidSyslogPosixTcpStreamTest.cpp b/Tests/SolidSyslogPosixTcpStreamTest.cpp index c99d1e2f..b90e713a 100644 --- a/Tests/SolidSyslogPosixTcpStreamTest.cpp +++ b/Tests/SolidSyslogPosixTcpStreamTest.cpp @@ -13,8 +13,9 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f // macros #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" #include "SolidSyslogErrorMessages.h" +#include "SolidSyslogPosixAddress.h" +#include "SolidSyslogPosixAddressPrivate.h" #include "SolidSyslogPosixTcpStream.h" #include "SolidSyslogPrival.h" #include "SolidSyslogStream.h" @@ -33,7 +34,6 @@ TEST_GROUP(SolidSyslogPosixTcpStream) { // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros struct SolidSyslogStream* stream = nullptr; - SolidSyslogAddressStorage addrStorage{}; // cppcheck-suppress unreadVariable -- assigned in setup; cppcheck does not model CppUTest macros struct SolidSyslogAddress* addr = nullptr; @@ -41,20 +41,17 @@ TEST_GROUP(SolidSyslogPosixTcpStream) { SocketFake_Reset(); // cppcheck-suppress unreadVariable -- used in tests; cppcheck does not model CppUTest macros - stream = SolidSyslogPosixTcpStream_Create(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing, legal and necessary - auto* bytes = reinterpret_cast(&addrStorage); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- reinterpret to platform layout, storage is intptr_t-aligned - auto* sin = reinterpret_cast(bytes); - sin->sin_family = AF_INET; - sin->sin_port = htons(TEST_PORT); + stream = SolidSyslogPosixTcpStream_Create(); + addr = SolidSyslogPosixAddress_Create(); + struct sockaddr_in* sin = SolidSyslogPosixAddress_AsSockaddrIn(addr); + sin->sin_family = AF_INET; + sin->sin_port = htons(TEST_PORT); inet_pton(AF_INET, TEST_ADDRESS, &sin->sin_addr); - // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros - addr = SolidSyslogAddress_FromStorage(&addrStorage); } void teardown() override { + SolidSyslogPosixAddress_Destroy(addr); SolidSyslogPosixTcpStream_Destroy(stream); } diff --git a/Tests/SolidSyslogTlsStreamTest.cpp b/Tests/SolidSyslogTlsStreamTest.cpp index d1b90548..4f0ab561 100644 --- a/Tests/SolidSyslogTlsStreamTest.cpp +++ b/Tests/SolidSyslogTlsStreamTest.cpp @@ -5,7 +5,7 @@ #include #include "OpenSslFake.h" -#include "SolidSyslogAddress.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogStream.h" #include "SolidSyslogTlsStream.h" #include "SolidSyslogTransport.h" @@ -32,11 +32,10 @@ static void NoOpSleep(int milliseconds) // clang-format off TEST_GROUP(SolidSyslogTlsStream) { - struct SolidSyslogStream* transport = nullptr; - struct SolidSyslogTlsStreamConfig config = {}; - struct SolidSyslogStream* stream = nullptr; - SolidSyslogAddressStorage addrStorage = {0}; - struct SolidSyslogAddress* addr = nullptr; + struct SolidSyslogStream* transport = nullptr; + struct SolidSyslogTlsStreamConfig config = {}; + struct SolidSyslogStream* stream = nullptr; + struct SolidSyslogAddress* addr = nullptr; void setup() override { @@ -49,12 +48,13 @@ TEST_GROUP(SolidSyslogTlsStream) // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros stream = SolidSyslogTlsStream_Create(&config); // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros - addr = SolidSyslogAddress_FromStorage(&addrStorage); + addr = SolidSyslogPosixAddress_Create(); } void teardown() override { SolidSyslogTlsStream_Destroy(stream); + SolidSyslogPosixAddress_Destroy(addr); StreamFake_Destroy(transport); } diff --git a/Tests/SolidSyslogWinsockDatagramTest.cpp b/Tests/SolidSyslogWinsockDatagramTest.cpp index b03fe7ec..200797cd 100644 --- a/Tests/SolidSyslogWinsockDatagramTest.cpp +++ b/Tests/SolidSyslogWinsockDatagramTest.cpp @@ -5,7 +5,8 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f // macros #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" +#include "SolidSyslogWinsockAddress.h" +#include "SolidSyslogWinsockAddressPrivate.h" #include "SolidSyslogDatagram.h" #include "SolidSyslogDatagramDefinition.h" #include "SolidSyslogErrorMessages.h" @@ -45,7 +46,6 @@ TEST_GROUP(SolidSyslogWinsockDatagram) { // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros struct SolidSyslogDatagram* datagram = nullptr; - SolidSyslogAddressStorage addrStorage{}; // cppcheck-suppress unreadVariable -- assigned in setup; cppcheck does not model CppUTest macros struct SolidSyslogAddress* addr = nullptr; @@ -59,20 +59,17 @@ TEST_GROUP(SolidSyslogWinsockDatagram) UT_PTR_SET(Winsock_setsockopt, WinsockFake_setsockopt); UT_PTR_SET(Winsock_getsockopt, WinsockFake_getsockopt); // cppcheck-suppress unreadVariable -- used in tests; cppcheck does not model CppUTest macros - datagram = SolidSyslogWinsockDatagram_Create(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing, legal and necessary - auto* bytes = reinterpret_cast(&addrStorage); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- reinterpret to platform layout, storage is intptr_t-aligned - auto* sin = reinterpret_cast(bytes); - sin->sin_family = AF_INET; - sin->sin_port = htons(TEST_PORT); + datagram = SolidSyslogWinsockDatagram_Create(); + addr = SolidSyslogWinsockAddress_Create(); + struct sockaddr_in* sin = SolidSyslogWinsockAddress_AsSockaddrIn(addr); + sin->sin_family = AF_INET; + sin->sin_port = htons(TEST_PORT); inet_pton(AF_INET, TEST_ADDRESS, &sin->sin_addr); - // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros - addr = SolidSyslogAddress_FromStorage(&addrStorage); } void teardown() override { + SolidSyslogWinsockAddress_Destroy(addr); SolidSyslogWinsockDatagram_Destroy(datagram); } }; @@ -339,16 +336,14 @@ TEST(SolidSyslogWinsockDatagramPool, FallbackSendToIsNoOp) { FillPool(); overflow = SolidSyslogWinsockDatagram_Create(); - SolidSyslogAddressStorage addrStorage{}; - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing, legal and necessary - auto* bytes = reinterpret_cast(&addrStorage); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- reinterpret to platform layout, storage is intptr_t-aligned - auto* sin = reinterpret_cast(bytes); + struct SolidSyslogAddress* nullAddr = SolidSyslogWinsockAddress_Create(); + struct sockaddr_in* sin = SolidSyslogWinsockAddress_AsSockaddrIn(nullAddr); sin->sin_family = AF_INET; sin->sin_port = htons(514); - struct SolidSyslogAddress* nullAddr = SolidSyslogAddress_FromStorage(&addrStorage); LONGS_EQUAL(SOLIDSYSLOG_DATAGRAM_SEND_RESULT_SENT, SolidSyslogDatagram_SendTo(overflow, "x", 1, nullAddr)); + + SolidSyslogWinsockAddress_Destroy(nullAddr); } TEST(SolidSyslogWinsockDatagramPool, CreateAcquiresAndReleasesConfigLockOnFirstFreeSlot) diff --git a/Tests/SolidSyslogWinsockResolverTest.cpp b/Tests/SolidSyslogWinsockResolverTest.cpp index f0d2b674..7bf37ed3 100644 --- a/Tests/SolidSyslogWinsockResolverTest.cpp +++ b/Tests/SolidSyslogWinsockResolverTest.cpp @@ -5,7 +5,8 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f // macros #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" +#include "SolidSyslogWinsockAddress.h" +#include "SolidSyslogWinsockAddressPrivate.h" #include "SolidSyslogErrorMessages.h" #include "SolidSyslogPrival.h" #include "SolidSyslogResolver.h" @@ -45,7 +46,7 @@ static const uint16_t TEST_ALTERNATE_PORT = 9999; TEST_GROUP(SolidSyslogWinsockResolver) { struct SolidSyslogResolver* resolver = nullptr; - SolidSyslogAddressStorage resultStorage{}; + struct SolidSyslogAddress* result = nullptr; void setup() override { @@ -53,26 +54,24 @@ TEST_GROUP(SolidSyslogWinsockResolver) UT_PTR_SET(Winsock_getaddrinfo, WinsockFake_getaddrinfo); UT_PTR_SET(Winsock_freeaddrinfo, WinsockFake_freeaddrinfo); resolver = SolidSyslogWinsockResolver_Create(); + result = SolidSyslogWinsockAddress_Create(); } void teardown() override { + SolidSyslogWinsockAddress_Destroy(result); SolidSyslogWinsockResolver_Destroy(resolver); } bool Resolve(const char* host, uint16_t port, enum SolidSyslogTransport transport = SOLIDSYSLOG_TRANSPORT_UDP) { - struct SolidSyslogAddress* address = SolidSyslogAddress_FromStorage(&resultStorage); - return SolidSyslogResolver_Resolve(resolver, transport, host, port, address); + return SolidSyslogResolver_Resolve(resolver, transport, host, port, result); } // NOLINTNEXTLINE(modernize-use-nodiscard) -- used through accessor syntax in tests const struct sockaddr_in* Result() const { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing, legal and necessary - const auto* bytes = reinterpret_cast(&resultStorage); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- reinterpret to platform layout, storage is intptr_t-aligned - return reinterpret_cast(bytes); + return SolidSyslogWinsockAddress_AsConstSockaddrIn(result); } }; @@ -206,10 +205,11 @@ TEST(SolidSyslogWinsockResolverPool, FallbackResolveIsNoOp) { FillPool(); overflow = SolidSyslogWinsockResolver_Create(); - SolidSyslogAddressStorage addrStorage{}; - struct SolidSyslogAddress* address = SolidSyslogAddress_FromStorage(&addrStorage); + struct SolidSyslogAddress* address = SolidSyslogWinsockAddress_Create(); CHECK_FALSE(SolidSyslogResolver_Resolve(overflow, SOLIDSYSLOG_TRANSPORT_UDP, "h", 1, address)); + + SolidSyslogWinsockAddress_Destroy(address); } TEST(SolidSyslogWinsockResolverPool, CreateAcquiresAndReleasesConfigLockOnFirstFreeSlot) diff --git a/Tests/SolidSyslogWinsockTcpStreamTest.cpp b/Tests/SolidSyslogWinsockTcpStreamTest.cpp index d8395167..5e1b7fe0 100644 --- a/Tests/SolidSyslogWinsockTcpStreamTest.cpp +++ b/Tests/SolidSyslogWinsockTcpStreamTest.cpp @@ -5,7 +5,8 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f // macros #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" -#include "SolidSyslogAddress.h" +#include "SolidSyslogWinsockAddress.h" +#include "SolidSyslogWinsockAddressPrivate.h" #include "SolidSyslogErrorMessages.h" #include "SolidSyslogPrival.h" #include "SolidSyslogStream.h" @@ -45,7 +46,6 @@ TEST_GROUP(SolidSyslogWinsockTcpStream) { // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros struct SolidSyslogStream* stream = nullptr; - SolidSyslogAddressStorage addrStorage{}; // cppcheck-suppress unreadVariable -- assigned in setup; cppcheck does not model CppUTest macros struct SolidSyslogAddress* addr = nullptr; @@ -63,20 +63,17 @@ TEST_GROUP(SolidSyslogWinsockTcpStream) UT_PTR_SET(WinsockTcpStream_select, WinsockFake_select); UT_PTR_SET(WinsockTcpStream_WSAGetLastError, WinsockFake_WSAGetLastError); // cppcheck-suppress unreadVariable -- used in tests; cppcheck does not model CppUTest macros - stream = SolidSyslogWinsockTcpStream_Create(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- char-type aliasing, legal and necessary - auto* bytes = reinterpret_cast(&addrStorage); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- reinterpret to platform layout, storage is intptr_t-aligned - auto* sin = reinterpret_cast(bytes); - sin->sin_family = AF_INET; - sin->sin_port = htons(TEST_PORT); + stream = SolidSyslogWinsockTcpStream_Create(); + addr = SolidSyslogWinsockAddress_Create(); + struct sockaddr_in* sin = SolidSyslogWinsockAddress_AsSockaddrIn(addr); + sin->sin_family = AF_INET; + sin->sin_port = htons(TEST_PORT); inet_pton(AF_INET, TEST_ADDRESS, &sin->sin_addr); - // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros - addr = SolidSyslogAddress_FromStorage(&addrStorage); } void teardown() override { + SolidSyslogWinsockAddress_Destroy(addr); SolidSyslogWinsockTcpStream_Destroy(stream); } diff --git a/Tests/StreamFakeTest.cpp b/Tests/StreamFakeTest.cpp index 33fa1485..0629518a 100644 --- a/Tests/StreamFakeTest.cpp +++ b/Tests/StreamFakeTest.cpp @@ -1,4 +1,4 @@ -#include "SolidSyslogAddress.h" +#include "SolidSyslogPosixAddress.h" #include "SolidSyslogStream.h" #include "StreamFake.h" #include "TestUtils.h" @@ -27,18 +27,18 @@ TEST(StreamFake, CreateSucceeds) TEST(StreamFake, OpenIncrementsCount) { - SolidSyslogAddressStorage storage = {0}; - struct SolidSyslogAddress* addr = SolidSyslogAddress_FromStorage(&storage); + struct SolidSyslogAddress* addr = SolidSyslogPosixAddress_Create(); SolidSyslogStream_Open(stream, addr); CALLED_FAKE_ON(StreamFake_Open, stream, ONCE); + SolidSyslogPosixAddress_Destroy(addr); } TEST(StreamFake, OpenCapturesAddr) { - SolidSyslogAddressStorage storage = {0}; - struct SolidSyslogAddress* addr = SolidSyslogAddress_FromStorage(&storage); + struct SolidSyslogAddress* addr = SolidSyslogPosixAddress_Create(); SolidSyslogStream_Open(stream, addr); POINTERS_EQUAL(addr, StreamFake_LastOpenAddr(stream)); + SolidSyslogPosixAddress_Destroy(addr); } TEST(StreamFake, SendIncrementsCount) @@ -99,15 +99,15 @@ TEST(StreamFake, CloseIncrementsCount) TEST(StreamFake, OpenDefaultsToSuccess) { - SolidSyslogAddressStorage storage = {0}; - struct SolidSyslogAddress* addr = SolidSyslogAddress_FromStorage(&storage); + struct SolidSyslogAddress* addr = SolidSyslogPosixAddress_Create(); CHECK_TRUE(SolidSyslogStream_Open(stream, addr)); + SolidSyslogPosixAddress_Destroy(addr); } TEST(StreamFake, SetOpenFailsMakesOpenReturnFalse) { StreamFake_SetOpenFails(stream, true); - SolidSyslogAddressStorage storage = {0}; - struct SolidSyslogAddress* addr = SolidSyslogAddress_FromStorage(&storage); + struct SolidSyslogAddress* addr = SolidSyslogPosixAddress_Create(); CHECK_FALSE(SolidSyslogStream_Open(stream, addr)); + SolidSyslogPosixAddress_Destroy(addr); } From e98a23f98c134f7165e3f57c556a42b08e89fe68 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 10:07:03 +0100 Subject: [PATCH 10/12] docs: S24.07 D.002 narrowed + CLAUDE.md table + cppcheck cstyleCast suppressions + DEVLOG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes out S24.07's documentation tail: - docs/misra-deviations.md D.002: drops the (b) Address paragraph (caller-supplied-storage rationale retired); folds Address into D.002(a) standard vtable / opaque-handle downcast scope. - misra_suppressions.txt: removes the nine legacy SolidSyslogAddress.c / SolidSyslogAddressInternal.h suppression entries; adds the new SolidSyslog{Posix,Winsock,FreeRtos}Address (`.c` + `Private.h` + `Static.c`) cast sites under the same D.002 scope. - CLAUDE.md public-header table: adds rows for `SolidSyslogAddress.h` (opaque only), `SolidSyslog{Posix,Winsock,FreeRtos}Address.h`; updates `SolidSyslog{Udp,Stream}Sender.h` to mention the new `Address` field. - Inline cppcheck-suppress cstyleCast in each per-platform AddressPrivate.h — opaque-to-impl downcast, explained at the site (cstyleCast is a non-MISRA cppcheck style warning; the MISRA-rule suppressions for the same casts live in misra_suppressions.txt). - DEVLOG entry documenting the per-platform-fallback design pivot, pool default 3, HandleFromIndex helper, and the deferred StreamSender bad-setup contract alignment. Co-Authored-By: Claude Opus 4.7 (1M context) --- CLAUDE.md | 8 +- DEVLOG.md | 49 +++++++++++ .../SolidSyslogFreeRtosAddressPrivate.h | 2 + .../Source/SolidSyslogPosixAddressPrivate.h | 2 + .../Source/SolidSyslogWinsockAddressPrivate.h | 2 + Tests/SolidSyslogPosixAddressTest.cpp | 1 + docs/misra-deviations.md | 84 +++++++++---------- misra_suppressions.txt | 41 ++++----- 8 files changed, 124 insertions(+), 65 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 88235b86..a0180569 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -323,6 +323,10 @@ live under `Core/Interface/`; platform-specific helpers (the `SolidSyslogPosix*` | `SolidSyslogSenderDefinition.h` | Sender implementors (extension point) | `SolidSyslogSender` vtable struct (`Send`, `Disconnect`) | | `SolidSyslogNullSender.h` | Any code installing a no-op sender slot (Send returns `true` to drop on the floor — keeps Store from filling with undeliverables; Disconnect is a no-op) | `SolidSyslogNullSender_Get` | | `SolidSyslogTransport.h` | Any code selecting a transport or needing default port constants | `SolidSyslogTransport` enum (`UDP`, `TCP`), `SOLIDSYSLOG_UDP_DEFAULT_PORT`, `SOLIDSYSLOG_TCP_DEFAULT_PORT` | +| `SolidSyslogAddress.h` | Any code holding an address handle | Opaque `struct SolidSyslogAddress` forward declaration only — the destination slot a Resolver writes into and a Datagram / Stream reads from. Handles come from the per-platform `SolidSyslog{Posix,Winsock,FreeRtos}Address_Create()` factories below. | +| `SolidSyslogPosixAddress.h` | System setup code on POSIX targets wiring a UDP / TCP destination | `SolidSyslogPosixAddress_Create(void)`, `_Destroy(base)` (wraps `struct sockaddr_in`). Instance struct lives in a library-internal static pool sized by `SOLIDSYSLOG_ADDRESS_POOL_SIZE` (default 3 — covers the canonical multi-transport BDD wiring). Pool-exhaustion fallback is a TU-private singleton sized as a real `SolidSyslogPosixAddress`; multi-overflow integrators share that storage and race. | +| `SolidSyslogWinsockAddress.h` | System setup code on Windows targets wiring a UDP / TCP destination | `SolidSyslogWinsockAddress_Create(void)`, `_Destroy(base)` (wraps Winsock `struct sockaddr_in`). Same pool semantics as `SolidSyslogPosixAddress`. | +| `SolidSyslogFreeRtosAddress.h` | System setup code on FreeRTOS targets wiring a UDP / TCP destination | `SolidSyslogFreeRtosAddress_Create(void)`, `_Destroy(base)` (wraps `struct freertos_sockaddr`). Same pool semantics as `SolidSyslogPosixAddress`. | | `SolidSyslogResolver.h` | Any code that needs to resolve a destination | `SolidSyslogResolver_Resolve(resolver, transport, host, port, *out)` | | `SolidSyslogResolverDefinition.h` | Resolver implementors (extension point) | `SolidSyslogResolver` vtable struct (`Resolve`) | | `SolidSyslogNullResolver.h` | Any code installing a no-op resolver slot (Resolve returns `false` so the caller's unresolved-host error path runs naturally) | `SolidSyslogNullResolver_Get` | @@ -335,9 +339,9 @@ live under `Core/Interface/`; platform-specific helpers (the `SolidSyslogPosix*` | `SolidSyslogStreamDefinition.h` | Stream implementors (extension point) | `SolidSyslogStream` vtable struct (`Open`, `Send`, `Read`, `Close`) | | `SolidSyslogNullStream.h` | Any code installing a no-op stream slot (Open/Close are no-ops, Send returns `true` to drop on the floor so the Store does not fill with undeliverables, Read returns `0` for would-block so the caller does not tear the connection down) | `SolidSyslogNullStream_Get` | | `SolidSyslogFreeRtosTcpStream.h` | System setup code on FreeRTOS targets using FreeRTOS-Plus-TCP for TCP | `SolidSyslogFreeRtosTcpStream_Create(void)`, `_Destroy(base)` (wraps `FreeRTOS_socket` / `FreeRTOS_connect` / `FreeRTOS_send` / `FreeRTOS_recv` / `FreeRTOS_closesocket`; bounded blocking connect via `SO_SNDTIMEO=200ms`, cleared post-connect so Send/Read are non-blocking). Instance struct lives in a library-internal static pool (E11); default pool size 2 to support the future TLS-via-mbedTLS + plain-TCP pair (S08.07). Pool-exhaustion fallback is the shared `SolidSyslogNullStream`. | -| `SolidSyslogUdpSender.h` | System setup code using UDP transport | `SolidSyslogUdpSenderConfig` (resolver, datagram, endpoint, endpointVersion), `SolidSyslogUdpSender_Create(config)`, `_Destroy(sender)`. Instance struct lives in a library-internal static pool (E11); `_Destroy` takes the handle returned by `_Create`. Pool-exhaustion and bad-config fallback is the shared `SolidSyslogNullSender`. | +| `SolidSyslogUdpSender.h` | System setup code using UDP transport | `SolidSyslogUdpSenderConfig` (resolver, datagram, address, endpoint, endpointVersion — the integrator supplies one platform Address handle per sender from `SolidSyslog{Posix,Winsock,FreeRtos}Address_Create`), `SolidSyslogUdpSender_Create(config)`, `_Destroy(sender)`. Instance struct lives in a library-internal static pool (E11); `_Destroy` takes the handle returned by `_Create`. Pool-exhaustion and bad-config (including NULL Address) fallback is the shared `SolidSyslogNullSender`. | | `SolidSyslogPosixTcpStream.h` | System setup code on POSIX targets using non-blocking TCP with bounded connect/keepalive | `SolidSyslogPosixTcpStream_Create(void)`, `_Destroy(base)`. Instance struct lives in a library-internal static pool (E11); default pool size 2 to support the BDD-target plain-TCP + TLS-underlying-TCP pair. Pool-exhaustion fallback is the shared `SolidSyslogNullStream`. | -| `SolidSyslogStreamSender.h` | System setup code using octet-framed transport (RFC 6587) over any Stream — `SolidSyslogPosixTcpStream` (POSIX TCP), `SolidSyslogWinsockTcpStream` (Windows TCP), `SolidSyslogFreeRtosTcpStream` (FreeRTOS-Plus-TCP), `SolidSyslogTlsStream` (TLS; OpenSSL reference integration), `SolidSyslogMbedTlsStream` (TLS; Mbed TLS reference integration for embedded targets), or a caller-supplied Stream backend | `SolidSyslogStreamSenderConfig` (resolver, stream, endpoint, endpointVersion), `SolidSyslogStreamSender_Create(config)`, `_Destroy(base)`. Instance struct lives in a library-internal static pool (E11); `_Destroy` takes the handle returned by `_Create`. Pool exhaustion resolves to the shared `SolidSyslogNullSender`. | +| `SolidSyslogStreamSender.h` | System setup code using octet-framed transport (RFC 6587) over any Stream — `SolidSyslogPosixTcpStream` (POSIX TCP), `SolidSyslogWinsockTcpStream` (Windows TCP), `SolidSyslogFreeRtosTcpStream` (FreeRTOS-Plus-TCP), `SolidSyslogTlsStream` (TLS; OpenSSL reference integration), `SolidSyslogMbedTlsStream` (TLS; Mbed TLS reference integration for embedded targets), or a caller-supplied Stream backend | `SolidSyslogStreamSenderConfig` (resolver, stream, address, endpoint, endpointVersion — the integrator supplies one platform Address handle per sender from `SolidSyslog{Posix,Winsock,FreeRtos}Address_Create`), `SolidSyslogStreamSender_Create(config)`, `_Destroy(base)`. Instance struct lives in a library-internal static pool (E11); `_Destroy` takes the handle returned by `_Create`. Pool exhaustion resolves to the shared `SolidSyslogNullSender`. | | `SolidSyslogTlsStream.h` | System setup code using TLS over an injected `SolidSyslogStream` transport (OpenSSL reference integration) | `SolidSyslogTlsStreamConfig` (transport, sleep, caBundlePath, serverName, cipherList, clientCertChainPath, clientKeyPath), `SolidSyslogTlsStream_Create(config)`, `_Destroy(base)`. Instance struct lives in a library-internal static pool (E11). Pool-exhaustion fallback is the shared `SolidSyslogNullStream`. | | `SolidSyslogMbedTlsStream.h` | System setup code using TLS over an injected `SolidSyslogStream` transport via Mbed TLS (embedded-target reference integration; pair with `SolidSyslogFreeRtosTcpStream`, `SolidSyslogPosixTcpStream`, `SolidSyslogWinsockTcpStream`, or a caller-supplied byte transport) | `SolidSyslogMbedTlsStreamConfig` (transport, sleep, rng, caChain, serverName, clientCertChain, clientKey — caller-built `mbedtls_ctr_drbg_context*` / `mbedtls_x509_crt*` / `mbedtls_pk_context*` handles, never file paths or PEM blobs), `SolidSyslogMbedTlsStream_Create(config)`, `_Destroy(base)`. Instance struct lives in a library-internal static pool (E11); coexistence contract — `Platform/MbedTls/Source/` never calls process-global Mbed TLS APIs (`mbedtls_platform_setup` / `_teardown`, `psa_crypto_init`, threading-alt, debug hooks). Pool-exhaustion fallback is the shared `SolidSyslogNullStream`. See [`docs/integrating-mbedtls.md`](docs/integrating-mbedtls.md) for the full integrator guide. | | `SolidSyslogSwitchingSender.h` | System setup code composing multiple inner senders | `SolidSyslogSwitchingSenderConfig` (senders, senderCount, selector), `SolidSyslogSwitchingSenderSelector`, `SolidSyslogSwitchingSender_Create(config)`, `_Destroy(sender)`. Instance struct lives in a library-internal static pool (E11); `_Destroy` takes the handle returned by `_Create`. Out-of-range selector and pool exhaustion both resolve to the shared `SolidSyslogNullSender`. | diff --git a/DEVLOG.md b/DEVLOG.md index a94354ef..fc1601e4 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -10792,3 +10792,52 @@ MISRA rule — different category, doesn't set precedent. ### Open questions - None. + +## 2026-05-22 — S24.07 SolidSyslogAddress as pool-allocated handle + +### Decisions + +- **Per-platform pool + TU-private fallback singleton.** The first + attempt at this story used a single `SolidSyslogNullAddress` + singleton in `Core/Source/` as the pool-exhaustion fallback. + David caught the bug: `Core/` can't include `` / + `` / ``, so the singleton was + 1 byte of storage. A platform Resolver writing a 16-byte + `sockaddr_in` into it on pool exhaustion was silent corruption. + Reverted, switched to a TU-private `Address_Fallback` + inside each platform's `SolidSyslogAddressStatic.c` — + sized as a real `SolidSyslogAddress`, so a Resolver + overwrite is bounded. Multi-overflow integrators share the + fallback storage and race; the `POOL_EXHAUSTED` error handler + call at every exhaustion is the signal to bump the tunable. +- **Default pool size 3.** Matches the canonical BDD multi- + transport wiring (UDP + plain-TCP + TLS-stream). David + initially asked for default 1 with BDD-target overrides; + switched after I confirmed the library's pool array size is + baked at library build time, so a per-BDD-target override + would need a new top-level mechanism. The default-3 trade- + off matches the existing `SOLIDSYSLOG_POSIX_TCP_STREAM_POOL_SIZE` + / `_STREAM_SENDER_POOL_SIZE` defaults. +- **`HandleFromIndex` cast helper.** Centralises the pool-slot + `(struct SolidSyslogAddress*) &Pool[i]` cast at three call + sites (Create success path, IndexFromHandle comparison loop, + CleanupAtIndex). Fallback cast stays inline — one occurrence, + not worth a separate helper. +- **D.002 narrowed.** Address moves off the old caller-supplied- + storage exception (D.002(b), retired) onto the standard + vtable / opaque-handle downcast (D.002(a)). The casts are + still there but their rationale is the same as every other + pool class. + +### Deferred + +- **StreamSender bad-setup contract.** UdpSender now rejects + NULL Address explicitly with the standard bad-setup error + pattern. StreamSender has historically been permissive + (no NULL-field validation) — kept as-is to avoid scope + creep. A future cleanup pass should align StreamSender with + UdpSender's contract for all NULL fields, not just Address. + +### Open questions + +- None. diff --git a/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h b/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h index 3a3df552..1dcd9e07 100644 --- a/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h +++ b/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h @@ -16,6 +16,7 @@ void FreeRtosAddress_Cleanup(struct SolidSyslogAddress* base); static inline struct freertos_sockaddr* SolidSyslogFreeRtosAddress_AsFreertosSockaddr(struct SolidSyslogAddress* base) { + // cppcheck-suppress cstyleCast -- opaque-to-impl downcast: pool slot is a real SolidSyslogFreeRtosAddress return &((struct SolidSyslogFreeRtosAddress*) base)->Sockaddr; } @@ -23,6 +24,7 @@ static inline const struct freertos_sockaddr* SolidSyslogFreeRtosAddress_AsConst const struct SolidSyslogAddress* base ) { + // cppcheck-suppress cstyleCast -- opaque-to-impl downcast: pool slot is a real SolidSyslogFreeRtosAddress return &((const struct SolidSyslogFreeRtosAddress*) base)->Sockaddr; } diff --git a/Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h b/Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h index 30cf79fa..2b50eba3 100644 --- a/Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h +++ b/Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h @@ -16,11 +16,13 @@ void PosixAddress_Cleanup(struct SolidSyslogAddress* base); static inline struct sockaddr_in* SolidSyslogPosixAddress_AsSockaddrIn(struct SolidSyslogAddress* base) { + // cppcheck-suppress cstyleCast -- opaque-to-impl downcast: pool slot is a real SolidSyslogPosixAddress return &((struct SolidSyslogPosixAddress*) base)->Sockaddr; } static inline const struct sockaddr_in* SolidSyslogPosixAddress_AsConstSockaddrIn(const struct SolidSyslogAddress* base) { + // cppcheck-suppress cstyleCast -- opaque-to-impl downcast: pool slot is a real SolidSyslogPosixAddress return &((const struct SolidSyslogPosixAddress*) base)->Sockaddr; } diff --git a/Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h b/Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h index 8df1e233..657224d2 100644 --- a/Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h +++ b/Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h @@ -16,6 +16,7 @@ void WinsockAddress_Cleanup(struct SolidSyslogAddress* base); static inline struct sockaddr_in* SolidSyslogWinsockAddress_AsSockaddrIn(struct SolidSyslogAddress* base) { + // cppcheck-suppress cstyleCast -- opaque-to-impl downcast: pool slot is a real SolidSyslogWinsockAddress return &((struct SolidSyslogWinsockAddress*) base)->Sockaddr; } @@ -23,6 +24,7 @@ static inline const struct sockaddr_in* SolidSyslogWinsockAddress_AsConstSockadd const struct SolidSyslogAddress* base ) { + // cppcheck-suppress cstyleCast -- opaque-to-impl downcast: pool slot is a real SolidSyslogWinsockAddress return &((const struct SolidSyslogWinsockAddress*) base)->Sockaddr; } diff --git a/Tests/SolidSyslogPosixAddressTest.cpp b/Tests/SolidSyslogPosixAddressTest.cpp index 27820f4f..bef6c898 100644 --- a/Tests/SolidSyslogPosixAddressTest.cpp +++ b/Tests/SolidSyslogPosixAddressTest.cpp @@ -38,6 +38,7 @@ TEST_GROUP(SolidSyslogPosixAddress) void setup() override { + // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros address = SolidSyslogPosixAddress_Create(); } diff --git a/docs/misra-deviations.md b/docs/misra-deviations.md index e278c67f..6bf5a94d 100644 --- a/docs/misra-deviations.md +++ b/docs/misra-deviations.md @@ -110,7 +110,7 @@ document under [S10.01](https://github.com/DavidCozens/solid-syslog/issues/357). --- -## D.002 — Rules 11.2 / 11.3 / 11.5: vtable downcasts + Address + Formatter +## D.002 — Rules 11.2 / 11.3 / 11.5: vtable downcasts + Formatter ### Rule @@ -125,12 +125,11 @@ document under [S10.01](https://github.com/DavidCozens/solid-syslog/issues/357). ### Deviation -SolidSyslog accepts three structural pointer conversions that are +SolidSyslog accepts two structural pointer conversions that are identified in code as `SelfFromBase` (vtable) or `(struct X*) storage` -(Address / Formatter). All three are reviewed once here, not per call -site. +(Formatter). Both are reviewed once here, not per call site. -#### (a) Vtable downcasts — every pool-allocated class +#### (a) Vtable / opaque-handle downcasts — every pool-allocated class Every implementation class that participates in a vtable interface (`SolidSyslogBuffer`, `SolidSyslogSender`, `SolidSyslogStream`, @@ -149,23 +148,21 @@ CircularBuffer_SelfFromBase(struct SolidSyslogBuffer* base) } ``` -Rule 11.3 fires on every such cast. This is the standard OO-in-C -"interface pointer back to derived implementation" cast that every -vtable method needs. +The same structural cast applies to `SolidSyslogAddress` — a pool- +allocated handle whose `struct SolidSyslogAddress` is an incomplete +public type, fully defined per platform as +`struct SolidSyslog{Posix,Winsock,FreeRtos}Address`. Each platform's +`*AddressPrivate.h` carries downcast accessors +(`SolidSyslogAddress_AsSockaddrIn` / `_AsConstSockaddrIn` / +`_AsFreertosSockaddr` / `_AsConstFreertosSockaddr`) plus a +`HandleFromIndex(size_t)` helper in `*AddressStatic.c` that converts a +pool slot index back to the public handle type. Rule 11.3 fires on +every such cast. -#### (b) `SolidSyslogAddress` — strict-tier opaque value type +This is the standard OO-in-C "interface pointer back to derived +implementation" cast. -`Address.h` exposes an opaque public type with a caller-supplied -storage shape (`SolidSyslogAddressStorage` + `SOLIDSYSLOG_ADDRESS_SIZE`) -across three platform-specific implementations -(`Platform/{FreeRtos,Posix,Windows}/Source/SolidSyslogAddressInternal.h`). -Address is a transient value type, not a Created object — it has no -`_Create`/`_Destroy` lifecycle and so was deliberately left out of E11's -pool migration. Rules 11.2 / 11.3 / 11.5 all fire on the casts between -`SolidSyslogAddress*` (incomplete public type) and the platform -implementation struct. - -#### (c) `SolidSyslogFormatter` — variable-size stack builder +#### (b) `SolidSyslogFormatter` — variable-size stack builder `SolidSyslogFormatter` is a transient stack-built builder whose backing storage is sized at the call site via the @@ -177,35 +174,30 @@ SolidSyslogFormatter*`. ### Rationale -The pool migration under E11 retired the caller-supplied-storage pattern -for every class that has a Create/Destroy lifecycle, leaving only the -vtable downcast (which is required by the OO-in-C interface decoupling) -and the two non-pool exceptions above (Address as a value type, -Formatter as a per-call builder). All three would otherwise require -either dynamic allocation (not available on bare-metal / FreeRTOS- -static-allocation / DO-178C-style targets — the library is callable from +The pool migration under E11 / E24 retired the caller-supplied-storage +pattern for every class that has a Create/Destroy lifecycle, leaving +only the vtable / opaque-handle downcast (which is required by the +OO-in-C interface decoupling) and the one non-pool exception above +(Formatter as a per-call builder). Both would otherwise require either +dynamic allocation (not available on bare-metal / FreeRTOS-static- +allocation / DO-178C-style targets — the library is callable from boot before any heap exists) or leaking the implementation struct through the public API (breaks ABI stability and the embedded-friendly opaque-type design). ### Risk and mitigation -- **Type safety** — For (b) Address and (c) Formatter, a - `_Static_assert` immediately below the impl definition pins the - relationship between the public storage type and the private impl - struct at build time: - - ```c - SOLIDSYSLOG_STATIC_ASSERT( - sizeof(struct SolidSyslogX) <= sizeof(SolidSyslogXStorage), - "SOLIDSYSLOG_X_STORAGE_SIZE is too small for struct SolidSyslogX" - ); - ``` - - An integrator who allocates undersized storage is caught at compile - time. For (a) vtable downcasts, type safety is enforced by the - contract that each vtable method receives is only called via the - vtable installed in its own `SelfFromBase`-aware implementation. +- **Type safety** — For (b) Formatter, a `_Static_assert` immediately + below the impl definition pins the relationship between the public + storage type and the private impl struct at build time. An + integrator who allocates undersized storage is caught at compile + time. For (a) vtable / opaque-handle downcasts, type safety is + enforced by the contract that vtable methods are only called via the + vtable installed in their own `SelfFromBase`-aware implementation; + the per-platform Address downcast is similarly locked down because + the pool slot is statically-typed `struct SolidSyslogAddress`, + so the cast back from the opaque `struct SolidSyslogAddress*` cannot + lie. - **Alignment** — Storage types are declared as `intptr_t storage[N]` (or a struct of the same shape), giving alignment at least as strict as any pointer or scalar the impl contains. The cast is therefore @@ -222,7 +214,11 @@ Project owner — David Cozens. Recorded under narrowed under [S11.11](https://github.com/DavidCozens/solid-syslog/issues/414) once every Create-lifecycle class moved off caller-supplied storage onto the -pool allocator. +pool allocator; further narrowed under +[S24.07](https://github.com/DavidCozens/solid-syslog/issues/418) once +Address itself moved onto per-platform pool classes — the casts are +now the same OO-in-C downcast that authorised (a), not a separate +caller-supplied-storage exception. --- diff --git a/misra_suppressions.txt b/misra_suppressions.txt index 34f7abd2..42f906c6 100644 --- a/misra_suppressions.txt +++ b/misra_suppressions.txt @@ -9,18 +9,15 @@ # Format: misra-c2012-:: # Lines starting with # are comments. -# D.002 — Rules 11.2 / 11.3 / 11.5: vtable downcasts + Address + Formatter +# D.002 — Rules 11.2 / 11.3 / 11.5: vtable downcasts + Formatter # See docs/misra-deviations.md#d002 misra-c2012-11.2:Core/Interface/SolidSyslogFormatter.h:30 -misra-c2012-11.2:Platform/FreeRtos/Source/SolidSyslogAddress.c:5 -misra-c2012-11.2:Platform/FreeRtos/Source/SolidSyslogAddressInternal.h:19 -misra-c2012-11.2:Platform/FreeRtos/Source/SolidSyslogAddressInternal.h:25 -misra-c2012-11.2:Platform/Posix/Source/SolidSyslogAddress.c:5 -misra-c2012-11.2:Platform/Posix/Source/SolidSyslogAddressInternal.h:17 -misra-c2012-11.2:Platform/Posix/Source/SolidSyslogAddressInternal.h:23 -misra-c2012-11.2:Platform/Windows/Source/SolidSyslogAddress.c:5 -misra-c2012-11.2:Platform/Windows/Source/SolidSyslogAddressInternal.h:17 -misra-c2012-11.2:Platform/Windows/Source/SolidSyslogAddressInternal.h:23 +misra-c2012-11.2:Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h:19 +misra-c2012-11.2:Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h:26 +misra-c2012-11.2:Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h:17 +misra-c2012-11.2:Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h:23 +misra-c2012-11.2:Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h:19 +misra-c2012-11.2:Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h:26 misra-c2012-11.3:Core/Interface/SolidSyslogFormatter.h:30 misra-c2012-11.3:Core/Source/SolidSyslogBlockStore.c:69 misra-c2012-11.3:Core/Source/SolidSyslogCircularBuffer.c:87 @@ -35,25 +32,31 @@ misra-c2012-11.3:Core/Source/SolidSyslogTimeQualitySd.c:59 misra-c2012-11.3:Core/Source/SolidSyslogUdpSender.c:98 misra-c2012-11.3:Platform/Atomics/Source/SolidSyslogStdAtomicCounter.c:36 misra-c2012-11.3:Platform/FatFs/Source/SolidSyslogFatFsFile.c:53 -misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogAddress.c:5 -misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogAddressInternal.h:20 -misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogAddressInternal.h:26 +misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c:8 +misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h:20 +misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressPrivate.h:27 +misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c:34 +misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c:60 misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagram.c:62 misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosMutex.c:52 misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosStaticResolver.c:50 misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c:112 misra-c2012-11.3:Platform/OpenSsl/Source/SolidSyslogTlsStream.c:85 -misra-c2012-11.3:Platform/Posix/Source/SolidSyslogAddress.c:5 -misra-c2012-11.3:Platform/Posix/Source/SolidSyslogAddressInternal.h:18 -misra-c2012-11.3:Platform/Posix/Source/SolidSyslogAddressInternal.h:24 +misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixAddress.c:8 +misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h:18 +misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixAddressPrivate.h:24 +misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixAddressStatic.c:33 +misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixAddressStatic.c:60 misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixDatagram.c:77 misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixFile.c:66 misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixMessageQueueBuffer.c:99 misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixMutex.c:47 misra-c2012-11.3:Platform/Posix/Source/SolidSyslogPosixTcpStream.c:88 -misra-c2012-11.3:Platform/Windows/Source/SolidSyslogAddress.c:5 -misra-c2012-11.3:Platform/Windows/Source/SolidSyslogAddressInternal.h:18 -misra-c2012-11.3:Platform/Windows/Source/SolidSyslogAddressInternal.h:24 +misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWinsockAddress.c:8 +misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h:20 +misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWinsockAddressPrivate.h:27 +misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWinsockAddressStatic.c:33 +misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWinsockAddressStatic.c:60 misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWindowsAtomicCounter.c:40 misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWindowsFile.c:73 misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWindowsMutex.c:34 From 6b9eb5d4bd851700a350ff412d8a7762efdf7a79 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 10:16:53 +0100 Subject: [PATCH 11/12] chore: S24.07 IWYU + clang-tidy fixes - Add direct to SolidSyslogPosixAddress.c (was relying on transitive include from Private.h). - Trim per-file unused includes (, ) and add / where IWYU pointed out missing direct includes for htons / inet_pton / AF_INET in tests touched by the S24.07 fixture migrations. - Make SolidSyslogGetAddrInfoResolverTest::Resolve const (readability-make-member-function-const). - clang-format pass on every file the PR touches. Co-Authored-By: Claude Opus 4.7 (1M context) --- Platform/Posix/Source/SolidSyslogPosixAddress.c | 1 + Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp | 5 ++++- Tests/SolidSyslogGetAddrInfoResolverTest.cpp | 2 +- Tests/SolidSyslogPosixAddressTest.cpp | 3 ++- Tests/SolidSyslogPosixDatagramTest.cpp | 1 - Tests/SolidSyslogPosixTcpStreamTest.cpp | 1 - 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Platform/Posix/Source/SolidSyslogPosixAddress.c b/Platform/Posix/Source/SolidSyslogPosixAddress.c index 176f019b..d5182f25 100644 --- a/Platform/Posix/Source/SolidSyslogPosixAddress.c +++ b/Platform/Posix/Source/SolidSyslogPosixAddress.c @@ -1,5 +1,6 @@ #include "SolidSyslogPosixAddressPrivate.h" +#include #include struct SolidSyslogAddress; diff --git a/Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp b/Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp index 28d72e5d..16df759e 100644 --- a/Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp +++ b/Tests/FreeRtos/SolidSyslogFreeRtosDatagramTest.cpp @@ -187,7 +187,10 @@ TEST(SolidSyslogFreeRtosDatagram, SendToSendsBufferToDestinationAfterOpen) POINTERS_EQUAL(TEST_MESSAGE, FreeRtosSocketsFake_LastSendtoBuffer()); LONGS_EQUAL(TEST_MESSAGE_LEN, FreeRtosSocketsFake_LastSendtoLength()); LONGS_EQUAL(0, FreeRtosSocketsFake_LastSendtoFlags()); - POINTERS_EQUAL(SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr), FreeRtosSocketsFake_LastSendtoDestination()); + POINTERS_EQUAL( + SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr), + FreeRtosSocketsFake_LastSendtoDestination() + ); LONGS_EQUAL(sizeof(struct freertos_sockaddr), FreeRtosSocketsFake_LastSendtoDestinationLength()); } diff --git a/Tests/SolidSyslogGetAddrInfoResolverTest.cpp b/Tests/SolidSyslogGetAddrInfoResolverTest.cpp index 70194e78..ef23d96a 100644 --- a/Tests/SolidSyslogGetAddrInfoResolverTest.cpp +++ b/Tests/SolidSyslogGetAddrInfoResolverTest.cpp @@ -47,7 +47,7 @@ TEST_GROUP(SolidSyslogGetAddrInfoResolver) SolidSyslogGetAddrInfoResolver_Destroy(resolver); } - bool Resolve(const char* host, uint16_t port, enum SolidSyslogTransport transport = SOLIDSYSLOG_TRANSPORT_UDP) + bool Resolve(const char* host, uint16_t port, enum SolidSyslogTransport transport = SOLIDSYSLOG_TRANSPORT_UDP) const { return SolidSyslogResolver_Resolve(resolver, transport, host, port, result); } diff --git a/Tests/SolidSyslogPosixAddressTest.cpp b/Tests/SolidSyslogPosixAddressTest.cpp index bef6c898..a4d82e9f 100644 --- a/Tests/SolidSyslogPosixAddressTest.cpp +++ b/Tests/SolidSyslogPosixAddressTest.cpp @@ -4,8 +4,9 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-file scope only; brings NEVER/ONCE/TWICE/THRICE into scope for the CALLED_* // macros +#include #include -#include +#include #include "ConfigLockFake.h" #include "ErrorHandlerFake.h" diff --git a/Tests/SolidSyslogPosixDatagramTest.cpp b/Tests/SolidSyslogPosixDatagramTest.cpp index 19663e38..773980ad 100644 --- a/Tests/SolidSyslogPosixDatagramTest.cpp +++ b/Tests/SolidSyslogPosixDatagramTest.cpp @@ -17,7 +17,6 @@ using namespace CososoTesting; // NOLINT(google-build-using-namespace) -- test-f #include "SocketFake.h" #include #include -#include #include #include #include diff --git a/Tests/SolidSyslogPosixTcpStreamTest.cpp b/Tests/SolidSyslogPosixTcpStreamTest.cpp index b90e713a..7b2b9658 100644 --- a/Tests/SolidSyslogPosixTcpStreamTest.cpp +++ b/Tests/SolidSyslogPosixTcpStreamTest.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "TestUtils.h" #include "CppUTest/TestHarness.h" From 555b9fb056129abd42e60afd455a3501442b9e62 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 13:12:31 +0100 Subject: [PATCH 12/12] =?UTF-8?q?fix:=20S24.07=20CI=20fixes=20=E2=80=94=20?= =?UTF-8?q?cross-platform=20AddressFake=20+=20missed=20FreeRtos=20cast=20+?= =?UTF-8?q?=20cppcheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses four CI failures and one CodeRabbit miss on PR #422: - build-freertos-target: Bdd/Targets/FreeRtos/CMakeLists.txt still listed the deleted Platform/FreeRtos/Source/SolidSyslogAddress.c. Swapped to the new SolidSyslogFreeRtosAddress{.c,Static.c} pair; updated the stale Address.h / AddressInternal.h header comments. - build-windows-msvc + integration-windows-openssl: five test / integration files hard-coded `#include "SolidSyslogPosixAddress.h"`, which doesn't exist on Windows. Introduces Tests/AddressFake.{h,c} — a tiny cross-platform opaque-singleton helper for tests that treat SolidSyslogAddress* purely as a pass-through token (StreamFakeTest, TlsStreamTest, MbedTlsStreamTest, both TLS integration tests). Wired into each test executable's CMakeLists (SolidSyslogTests, MbedTlsStreamTest, MbedTlsIntegrationTests, OpenSslIntegrationTests). - analyze-cppcheck: two unreadVariable warnings on the SolidSyslogGetAddrInfoResolver fixture I refactored. Added the standard cppcheck-suppress comments matching the convention used elsewhere — cppcheck does not model CppUTest TEST_GROUP lifecycle. - CodeRabbit comment (outside diff range): one missed migration in Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp — replaced reinterpret_cast(addr) with SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr) to match the equivalent fix in SolidSyslogFreeRtosDatagramTest.cpp. Verified locally in the cpputest-freertos image: SolidSyslogTests 1290/1292; all six FreeRTOS host tests green; MbedTlsStreamTest 42/42; OpenSslIntegrationTests 9/9; MbedTlsIntegrationTests 7/7; cppcheck preset clean. Co-Authored-By: Claude Opus 4.7 (1M context) --- Bdd/Targets/FreeRtos/CMakeLists.txt | 7 ++++--- Tests/AddressFake.c | 10 ++++++++++ Tests/AddressFake.h | 19 +++++++++++++++++++ Tests/CMakeLists.txt | 1 + .../SolidSyslogFreeRtosTcpStreamTest.cpp | 3 +-- Tests/MbedTls/CMakeLists.txt | 1 + .../MbedTls/SolidSyslogMbedTlsStreamTest.cpp | 5 ++--- Tests/MbedTlsIntegration/CMakeLists.txt | 2 ++ ...olidSyslogMbedTlsStreamIntegrationTest.cpp | 5 ++--- Tests/OpenSslIntegration/CMakeLists.txt | 2 ++ .../SolidSyslogTlsStreamIntegrationTest.cpp | 5 ++--- Tests/SolidSyslogGetAddrInfoResolverTest.cpp | 2 ++ Tests/SolidSyslogTlsStreamTest.cpp | 5 ++--- Tests/StreamFakeTest.cpp | 14 +++++--------- 14 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 Tests/AddressFake.c create mode 100644 Tests/AddressFake.h diff --git a/Bdd/Targets/FreeRtos/CMakeLists.txt b/Bdd/Targets/FreeRtos/CMakeLists.txt index a9282429..8da8aea6 100644 --- a/Bdd/Targets/FreeRtos/CMakeLists.txt +++ b/Bdd/Targets/FreeRtos/CMakeLists.txt @@ -261,7 +261,8 @@ add_executable(SolidSyslogBddTarget ${CMAKE_CURRENT_SOURCE_DIR}/Common/Syscalls.c ${CMAKE_SOURCE_DIR}/Platform/FatFs/Source/SolidSyslogFatFsFile.c ${CMAKE_SOURCE_DIR}/Platform/FatFs/Source/SolidSyslogFatFsFileStatic.c - ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogAddress.c + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosAddressStatic.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagram.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosDatagramStatic.c ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source/SolidSyslogFreeRtosMutex.c @@ -298,10 +299,10 @@ target_include_directories(SolidSyslogBddTarget PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} # FreeRTOSConfig.h, FreeRTOSIPConfig.h ${CMAKE_CURRENT_SOURCE_DIR}/Common # CmsdkUart.h ${CMAKE_SOURCE_DIR}/Core/Interface # SolidSyslog*.h - ${CMAKE_SOURCE_DIR}/Core/Source # SolidSyslogAddress.h (consumed by adapters) + ${CMAKE_SOURCE_DIR}/Core/Source # internal headers consumed by adapters ${CMAKE_SOURCE_DIR}/Platform/FatFs/Interface # SolidSyslogFatFsFile.h ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Interface # SolidSyslogFreeRtos*.h - ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source # SolidSyslogAddressInternal.h + ${CMAKE_SOURCE_DIR}/Platform/FreeRtos/Source # SolidSyslogFreeRtosAddressPrivate.h ${CMAKE_SOURCE_DIR}/Platform/MbedTls/Interface # SolidSyslogMbedTlsStream.h ${CMAKE_SOURCE_DIR}/Platform/MbedTls/Source # SolidSyslogMbedTlsStreamPrivate.h ${CMAKE_SOURCE_DIR}/Bdd/Targets/Common # BddTargetInteractive.h diff --git a/Tests/AddressFake.c b/Tests/AddressFake.c new file mode 100644 index 00000000..a91f67aa --- /dev/null +++ b/Tests/AddressFake.c @@ -0,0 +1,10 @@ +#include "AddressFake.h" + +struct SolidSyslogAddress; + +static char instance; + +struct SolidSyslogAddress* AddressFake_Get(void) +{ + return (struct SolidSyslogAddress*) &instance; +} diff --git a/Tests/AddressFake.h b/Tests/AddressFake.h new file mode 100644 index 00000000..15082d47 --- /dev/null +++ b/Tests/AddressFake.h @@ -0,0 +1,19 @@ +#ifndef ADDRESSFAKE_H +#define ADDRESSFAKE_H + +#include "ExternC.h" + +EXTERN_C_BEGIN + + /* + * Returns an opaque SolidSyslogAddress* suitable for tests that treat + * Address as a pure pass-through token (StreamFakeTest, TlsStreamTest) + * — they never read the platform sockaddr inside. Platform-agnostic so + * the same test executable builds on POSIX, Winsock, and FreeRTOS hosts + * without conditional compilation. + */ + struct SolidSyslogAddress* AddressFake_Get(void); + +EXTERN_C_END + +#endif /* ADDRESSFAKE_H */ diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 10ddd24c..89fec9ea 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -51,6 +51,7 @@ set(TEST_SOURCES SolidSyslogFormatterTest.cpp SolidSyslogUdpPayloadTest.cpp BufferFakeTest.cpp + AddressFake.c BufferFake.c MutexFake.c StoreFakeTest.cpp diff --git a/Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp b/Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp index c6268cdb..ee88114a 100644 --- a/Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp +++ b/Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp @@ -167,8 +167,7 @@ TEST(SolidSyslogFreeRtosTcpStream, OpenCallsConnectWithSocketAndAddress) openStream(); CALLED_FAKE(FreeRtosSocketsFake_Connect, ONCE); POINTERS_EQUAL(FreeRtosSocketsFake_LastSocketReturned(), FreeRtosSocketsFake_LastConnectSocket()); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) -- platform-layout cast, see setup - POINTERS_EQUAL(reinterpret_cast(addr), FreeRtosSocketsFake_LastConnectAddress()); + POINTERS_EQUAL(SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr), FreeRtosSocketsFake_LastConnectAddress()); LONGS_EQUAL(sizeof(struct freertos_sockaddr), FreeRtosSocketsFake_LastConnectAddressLength()); } diff --git a/Tests/MbedTls/CMakeLists.txt b/Tests/MbedTls/CMakeLists.txt index 2ace48d8..ceadb8f4 100644 --- a/Tests/MbedTls/CMakeLists.txt +++ b/Tests/MbedTls/CMakeLists.txt @@ -51,6 +51,7 @@ add_executable(SolidSyslogMbedTlsStreamTest main.cpp ${CMAKE_SOURCE_DIR}/Platform/MbedTls/Source/SolidSyslogMbedTlsStream.c ${CMAKE_SOURCE_DIR}/Platform/MbedTls/Source/SolidSyslogMbedTlsStreamStatic.c + ${CMAKE_SOURCE_DIR}/Tests/AddressFake.c ${CMAKE_SOURCE_DIR}/Tests/StreamFake.c ) diff --git a/Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp b/Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp index 53a84496..bbc17b99 100644 --- a/Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp +++ b/Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp @@ -7,7 +7,7 @@ extern "C" #include "MbedTlsFake.h" #include "SolidSyslogMbedTlsStream.h" -#include "SolidSyslogPosixAddress.h" +#include "AddressFake.h" #include "SolidSyslogStream.h" #include "SolidSyslogStreamDefinition.h" #include "StreamFake.h" @@ -44,13 +44,12 @@ TEST_GROUP(SolidSyslogMbedTlsStream) config.Sleep = NoOpSleep; handle = SolidSyslogMbedTlsStream_Create(&config); // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros - addr = SolidSyslogPosixAddress_Create(); + addr = AddressFake_Get(); } void teardown() override { SolidSyslogMbedTlsStream_Destroy(handle); - SolidSyslogPosixAddress_Destroy(addr); StreamFake_Destroy(transport); } diff --git a/Tests/MbedTlsIntegration/CMakeLists.txt b/Tests/MbedTlsIntegration/CMakeLists.txt index 584be079..ee9db925 100644 --- a/Tests/MbedTlsIntegration/CMakeLists.txt +++ b/Tests/MbedTlsIntegration/CMakeLists.txt @@ -50,6 +50,7 @@ add_executable(MbedTlsIntegrationTests SocketStream.c MbedTlsTestCert.c MbedTlsTestServer.c + ${CMAKE_SOURCE_DIR}/Tests/AddressFake.c ${CMAKE_SOURCE_DIR}/Tests/Support/SafeStringStandard.c ${CMAKE_SOURCE_DIR}/Platform/MbedTls/Source/SolidSyslogMbedTlsStream.c ${CMAKE_SOURCE_DIR}/Platform/MbedTls/Source/SolidSyslogMbedTlsStreamStatic.c @@ -69,6 +70,7 @@ target_include_directories(MbedTlsIntegrationTests PRIVATE ${CMAKE_SOURCE_DIR}/Platform/MbedTls/Interface ${CMAKE_SOURCE_DIR}/Core/Interface ${CMAKE_SOURCE_DIR}/Core/Source + ${CMAKE_SOURCE_DIR}/Tests ${CMAKE_SOURCE_DIR}/Tests/Support ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/Tests/MbedTlsIntegration/SolidSyslogMbedTlsStreamIntegrationTest.cpp b/Tests/MbedTlsIntegration/SolidSyslogMbedTlsStreamIntegrationTest.cpp index 15130c4f..60c9bbfd 100644 --- a/Tests/MbedTlsIntegration/SolidSyslogMbedTlsStreamIntegrationTest.cpp +++ b/Tests/MbedTlsIntegration/SolidSyslogMbedTlsStreamIntegrationTest.cpp @@ -14,7 +14,7 @@ extern "C" #include "MbedTlsTestServer.h" #include "SocketStream.h" #include "SolidSyslogMbedTlsStream.h" -#include "SolidSyslogPosixAddress.h" +#include "AddressFake.h" #include "SolidSyslogStream.h" } @@ -45,7 +45,7 @@ TEST_GROUP(SolidSyslogMbedTlsStreamIntegration) void setup() override { - addr = SolidSyslogPosixAddress_Create(); + addr = AddressFake_Get(); mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&rng); const unsigned char pers[] = "mbedtls-integration-test"; @@ -93,7 +93,6 @@ TEST_GROUP(SolidSyslogMbedTlsStreamIntegration) MbedTlsTestCert_Destroy(&trustedCa); mbedtls_ctr_drbg_free(&rng); mbedtls_entropy_free(&entropy); - SolidSyslogPosixAddress_Destroy(addr); } struct SolidSyslogStream* StartServerWithCert(const struct MbedTlsTestCert* cert) diff --git a/Tests/OpenSslIntegration/CMakeLists.txt b/Tests/OpenSslIntegration/CMakeLists.txt index c2a8dba4..59d46164 100644 --- a/Tests/OpenSslIntegration/CMakeLists.txt +++ b/Tests/OpenSslIntegration/CMakeLists.txt @@ -8,6 +8,7 @@ set(OPENSSL_INTEGRATION_TESTS_SOURCES TlsTestServer.c SolidSyslogTlsStreamIntegrationTest.cpp main.cpp + ${CMAKE_SOURCE_DIR}/Tests/AddressFake.c ) # OpenSSL on MSVC requires applink.c when the application passes FILE* across @@ -35,6 +36,7 @@ target_link_libraries(OpenSslIntegrationTests PRIVATE target_include_directories(OpenSslIntegrationTests PRIVATE ${CMAKE_SOURCE_DIR}/Core/Source + ${CMAKE_SOURCE_DIR}/Tests ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp b/Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp index 1ad7de2e..5a48d863 100644 --- a/Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp +++ b/Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp @@ -8,7 +8,7 @@ #include #include "BioPairStream.h" -#include "SolidSyslogPosixAddress.h" +#include "AddressFake.h" #include "SolidSyslogStream.h" #include "SolidSyslogTlsStream.h" #include "TlsTestCert.h" @@ -42,12 +42,11 @@ TEST_GROUP(TlsStreamIntegration) void setup() override { - addr = SolidSyslogPosixAddress_Create(); + addr = AddressFake_Get(); } void teardown() override { - if (addr != nullptr) { SolidSyslogPosixAddress_Destroy(addr); } if (tlsStream != nullptr) { SolidSyslogTlsStream_Destroy(tlsStream); } if (transport != nullptr) { BioPairStream_Destroy(transport); } if (server != nullptr) { TlsTestServer_Destroy(server); } diff --git a/Tests/SolidSyslogGetAddrInfoResolverTest.cpp b/Tests/SolidSyslogGetAddrInfoResolverTest.cpp index ef23d96a..68d58a34 100644 --- a/Tests/SolidSyslogGetAddrInfoResolverTest.cpp +++ b/Tests/SolidSyslogGetAddrInfoResolverTest.cpp @@ -37,7 +37,9 @@ TEST_GROUP(SolidSyslogGetAddrInfoResolver) void setup() override { SocketFake_Reset(); + // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros resolver = SolidSyslogGetAddrInfoResolver_Create(); + // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros result = SolidSyslogPosixAddress_Create(); } diff --git a/Tests/SolidSyslogTlsStreamTest.cpp b/Tests/SolidSyslogTlsStreamTest.cpp index 4f0ab561..f304364b 100644 --- a/Tests/SolidSyslogTlsStreamTest.cpp +++ b/Tests/SolidSyslogTlsStreamTest.cpp @@ -5,7 +5,7 @@ #include #include "OpenSslFake.h" -#include "SolidSyslogPosixAddress.h" +#include "AddressFake.h" #include "SolidSyslogStream.h" #include "SolidSyslogTlsStream.h" #include "SolidSyslogTransport.h" @@ -48,13 +48,12 @@ TEST_GROUP(SolidSyslogTlsStream) // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros stream = SolidSyslogTlsStream_Create(&config); // cppcheck-suppress unreadVariable -- used across TEST_GROUP methods; cppcheck does not model CppUTest macros - addr = SolidSyslogPosixAddress_Create(); + addr = AddressFake_Get(); } void teardown() override { SolidSyslogTlsStream_Destroy(stream); - SolidSyslogPosixAddress_Destroy(addr); StreamFake_Destroy(transport); } diff --git a/Tests/StreamFakeTest.cpp b/Tests/StreamFakeTest.cpp index 0629518a..eadad522 100644 --- a/Tests/StreamFakeTest.cpp +++ b/Tests/StreamFakeTest.cpp @@ -1,4 +1,4 @@ -#include "SolidSyslogPosixAddress.h" +#include "AddressFake.h" #include "SolidSyslogStream.h" #include "StreamFake.h" #include "TestUtils.h" @@ -27,18 +27,16 @@ TEST(StreamFake, CreateSucceeds) TEST(StreamFake, OpenIncrementsCount) { - struct SolidSyslogAddress* addr = SolidSyslogPosixAddress_Create(); + struct SolidSyslogAddress* addr = AddressFake_Get(); SolidSyslogStream_Open(stream, addr); CALLED_FAKE_ON(StreamFake_Open, stream, ONCE); - SolidSyslogPosixAddress_Destroy(addr); } TEST(StreamFake, OpenCapturesAddr) { - struct SolidSyslogAddress* addr = SolidSyslogPosixAddress_Create(); + struct SolidSyslogAddress* addr = AddressFake_Get(); SolidSyslogStream_Open(stream, addr); POINTERS_EQUAL(addr, StreamFake_LastOpenAddr(stream)); - SolidSyslogPosixAddress_Destroy(addr); } TEST(StreamFake, SendIncrementsCount) @@ -99,15 +97,13 @@ TEST(StreamFake, CloseIncrementsCount) TEST(StreamFake, OpenDefaultsToSuccess) { - struct SolidSyslogAddress* addr = SolidSyslogPosixAddress_Create(); + struct SolidSyslogAddress* addr = AddressFake_Get(); CHECK_TRUE(SolidSyslogStream_Open(stream, addr)); - SolidSyslogPosixAddress_Destroy(addr); } TEST(StreamFake, SetOpenFailsMakesOpenReturnFalse) { StreamFake_SetOpenFails(stream, true); - struct SolidSyslogAddress* addr = SolidSyslogPosixAddress_Create(); + struct SolidSyslogAddress* addr = AddressFake_Get(); CHECK_FALSE(SolidSyslogStream_Open(stream, addr)); - SolidSyslogPosixAddress_Destroy(addr); }