mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
Test case for reading the partial output of a background process
This commit is contained in:
parent
99baa7e45c
commit
5bf9890b3b
@ -3292,8 +3292,8 @@ tor_get_exit_code(const process_handle_t process_handle)
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* Windows equivalent of read_all */
|
||||
static ssize_t
|
||||
read_all_handle(HANDLE h, char *buf, size_t count, HANDLE hProcess)
|
||||
ssize_t
|
||||
tor_read_all_handle(HANDLE h, char *buf, size_t count, HANDLE hProcess)
|
||||
{
|
||||
size_t numread = 0;
|
||||
BOOL retval;
|
||||
@ -3310,7 +3310,7 @@ read_all_handle(HANDLE h, char *buf, size_t count, HANDLE hProcess)
|
||||
"Failed to peek from handle: %s",
|
||||
format_win32_error(GetLastError()));
|
||||
return -1;
|
||||
} else if (0 == byte_count)
|
||||
} else if (0 == byte_count) {
|
||||
/* Nothing available: process exited or it is busy */
|
||||
|
||||
/* Exit if we don't know whether the process is running */
|
||||
@ -3352,7 +3352,7 @@ tor_read_all_from_process_stdout(const process_handle_t process_handle,
|
||||
char *buf, size_t count)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
return read_all_handle(process_handle.stdout_pipe, buf, count,
|
||||
return tor_read_all_handle(process_handle.stdout_pipe, buf, count,
|
||||
process_handle.pid.hProcess);
|
||||
#else
|
||||
return read_all(process_handle.stdout_pipe, buf, count, 0);
|
||||
@ -3364,7 +3364,7 @@ tor_read_all_from_process_stderr(const process_handle_t process_handle,
|
||||
char *buf, size_t count)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
return read_all_handle(process_handle.stderr_pipe, buf, count,
|
||||
return tor_read_all_handle(process_handle.stderr_pipe, buf, count,
|
||||
process_handle.pid.hProcess);
|
||||
#else
|
||||
return read_all(process_handle.stderr_pipe, buf, count, 0);
|
||||
|
@ -364,6 +364,7 @@ typedef struct process_handle_s {
|
||||
process_handle_t tor_spawn_background(const char *const filename,
|
||||
const char **argv);
|
||||
int tor_get_exit_code(const process_handle_t pid);
|
||||
ssize_t tor_read_all_handle(HANDLE h, char *buf, size_t count, HANDLE hProcess);
|
||||
ssize_t tor_read_all_from_process_stdout(const process_handle_t process_handle,
|
||||
char *buf, size_t count);
|
||||
ssize_t tor_read_all_from_process_stderr(const process_handle_t process_handle,
|
||||
|
@ -19,6 +19,10 @@ main(int argc, char **argv)
|
||||
for (i = 1; i < argc; i++)
|
||||
fprintf(stdout, "%s\n", argv[i]);
|
||||
fprintf(stdout, "SLEEPING\n");
|
||||
/* We need to flush stdout so that test_util_spawn_background_partial_read()
|
||||
succeed. Otherwise ReadFile() will get the entire output in one */
|
||||
// XXX: Can we make stdio flush on newline?
|
||||
fflush(stdout);
|
||||
#ifdef MS_WINDOWS
|
||||
Sleep(1000);
|
||||
#else
|
||||
|
@ -1468,6 +1468,83 @@ test_util_spawn_background_fail(void *ptr)
|
||||
run_util_spawn_background(argv, expected_out, expected_err, 255, expected_status);
|
||||
}
|
||||
|
||||
/** Helper function for testing tor_spawn_background */
|
||||
static void
|
||||
test_util_spawn_background_partial_read(void *ptr)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
// TODO: Under MSYS, BUILDDIR in orconfig.h needs to be tweaked
|
||||
const char *argv[] = {BUILDDIR "/src/test/test-child.exe", "--test", NULL};
|
||||
const char *expected_out[] = { "OUT\r\n--test\r\nSLEEPING\r\n",
|
||||
"DONE\r\n",
|
||||
NULL };
|
||||
const char *expected_err = "ERR\r\n";
|
||||
int expected_out_ctr;
|
||||
#else
|
||||
const char *argv[] = {BUILDDIR "/src/test/test-child", "--test", NULL};
|
||||
const char *expected_out = "OUT\n--test\nSLEEPING\nDONE\n";
|
||||
const char *expected_err = "ERR\r\n";
|
||||
#endif
|
||||
const int expected_exit = 0;
|
||||
const int expected_status = 0;
|
||||
|
||||
int retval;
|
||||
ssize_t pos;
|
||||
process_handle_t process_handle;
|
||||
char stdout_buf[100], stderr_buf[100];
|
||||
|
||||
/* Start the program */
|
||||
process_handle = tor_spawn_background(argv[0], argv);
|
||||
tt_int_op(process_handle.status, ==, expected_status);
|
||||
|
||||
/* Check stdout */
|
||||
#ifdef MS_WINDOWS
|
||||
for (expected_out_ctr =0; expected_out[expected_out_ctr] != NULL;) {
|
||||
pos = tor_read_all_handle(process_handle.stdout_pipe, stdout_buf,
|
||||
sizeof(stdout_buf) - 1, NULL);
|
||||
log_info(LD_GENERAL, "tor_read_all_handle() returned %d", (int)pos);
|
||||
|
||||
/* We would have blocked, keep on trying */
|
||||
if (0 == pos)
|
||||
continue;
|
||||
|
||||
tt_assert(pos >= 0);
|
||||
stdout_buf[pos] = '\0';
|
||||
tt_str_op(stdout_buf, ==, expected_out[expected_out_ctr]);
|
||||
tt_int_op(pos, ==, strlen(expected_out[expected_out_ctr]));
|
||||
expected_out_ctr++;
|
||||
}
|
||||
/* The process should have exited without writing more */
|
||||
pos = tor_read_all_handle(process_handle.stdout_pipe, stdout_buf,
|
||||
sizeof(stdout_buf) - 1,
|
||||
process_handle.pid.hProcess);
|
||||
tt_int_op(pos, ==, 0);
|
||||
#else
|
||||
pos = tor_read_all_from_process_stdout(process_handle, stdout_buf,
|
||||
sizeof(stdout_buf) - 1);
|
||||
tt_assert(pos >= 0);
|
||||
stdout_buf[pos] = '\0';
|
||||
tt_str_op(stdout_buf, ==, expected_out);
|
||||
tt_int_op(pos, ==, strlen(expected_out));
|
||||
#endif
|
||||
|
||||
/* Check it terminated correctly */
|
||||
retval = tor_get_exit_code(process_handle);
|
||||
tt_int_op(retval, ==, expected_exit);
|
||||
// TODO: Make test-child exit with something other than 0
|
||||
|
||||
/* Check stderr */
|
||||
pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
|
||||
sizeof(stderr_buf) - 1);
|
||||
tt_assert(pos >= 0);
|
||||
stderr_buf[pos] = '\0';
|
||||
tt_str_op(stderr_buf, ==, expected_err);
|
||||
tt_int_op(pos, ==, strlen(expected_err));
|
||||
|
||||
done:
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
test_util_di_ops(void)
|
||||
{
|
||||
@ -1555,6 +1632,7 @@ struct testcase_t util_tests[] = {
|
||||
#endif
|
||||
UTIL_TEST(spawn_background_ok, 0),
|
||||
UTIL_TEST(spawn_background_fail, 0),
|
||||
UTIL_TEST(spawn_background_partial_read, 0),
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user