coreutils / tests /cksum /tests_for_cksum_slice8.c
AryaWu's picture
Upload folder using huggingface_hub
78d2150 verified
#include "../../unity/unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>
/* Unity fixture hooks */
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
/* Forward declarations of functions under test (already visible since
this test is included into the same translation unit):
static bool cksum_slice8 (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out);
int crc_sum_stream (FILE *stream, void *resstream, uintmax_t *length);
*/
/* Helper: write data to a new temporary file, rewind, and return the stream.
Caller must fclose(fp). Returns NULL on failure. */
static FILE* make_tmp_stream_with_data(const unsigned char *data, size_t size) {
FILE *fp = tmpfile();
if (!fp)
return NULL;
if (size > 0) {
if (fwrite(data, 1, size, fp) != size) {
fclose(fp);
return NULL;
}
}
fflush(fp);
rewind(fp);
return fp;
}
/* Helper: finalize POSIX cksum CRC from cksum_slice8 outputs.
This mirrors the finalization in crc_sum_stream:
for (; len; len >>= 8)
crc = (crc << 8) ^ crctab[0][((crc >> 24) ^ len) & 0xFF];
crc = ~crc & 0xFFFFFFFF;
crctab is declared by the program headers included earlier in this TU. */
static uint32_t finalize_posix_crc(uint_fast32_t crc, uintmax_t len) {
for (; len; len >>= 8) {
crc = (crc << 8) ^ crctab[0][((crc >> 24) ^ len) & 0xFF];
}
crc = ~crc & 0xFFFFFFFFu;
return (uint32_t)crc;
}
/* Helper: run cksum_slice8 and crc_sum_stream on identical data
and compare finalized CRCs and lengths. */
static void check_cksum_slice8_matches_crc_sum_stream(const unsigned char *data, size_t size) {
/* Prepare two identical streams */
FILE *fp1 = make_tmp_stream_with_data(data, size);
FILE *fp2 = make_tmp_stream_with_data(data, size);
TEST_ASSERT_NOT_NULL_MESSAGE(fp1, "tmpfile creation failed for fp1");
TEST_ASSERT_NOT_NULL_MESSAGE(fp2, "tmpfile creation failed for fp2");
uint_fast32_t crc_mid = 0;
uintmax_t len_mid = 0;
bool ok = cksum_slice8(fp1, &crc_mid, &len_mid);
TEST_ASSERT_TRUE_MESSAGE(ok, "cksum_slice8 returned false unexpectedly");
TEST_ASSERT_EQUAL_UINT64((uint64_t)size, (uint64_t)len_mid);
uint32_t crc_final_from_mid = finalize_posix_crc(crc_mid, len_mid);
uint32_t crc_final_stream = 0;
uintmax_t len_stream = 0;
int rc = crc_sum_stream(fp2, &crc_final_stream, &len_stream);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, rc, "crc_sum_stream failed");
TEST_ASSERT_EQUAL_UINT64((uint64_t)size, (uint64_t)len_stream);
TEST_ASSERT_EQUAL_UINT32(crc_final_stream, crc_final_from_mid);
fclose(fp1);
fclose(fp2);
}
/* Tests */
static void test_cksum_slice8_null_params(void) {
uint_fast32_t crc;
uintmax_t length;
/* NULL file pointer */
TEST_ASSERT_FALSE(cksum_slice8(NULL, &crc, &length));
/* Valid stream but NULL crc_out */
FILE *fp = make_tmp_stream_with_data(NULL, 0);
TEST_ASSERT_NOT_NULL(fp);
TEST_ASSERT_FALSE(cksum_slice8(fp, NULL, &length));
rewind(fp);
/* Valid stream but NULL length_out */
TEST_ASSERT_FALSE(cksum_slice8(fp, &crc, NULL));
fclose(fp);
}
static void test_cksum_slice8_empty_stream(void) {
FILE *fp1 = make_tmp_stream_with_data(NULL, 0);
FILE *fp2 = make_tmp_stream_with_data(NULL, 0);
TEST_ASSERT_NOT_NULL(fp1);
TEST_ASSERT_NOT_NULL(fp2);
uint_fast32_t crc_mid = 0;
uintmax_t len_mid = 0;
bool ok = cksum_slice8(fp1, &crc_mid, &len_mid);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT64(0, (uint64_t)len_mid);
TEST_ASSERT_EQUAL_UINT32(0u, (uint32_t)crc_mid);
uint32_t crc_final_from_mid = finalize_posix_crc(crc_mid, len_mid);
uint32_t crc_final_stream = 0;
uintmax_t len_stream = 0;
int rc = crc_sum_stream(fp2, &crc_final_stream, &len_stream);
TEST_ASSERT_EQUAL_INT(0, rc);
TEST_ASSERT_EQUAL_UINT64(0, (uint64_t)len_stream);
TEST_ASSERT_EQUAL_UINT32(crc_final_stream, crc_final_from_mid);
fclose(fp1);
fclose(fp2);
}
static void test_cksum_slice8_single_byte(void) {
const unsigned char data[1] = { 'A' };
check_cksum_slice8_matches_crc_sum_stream(data, sizeof(data));
}
static void test_cksum_slice8_various_small_inputs(void) {
const unsigned char s1[] = "abc";
check_cksum_slice8_matches_crc_sum_stream(s1, strlen((const char*)s1));
const unsigned char s2[] = "abcdefg"; /* 7 bytes */
check_cksum_slice8_matches_crc_sum_stream(s2, strlen((const char*)s2));
const unsigned char s3[] = "abcdefgh"; /* 8 bytes exact */
check_cksum_slice8_matches_crc_sum_stream(s3, strlen((const char*)s3));
const unsigned char s4[] = "abcdefghi"; /* 9 bytes */
check_cksum_slice8_matches_crc_sum_stream(s4, strlen((const char*)s4));
/* Binary data with zeros and 0xFF */
unsigned char s5[16];
for (size_t i = 0; i < sizeof(s5); i++)
s5[i] = (i % 2) ? 0x00 : 0xFF;
check_cksum_slice8_matches_crc_sum_stream(s5, sizeof(s5));
}
static void test_cksum_slice8_large_buffer_spanning_chunks(void) {
/* Use size > BUFLEN to ensure multiple fread loops and both aligned and remainder processing */
const size_t big_size = (size_t)BUFLEN * 3 + 123;
unsigned char *buf = (unsigned char *)malloc(big_size);
TEST_ASSERT_NOT_NULL(buf);
for (size_t i = 0; i < big_size; i++) {
buf[i] = (unsigned char)(i & 0xFFu);
}
check_cksum_slice8_matches_crc_sum_stream(buf, big_size);
free(buf);
}
/* Unity main */
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_cksum_slice8_null_params);
RUN_TEST(test_cksum_slice8_empty_stream);
RUN_TEST(test_cksum_slice8_single_byte);
RUN_TEST(test_cksum_slice8_various_small_inputs);
RUN_TEST(test_cksum_slice8_large_buffer_spanning_chunks);
return UNITY_END();
}