Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Kamil Konieczny <kamil.konieczny@linux.intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>,
	Ewelina Musial <ewelina.musial@intel.com>,
	Lucas De Marchi <lucas.demarchi@intel.com>,
	Ryszard Knop <ryszard.knop@intel.com>,
	Petri Latvala <adrinael@adrinael.net>
Subject: [PATCH i-g-t] runner: Parse results harder
Date: Wed, 26 Feb 2025 20:33:28 +0100	[thread overview]
Message-ID: <20250226193328.132817-1-kamil.konieczny@linux.intel.com> (raw)

  Sometimes an error happens in kernel or in test that leaves
output files in corrupted or incorrect state. While runner or
resume will just move on to executing next test, when generating
results it could end up with no results.json

  Try processing outputs a little more persistently and use any
output file left there, even if only dmesg.txt. Also, when no
useful output files were present, instead of breaking out add
notrun.

  Inform about processing results for each test so a problem
could be spotted more easily.

Cc: Ewelina Musial <ewelina.musial@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Ryszard Knop <ryszard.knop@intel.com>
Cc: Petri Latvala <adrinael@adrinael.net>
Signed-off-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
---
 runner/executor.c  | 21 +++++++++++++++++++++
 runner/executor.h  |  1 +
 runner/resultgen.c | 45 ++++++++++++++++++++++++++++++---------------
 3 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/runner/executor.c b/runner/executor.c
index 2abb18732..96b8b5057 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -576,6 +576,27 @@ bool open_output_files(int dirfd, int *fds, bool write)
 	return true;
 }
 
+/**
+ * open_output_files_rdonly:
+ * @dirfd: fd of output directory with err.txt, dmesg.txt and other files
+ * @fds: array for fd's of opened output files
+ *
+ * Tries to open output files in read-only mode and saves file descriptors
+ * in fds arrray.
+ *
+ * Returns: true if all files opened, false otherwise
+ */
+bool open_output_files_rdonly(int dirfd, int *fds)
+{
+	bool ret = true;
+
+	for (int i = 0; i < _F_LAST; i++)
+		if ((fds[i] = openat(dirfd, filenames[i], O_RDONLY)) < 0)
+			ret = false; /* Remember failure */
+
+	return ret;
+}
+
 void close_outputs(int *fds)
 {
 	int i;
diff --git a/runner/executor.h b/runner/executor.h
index ab6a0c176..56c7323a8 100644
--- a/runner/executor.h
+++ b/runner/executor.h
@@ -26,6 +26,7 @@ enum {
 };
 
 bool open_output_files(int dirfd, int *fds, bool write);
+bool open_output_files_rdonly(int dirfd, int *fds);
 void close_outputs(int *fds);
 
 /*
diff --git a/runner/resultgen.c b/runner/resultgen.c
index 0d3a569cf..b50c417e3 100644
--- a/runner/resultgen.c
+++ b/runner/resultgen.c
@@ -2176,12 +2176,26 @@ static bool parse_test_directory(int dirfd,
 {
 	int fds[_F_LAST];
 	struct subtest_list subtests = {};
-	bool status = true;
 	int commsparsed;
 
-	if (!open_output_files(dirfd, fds, false)) {
-		fprintf(stderr, "Error opening output files\n");
-		return false;
+	if (!open_output_files_rdonly(dirfd, fds)) {
+		struct stat statbuf;
+		size_t sz = 0;
+
+		for (int i = 0; i < _F_LAST; ++i) {
+			if (fds[i] > 0 && !fstat(fds[i], &statbuf) && statbuf.st_size != 0)
+				sz = statbuf.st_size;
+		}
+
+		if (sz == 0) {
+			/* no output saved in any file */
+			fprintf(stderr, "results: Error opening output files\n");
+			close_outputs(fds);
+
+			return false;
+		}
+
+		fprintf(stderr, "results: Missing few output file(s)\n");
 	}
 
 	/*
@@ -2191,8 +2205,6 @@ static bool parse_test_directory(int dirfd,
 	commsparsed = fill_from_comms(fds[_F_SOCKET], entry, &subtests, results);
 	if (commsparsed == COMMSPARSE_ERROR) {
 		fprintf(stderr, "Error parsing output files (comms)\n");
-		status = false;
-		goto parse_output_end;
 	}
 
 	if (commsparsed == COMMSPARSE_EMPTY) {
@@ -2200,20 +2212,17 @@ static bool parse_test_directory(int dirfd,
 		 * fill_from_journal fills the subtests struct and
 		 * adds timeout results where applicable.
 		 */
