diff options
Diffstat (limited to 'src/test/test_util.c')
-rw-r--r-- | src/test/test_util.c | 127 |
1 files changed, 108 insertions, 19 deletions
diff --git a/src/test/test_util.c b/src/test/test_util.c index 09a27b7024..6f95c7bfc9 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -87,6 +87,20 @@ test_util_read_file_eof_tiny_limit(void *arg) } static void +test_util_read_file_eof_one_loop_a(void *arg) +{ + (void)arg; + test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023); +} + +static void +test_util_read_file_eof_one_loop_b(void *arg) +{ + (void)arg; + test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024); +} + +static void test_util_read_file_eof_two_loops(void *arg) { (void)arg; @@ -98,6 +112,14 @@ test_util_read_file_eof_two_loops(void *arg) } static void +test_util_read_file_eof_two_loops_b(void *arg) +{ + (void)arg; + + test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048); +} + +static void test_util_read_file_eof_zero_bytes(void *arg) { (void)arg; @@ -1383,12 +1405,6 @@ test_util_threads(void) tv.tv_sec=0; tv.tv_usec=100*1000; #endif -#ifndef TOR_IS_MULTITHREADED - /* Skip this test if we aren't threading. We should be threading most - * everywhere by now. */ - if (1) - return; -#endif thread_test_mutex_ = tor_mutex_new(); thread_test_start1_ = tor_mutex_new(); thread_test_start2_ = tor_mutex_new(); @@ -1493,7 +1509,7 @@ test_util_gzip(void) /* Check whether we can uncompress concatenated, compressed strings. */ tor_free(buf3); - buf2 = tor_realloc(buf2, len1*2); + buf2 = tor_reallocarray(buf2, len1, 2); memcpy(buf2+len1, buf2, len1); test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2, ZLIB_METHOD, 1, LOG_INFO)); @@ -2532,6 +2548,54 @@ test_util_parent_dir(void *ptr) tor_free(cp); } +static void +test_util_ftruncate(void *ptr) +{ + char *buf = NULL; + const char *fname; + int fd = -1; + const char *message = "Hello world"; + const char *message2 = "Hola mundo"; + struct stat st; + + (void) ptr; + + fname = get_fname("ftruncate"); + + fd = tor_open_cloexec(fname, O_WRONLY|O_CREAT, 0600); + tt_int_op(fd, >=, 0); + + /* Make the file be there. */ + tt_int_op(strlen(message), ==, write_all(fd, message, strlen(message), 0)); + tt_int_op((int)tor_fd_getpos(fd), ==, strlen(message)); + tt_int_op(0, ==, fstat(fd, &st)); + tt_int_op((int)st.st_size, ==, strlen(message)); + + /* Truncate and see if it got truncated */ + tt_int_op(0, ==, tor_ftruncate(fd)); + tt_int_op((int)tor_fd_getpos(fd), ==, 0); + tt_int_op(0, ==, fstat(fd, &st)); + tt_int_op((int)st.st_size, ==, 0); + + /* Replace, and see if it got replaced */ + tt_int_op(strlen(message2), ==, + write_all(fd, message2, strlen(message2), 0)); + tt_int_op((int)tor_fd_getpos(fd), ==, strlen(message2)); + tt_int_op(0, ==, fstat(fd, &st)); + tt_int_op((int)st.st_size, ==, strlen(message2)); + + close(fd); + fd = -1; + + buf = read_file_to_str(fname, 0, NULL); + tt_str_op(message2, ==, buf); + + done: + if (fd >= 0) + close(fd); + tor_free(buf); +} + #ifdef _WIN32 static void test_util_load_win_lib(void *ptr) @@ -2617,8 +2681,9 @@ test_util_exit_status(void *ptr) #endif #ifndef _WIN32 -/** Check that fgets waits until a full line, and not return a partial line, on - * a EAGAIN with a non-blocking pipe */ +/* Check that fgets with a non-blocking pipe returns partial lines and sets + * EAGAIN, returns full lines and sets no error, and returns NULL on EOF and + * sets no error */ static void test_util_fgets_eagain(void *ptr) { @@ -2627,17 +2692,19 @@ test_util_fgets_eagain(void *ptr) ssize_t retlen; char *retptr; FILE *test_stream = NULL; - char buf[10]; + char buf[4] = { 0 }; (void)ptr; + errno = 0; + /* Set up a pipe to test on */ retval = pipe(test_pipe); - tt_int_op(retval, >=, 0); + tt_int_op(retval, ==, 0); /* Set up the read-end to be non-blocking */ retval = fcntl(test_pipe[0], F_SETFL, O_NONBLOCK); - tt_int_op(retval, >=, 0); + tt_int_op(retval, ==, 0); /* Open it as a stdio stream */ test_stream = fdopen(test_pipe[0], "r"); @@ -2647,51 +2714,69 @@ test_util_fgets_eagain(void *ptr) retlen = write(test_pipe[1], "A", 1); tt_int_op(retlen, ==, 1); retptr = fgets(buf, sizeof(buf), test_stream); - tt_want(retptr == NULL); tt_int_op(errno, ==, EAGAIN); + tt_ptr_op(retptr, ==, buf); + tt_str_op(buf, ==, "A"); + errno = 0; /* Send in the rest */ retlen = write(test_pipe[1], "B\n", 2); tt_int_op(retlen, ==, 2); retptr = fgets(buf, sizeof(buf), test_stream); + tt_int_op(errno, ==, 0); tt_ptr_op(retptr, ==, buf); - tt_str_op(buf, ==, "AB\n"); + tt_str_op(buf, ==, "B\n"); + errno = 0; /* Send in a full line */ retlen = write(test_pipe[1], "CD\n", 3); tt_int_op(retlen, ==, 3); retptr = fgets(buf, sizeof(buf), test_stream); + tt_int_op(errno, ==, 0); tt_ptr_op(retptr, ==, buf); tt_str_op(buf, ==, "CD\n"); + errno = 0; /* Send in a partial line */ retlen = write(test_pipe[1], "E", 1); tt_int_op(retlen, ==, 1); retptr = fgets(buf, sizeof(buf), test_stream); - tt_ptr_op(retptr, ==, NULL); tt_int_op(errno, ==, EAGAIN); + tt_ptr_op(retptr, ==, buf); + tt_str_op(buf, ==, "E"); + errno = 0; /* Send in the rest */ retlen = write(test_pipe[1], "F\n", 2); tt_int_op(retlen, ==, 2); retptr = fgets(buf, sizeof(buf), test_stream); + tt_int_op(errno, ==, 0); tt_ptr_op(retptr, ==, buf); - tt_str_op(buf, ==, "EF\n"); + tt_str_op(buf, ==, "F\n"); + errno = 0; /* Send in a full line and close */ retlen = write(test_pipe[1], "GH", 2); tt_int_op(retlen, ==, 2); retval = close(test_pipe[1]); - test_pipe[1] = -1; tt_int_op(retval, ==, 0); + test_pipe[1] = -1; retptr = fgets(buf, sizeof(buf), test_stream); + tt_int_op(errno, ==, 0); tt_ptr_op(retptr, ==, buf); tt_str_op(buf, ==, "GH"); + errno = 0; /* Check for EOF */ retptr = fgets(buf, sizeof(buf), test_stream); + tt_int_op(errno, ==, 0); tt_ptr_op(retptr, ==, NULL); - tt_int_op(feof(test_stream), >, 0); + retval = feof(test_stream); + tt_int_op(retval, !=, 0); + errno = 0; + + /* Check that buf is unchanged according to C99 and C11 */ + tt_str_op(buf, ==, "GH"); done: if (test_stream != NULL) @@ -3972,12 +4057,13 @@ struct testcase_t util_tests[] = { UTIL_TEST(asprintf, 0), UTIL_TEST(listdir, 0), UTIL_TEST(parent_dir, 0), + UTIL_TEST(ftruncate, 0), #ifdef _WIN32 UTIL_TEST(load_win_lib, 0), #endif #ifndef _WIN32 UTIL_TEST(exit_status, 0), - UTIL_TEST(fgets_eagain, TT_SKIP), + UTIL_TEST(fgets_eagain, 0), #endif UTIL_TEST(spawn_background_ok, 0), UTIL_TEST(spawn_background_fail, 0), @@ -3995,7 +4081,10 @@ struct testcase_t util_tests[] = { UTIL_TEST(make_environment, 0), UTIL_TEST(set_env_var_in_sl, 0), UTIL_TEST(read_file_eof_tiny_limit, 0), + UTIL_TEST(read_file_eof_one_loop_a, 0), + UTIL_TEST(read_file_eof_one_loop_b, 0), UTIL_TEST(read_file_eof_two_loops, 0), + UTIL_TEST(read_file_eof_two_loops_b, 0), UTIL_TEST(read_file_eof_zero_bytes, 0), UTIL_TEST(write_chunks_to_file, 0), UTIL_TEST(mathlog, 0), |