[PATCH i-g-t 08/28] Test exit to comms.txt

Petri Latvala petri.latvala at intel.com
Mon Mar 22 11:34:00 UTC 2021


---
 lib/runnercomms.c |  27 +++++++++
 lib/runnercomms.h |  13 +++++
 runner/executor.c | 139 ++++++++++++++++++++++++++++++++++------------
 3 files changed, 145 insertions(+), 34 deletions(-)

diff --git a/lib/runnercomms.c b/lib/runnercomms.c
index d300fe7f..950e5373 100644
--- a/lib/runnercomms.c
+++ b/lib/runnercomms.c
@@ -434,3 +434,30 @@ struct runnerpacket *runnerpacket_versionstring(const char *text)
 
 	return packet;
 }
+
+struct runnerpacket *runnerpacket_resultoverride(const char *result)
+{
+	struct runnerpacket *packet;
+	uint32_t size;
+	char *p;
+
+	size = sizeof(struct runnerpacket) + strlen(result) + 1;
+	packet = malloc(size);
+
+	packet->size = size;
+	packet->type = PACKETTYPE_RESULT_OVERRIDE;
+	packet->senderpid = getpid();
+	packet->sendertid = gettid();
+
+	p = packet->data;
+
+	strcpy(p, result);
+	p += strlen(result) + 1;
+
+	return packet;
+}
+
+uint32_t socket_dump_canary(void)
+{
+	return 'I' << 24 | 'G' << 16 | 'T' << 8 | '1';
+}
diff --git a/lib/runnercomms.h b/lib/runnercomms.h
index 41e92f17..b4ecfed6 100644
--- a/lib/runnercomms.h
+++ b/lib/runnercomms.h
@@ -112,6 +112,10 @@ union runnerpacket_read_helper {
 
 		const char *text;
 	} versionstring;
+
+	struct {
+		const char *result;
+	} resultoverride;
 };
 
 void set_runner_socket(int fd);
@@ -192,6 +196,12 @@ typedef enum runnerpacket_type {
        * cstring: Version string
        */
 
+      PACKETTYPE_RESULT_OVERRIDE,
+      /*
+       * Override the result of the most recently started test/subtest/dynamic subtest. Used for timeout and abort etc.
+       * cstring: The result to use, as text. All lowercase.
+       */
+
 } runnerpacket_type_t;
 
 struct runnerpacket *runnerpacket_log(uint8_t stream, const char *text);
@@ -204,5 +214,8 @@ struct runnerpacket *runnerpacket_dynamic_subtest_start(const char *name);
 struct runnerpacket *runnerpacket_dynamic_subtest_result(const char *name, const char *result,
 							 const char *timeused, const char *reason);
 struct runnerpacket *runnerpacket_versionstring(const char *text);
+struct runnerpacket *runnerpacket_resultoverride(const char *result);
+
+uint32_t socket_dump_canary(void);
 
 #endif
diff --git a/runner/executor.c b/runner/executor.c
index 5ee4dad7..1083f61f 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -761,9 +761,14 @@ static int next_kill_signal(int killed)
 	}
 }
 
-static uint32_t socket_dump_canary(void)
+static void write_packet_with_canary(int fd, struct runnerpacket *packet, bool sync)
 {
-	return 'I' << 24 | 'G' << 16 | 'T' << 8 | '1';
+	uint32_t canary = socket_dump_canary();
+
+	write(fd, &canary, sizeof(canary));
+	write(fd, packet, packet->size);
+	if (sync)
+		fdatasync(fd);
 }
 
 /*
@@ -796,6 +801,7 @@ static int monitor_output(pid_t child,
 	unsigned long taints = 0;
 	bool aborting = false;
 	size_t disk_usage = 0;
+	bool socket_comms_used = false; /* whether the test actually uses comms */
 
 	igt_gettime(&time_beg);
 	time_last_activity = time_last_subtest = time_killed = time_beg;
