| #include "unity/unity.h" |
| #include "zlib.h" |
|
|
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <fcntl.h> |
| #include <sys/stat.h> |
| #include <errno.h> |
|
|
| |
| static const char *kSampleText = "Hello world! This is a test of gzrewind."; |
| static const size_t kSampleLen = 44; |
|
|
| |
| void setUp(void) { |
| |
| } |
| void tearDown(void) { |
| |
| } |
|
|
| |
| static void make_temp_path(char *buf, size_t buflen) { |
| |
| |
| snprintf(buf, buflen, "/tmp/test_gzrewind_%ld_XXXXXX", (long)getpid()); |
| } |
|
|
| static void create_gz_file(const char *path, const char *data, size_t len) { |
| gzFile gz = gzopen(path, "wb"); |
| TEST_ASSERT_NOT_NULL(gz); |
| int wrote = gzwrite(gz, data, (unsigned)len); |
| TEST_ASSERT_EQUAL_INT((int)len, wrote); |
| int rc = gzclose(gz); |
| TEST_ASSERT_EQUAL_INT(0, rc); |
| } |
|
|
| static void read_exact(gzFile gz, void *buf, size_t len) { |
| unsigned char *p = (unsigned char *)buf; |
| size_t total = 0; |
| while (total < len) { |
| int n = gzread(gz, p + total, (unsigned)(len - total)); |
| TEST_ASSERT_TRUE_MESSAGE(n >= 0, "gzread returned error"); |
| if (n == 0) break; |
| total += (size_t)n; |
| } |
| TEST_ASSERT_EQUAL_UINT64(len, total); |
| } |
|
|
| |
|
|
| void test_gzrewind_null(void) { |
| TEST_ASSERT_EQUAL_INT(-1, gzrewind(NULL)); |
| } |
|
|
| void test_gzrewind_write_mode_returns_error(void) { |
| char tmpl[256]; |
| make_temp_path(tmpl, sizeof(tmpl)); |
| int fd = mkstemp(tmpl); |
| TEST_ASSERT_TRUE_MESSAGE(fd != -1, "mkstemp failed"); |
| close(fd); |
|
|
| gzFile gz = gzopen(tmpl, "wb"); |
| TEST_ASSERT_NOT_NULL(gz); |
|
|
| |
| int rc = gzrewind(gz); |
| TEST_ASSERT_EQUAL_INT(-1, rc); |
|
|
| |
| gzclose(gz); |
| unlink(tmpl); |
| } |
|
|
| void test_gzrewind_seekable_basic_reset(void) { |
| char tmpl[256]; |
| make_temp_path(tmpl, sizeof(tmpl)); |
| int fd = mkstemp(tmpl); |
| TEST_ASSERT_TRUE_MESSAGE(fd != -1, "mkstemp failed"); |
| close(fd); |
|
|
| create_gz_file(tmpl, kSampleText, strlen(kSampleText)); |
|
|
| gzFile gz = gzopen(tmpl, "rb"); |
| TEST_ASSERT_NOT_NULL(gz); |
|
|
| |
| char first[6] = {0}; |
| int n = gzread(gz, first, 5); |
| TEST_ASSERT_EQUAL_INT(5, n); |
| TEST_ASSERT_EQUAL_STRING_LEN("Hello", first, 5); |
|
|
| |
| z_off_t pos = gztell(gz); |
| TEST_ASSERT_EQUAL_INT(5, (int)pos); |
|
|
| |
| int rc = gzrewind(gz); |
| TEST_ASSERT_EQUAL_INT(0, rc); |
|
|
| |
| pos = gztell(gz); |
| TEST_ASSERT_EQUAL_INT(0, (int)pos); |
|
|
| |
| memset(first, 0, sizeof(first)); |
| n = gzread(gz, first, 5); |
| TEST_ASSERT_EQUAL_INT(5, n); |
| TEST_ASSERT_EQUAL_STRING_LEN("Hello", first, 5); |
|
|
| gzclose(gz); |
| unlink(tmpl); |
| } |
|
|
| void test_gzrewind_clears_eof_and_restarts(void) { |
| char tmpl[256]; |
| make_temp_path(tmpl, sizeof(tmpl)); |
| int fd = mkstemp(tmpl); |
| TEST_ASSERT_TRUE_MESSAGE(fd != -1, "mkstemp failed"); |
| close(fd); |
|
|
| const char *data = kSampleText; |
| const size_t len = strlen(kSampleText); |
| create_gz_file(tmpl, data, len); |
|
|
| gzFile gz = gzopen(tmpl, "rb"); |
| TEST_ASSERT_NOT_NULL(gz); |
|
|
| |
| char *buf = (char *)malloc(len); |
| TEST_ASSERT_NOT_NULL(buf); |
| read_exact(gz, buf, len); |
|
|
| |
| int eof = gzeof(gz); |
| TEST_ASSERT_TRUE(eof != 0); |
|
|
| |
| int rc = gzrewind(gz); |
| TEST_ASSERT_EQUAL_INT(0, rc); |
|
|
| eof = gzeof(gz); |
| TEST_ASSERT_EQUAL_INT(0, eof); |
|
|
| |
| memset(buf, 0, len); |
| read_exact(gz, buf, len); |
| TEST_ASSERT_EQUAL_INT(0, memcmp(buf, data, len)); |
|
|
| free(buf); |
| gzclose(gz); |
| unlink(tmpl); |
| } |
|
|
| void test_gzrewind_nonseekable_fd_returns_error(void) { |
| int fds[2]; |
| int prc = pipe(fds); |
| TEST_ASSERT_EQUAL_INT(0, prc); |
|
|
| int rfd = fds[0]; |
| int wfd = fds[1]; |
|
|
| |
| gzFile gz = gzdopen(rfd, "rb"); |
| TEST_ASSERT_NOT_NULL(gz); |
|
|
| |
| int rc = gzrewind(gz); |
| TEST_ASSERT_EQUAL_INT(-1, rc); |
|
|
| |
| gzclose(gz); |
| close(wfd); |
| } |
|
|
| void test_gzrewind_multiple_calls_idempotent(void) { |
| char tmpl[256]; |
| make_temp_path(tmpl, sizeof(tmpl)); |
| int fd = mkstemp(tmpl); |
| TEST_ASSERT_TRUE_MESSAGE(fd != -1, "mkstemp failed"); |
| close(fd); |
|
|
| create_gz_file(tmpl, kSampleText, strlen(kSampleText)); |
|
|
| gzFile gz = gzopen(tmpl, "rb"); |
| TEST_ASSERT_NOT_NULL(gz); |
|
|
| |
| TEST_ASSERT_EQUAL_INT(0, gzrewind(gz)); |
|
|
| |
| char buf[6] = {0}; |
| int n = gzread(gz, buf, 5); |
| TEST_ASSERT_EQUAL_INT(5, n); |
| TEST_ASSERT_EQUAL_STRING_LEN("Hello", buf, 5); |
|
|
| TEST_ASSERT_EQUAL_INT(0, gzrewind(gz)); |
| TEST_ASSERT_EQUAL_INT(0, gzrewind(gz)); |
|
|
| |
| memset(buf, 0, sizeof(buf)); |
| n = gzread(gz, buf, 5); |
| TEST_ASSERT_EQUAL_INT(5, n); |
| TEST_ASSERT_EQUAL_STRING_LEN("Hello", buf, 5); |
|
|
| gzclose(gz); |
| unlink(tmpl); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_gzrewind_null); |
| RUN_TEST(test_gzrewind_write_mode_returns_error); |
| RUN_TEST(test_gzrewind_seekable_basic_reset); |
| RUN_TEST(test_gzrewind_clears_eof_and_restarts); |
| RUN_TEST(test_gzrewind_nonseekable_fd_returns_error); |
| RUN_TEST(test_gzrewind_multiple_calls_idempotent); |
| return UNITY_END(); |
| } |