From 4b7769677de942cfa4f4d1312fd92344564c5e0b Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Sat, 14 Sep 2024 03:40:09 +0200 Subject: [PATCH] Test writing big data to child, and write to dead child --- test/testprocess.c | 121 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 6 deletions(-) diff --git a/test/testprocess.c b/test/testprocess.c index d4c63dd3fb771..98a9c3a85f415 100644 --- a/test/testprocess.c +++ b/test/testprocess.c @@ -316,7 +316,7 @@ static int SDLCALL process_testNewEnv(void *arg) test_env_val1 = SDLTest_RandomAsciiStringOfSize(32); SDL_snprintf(random_env1, sizeof(random_env1), "%s=%s", TEST_ENV_KEY1, test_env_val1); - SDLTest_AssertPass("Unsetting parrent environment variable %s", TEST_ENV_KEY1); + SDLTest_AssertPass("Unsetting parent environment variable %s", TEST_ENV_KEY1); SDL_unsetenv(TEST_ENV_KEY1); process_args[3] = random_env1; @@ -369,7 +369,7 @@ static int SDLCALL process_testNewEnv(void *arg) return TEST_ABORTED; } -static int process_testStdinToStdoutAndStderr(void *arg) +static int process_testStdinToStdout(void *arg) { TestProcessData *data = (TestProcessData *)arg; const char *process_args[] = { @@ -383,6 +383,7 @@ static int process_testStdinToStdoutAndStderr(void *arg) Sint64 pid; SDL_IOStream *process_stdin = NULL; SDL_IOStream *process_stdout = NULL; + SDL_IOStream *process_stderr = NULL; const char *text_in = "Tests whether we can write to stdin and read from stdout\r\n{'succes': true, 'message': 'Success!'}\r\nYippie ka yee\r\nEOF"; size_t amount_written; size_t amount_to_write; @@ -413,10 +414,12 @@ static int process_testStdinToStdoutAndStderr(void *arg) SDLTest_AssertCheck(process_stdin != NULL, "SDL_GetPointerProperty(SDL_PROP_PROCESS_STDIN_POINTER) returns a valid IO stream"); process_stdout = (SDL_IOStream *)SDL_GetPointerProperty(props, SDL_PROP_PROCESS_STDOUT_POINTER, NULL); SDLTest_AssertCheck(process_stdout != NULL, "SDL_GetPointerProperty(SDL_PROP_PROCESS_STDOUT_POINTER) returns a valid IO stream"); + process_stderr = (SDL_IOStream *)SDL_GetPointerProperty(props, SDL_PROP_PROCESS_STDERR_POINTER, NULL); + SDLTest_AssertCheck(process_stderr == NULL, "SDL_GetPointerProperty(SDL_PROP_PROCESS_STDOUT_POINTER) returns NULL"); if (!process_stdin || !process_stdout) { goto failed; } - SDLTest_AssertPass("About to write to process"); + SDLTest_AssertPass("About to write to process using SDL_WriteIO"); amount_to_write = SDL_strlen(text_in); amount_written = SDL_WriteIO(process_stdin, text_in, amount_to_write); SDLTest_AssertCheck(amount_written == amount_to_write, "SDL_WriteIO(subprocess.stdin) wrote %" SDL_PRIu64 " bytes, expected %" SDL_PRIu64, (Uint64)amount_written, (Uint64)amount_to_write); @@ -530,6 +533,64 @@ static int process_testSimpleStdinToStdout(void *arg) return TEST_ABORTED; } +static int process_testBigSimpleStdinToStdout(void *arg) +{ + TestProcessData *data = (TestProcessData *)arg; + const char *process_args[] = { + data->childprocess_path, + "--stdin-to-stdout", + NULL, + }; + SDL_Process *process = NULL; + char *buffer; + SDL_bool result; + int exit_code; + char *text_in = NULL; + size_t text_in_buffer_size = 64 * 1024 + 1 + 1; /* 64kiB is the limit on Linux (+1 for null character) */ + size_t total_read = 0; + + process = SDL_CreateProcess(process_args, SDL_TRUE); + SDLTest_AssertCheck(process != NULL, "SDL_CreateProcess()"); + if (!process) { + goto failed; + } + + text_in = SDL_malloc(text_in_buffer_size); + SDL_memset(text_in, 'a', text_in_buffer_size); + text_in[text_in_buffer_size - 1] = '\0'; + + SDLTest_AssertPass("About to write to process"); + result = SDL_WriteProcess(process, text_in, text_in_buffer_size - 1, SDL_TRUE); + SDLTest_AssertCheck(result, "SDL_WriteProcess()"); + if (!result) { + goto failed; + } + + exit_code = 0xdeadbeef; + buffer = (char *)SDL_ReadProcess(process, &total_read, &exit_code); + SDLTest_AssertCheck(buffer != NULL, "SDL_ReadProcess()"); + SDLTest_AssertCheck(exit_code == 0, "Exit code should be 0, is %d", exit_code); + if (!buffer) { + goto failed; + } + + SDLTest_LogEscapedString("Expected text read from subprocess: %s", text_in, SDL_strlen(text_in)); + SDLTest_LogEscapedString("Actual text read from subprocess: %s", buffer, total_read); + SDLTest_AssertCheck(total_read == text_in_buffer_size - 1, "Expected to read %u bytes, actually read %u bytes", (unsigned)(text_in_buffer_size - 1), (unsigned)total_read); + SDLTest_AssertCheck(SDL_strcmp(buffer, text_in) == 0, "Subprocess stdout should match text written to stdin"); + SDL_free(buffer); + + SDLTest_AssertPass("About to destroy process"); + SDL_DestroyProcess(process); + SDL_free(text_in); + return TEST_COMPLETED; + +failed: + SDL_DestroyProcess(process); + SDL_free(text_in); + return TEST_ABORTED; +} + static int process_testMultiprocessStdinToStdout(void *arg) { TestProcessData *data = (TestProcessData *)arg; @@ -597,6 +658,44 @@ static int process_testMultiprocessStdinToStdout(void *arg) return TEST_ABORTED; } +static int process_testWriteToFinishedProcess(void *arg) +{ + TestProcessData *data = (TestProcessData *)arg; + const char *process_args[] = { + data->childprocess_path, + NULL, + }; + SDL_Process *process = NULL; + SDL_bool result; + int exit_code; + const char *text_in = "text_in"; + + SDLTest_AssertPass("About to call SDL_CreateProcess"); + process = SDL_CreateProcess(process_args, SDL_TRUE); + SDLTest_AssertCheck(process != NULL, "SDL_CreateProcess()"); + if (!process) { + goto failed; + } + + exit_code = 0xdeadbeef; + SDLTest_AssertPass("About to call SDL_WaitProcess"); + result = SDL_WaitProcess(process, SDL_TRUE, &exit_code); + SDLTest_AssertCheck(result, "SDL_WaitProcess()"); + SDLTest_AssertCheck(exit_code == 0, "Exit code should be 0, is %d", exit_code); + + SDLTest_AssertPass("About to call SDL_WriteProcess"); + result = SDL_WriteProcess(process, text_in, SDL_strlen(text_in), SDL_TRUE); + SDLTest_AssertCheck(!result, "SDL_WriteProcess() should fail, because the child process is dead"); + + SDLTest_AssertPass("About to destroy process"); + SDL_DestroyProcess(process); + return TEST_COMPLETED; + +failed: + SDL_DestroyProcess(process); + return TEST_ABORTED; +} + static const SDLTest_TestCaseReference processTestArguments = { process_testArguments, "process_testArguments", "Test passing arguments to child process", TEST_ENABLED }; @@ -613,26 +712,36 @@ static const SDLTest_TestCaseReference processTestNewEnv = { process_testNewEnv, "process_testNewEnv", "Test creating new environment for child process", TEST_ENABLED }; -static const SDLTest_TestCaseReference processTestStdinToStdoutAndStderr = { - process_testStdinToStdoutAndStderr, "processTestStdinToStdoutAndStderr", "Test writing to stdin and reading from stdout and stderr", TEST_ENABLED +static const SDLTest_TestCaseReference processTestStdinToStdout = { + process_testStdinToStdout, "processTestStdinToStdout", "Test writing to stdin and reading from stdout", TEST_ENABLED }; static const SDLTest_TestCaseReference processTestSimpleStdinToStdout = { process_testSimpleStdinToStdout, "process_testSimpleStdinToStdout", "Test writing to stdin and reading from stdout using the simplified API", TEST_ENABLED }; +static const SDLTest_TestCaseReference processTestBigSimpleStdinToStdout = { + process_testBigSimpleStdinToStdout, "process_testBigSimpleStdinToStdout", "Test writing big data to stdin and reading from stdout using the simplified API", TEST_DISABLED +}; + static const SDLTest_TestCaseReference processTestMultiprocessStdinToStdout = { process_testMultiprocessStdinToStdout, "process_testMultiprocessStdinToStdout", "Test writing to stdin and reading from stdout using the simplified API", TEST_ENABLED }; +static const SDLTest_TestCaseReference processWriteToFinishedProcess = { + process_testWriteToFinishedProcess, "process_testWriteToFinishedProcess", "Test writing to stdin of terminated process", TEST_DISABLED +}; + static const SDLTest_TestCaseReference *processTests[] = { &processTestArguments, &processTestExitCode, &processTestInheritedEnv, &processTestNewEnv, - &processTestStdinToStdoutAndStderr, + &processTestStdinToStdout, &processTestSimpleStdinToStdout, + &processTestBigSimpleStdinToStdout, &processTestMultiprocessStdinToStdout, + &processWriteToFinishedProcess, NULL };