-		fill_from_journal(fds[_F_JOURNAL], entry, &subtests, results);
+		if (fds[_F_JOURNAL] > 0)
+			fill_from_journal(fds[_F_JOURNAL], entry, &subtests, results);
 
 		if (!fill_from_output(fds[_F_OUT], entry->binary, "out", &subtests, results->tests) ||
 		    !fill_from_output(fds[_F_ERR], entry->binary, "err", &subtests, results->tests)) {
 			fprintf(stderr, "Error parsing output files (out.txt, err.txt)\n");
-			status = false;
-			goto parse_output_end;
 		}
 	}
 
 	if (!fill_from_dmesg(fds[_F_DMESG], settings, entry->binary, &subtests, results->tests)) {
 		fprintf(stderr, "Error parsing output files (dmesg.txt)\n");
-		status = false;
-		goto parse_output_end;
 	}
 
 	override_results(entry->binary, &subtests, results->tests);
@@ -2221,11 +2230,10 @@ static bool parse_test_directory(int dirfd,
 
 	add_to_totals(entry->binary, &subtests, results);
 
- parse_output_end:
 	close_outputs(fds);
 	free_subtests(&subtests);
 
-	return status;
+	return true;
 }
 
 static void try_add_notrun_results(const struct job_list_entry *entry,
@@ -2359,14 +2367,21 @@ struct json_object *generate_results_json(int dirfd)
 		char name[16];
 
 		snprintf(name, 16, "%zd", i);
+		fprintf(stderr, "results: parsing output: %s/ for test: %s\n",
+			name, job_list.entries[i].binary);
 		if ((testdirfd = openat(dirfd, name, O_DIRECTORY | O_RDONLY)) < 0) {
+			if (settings.log_level >= LOG_LEVEL_NORMAL)
+				fprintf(stderr, "results: no output, setting notrun\n)");
+
 			try_add_notrun_results(&job_list.entries[i], &settings, &results);
 			continue;
 		}
 
 		if (!parse_test_directory(testdirfd, &job_list.entries[i], &settings, &results)) {
-			close(testdirfd);
-			return NULL;
+			if (settings.log_level >= LOG_LEVEL_NORMAL)
+				fprintf(stderr, "results: no useful output, setting notrun\n");
+
+			try_add_notrun_results(&job_list.entries[i], &settings, &results);
 		}
 		close(testdirfd);
 	}
-- 
2.48.1


             reply	other threads:[~2025-02-26 19:33 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-26 19:33 Kamil Konieczny [this message]
2025-02-27 16:37 ` [PATCH i-g-t] runner: Parse results harder Knop, Ryszard
2025-02-28 17:08   ` Kamil Konieczny
2025-02-28  0:49 ` ✓ Xe.CI.BAT: success for " Patchwork
2025-02-28  1:06 ` ✓ i915.CI.BAT: " Patchwork
2025-02-28  5:21 ` ✗ Xe.CI.Full: failure " Patchwork
2025-02-28 15:52   ` Kamil Konieczny
2025-02-28 10:59 ` ✗ i915.CI.Full: " Patchwork
2025-02-28 15:53   ` Kamil Konieczny
  -- strict thread matches above, loose matches on Subject: below --
2025-02-28 17:15 [PATCH i-g-t] " Kamil Konieczny
2025-03-03 11:02 ` Krzysztof Karas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250226193328.132817-1-kamil.konieczny@linux.intel.com \
    --to=kamil.konieczny@linux.intel.com \
    --cc=adrinael@adrinael.net \
    --cc=ewelina.musial@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=lucas.demarchi@intel.com \
    --cc=ryszard.knop@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox