coreutils / tests /dd /tests_for_ifdatasync.c
AryaWu's picture
Upload folder using huggingface_hub
78d2150 verified
#include "../../unity/unity.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
/* The test file is included into dd.c, so we can directly access
internal static variables and the target function ifdatasync(). */
static int make_tempfile(char *tmpl, size_t tmpls)
{
/* Use a template in /tmp. */
const char *prefix = "/tmp/dd_ifdatasync_test_XXXXXX";
size_t need = strlen(prefix) + 1;
if (tmpls < need) return -1;
strcpy(tmpl, prefix);
int fd = mkstemp(tmpl);
return fd;
}
void setUp(void) {
/* Ensure process_signals() is safe to run during tests. */
/* These globals come from dd.c and are visible here due to inclusion. */
/* Avoid printing transfer stats that might use uninitialized timing. */
extern int status_level; /* from dd.c */
extern sigset_t caught_signals; /* from dd.c */
extern volatile sig_atomic_t interrupt_signal; /* from dd.c */
extern volatile sig_atomic_t info_signal_count; /* from dd.c */
extern int progress_len; /* from dd.c */
status_level = 2; /* STATUS_NOXFER */
sigemptyset(&caught_signals);
interrupt_signal = 0;
info_signal_count = 0;
progress_len = 0;
}
void tearDown(void) {
/* Nothing to clean up globally. */
}
/* Test that ifdatasync succeeds (returns 0) on a valid regular file descriptor. */
void test_ifdatasync_valid_fd_returns_zero(void)
{
char path[128];
int fd = make_tempfile(path, sizeof(path));
TEST_ASSERT_TRUE_MESSAGE(fd >= 0, "mkstemp failed to create temp file");
/* Write some data so there is something to sync. */
const char *data = "hello";
ssize_t w = write(fd, data, (size_t)5);
TEST_ASSERT_TRUE_MESSAGE(w == 5, "write to temp file failed");
/* Call the target. */
errno = 0;
int ret = ifdatasync(fd);
/* On a regular file with fdatasync available, this should succeed. */
TEST_ASSERT_EQUAL_INT_MESSAGE(0, ret, "ifdatasync failed on regular file");
/* Cleanup */
close(fd);
unlink(path);
}
/* Test that ifdatasync returns -1 and sets errno to EBADF for an invalid fd. */
void test_ifdatasync_invalid_fd_sets_errno_and_returns_minus1(void)
{
errno = 0;
int ret = ifdatasync(-1);
TEST_ASSERT_EQUAL_INT(-1, ret);
TEST_ASSERT_EQUAL_INT(EBADF, errno);
}
/* Test that ifdatasync processes pending signals by consuming an info signal. */
void test_ifdatasync_process_signals_consumes_info_signal(void)
{
/* Prepare a valid fd to ensure fdatasync itself can succeed. */
char path[128];
int fd = make_tempfile(path, sizeof(path));
TEST_ASSERT_TRUE_MESSAGE(fd >= 0, "mkstemp failed to create temp file");
const char *data = "abc";
ssize_t w = write(fd, data, (size_t)3);
TEST_ASSERT_TRUE_MESSAGE(w == 3, "write to temp file failed");
/* Set a pending info signal and ensure caught_signals is safe. */
extern volatile sig_atomic_t info_signal_count; /* from dd.c */
extern sigset_t caught_signals; /* from dd.c */
extern int status_level; /* from dd.c */
sigemptyset(&caught_signals);
status_level = 2; /* STATUS_NOXFER to avoid print_xfer_stats */
info_signal_count = 1; /* Simulate an info signal pending */
errno = 0;
int ret = ifdatasync(fd);
TEST_ASSERT_EQUAL_INT(0, ret);
TEST_ASSERT_EQUAL_INT(0, info_signal_count);
close(fd);
unlink(path);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_ifdatasync_valid_fd_returns_zero);
RUN_TEST(test_ifdatasync_invalid_fd_sets_errno_and_returns_minus1);
RUN_TEST(test_ifdatasync_process_signals_consumes_info_signal);
return UNITY_END();
}