diff mbox series

[ptest-runner,3/4] Report if child dies from a signal

Message ID 20230717142831.1634172-4-JPEWhacker@gmail.com
State New
Headers show
Series Stop running ptests in parallel | expand

Commit Message

Joshua Watt July 17, 2023, 2:28 p.m. UTC
Tests can exit due to a signal, which should also be reported in the
test output.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 tests/data/signal/ptest/run-ptest | 10 ++++++++
 tests/utils.c                     | 39 +++++++++++++++++++++++++++---
 utils.c                           | 40 +++++++++++++++++--------------
 3 files changed, 68 insertions(+), 21 deletions(-)
 create mode 100755 tests/data/signal/ptest/run-ptest
diff mbox series

Patch

diff --git a/tests/data/signal/ptest/run-ptest b/tests/data/signal/ptest/run-ptest
new file mode 100755
index 0000000..93ac65b
--- /dev/null
+++ b/tests/data/signal/ptest/run-ptest
@@ -0,0 +1,10 @@ 
+#!/bin/sh
+
+echo "signal" 1>&2
+echo "signal"
+
+kill -ABRT $$
+
+while true; do
+	sleep 1
+done
diff --git a/tests/utils.c b/tests/utils.c
index 19657ee..d82b90e 100644
--- a/tests/utils.c
+++ b/tests/utils.c
@@ -50,9 +50,10 @@  static char *ptests_found[] = {
 	"glibc",
 	"hang",
 	"python",
+	"signal",
 	NULL
 };
-static int ptests_found_length = 6;
+static int ptests_found_length = 7;
 static char *ptests_not_found[] = {
 	"busybox",
 	"perl",
@@ -186,6 +187,7 @@  START_TEST(test_run_ptests)
 	head = get_available_ptests(opts_directory);
 	ptest_list_remove(head, "hang", 1);
 	ptest_list_remove(head, "fail", 1);
+	ptest_list_remove(head, "signal", 1);
 
 	rc = run_ptests(head, opts, "test_run_ptests", fp_stdout, fp_stderr);
 	ck_assert(rc == 0);
@@ -215,8 +217,8 @@  search_for_timeout_and_duration(const int rp, FILE *fp_stdout)
 		found_duration = found_duration ? found_duration : find_word(line, duration_str);
 	}
 
-	ck_assert(found_timeout == true);
-	ck_assert(found_duration == true);
+	ck_assert_msg(found_timeout == true, "TIMEOUT not found");
+	ck_assert_msg(found_duration == true, "DURATION not found");
 }
 
 START_TEST(test_run_timeout_duration_ptest)
@@ -230,6 +232,36 @@  START_TEST(test_run_timeout_duration_ptest)
 }
 END_TEST
 
+static void
+search_for_signal_and_duration(const int rp, FILE *fp_stdout)
+{
+	char line_buf[PRINT_PTEST_BUF_SIZE];
+	bool found_error = false, found_duration = false;
+	char *line = NULL;
+
+	ck_assert(rp != 0);
+
+	while ((line = fgets(line_buf, PRINT_PTEST_BUF_SIZE, fp_stdout)) != NULL) {
+		// once true, stay true
+		found_error = found_error ? found_error : find_word(line, "ERROR: Exited from signal");
+		found_duration = found_duration ? found_duration : find_word(line, "DURATION");
+	}
+
+	ck_assert_msg(found_error == true, "ERROR not found");
+	ck_assert_msg(found_duration == true, "DURATION not found");
+}
+
+START_TEST(test_run_signal_ptest)
+{
+	struct ptest_list *head = get_available_ptests(opts_directory);
+	unsigned int timeout = 10;
+
+	test_ptest_expected_failure(head, timeout, "signal", search_for_signal_and_duration);
+
+	ptest_list_free_all(head);
+}
+END_TEST
+
 static void
 search_for_fail(const int rp, FILE *fp_stdout)
 {
@@ -318,6 +350,7 @@  utils_suite(void)
 	tcase_add_test(tc_core, test_filter_ptests);
 	tcase_add_test(tc_core, test_run_ptests);
 	tcase_add_test(tc_core, test_run_timeout_duration_ptest);
+	tcase_add_test(tc_core, test_run_signal_ptest);
 	tcase_add_test(tc_core, test_run_fail_ptest);
 	tcase_add_test(tc_core, test_xml_pass);
 	tcase_add_test(tc_core, test_xml_fail);
diff --git a/utils.c b/utils.c
index c1188dd..34ca2f0 100644
--- a/utils.c
+++ b/utils.c
@@ -343,18 +343,6 @@  run_child(char *run_ptest, int fd_stdout, int fd_stderr)
 	/* exit(1); not needed? */
 }
 
-static inline int
-wait_child(pid_t pid)
-{
-	int status = -1;
-
-	waitpid(pid, &status, 0);
-	if (WIFEXITED(status))
-		status = WEXITSTATUS(status);
-
-	return status;
-}
-
 /* Returns an integer file descriptor.
  * If it returns < 0, an error has occurred.
  * Otherwise, it has returned the slave pty file descriptor.
@@ -585,21 +573,37 @@  run_ptests(struct ptest_list *head, const struct ptest_options opts,
 				if (!_child_reader.timeouted) {
 					kill(-child, SIGKILL);
 				}
-				status = wait_child(child);
+				waitpid(child, &status, 0);
 
 				entime = time(NULL);
 				duration = entime - sttime;
 
-				if (status) {
-					fprintf(fp, "\nERROR: Exit status is %d\n", status);
-					rc += 1;
+				int exit_code = 0;
+
+				if (!_child_reader.timeouted) {
+					if (WIFEXITED(status)) {
+						exit_code = WEXITSTATUS(status);
+						if (exit_code) {
+							fprintf(fp, "\nERROR: Exit status is %d\n", exit_code);
+							rc += 1;
+						}
+					} else if (WIFSIGNALED(status)) {
+						int signal = WTERMSIG(status);
+						fprintf(fp, "\nERROR: Exited from signal %s (%d)\n", strsignal(signal), signal);
+						rc += 1;
+					} else {
+						fprintf(fp, "\nERROR: Exited for unknown reason (%d)\n", status);
+						rc += 1;
+					}
 				}
 				fprintf(fp, "DURATION: %d\n", (int) duration);
-				if (_child_reader.timeouted)
+				if (_child_reader.timeouted) {
 					fprintf(fp, "TIMEOUT: %s\n", ptest_dir);
+					rc += 1;
+				}
 
 				if (opts.xml_filename)
-					xml_add_case(xh, status, ptest_dir, _child_reader.timeouted, (int) duration);
+					xml_add_case(xh, exit_code, ptest_dir, _child_reader.timeouted, (int) duration);
 
 				fprintf(fp, "END: %s\n", ptest_dir);
 				fprintf(fp, "%s\n", get_stime(stime, GET_STIME_BUF_SIZE, entime));