#include "../../unity/unity.h" #include #include #include #include /* The test file is included into the dd.c translation unit, so the following globals and functions are visible here: - static globals: obuf, ibuf, conversions_mask, page_size, input_blocksize, output_blocksize - constants/masks: C_TWOBUFS - function under test: alloc_obuf(void) - helper used by alloc_obuf when not C_TWOBUFS: alloc_ibuf(void) */ void setUp(void) { /* Provide a clean baseline for each test. We do not free previously allocated buffers to avoid coupling to allocator specifics; instead we reset pointers to ensure alloc_obuf's behavior is testable in isolation. */ obuf = NULL; ibuf = NULL; conversions_mask = 0; /* Reasonable sizes to ensure allocations succeed. */ page_size = 4096; /* typical page size and valid alignment */ input_blocksize = 64; /* >0 so alloc_ibuf can allocate */ output_blocksize = 128; /* >0 so alloc_obuf(C_TWOBUFS) can allocate */ } void tearDown(void) { /* Nothing to clean beyond pointer resets done in setUp. */ } /* Test: With C_TWOBUFS set and obuf == NULL, alloc_obuf allocates a distinct output buffer and does not touch ibuf. */ void test_alloc_obuf_twobufs_allocates_separate_buffer(void) { conversions_mask = C_TWOBUFS; /* Ensure a valid environment for allocation. */ page_size = 4096; output_blocksize = 128; ibuf = NULL; obuf = NULL; alloc_obuf(); TEST_ASSERT_NOT_NULL(obuf); TEST_ASSERT_NULL(ibuf); /* alloc_obuf should not allocate ibuf in this path */ } /* Test: Without C_TWOBUFS, alloc_obuf uses alloc_ibuf and sets obuf == ibuf. */ void test_alloc_obuf_without_twobufs_uses_ibuf_buffer(void) { conversions_mask = 0; /* no C_TWOBUFS */ page_size = 4096; input_blocksize = 64; /* ensure alloc_ibuf can allocate */ obuf = NULL; ibuf = NULL; alloc_obuf(); TEST_ASSERT_NOT_NULL(ibuf); TEST_ASSERT_EQUAL_PTR(ibuf, obuf); } /* Test: If obuf is already set, alloc_obuf is idempotent and returns early without changing obuf or ibuf regardless of flags. */ void test_alloc_obuf_idempotent_when_already_allocated(void) { static char dummy_out[8]; /* Pre-set obuf to a known pointer. */ obuf = dummy_out; /* Set flags such that alloc_obuf would otherwise allocate or assign. */ conversions_mask = C_TWOBUFS; output_blocksize = 256; ibuf = NULL; alloc_obuf(); TEST_ASSERT_EQUAL_PTR(dummy_out, obuf); TEST_ASSERT_NULL(ibuf); } /* Test: With C_TWOBUFS set and a preexisting ibuf, alloc_obuf must not modify ibuf and must allocate a distinct obuf. */ void test_alloc_obuf_twobufs_does_not_touch_existing_ibuf(void) { static char existing_ibuf[16]; ibuf = existing_ibuf; obuf = NULL; conversions_mask = C_TWOBUFS; output_blocksize = 128; alloc_obuf(); TEST_ASSERT_NOT_NULL(obuf); TEST_ASSERT_EQUAL_PTR(existing_ibuf, ibuf); TEST_ASSERT_NOT_EQUAL(obuf, ibuf); } /* Test: Without C_TWOBUFS and a preexisting ibuf, alloc_obuf should not allocate but simply set obuf to the existing ibuf. */ void test_alloc_obuf_non_twobufs_uses_existing_ibuf(void) { static char existing_ibuf[32]; ibuf = existing_ibuf; obuf = NULL; conversions_mask = 0; /* no C_TWOBUFS */ alloc_obuf(); TEST_ASSERT_EQUAL_PTR(existing_ibuf, ibuf); TEST_ASSERT_EQUAL_PTR(ibuf, obuf); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_alloc_obuf_twobufs_allocates_separate_buffer); RUN_TEST(test_alloc_obuf_without_twobufs_uses_ibuf_buffer); RUN_TEST(test_alloc_obuf_idempotent_when_already_allocated); RUN_TEST(test_alloc_obuf_twobufs_does_not_touch_existing_ibuf); RUN_TEST(test_alloc_obuf_non_twobufs_uses_existing_ibuf); return UNITY_END(); }