Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Apr 2024 18:36:26 GMT
From:      Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= <des@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 83a6e984ac01 - main - tftpd: Check the server status after each test.
Message-ID:  <202404251836.43PIaQYn032872@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=83a6e984ac01657819418746f722163367ec30db

commit 83a6e984ac01657819418746f722163367ec30db
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2024-04-25 18:35:24 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2024-04-25 18:36:13 +0000

    tftpd: Check the server status after each test.
    
    * In the setup phase, wait for the server to start (or fail to start)
      before proceeding with the test.  This makes it possible to write test
      cases that don't expect a response from the server without ending up
      in a race over the server PID file.
    * After running each test, wait up to 30 seconds for the server to exit
      and check that the exit status matches what the test case says to
      expect (usually 0).
    * We still kill and collect the server in the cleanup phase, in case the
      test ended early.
    
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    Reviewed by:    kevans
    Differential Revision:  https://reviews.freebsd.org/D44956
---
 libexec/tftpd/tests/functional.c | 44 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/libexec/tftpd/tests/functional.c b/libexec/tftpd/tests/functional.c
index bbe4f3782192..3b70962854ba 100644
--- a/libexec/tftpd/tests/functional.c
+++ b/libexec/tftpd/tests/functional.c
@@ -208,11 +208,14 @@ ATF_TC_HEAD(name ## _v4, tc)						\
 }									\
 ATF_TC_BODY(name ## _v4, tc)						\
 {									\
+	int exitcode = 0;						\
 	__VA_ARGS__;							\
 	protocol = AF_INET;						\
 	s = setup(&addr, __COUNTER__);					\
 	name ## _body();						\
 	close(s);							\
+	if (exitcode >= 0)						\
+		check_server(exitcode);					\
 }									\
 ATF_TC_CLEANUP(name ## _v4, tc)						\
 {									\
@@ -225,11 +228,14 @@ ATF_TC_HEAD(name ## _v6, tc)						\
 }									\
 ATF_TC_BODY(name ## _v6, tc)						\
 {									\
+	int exitcode = 0;						\
 	__VA_ARGS__;							\
 	protocol = AF_INET6;						\
 	s = setup(&addr, __COUNTER__);					\
 	name ## _body();						\
 	close(s);							\
+	if (exitcode >= 0)						\
+		check_server(exitcode);					\
 }									\
 ATF_TC_CLEANUP(name ## _v6, tc)						\
 {									\
@@ -244,6 +250,33 @@ name ## _body(void)
 	ATF_TP_ADD_TC(tp, name ## _v6);					\
 } while (0)
 
+static void
+sigalrm(int signo __unused)
+{
+}
+
+/* Check that server exits with specific exit code */
+static void
+check_server(int exitcode)
+{
+	struct sigaction sa = { .sa_handler = sigalrm };
+	struct itimerval it = { .it_value = { .tv_sec = 30 } };
+	FILE *f;
+	pid_t pid;
+	int wstatus;
+
+	f = fopen(pidfile, "r");
+	ATF_REQUIRE(f != NULL);
+	ATF_REQUIRE_INTEQ(1, fscanf(f, "%d", &pid));
+	ATF_CHECK_INTEQ(0, fclose(f));
+	ATF_REQUIRE_INTEQ(0, sigaction(SIGALRM, &sa, NULL));
+	ATF_REQUIRE_EQ(0, setitimer(ITIMER_REAL, &it, NULL));
+	ATF_REQUIRE_EQ(pid, waitpid(pid, &wstatus, 0));
+	ATF_CHECK(WIFEXITED(wstatus));
+	ATF_CHECK_INTEQ(exitcode, WEXITSTATUS(wstatus));
+	unlink(pidfile);
+}
+
 /* Standard cleanup used by all testcases */
 static void
 cleanup(void)
@@ -254,12 +287,12 @@ cleanup(void)
 	f = fopen(pidfile, "r");
 	if (f == NULL)
 		return;
+	unlink(pidfile);
 	if (fscanf(f, "%d", &pid) == 1) {
 		kill(pid, SIGTERM);
 		waitpid(pid, NULL, 0);
 	}
 	fclose(f);
-	unlink(pidfile);
 }
 
 /* Assert that two binary buffers are identical */
@@ -299,6 +332,9 @@ setup(struct sockaddr_storage *to, uint16_t idx)
 	struct pidfh *pfh;
 	uint16_t port = BASEPORT + idx;
 	socklen_t len;
+	int pd[2];
+
+	ATF_REQUIRE_EQ(0, pipe2(pd, O_CLOEXEC));
 
 	if (protocol == PF_INET) {
 		len = sizeof(addr4);
@@ -358,6 +394,10 @@ setup(struct sockaddr_storage *to, uint16_t idx)
 		break;
 	default:
 		/* In parent */
+		ATF_REQUIRE_INTEQ(0, close(pd[1]));
+		/* block until other end is closed on exec() or exit() */
+		ATF_REQUIRE_INTEQ(0, read(pd[0], &pd[1], sizeof(pd[1])));
+		ATF_REQUIRE_INTEQ(0, close(pd[0]));
 		bzero(to, sizeof(*to));
 		if (protocol == PF_INET) {
 			struct sockaddr_in *to4 = (struct sockaddr_in *)to;
@@ -374,7 +414,7 @@ setup(struct sockaddr_storage *to, uint16_t idx)
 			to6->sin6_addr = loopback;
 		}
 
-		close(server_s);
+		ATF_REQUIRE_INTEQ(0, close(server_s));
 		ATF_REQUIRE((client_s = socket(protocol, SOCK_DGRAM, 0)) > 0);
 		break;
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202404251836.43PIaQYn032872>