@@ -978,7 +984,6 @@ static int monitor_output(pid_t child,
 
 		if (socketfd >= 0 && FD_ISSET(socketfd, &set)) {
 			struct runnerpacket *packet;
-			uint32_t canary = socket_dump_canary();
 
 			time_last_activity = time_now;
 
@@ -1003,11 +1008,16 @@ static int monitor_output(pid_t child,
 				goto socket_end;
 			}
 
-			write(outputs[_F_SOCKET], &canary, sizeof(canary));
-			write(outputs[_F_SOCKET], buf, s);
-			disk_usage += s;
-			if (settings->sync)
-				fdatasync(outputs[_F_SOCKET]);
+			write_packet_with_canary(outputs[_F_SOCKET], packet, settings->sync);
+			disk_usage += packet->size;
+
+			/*
+			 * runner sends EXEC itself before executing
+			 * the test, other types indicate the test
+			 * really uses socket comms
+			 */
+			if (packet->type != PACKETTYPE_EXEC)
+				socket_comms_used = true;
 
 			if (settings->log_level >= LOG_LEVEL_VERBOSE) {
 				union runnerpacket_read_helper helper = {};
@@ -1126,11 +1136,23 @@ static int monitor_output(pid_t child,
 					if (settings->log_level >= LOG_LEVEL_NORMAL)
 						outf("Exiting gracefully, currently running test will have a 'notrun' result\n");
 
-					dprintf(outputs[_F_JOURNAL], "%s%d (%.3fs)\n",
-						EXECUTOR_EXIT,
-						-SIGHUP, 0.0);
-					if (settings->sync)
-						fdatasync(outputs[_F_JOURNAL]);
+					if (socket_comms_used) {
+						struct runnerpacket *message, *override;
+
+						message = runnerpacket_log(STDOUT_FILENO, "runner: Exiting gracefully, overriding this test's result to be notrun\n");
+						write_packet_with_canary(outputs[_F_SOCKET], message, false); /* possible sync after the override packet */
+						free(message);
+
+						override = runnerpacket_resultoverride("notrun");
+						write_packet_with_canary(outputs[_F_SOCKET], override, settings->sync);
+						free(override);
+					} else {
+						dprintf(outputs[_F_JOURNAL], "%s%d (%.3fs)\n",
+							EXECUTOR_EXIT,
+							-SIGHUP, 0.0);
+						if (settings->sync)
+							fdatasync(outputs[_F_JOURNAL]);
+					}
 				}
 
 				aborting = true;
@@ -1147,9 +1169,10 @@ static int monitor_output(pid_t child,
 				time = 0.0;
 
 			if (!aborting) {
-				const char *exitline;
+				bool timeoutresult = false;
 
-				exitline = killed ? EXECUTOR_TIMEOUT : EXECUTOR_EXIT;
+				if (killed)
+					timeoutresult = true;
 
 				/* If we're stopping because we killed
 				 * the test for tainting, let's not
@@ -1163,7 +1186,7 @@ static int monitor_output(pid_t child,
 				 * journaling a timeout here.
 				 */
 				if (killed && is_tainted(taints)) {
-					exitline = EXECUTOR_EXIT;
+					timeoutresult = false;
 
 					/*
 					 * Also inject a message to
@@ -1176,11 +1199,22 @@ static int monitor_output(pid_t child,
 					 * have newlines on both ends
 					 * of this injection though.
 					 */
-					dprintf(outputs[_F_OUT],
-						"\nrunner: This test was killed due to a kernel taint (0x%lx).\n",
-						taints);
-					if (settings->sync)
-						fdatasync(outputs[_F_OUT]);
+					if (socket_comms_used) {
+						struct runnerpacket *message;
+						char killmsg[256];
+
+						snprintf(killmsg, sizeof(killmsg),
+							 "runner: This test was killed due to a kernel taint (0x%lx).\n", taints);
+						message = runnerpacket_log(STDOUT_FILENO, killmsg);
+						write_packet_with_canary(outputs[_F_SOCKET], message, settings->sync);
+						free(message);
+					} else {
+						dprintf(outputs[_F_OUT],
+							"\nrunner: This test was killed due to a kernel taint (0x%lx).\n",
+							taints);
+						if (settings->sync)
+							fdatasync(outputs[_F_OUT]);
+					}
 				}
 
 				/*
@@ -1188,21 +1222,58 @@ static int monitor_output(pid_t child,
 				 * exceeded the disk usage limit.
 				 */
 				if (killed && disk_usage_limit_exceeded(settings, disk_usage)) {
-					exitline = EXECUTOR_EXIT;
-					dprintf(outputs[_F_OUT],
-						"\nrunner: This test was killed due to exceeding disk usage limit. "
-						"(Used %zd bytes, limit %zd)\n",
-						disk_usage,
-						settings->disk_usage_limit);
-					if (settings->sync)
-						fdatasync(outputs[_F_OUT]);
+					timeoutresult = false;
+
+					if (socket_comms_used) {
+						struct runnerpacket *message;
+						char killmsg[256];
+
+						snprintf(killmsg, sizeof(killmsg),
+							 "runner: This test was killed due to exceeding disk usage limit. "
+							 "(Used %zd bytes, limit %zd)\n",
+							 disk_usage,
+							 settings->disk_usage_limit);
+						message = runnerpacket_log(STDOUT_FILENO, killmsg);
+						write_packet_with_canary(outputs[_F_SOCKET], message, settings->sync);
+						free(message);
+					} else {
+						dprintf(outputs[_F_OUT],
+							"\nrunner: This test was killed due to exceeding disk usage limit. "
+							"(Used %zd bytes, limit %zd)\n",
+							disk_usage,
+							settings->disk_usage_limit);
+						if (settings->sync)
+							fdatasync(outputs[_F_OUT]);
+					}
 				}
 
-				dprintf(outputs[_F_JOURNAL], "%s%d (%.3fs)\n",
-					exitline,
-					status, time);
-				if (settings->sync) {
-					fdatasync(outputs[_F_JOURNAL]);
+				if (socket_comms_used) {
+					struct runnerpacket *exitpacket;
+					char timestr[32];
+
+					snprintf(timestr, sizeof(timestr), "%.3f", time);
+
+					if (timeoutresult) {
+						struct runnerpacket *override;
+
+						override = runnerpacket_resultoverride("timeout");
+						write_packet_with_canary(outputs[_F_SOCKET], override, false); /* sync after exitpacket */
+						free(override);
+					}
+
+					exitpacket = runnerpacket_exit(status, timestr);
+					write_packet_with_canary(outputs[_F_SOCKET], exitpacket, settings->sync);
+					free(exitpacket);
+				} else {
+					const char *exitline;
+
+					exitline = timeoutresult ? EXECUTOR_TIMEOUT : EXECUTOR_EXIT;
+					dprintf(outputs[_F_JOURNAL], "%s%d (%.3fs)\n",
+						exitline,
+						status, time);
+					if (settings->sync) {
+						fdatasync(outputs[_F_JOURNAL]);
+					}
 				}
 
 				if (status == IGT_EXIT_ABORT) {
-- 
2.29.2



More information about the Intel-gfx-trybot mailing list