misc: Add new test for daemon
Checks
Context |
Check |
Description |
redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
fail
|
Test failed
|
linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-arm |
fail
|
Test failed
|
Commit Message
This commit adds a new testcase for the daemon function.
---
The dev_null_redir function may be too linux specific. Not sure about
a better way to do it.
---
misc/Makefile | 1 +
misc/tst-daemon.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 156 insertions(+)
create mode 100644 misc/tst-daemon.c
Comments
On 27/06/24 13:20, Martin Cermak wrote:
> This commit adds a new testcase for the daemon function.
> ---
> The dev_null_redir function may be too linux specific. Not sure about
> a better way to do it.
This new tests has failed for some reason on aarch64/armhf buildbot [1][2].
The log does not show much information though [2]
FAIL: misc/tst-daemon
original exit status 127
Usually '127' means a SEGFAULT.
[1] https://patchwork.sourceware.org/project/glibc/patch/20240627162005.407679-1-mcermak@redhat.com/
[2] https://ci.linaro.org/job/tcwg_glibc_check--master-aarch64-precommit/2000/artifact/artifacts/artifacts.precommit/00-sumfiles/
> ---
> misc/Makefile | 1 +
> misc/tst-daemon.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 156 insertions(+)
> create mode 100644 misc/tst-daemon.c
>
> diff --git a/misc/Makefile b/misc/Makefile
> index c273ec6974..7313f9122d 100644
> --- a/misc/Makefile
> +++ b/misc/Makefile
> @@ -232,6 +232,7 @@ gpl2lgpl := \
> tests := \
> bug-hsearch1 \
> bug18240 \
> + tst-daemon \
> tst-dbl-efgcvt \
> tst-dirname \
> tst-empty \
> diff --git a/misc/tst-daemon.c b/misc/tst-daemon.c
> new file mode 100644
> index 0000000000..9ab72781e1
> --- /dev/null
> +++ b/misc/tst-daemon.c
> @@ -0,0 +1,155 @@
> +/* Tests for daemon.
> + Copyright (C) 2024 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <errno.h>
> +#include <error.h>
> +#include <stdlib.h>
> +#include <wait.h>
> +#include <support/check.h>
> +#include <string.h>
> +#include <stdio.h>
> +
> +/* Define pipe communication encoding. */
> +#define STATUS_PASS 'p'
> +#define STATUS_FAIL 'f'
> +
> +/* Check if given file descriptor is redirected to /dev/null. */
> +unsigned char
> +dev_null_redir (FILE * f)
> +{
> + char b1[1024];
> + char b2[1024];
> + ssize_t len;
> +
> + int fd = fileno (f);
> +
> + len = snprintf (b1, sizeof (b1), "/proc/self/fd/%d", fd);
> + if (len < 0 || len >= sizeof (b1))
> + return 1;
> +
> + len = readlink (b1, b2, sizeof (b2) - 1);
> + if (len < 0)
> + return 1;
> +
> + b2[len] = '\0';
> +
> + if (strcmp (b2, "/dev/null") != 0)
> + return 1;
> +
> + return 0;
> +}
> +
> +/* Run one daemon test with specified parameters. */
> +void
> +test_daemon (int nochdir, int noclose)
> +{
> + pid_t pid;
> + int status;
> + int pipefd[2];
> + char buf;
> +
> + if (pipe (pipefd) == -1)
> + error (EXIT_FAILURE, errno, "failed to create the pipe");
> +
> + pid = fork ();
> + if (pid == 0)
> + {
> + /* This is the child. */
> + char cwd[1024];
> + char origcwd[1024];
> + char retval = STATUS_PASS;
> +
> + getcwd (origcwd, sizeof (origcwd));
> +
> + /* Daemonize the child. */
> + if (daemon (nochdir, noclose) != 0)
> + retval = STATUS_FAIL;
> +
> + switch (nochdir)
> + {
> + case 0:
> + getcwd (cwd, sizeof (cwd));
> + if (strcmp (cwd, "/") != 0)
> + retval = STATUS_FAIL;
> + break;
> + default:
> + getcwd (cwd, sizeof (cwd));
> + if (strcmp (cwd, origcwd) != 0)
> + retval = STATUS_FAIL;
> + }
> +
> + switch (noclose)
> + {
> + case 0:
> + if (dev_null_redir (stdin) != 0)
> + retval = STATUS_FAIL;
> + if (dev_null_redir (stdout) != 0)
> + retval = STATUS_FAIL;
> + if (dev_null_redir (stderr) != 0)
> + retval = STATUS_FAIL;
> + break;
> + default:
> + if (dev_null_redir (stdin) != 1)
> + retval = STATUS_FAIL;
> + if (dev_null_redir (stdout) != 1)
> + retval = STATUS_FAIL;
> + if (dev_null_redir (stderr) != 1)
> + retval = STATUS_FAIL;
> + }
> +
> + /* Report test result to the parent. */
> + close (pipefd[0]);
> + write (pipefd[1], &retval, 1);
> + close (pipefd[1]);
> +
> + _exit (0);
> + }
> + else if (pid < 0)
> + /* Something went wrong. */
> + error (EXIT_FAILURE, errno, "cannot fork");
> +
> + /* This is the parent. */
> + if (waitpid (pid, &status, 0) != pid)
> + error (EXIT_FAILURE, 0, "oops, wrong test program terminated");
> +
> + if (WTERMSIG (status) != 0)
> + error (EXIT_FAILURE, 0, "child terminated incorrectly");
> + status = WEXITSTATUS (status);
> +
> + /* Read test result from the daemon and report it. */
> + close (pipefd[1]);
> + if (read (pipefd[0], &buf, 1) != 1)
> + error (EXIT_FAILURE, 0, "failed reading daemon status");
> + close (pipefd[0]);
> + TEST_VERIFY_EXIT (buf == STATUS_PASS);
> +}
> +
> +
> +int
> +do_test (void)
> +{
> + /* Run daemon tests with various parameters. */
> + test_daemon (0, 0);
> + test_daemon (1, 0);
> + test_daemon (0, 1);
> + test_daemon (1, 1);
> +
> + return 0;
> +}
> +
> +#include <support/test-driver.c>
@@ -232,6 +232,7 @@ gpl2lgpl := \
tests := \
bug-hsearch1 \
bug18240 \
+ tst-daemon \
tst-dbl-efgcvt \
tst-dirname \
tst-empty \
new file mode 100644
@@ -0,0 +1,155 @@
+/* Tests for daemon.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <error.h>
+#include <stdlib.h>
+#include <wait.h>
+#include <support/check.h>
+#include <string.h>
+#include <stdio.h>
+
+/* Define pipe communication encoding. */
+#define STATUS_PASS 'p'
+#define STATUS_FAIL 'f'
+
+/* Check if given file descriptor is redirected to /dev/null. */
+unsigned char
+dev_null_redir (FILE * f)
+{
+ char b1[1024];
+ char b2[1024];
+ ssize_t len;
+
+ int fd = fileno (f);
+
+ len = snprintf (b1, sizeof (b1), "/proc/self/fd/%d", fd);
+ if (len < 0 || len >= sizeof (b1))
+ return 1;
+
+ len = readlink (b1, b2, sizeof (b2) - 1);
+ if (len < 0)
+ return 1;
+
+ b2[len] = '\0';
+
+ if (strcmp (b2, "/dev/null") != 0)
+ return 1;
+
+ return 0;
+}
+
+/* Run one daemon test with specified parameters. */
+void
+test_daemon (int nochdir, int noclose)
+{
+ pid_t pid;
+ int status;
+ int pipefd[2];
+ char buf;
+
+ if (pipe (pipefd) == -1)
+ error (EXIT_FAILURE, errno, "failed to create the pipe");
+
+ pid = fork ();
+ if (pid == 0)
+ {
+ /* This is the child. */
+ char cwd[1024];
+ char origcwd[1024];
+ char retval = STATUS_PASS;
+
+ getcwd (origcwd, sizeof (origcwd));
+
+ /* Daemonize the child. */
+ if (daemon (nochdir, noclose) != 0)
+ retval = STATUS_FAIL;
+
+ switch (nochdir)
+ {
+ case 0:
+ getcwd (cwd, sizeof (cwd));
+ if (strcmp (cwd, "/") != 0)
+ retval = STATUS_FAIL;
+ break;
+ default:
+ getcwd (cwd, sizeof (cwd));
+ if (strcmp (cwd, origcwd) != 0)
+ retval = STATUS_FAIL;
+ }
+
+ switch (noclose)
+ {
+ case 0:
+ if (dev_null_redir (stdin) != 0)
+ retval = STATUS_FAIL;
+ if (dev_null_redir (stdout) != 0)
+ retval = STATUS_FAIL;
+ if (dev_null_redir (stderr) != 0)
+ retval = STATUS_FAIL;
+ break;
+ default:
+ if (dev_null_redir (stdin) != 1)
+ retval = STATUS_FAIL;
+ if (dev_null_redir (stdout) != 1)
+ retval = STATUS_FAIL;
+ if (dev_null_redir (stderr) != 1)
+ retval = STATUS_FAIL;
+ }
+
+ /* Report test result to the parent. */
+ close (pipefd[0]);
+ write (pipefd[1], &retval, 1);
+ close (pipefd[1]);
+
+ _exit (0);
+ }
+ else if (pid < 0)
+ /* Something went wrong. */
+ error (EXIT_FAILURE, errno, "cannot fork");
+
+ /* This is the parent. */
+ if (waitpid (pid, &status, 0) != pid)
+ error (EXIT_FAILURE, 0, "oops, wrong test program terminated");
+
+ if (WTERMSIG (status) != 0)
+ error (EXIT_FAILURE, 0, "child terminated incorrectly");
+ status = WEXITSTATUS (status);
+
+ /* Read test result from the daemon and report it. */
+ close (pipefd[1]);
+ if (read (pipefd[0], &buf, 1) != 1)
+ error (EXIT_FAILURE, 0, "failed reading daemon status");
+ close (pipefd[0]);
+ TEST_VERIFY_EXIT (buf == STATUS_PASS);
+}
+
+
+int
+do_test (void)
+{
+ /* Run daemon tests with various parameters. */
+ test_daemon (0, 0);
+ test_daemon (1, 0);
+ test_daemon (0, 1);
+ test_daemon (1, 1);
+
+ return 0;
+}
+
+#include <support/test-driver.c>