File size: 4,646 Bytes
78d2150 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
#include "../../unity/unity.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
/* The following globals and functions are defined in dd.c and are
visible here because this test file is included into the same
translation unit. We simply use them. */
extern void alloc_ibuf(void);
/* Globals from dd.c (file-scope static there, but visible here as we're
included into the same translation unit):
- static idx_t page_size;
- static idx_t input_blocksize;
- static int conversions_mask;
- static char *ibuf;
- static char *obuf;
- enum conversion flags including C_SWAB
- static char *swab_buffer(char *buf, idx_t *nread, int *saved_byte);
*/
/* Forward declarations to inform the compiler; definitions are above in dd.c */
extern char *swab_buffer(char *buf, idx_t *nread, int *saved_byte);
/* From dd.c enum */
/* We don't redeclare C_SWAB; using it directly as it's an enum constant
defined earlier in dd.c. */
static size_t get_page_size_fallback(void)
{
long ps = -1;
#ifdef _SC_PAGESIZE
ps = sysconf(_SC_PAGESIZE);
#elif defined(_SC_PAGE_SIZE)
ps = sysconf(_SC_PAGE_SIZE);
#endif
if (ps <= 0)
return 4096; /* reasonable default */
return (size_t)ps;
}
void setUp(void)
{
/* Ensure a clean slate for each test. */
if (ibuf) {
free(ibuf);
}
ibuf = NULL;
/* obuf may alias ibuf in some modes; clear to avoid dangling pointer. */
obuf = NULL;
/* Reasonable defaults for globals used by alloc_ibuf. */
page_size = (typeof(page_size))get_page_size_fallback();
input_blocksize = 64; /* small, safe size */
conversions_mask = 0; /* no special conversions by default */
}
void tearDown(void)
{
if (ibuf) {
free(ibuf);
ibuf = NULL;
}
obuf = NULL;
}
static void assert_pointer_aligned(void *p, size_t align)
{
/* Unity doesn't have direct alignment assert; use generic assert. */
TEST_ASSERT_NOT_NULL_MESSAGE(p, "Pointer is NULL; expected an allocated buffer");
TEST_ASSERT_EQUAL_UINT64_MESSAGE(0ULL, ((uintptr_t)p) % align,
"Allocated buffer is not aligned to page_size");
}
void test_alloc_ibuf_basic_allocation_and_alignment(void)
{
/* Given defaults from setUp, allocate ibuf. */
alloc_ibuf();
/* Then ibuf should be non-NULL and page aligned. */
assert_pointer_aligned(ibuf, (size_t)page_size);
/* We can touch within input_blocksize range safely. */
ibuf[0] = (char)0xAA;
ibuf[input_blocksize - 1] = (char)0x55;
TEST_ASSERT_EQUAL_HEX8((char)0xAA, ibuf[0]);
TEST_ASSERT_EQUAL_HEX8((char)0x55, ibuf[input_blocksize - 1]);
}
void test_alloc_ibuf_idempotent_no_realloc(void)
{
/* First allocation */
alloc_ibuf();
char *first = ibuf;
TEST_ASSERT_NOT_NULL(first);
/* Change globals to values that would cause a different allocation
if alloc_ibuf() didn't early return, then call again. */
input_blocksize = 128; /* different size */
conversions_mask = C_SWAB; /* request extra byte */
alloc_ibuf();
/* Expect the same pointer; function should return early if ibuf is set. */
TEST_ASSERT_EQUAL_PTR(first, ibuf);
}
void test_alloc_ibuf_with_swab_extra_byte_supports_swab_buffer(void)
{
/* Ensure conv=swab set so alloc_ibuf allocates an extra byte. */
conversions_mask = C_SWAB;
input_blocksize = 6; /* Small even size to exercise swab */
alloc_ibuf();
assert_pointer_aligned(ibuf, (size_t)page_size);
/* Fill buffer with known pattern: A B C D E F */
const char pattern[6] = { 'A', 'B', 'C', 'D', 'E', 'F' };
memcpy(ibuf, pattern, sizeof(pattern));
/* swab_buffer writes to buf[*nread] when prev_saved<0 and *nread is even,
which requires the extra byte allocated by alloc_ibuf() when C_SWAB set. */
int saved_byte = -1;
typeof(input_blocksize) nread = input_blocksize; /* 6 */
char *start = swab_buffer(ibuf, &nread, &saved_byte);
/* For even nread=6 and no previous saved byte, swab_buffer returns buf+1.
The 6 bytes starting at start should be BA DC FE. */
TEST_ASSERT_EQUAL_PTR(ibuf + 1, start);
TEST_ASSERT_EQUAL_INT64(6, nread);
TEST_ASSERT_EQUAL_INT(-1, saved_byte);
const char expected[6] = { 'B', 'A', 'D', 'C', 'F', 'E' };
TEST_ASSERT_EQUAL_MEMORY(expected, start, sizeof(expected));
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_alloc_ibuf_basic_allocation_and_alignment);
RUN_TEST(test_alloc_ibuf_idempotent_no_realloc);
RUN_TEST(test_alloc_ibuf_with_swab_extra_byte_supports_swab_buffer);
return UNITY_END();
} |