From 754bb98ed952b589d41affdf677f8284926f368a Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Sun, 15 Sep 2024 16:12:26 -0400 Subject: Add test_multiprocessing.c --- tests/test_multiprocessing.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 tests/test_multiprocessing.c (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c new file mode 100644 index 0000000..3d1d972 --- /dev/null +++ b/tests/test_multiprocessing.c @@ -0,0 +1,73 @@ +#include "testing.h" + +static struct MultiProcessingPool *pool; +char *commands[] = { + "true", + "uname -a", + "/bin/echo hello world", +}; + +void test_mp_pool_init() { + STASIS_ASSERT((pool = mp_pool_init("mypool", "mplogs")) != NULL, "Pool initialization failed"); + STASIS_ASSERT_FATAL(pool != NULL, "Should not be NULL"); + STASIS_ASSERT(pool->num_alloc == MP_POOL_TASK_MAX, "Wrong number of default records"); + STASIS_ASSERT(pool->num_used == 0, "Wrong number of used records"); + STASIS_ASSERT(strcmp(pool->log_root, "mplogs") == 0, "Wrong log root directory"); + STASIS_ASSERT(strcmp(pool->ident, "mypool") == 0, "Wrong identity"); + int data_bad = 0; + char *data = calloc(pool->num_alloc, sizeof(*pool->task)); + for (size_t i = 0; i < pool->num_alloc * sizeof(*pool->task); i++) { + if (data[i] != 0) { + data_bad = 1; + break; + } + } + free(data); + STASIS_ASSERT(data_bad == 0, "Task array should be zeroed"); + mp_pool_free(&pool); +} + +void test_mp_task() { + pool = mp_pool_init("mypool", "mplogs"); + + if (pool) { + for (size_t i = 0; i < sizeof(commands) / sizeof(*commands); i++) { + struct MultiProcessingTask *task; + char task_name[100] = {0}; + sprintf(task_name, "mytask%zu", i); + STASIS_ASSERT_FATAL((task = mp_task(pool, task_name, commands[i])) != NULL, "Task should not be NULL"); + STASIS_ASSERT(task->pid != 0, "PID should be non-zero at this point"); + STASIS_ASSERT(task->parent_pid != MP_POOL_PID_UNUSED, "Parent PID should be non-zero"); + STASIS_ASSERT(task->status == 0, "Status should be zero"); + STASIS_ASSERT(strcmp(task->ident, task_name) == 0, "Wrong task identity"); + STASIS_ASSERT(strstr(task->log_file, pool->log_root) != NULL, "Log file path must be in log_root"); + STASIS_ASSERT(task->gate != NULL, "Semaphore should be initialized"); + } + } +} + +void test_mp_pool_join() { + STASIS_ASSERT(mp_pool_join(pool, get_cpu_count(), 0) == 0, "Pool tasks should have not have failed"); + for (size_t i = 0; i < pool->num_used; i++) { + struct MultiProcessingTask *task = &pool->task[i]; + STASIS_ASSERT(task->pid == MP_POOL_PID_UNUSED, "Task should be marked as unused"); + STASIS_ASSERT(task->status == 0, "Task should have succeeded"); + } +} + +void test_mp_pool_free() { + mp_pool_free(&pool); + STASIS_ASSERT(pool == NULL, "Should be NULL"); +} + +int main(int argc, char *argv[]) { + STASIS_TEST_BEGIN_MAIN(); + STASIS_TEST_FUNC *tests[] = { + test_mp_pool_init, + test_mp_task, + test_mp_pool_join, + test_mp_pool_free, + }; + STASIS_TEST_RUN(tests); + STASIS_TEST_END_MAIN(); +} \ No newline at end of file -- cgit From 3ef3a2758c572dcdeed7d693f52c5049394f11f5 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Tue, 17 Sep 2024 10:29:13 -0400 Subject: Fix test status expectation * Fix child not returning result of execvp(). task->status is for program status, not fork() status. --- tests/test_multiprocessing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index 3d1d972..67574e3 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -38,7 +38,7 @@ void test_mp_task() { STASIS_ASSERT_FATAL((task = mp_task(pool, task_name, commands[i])) != NULL, "Task should not be NULL"); STASIS_ASSERT(task->pid != 0, "PID should be non-zero at this point"); STASIS_ASSERT(task->parent_pid != MP_POOL_PID_UNUSED, "Parent PID should be non-zero"); - STASIS_ASSERT(task->status == 0, "Status should be zero"); + STASIS_ASSERT(task->status == -1, "Status should be -1 (not started yet)"); STASIS_ASSERT(strcmp(task->ident, task_name) == 0, "Wrong task identity"); STASIS_ASSERT(strstr(task->log_file, pool->log_root) != NULL, "Log file path must be in log_root"); STASIS_ASSERT(task->gate != NULL, "Semaphore should be initialized"); @@ -51,7 +51,7 @@ void test_mp_pool_join() { for (size_t i = 0; i < pool->num_used; i++) { struct MultiProcessingTask *task = &pool->task[i]; STASIS_ASSERT(task->pid == MP_POOL_PID_UNUSED, "Task should be marked as unused"); - STASIS_ASSERT(task->status == 0, "Task should have succeeded"); + STASIS_ASSERT(task->status == 0, "Task status should be zero (success)"); } } -- cgit From 8b47235f7c81e04fa5efef492974509789f40273 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 18 Sep 2024 10:04:21 -0400 Subject: Rename mp_task to mp_pool_task --- tests/test_multiprocessing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index 67574e3..1b2c865 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -35,7 +35,7 @@ void test_mp_task() { struct MultiProcessingTask *task; char task_name[100] = {0}; sprintf(task_name, "mytask%zu", i); - STASIS_ASSERT_FATAL((task = mp_task(pool, task_name, commands[i])) != NULL, "Task should not be NULL"); + STASIS_ASSERT_FATAL((task = mp_pool_task(pool, task_name, commands[i])) != NULL, "Task should not be NULL"); STASIS_ASSERT(task->pid != 0, "PID should be non-zero at this point"); STASIS_ASSERT(task->parent_pid != MP_POOL_PID_UNUSED, "Parent PID should be non-zero"); STASIS_ASSERT(task->status == -1, "Status should be -1 (not started yet)"); -- cgit From 6329270347c33d70a75248cb4b1926d2f651b7f3 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 18 Sep 2024 10:18:26 -0400 Subject: More tests --- tests/test_multiprocessing.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index 1b2c865..901666b 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -60,6 +60,35 @@ void test_mp_pool_free() { STASIS_ASSERT(pool == NULL, "Should be NULL"); } +void test_mp_pool_workflow() { + struct testcase { + const char *input_cmd; + int input_join_flags; + int expected_result; + int expected_status; + int expected_signal; + }; + struct testcase tc[] = { + {.input_cmd = "true && kill $$", .input_join_flags = 0, .expected_result = 1, .expected_status = 0, .expected_signal = SIGTERM}, + {.input_cmd = "false || kill -1 $$", .input_join_flags = 0, .expected_result = 1, .expected_status = 1, .expected_signal = SIGTERM}, + {.input_cmd = "true", .input_join_flags = 0,.expected_result = 0, .expected_status = 0, .expected_signal = 0}, + {.input_cmd = "false", .input_join_flags = 0, .expected_result = 1, .expected_status = 1, .expected_signal = 0}, + }; + for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) { + struct testcase *test = &tc[i]; + struct MultiProcessingPool *p; + struct MultiProcessingTask *task; + STASIS_ASSERT((p = mp_pool_init("workflow", "mplogs")) != NULL, "Failed to initialize pool"); + STASIS_ASSERT((task = mp_pool_task(p, "task", (char *) test->input_cmd)) != NULL, "Failed to queue task"); + STASIS_ASSERT(mp_pool_join(p, get_cpu_count(), test->input_join_flags) == test->expected_result, "Unexpected result"); + STASIS_ASSERT(task->status == test->expected_status, "Unexpected status"); + STASIS_ASSERT(task->signaled_by == test->expected_signal, "Unexpected signal"); + STASIS_ASSERT(task->pid == MP_POOL_PID_UNUSED, "Unexpected PID. Should be marked UNUSED."); + mp_pool_show_summary(p); + mp_pool_free(&p); + } +} + int main(int argc, char *argv[]) { STASIS_TEST_BEGIN_MAIN(); STASIS_TEST_FUNC *tests[] = { @@ -67,6 +96,7 @@ int main(int argc, char *argv[]) { test_mp_task, test_mp_pool_join, test_mp_pool_free, + test_mp_pool_workflow, }; STASIS_TEST_RUN(tests); STASIS_TEST_END_MAIN(); -- cgit From b9d1747f06a226ddbf7a0a61e7e21a9ce272a37a Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 18 Sep 2024 10:32:50 -0400 Subject: Fix test code and expected values within test code * Errant undo operation! --- tests/test_multiprocessing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index 901666b..f060e6a 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -70,7 +70,7 @@ void test_mp_pool_workflow() { }; struct testcase tc[] = { {.input_cmd = "true && kill $$", .input_join_flags = 0, .expected_result = 1, .expected_status = 0, .expected_signal = SIGTERM}, - {.input_cmd = "false || kill -1 $$", .input_join_flags = 0, .expected_result = 1, .expected_status = 1, .expected_signal = SIGTERM}, + {.input_cmd = "false || kill $$", .input_join_flags = 0, .expected_result = 1, .expected_status = 0, .expected_signal = SIGTERM}, {.input_cmd = "true", .input_join_flags = 0,.expected_result = 0, .expected_status = 0, .expected_signal = 0}, {.input_cmd = "false", .input_join_flags = 0, .expected_result = 1, .expected_status = 1, .expected_signal = 0}, }; -- cgit From cf5a1771ddf560da17d3dd869897ce2005315b15 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Fri, 20 Sep 2024 11:22:15 -0400 Subject: Finish mp_pool_init() test * Not sure what I was going to do with that data array, but whatever it was, it was wrong. --- tests/test_multiprocessing.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index f060e6a..e1a84e3 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -14,16 +14,39 @@ void test_mp_pool_init() { STASIS_ASSERT(pool->num_used == 0, "Wrong number of used records"); STASIS_ASSERT(strcmp(pool->log_root, "mplogs") == 0, "Wrong log root directory"); STASIS_ASSERT(strcmp(pool->ident, "mypool") == 0, "Wrong identity"); - int data_bad = 0; - char *data = calloc(pool->num_alloc, sizeof(*pool->task)); - for (size_t i = 0; i < pool->num_alloc * sizeof(*pool->task); i++) { - if (data[i] != 0) { - data_bad = 1; - break; + + int data_bad_total = 0; + for (size_t i = 0; i < pool->num_alloc; i++) { + int data_bad = 0; + struct MultiProcessingTask *task = &pool->task[i]; + + data_bad += task->status == 0 ? 0 : 1; + data_bad += task->pid == 0 ? 0 : 1; + data_bad += task->parent_pid == 0 ? 0 : 1; + data_bad += task->signaled_by == 0 ? 0 : 1; + data_bad += task->time_data.t_start.tv_nsec == 0 ? 0 : 1; + data_bad += task->time_data.t_start.tv_sec == 0 ? 0 : 1; + data_bad += task->time_data.t_stop.tv_nsec == 0 ? 0 : 1; + data_bad += task->time_data.t_stop.tv_sec == 0 ? 0 : 1; + data_bad += (int) strlen(task->ident) == 0 ? 0 : 1; + data_bad += (int) strlen(task->parent_script) == 0 ? 0 : 1; + data_bad += task->gate == NULL ? 0 : 1; + if (data_bad) { + SYSERROR("%s.task[%zu] has garbage values!", pool->ident, i); + SYSERROR(" ident: %s", task->ident); + SYSERROR(" status: %d", task->status); + SYSERROR(" pid: %d", task->pid); + SYSERROR(" parent_pid: %d", task->parent_pid); + SYSERROR(" signaled_by: %d", task->signaled_by); + SYSERROR(" t_start.tv_nsec: %ld", task->time_data.t_start.tv_nsec); + SYSERROR(" t_start.tv_sec: %ld", task->time_data.t_start.tv_sec); + SYSERROR(" t_stop.tv_nsec: %ld", task->time_data.t_stop.tv_nsec); + SYSERROR(" t_stop.tv_sec: %ld", task->time_data.t_stop.tv_sec); + SYSERROR(" gate: %s", task->gate == NULL ? "UNINITIALIZED (OK)" : "INITIALIZED (BAD)"); + data_bad_total++; } } - free(data); - STASIS_ASSERT(data_bad == 0, "Task array should be zeroed"); + STASIS_ASSERT(data_bad_total == 0, "Task array is not pristine"); mp_pool_free(&pool); } -- cgit From 3e610e935858995f411df7bb0a77e2efeeae3d66 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Thu, 26 Sep 2024 09:56:25 -0400 Subject: Implement cmd and working_dir --- tests/test_multiprocessing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index e1a84e3..5b3d9d1 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -58,7 +58,7 @@ void test_mp_task() { struct MultiProcessingTask *task; char task_name[100] = {0}; sprintf(task_name, "mytask%zu", i); - STASIS_ASSERT_FATAL((task = mp_pool_task(pool, task_name, commands[i])) != NULL, "Task should not be NULL"); + STASIS_ASSERT_FATAL((task = mp_pool_task(pool, task_name, NULL, commands[i])) != NULL, "Task should not be NULL"); STASIS_ASSERT(task->pid != 0, "PID should be non-zero at this point"); STASIS_ASSERT(task->parent_pid != MP_POOL_PID_UNUSED, "Parent PID should be non-zero"); STASIS_ASSERT(task->status == -1, "Status should be -1 (not started yet)"); @@ -102,7 +102,7 @@ void test_mp_pool_workflow() { struct MultiProcessingPool *p; struct MultiProcessingTask *task; STASIS_ASSERT((p = mp_pool_init("workflow", "mplogs")) != NULL, "Failed to initialize pool"); - STASIS_ASSERT((task = mp_pool_task(p, "task", (char *) test->input_cmd)) != NULL, "Failed to queue task"); + STASIS_ASSERT((task = mp_pool_task(p, "task", NULL, (char *) test->input_cmd)) != NULL, "Failed to queue task"); STASIS_ASSERT(mp_pool_join(p, get_cpu_count(), test->input_join_flags) == test->expected_result, "Unexpected result"); STASIS_ASSERT(task->status == test->expected_status, "Unexpected status"); STASIS_ASSERT(task->signaled_by == test->expected_signal, "Unexpected signal"); -- cgit From 1a95c340a77020bdb897ecb67974fa5c578a611a Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Thu, 26 Sep 2024 10:01:41 -0400 Subject: Remove more references to the semaphore "gate" --- tests/test_multiprocessing.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index 5b3d9d1..0b6c6ea 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -30,7 +30,6 @@ void test_mp_pool_init() { data_bad += task->time_data.t_stop.tv_sec == 0 ? 0 : 1; data_bad += (int) strlen(task->ident) == 0 ? 0 : 1; data_bad += (int) strlen(task->parent_script) == 0 ? 0 : 1; - data_bad += task->gate == NULL ? 0 : 1; if (data_bad) { SYSERROR("%s.task[%zu] has garbage values!", pool->ident, i); SYSERROR(" ident: %s", task->ident); @@ -42,7 +41,6 @@ void test_mp_pool_init() { SYSERROR(" t_start.tv_sec: %ld", task->time_data.t_start.tv_sec); SYSERROR(" t_stop.tv_nsec: %ld", task->time_data.t_stop.tv_nsec); SYSERROR(" t_stop.tv_sec: %ld", task->time_data.t_stop.tv_sec); - SYSERROR(" gate: %s", task->gate == NULL ? "UNINITIALIZED (OK)" : "INITIALIZED (BAD)"); data_bad_total++; } } @@ -64,7 +62,6 @@ void test_mp_task() { STASIS_ASSERT(task->status == -1, "Status should be -1 (not started yet)"); STASIS_ASSERT(strcmp(task->ident, task_name) == 0, "Wrong task identity"); STASIS_ASSERT(strstr(task->log_file, pool->log_root) != NULL, "Log file path must be in log_root"); - STASIS_ASSERT(task->gate != NULL, "Semaphore should be initialized"); } } } -- cgit From cfa8d04c01cb46c39f1a76005d777bd9e3ddd51d Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Thu, 26 Sep 2024 10:33:32 -0400 Subject: Fix test * Queuing a task does not fork anymore, so the default state is now UNUSED --- tests/test_multiprocessing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/test_multiprocessing.c') diff --git a/tests/test_multiprocessing.c b/tests/test_multiprocessing.c index 0b6c6ea..cd037d0 100644 --- a/tests/test_multiprocessing.c +++ b/tests/test_multiprocessing.c @@ -57,8 +57,8 @@ void test_mp_task() { char task_name[100] = {0}; sprintf(task_name, "mytask%zu", i); STASIS_ASSERT_FATAL((task = mp_pool_task(pool, task_name, NULL, commands[i])) != NULL, "Task should not be NULL"); - STASIS_ASSERT(task->pid != 0, "PID should be non-zero at this point"); - STASIS_ASSERT(task->parent_pid != MP_POOL_PID_UNUSED, "Parent PID should be non-zero"); + STASIS_ASSERT(task->pid == MP_POOL_PID_UNUSED, "PID should be non-zero at this point"); + STASIS_ASSERT(task->parent_pid == MP_POOL_PID_UNUSED, "Parent PID should be non-zero"); STASIS_ASSERT(task->status == -1, "Status should be -1 (not started yet)"); STASIS_ASSERT(strcmp(task->ident, task_name) == 0, "Wrong task identity"); STASIS_ASSERT(strstr(task->log_file, pool->log_root) != NULL, "Log file path must be in log_root"); -- cgit