coreutils / tests /dd /tests_for_iread_fullblock.c
AryaWu's picture
Upload folder using huggingface_hub
78d2150 verified
#include "../../unity/unity.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>
/* The function under test is: static ssize_t iread_fullblock (int fd, char *buf, idx_t size) */
static void fill_pattern(char *buf, size_t len, size_t start_index)
{
for (size_t i = 0; i < len; i++)
buf[i] = (char)('A' + ((start_index + i) % 26));
}
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
static int mk_tempfile(char *template_buf, size_t template_buf_sz)
{
/* Create a writable temporary file; caller should unlink if desired */
const char *tmpl = "/tmp/dd_iread_fullblock_testXXXXXX";
if (strlen(tmpl) + 1 > template_buf_sz) return -1;
strcpy(template_buf, tmpl);
int fd = mkstemp(template_buf);
return fd;
}
void test_iread_fullblock_full_read_from_file(void)
{
char path[128];
int fd = mk_tempfile(path, sizeof(path));
TEST_ASSERT_MESSAGE(fd >= 0, "mkstemp failed");
/* Prepare data */
const size_t total = 4096;
char *src = (char*)malloc(total);
TEST_ASSERT_NOT_NULL(src);
fill_pattern(src, total, 0);
ssize_t wr = write(fd, src, total);
TEST_ASSERT_EQUAL_INT64(total, wr);
/* Rewind and read */
lseek(fd, 0, SEEK_SET);
char *dst = (char*)malloc(total);
TEST_ASSERT_NOT_NULL(dst);
ssize_t rr = iread_fullblock(fd, dst, (idx_t)total);
TEST_ASSERT_EQUAL_INT64((ssize_t)total, rr);
TEST_ASSERT_EQUAL_UINT8_ARRAY(src, dst, total);
free(src);
free(dst);
close(fd);
unlink(path);
}
void test_iread_fullblock_aggregates_from_pipe(void)
{
int pipefd[2];
TEST_ASSERT_EQUAL_INT(0, pipe(pipefd));
const size_t total = 3000;
const size_t chunk1 = 700; /* ensure a partial first read */
const size_t chunk2 = total - chunk1;
fflush(stdout);
fflush(stderr);
pid_t pid = fork();
TEST_ASSERT_MESSAGE(pid >= 0, "fork failed");
if (pid == 0) {
/* Child: writer */
close(pipefd[0]);
char *buf1 = (char*)malloc(chunk1);
char *buf2 = (char*)malloc(chunk2);
if (!buf1 || !buf2) _exit(1);
fill_pattern(buf1, chunk1, 0);
fill_pattern(buf2, chunk2, chunk1);
/* Write first chunk, then delay, then second chunk */
ssize_t w1 = write(pipefd[1], buf1, chunk1);
(void)w1;
struct timespec ts = {0, 150 * 1000 * 1000}; /* 150ms */
nanosleep(&ts, NULL);
ssize_t w2 = write(pipefd[1], buf2, chunk2);
(void)w2;
free(buf1);
free(buf2);
close(pipefd[1]);
_exit(0);
}
/* Parent: reader */
close(pipefd[1]);
char *dst = (char*)malloc(total);
TEST_ASSERT_NOT_NULL(dst);
ssize_t rr = iread_fullblock(pipefd[0], dst, (idx_t)total);
TEST_ASSERT_EQUAL_INT64((ssize_t)total, rr);
/* Verify content */
char *expect = (char*)malloc(total);
TEST_ASSERT_NOT_NULL(expect);
fill_pattern(expect, total, 0);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expect, dst, total);
free(expect);
free(dst);
close(pipefd[0]);
int status = 0;
waitpid(pid, &status, 0);
TEST_ASSERT_TRUE(WIFEXITED(status));
TEST_ASSERT_EQUAL_INT(0, WEXITSTATUS(status));
}
void test_iread_fullblock_eof_before_full(void)
{
char path[128];
int fd = mk_tempfile(path, sizeof(path));
TEST_ASSERT_MESSAGE(fd >= 0, "mkstemp failed");
const size_t have = 100;
const size_t want = 200;
char *src = (char*)malloc(have);
TEST_ASSERT_NOT_NULL(src);
fill_pattern(src, have, 0);
TEST_ASSERT_EQUAL_INT64((ssize_t)have, write(fd, src, have));
lseek(fd, 0, SEEK_SET);
char *dst = (char*)malloc(want);
TEST_ASSERT_NOT_NULL(dst);
memset(dst, 0xCD, want);
ssize_t rr = iread_fullblock(fd, dst, (idx_t)want);
TEST_ASSERT_EQUAL_INT64((ssize_t)have, rr);
TEST_ASSERT_EQUAL_UINT8_ARRAY(src, dst, have);
free(src);
free(dst);
close(fd);
unlink(path);
}
void test_iread_fullblock_zero_size(void)
{
/* Any fd; use /dev/null */
int fd = open("/dev/null", O_RDONLY);
TEST_ASSERT_MESSAGE(fd >= 0, "open /dev/null failed");
char dummy;
ssize_t rr = iread_fullblock(fd, &dummy, (idx_t)0);
TEST_ASSERT_EQUAL_INT64(0, rr);
close(fd);
}
void test_iread_fullblock_error_bad_fd(void)
{
char buf[16];
errno = 0;
ssize_t rr = iread_fullblock(-1, buf, (idx_t)sizeof(buf));
TEST_ASSERT_EQUAL_INT64(-1, rr);
TEST_ASSERT_EQUAL_INT(EBADF, errno);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_iread_fullblock_full_read_from_file);
RUN_TEST(test_iread_fullblock_aggregates_from_pipe);
RUN_TEST(test_iread_fullblock_eof_before_full);
RUN_TEST(test_iread_fullblock_zero_size);
RUN_TEST(test_iread_fullblock_error_bad_fd);
return UNITY_END();
}