zlib / tests /tests_gzlib_if.c
AryaWu's picture
Upload folder using huggingface_hub
e996a55 verified
#include "unity/unity.h"
#include "zlib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
/* Unity fixtures */
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
/* Helpers */
static int make_temp_file(char *out_path, size_t out_size) {
if (out_size < 32) {
return -1;
}
/* Create a template for mkstemp */
snprintf(out_path, out_size, "/tmp/zlib_gzdopen_ut_%ld_XXXXXX", (long)getpid());
int fd = mkstemp(out_path);
return fd;
}
static int write_string_gz(const char *path, const char *s) {
gzFile g = gzopen(path, "wb");
if (g == NULL) return -1;
int w = gzwrite(g, s, (unsigned)strlen(s));
int zc = gzclose(g);
if (w <= 0 || zc != Z_OK) return -1;
return 0;
}
static int read_all_gz(const char *path, char *buf, size_t buf_size, int *out_len) {
*out_len = 0;
gzFile g = gzopen(path, "rb");
if (g == NULL) return -1;
int total = 0;
for (;;) {
int n = gzread(g, buf + total, (unsigned)(buf_size - (size_t)total));
if (n < 0) {
gzclose(g);
return -1;
}
if (n == 0) break;
total += n;
if ((size_t)total >= buf_size) break;
}
int zc = gzclose(g);
if (zc != Z_OK) return -1;
*out_len = total;
return 0;
}
/* Tests */
void test_gzdopen_invalid_fd_returns_null(void) {
gzFile g = gzdopen(-1, "rb");
TEST_ASSERT_NULL(g);
}
void test_gzdopen_write_and_close_closes_fd(void) {
char path[128];
int fd = make_temp_file(path, sizeof(path));
TEST_ASSERT_NOT_EQUAL(-1, fd);
/* Open gzip on provided fd and write some data */
gzFile g = gzdopen(fd, "wb");
TEST_ASSERT_NOT_NULL(g);
const char *msg = "hello world";
int w = gzwrite(g, msg, (unsigned)strlen(msg));
TEST_ASSERT_TRUE(w > 0);
int zc = gzclose(g);
TEST_ASSERT_EQUAL_INT(Z_OK, zc);
/* After gzclose, the provided fd should be closed by zlib */
errno = 0;
ssize_t wr = write(fd, "X", 1);
TEST_ASSERT_EQUAL_INT(-1, (int)wr);
/* Cleanup */
unlink(path);
}
void test_gzdopen_read_existing_gz_file(void) {
char path[128];
int fd_tmp = make_temp_file(path, sizeof(path));
TEST_ASSERT_NOT_EQUAL(-1, fd_tmp);
close(fd_tmp);
const char *payload = "abcdef";
TEST_ASSERT_EQUAL_INT(0, write_string_gz(path, payload));
int fd = open(path, O_RDONLY);
TEST_ASSERT_NOT_EQUAL(-1, fd);
gzFile g = gzdopen(fd, "rb");
TEST_ASSERT_NOT_NULL(g);
char buf[64];
int total = 0;
for (;;) {
int n = gzread(g, buf + total, (unsigned)(sizeof(buf) - (size_t)total));
TEST_ASSERT_TRUE(n >= 0);
if (n == 0) break;
total += n;
if ((size_t)total >= sizeof(buf)) break;
}
TEST_ASSERT_EQUAL_INT((int)strlen(payload), total);
TEST_ASSERT_EQUAL_INT(0, memcmp(buf, payload, (size_t)total));
int zc = gzclose(g);
TEST_ASSERT_EQUAL_INT(Z_OK, zc);
unlink(path);
}
void test_gzdopen_plus_mode_rejected_fd_not_closed(void) {
char path[128];
int fd = make_temp_file(path, sizeof(path));
TEST_ASSERT_NOT_EQUAL(-1, fd);
gzFile g = gzdopen(fd, "wb+"); /* '+' is not allowed */
TEST_ASSERT_NULL(g);
/* Ensure fd remains open (write should succeed) */
errno = 0;
const char c = 'Z';
ssize_t wr = write(fd, &c, 1);
TEST_ASSERT_EQUAL_INT(1, (int)wr);
close(fd);
unlink(path);
}
void test_gzdopen_append_mode_appends_and_can_be_read_as_concatenated_streams(void) {
char path[128];
int fd_tmp = make_temp_file(path, sizeof(path));
TEST_ASSERT_NOT_EQUAL(-1, fd_tmp);
close(fd_tmp);
const char *first = "first";
const char *second = "second";
TEST_ASSERT_EQUAL_INT(0, write_string_gz(path, first));
int fd = open(path, O_WRONLY);
TEST_ASSERT_NOT_EQUAL(-1, fd);
gzFile g = gzdopen(fd, "ab");
TEST_ASSERT_NOT_NULL(g);
int w = gzwrite(g, second, (unsigned)strlen(second));
TEST_ASSERT_TRUE(w > 0);
int zc = gzclose(g);
TEST_ASSERT_EQUAL_INT(Z_OK, zc);
char buf[128];
int len = 0;
TEST_ASSERT_EQUAL_INT(0, read_all_gz(path, buf, sizeof(buf), &len));
TEST_ASSERT_EQUAL_INT((int)(strlen(first) + strlen(second)), len);
TEST_ASSERT_EQUAL_INT(0, memcmp(buf, "firstsecond", (size_t)len));
unlink(path);
}
void test_gzdopen_invalid_mode_without_r_w_a_returns_null_and_fd_open(void) {
char path[128];
int fd = make_temp_file(path, sizeof(path));
TEST_ASSERT_NOT_EQUAL(-1, fd);
gzFile g = gzdopen(fd, "q"); /* no r/w/a, should be rejected */
TEST_ASSERT_NULL(g);
/* Ensure fd remains open */
const char c = 'Y';
ssize_t wr = write(fd, &c, 1);
TEST_ASSERT_EQUAL_INT(1, (int)wr);
close(fd);
unlink(path);
}
/* Test runner */
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_gzdopen_invalid_fd_returns_null);
RUN_TEST(test_gzdopen_write_and_close_closes_fd);
RUN_TEST(test_gzdopen_read_existing_gz_file);
RUN_TEST(test_gzdopen_plus_mode_rejected_fd_not_closed);
RUN_TEST(test_gzdopen_append_mode_appends_and_can_be_read_as_concatenated_streams);
RUN_TEST(test_gzdopen_invalid_mode_without_r_w_a_returns_null_and_fd_open);
return UNITY_END();
}