]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: test-smtp-payload - Use the new sub-process test API.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Sun, 5 Apr 2020 00:40:33 +0000 (02:40 +0200)
committerStephan Bosch <stephan.bosch@open-xchange.com>
Mon, 25 May 2020 15:29:02 +0000 (17:29 +0200)
This makes an effort to terminate server processes gracefully. Killing them
bluntly hampers test coverage measurement and valgrind testing.

src/lib-smtp/test-smtp-payload.c

index 975286f214dd601a5efb02fe5086fcbdbd889360..dc8f1a476ef8a9f2a358095d8af95134b4c29cc0 100644 (file)
@@ -1,7 +1,6 @@
 /* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
-#include "lib-signals.h"
 #include "str.h"
 #include "llist.h"
 #include "array.h"
@@ -20,6 +19,7 @@
 #endif
 #include "connection.h"
 #include "test-common.h"
+#include "test-subprocess.h"
 #include "smtp-server.h"
 #include "smtp-client.h"
 #include "smtp-client-connection.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/wait.h>
-#include <signal.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <dirent.h>
 
 #define CLIENT_PROGRESS_TIMEOUT     30
+#define SERVER_KILL_TIMEOUT_SECS    20
 #define MAX_PARALLEL_PENDING        200
 
 static bool debug = FALSE;
@@ -53,7 +52,8 @@ static enum test_ssl_mode test_ssl_mode = TEST_SSL_MODE_NONE;
 static struct ip_addr bind_ip;
 static in_port_t bind_port = 0;
 static int fd_listen = -1;
-static pid_t server_pid = (pid_t)-1;
+
+static void main_deinit(void);
 
 /*
  * Test files
@@ -842,6 +842,10 @@ static void test_client_deinit(void)
  * Tests
  */
 
+struct test_server_data {
+       const struct smtp_server_settings *set;
+};
+
 static void test_open_server_fd(void)
 {
        if (fd_listen != -1)
@@ -854,17 +858,9 @@ static void test_open_server_fd(void)
        net_set_nonblock(fd_listen, TRUE);
 }
 
-static void test_server_kill_forced(void)
-{
-       if (server_pid != (pid_t)-1) {
-               (void)kill(server_pid, SIGKILL);
-               (void)waitpid(server_pid, NULL, 0);
-       }
-       server_pid = (pid_t)-1;
-}
-
-static void test_run_server(struct smtp_server_settings *server_set)
+static int test_run_server(struct test_server_data *data)
 {
+       const struct smtp_server_settings *server_set = data->set;
        struct ioloop *ioloop;
 
        i_set_failure_prefix("SERVER: ");
@@ -883,6 +879,8 @@ static void test_run_server(struct smtp_server_settings *server_set)
 
        i_close_fd(&fd_listen);
        test_files_deinit();
+       main_deinit();
+       return 0;
 }
 
 static void
@@ -904,6 +902,9 @@ test_run_client(
        io_loop_run(ioloop);
        test_client_deinit();
        io_loop_destroy(&ioloop);
+
+       if (debug)
+               i_debug("Terminated");
 }
 
 static void
@@ -914,39 +915,29 @@ test_run_client_server(
        void (*client_init)(enum smtp_protocol protocol,
                            const struct smtp_client_settings *client_set))
 {
+       struct test_server_data data;
+
        if (test_ssl_mode == TEST_SSL_MODE_STARTTLS)
                server_set->capabilities |= SMTP_CAPABILITY_STARTTLS;
 
        failure = NULL;
-       test_open_server_fd();
-
-       test_files_init();
-
-       lib_signals_ioloop_detach();
 
-       if ((server_pid = fork()) == (pid_t)-1)
-               i_fatal("fork() failed: %m");
-       if (server_pid == 0) {
-               server_pid = (pid_t)-1;
-               hostpid_init();
-               lib_signals_deinit();
+       i_zero(&data);
+       data.set = server_set;
 
-               /* child: server */
-               test_run_server(server_set);
+       test_files_init();
 
-               lib_deinit();
-               exit(1);
-       }
+       /* Fork server */
+       test_open_server_fd();
+       test_subprocess_fork(test_run_server, &data, FALSE);
        i_close_fd(&fd_listen);
 
-       lib_signals_ioloop_attach();
-
-       /* parent: client */
+       /* Run client */
        test_run_client(protocol, client_set, client_init);
 
        i_unset_failure_prefix();
        bind_port = 0;
-       test_server_kill_forced();
+       test_subprocess_kill_all(SERVER_KILL_TIMEOUT_SECS);
        test_files_deinit();
 }
 
@@ -1101,42 +1092,11 @@ static void (*const test_functions[])(void) = {
  * Main
  */
 
-volatile sig_atomic_t terminating = 0;
-
-static void test_signal_handler(const siginfo_t *si, void *context ATTR_UNUSED)
-{
-       int signo = si->si_signo;
-
-       if (terminating != 0)
-               raise(signo);
-       terminating = 1;
-
-       /* make sure we don't leave any pesky children alive */
-       test_server_kill_forced();
-
-       (void)signal(signo, SIG_DFL);
-       raise(signo);
-}
-
-static void test_atexit(void)
-{
-       test_server_kill_forced();
-}
-
 static void main_init(void)
 {
-       lib_signals_init();
 #ifdef HAVE_OPENSSL
        ssl_iostream_openssl_init();
 #endif
-
-       atexit(test_atexit);
-       lib_signals_ignore(SIGPIPE, TRUE);
-       lib_signals_set_handler(SIGTERM, 0, test_signal_handler, NULL);
-       lib_signals_set_handler(SIGQUIT, 0, test_signal_handler, NULL);
-       lib_signals_set_handler(SIGINT, 0, test_signal_handler, NULL);
-       lib_signals_set_handler(SIGSEGV, 0, test_signal_handler, NULL);
-       lib_signals_set_handler(SIGABRT, 0, test_signal_handler, NULL);
 }
 
 static void main_deinit(void)
@@ -1145,7 +1105,6 @@ static void main_deinit(void)
 #ifdef HAVE_OPENSSL
        ssl_iostream_openssl_deinit();
 #endif
-       lib_signals_deinit();
 }
 
 int main(int argc, char *argv[])
@@ -1169,6 +1128,8 @@ int main(int argc, char *argv[])
                }
        }
 
+       test_subprocesses_init(debug);
+
        /* listen on localhost */
        i_zero(&bind_ip);
        bind_ip.family = AF_INET;
@@ -1176,6 +1137,7 @@ int main(int argc, char *argv[])
 
        ret = test_run(test_functions);
 
+       test_subprocesses_deinit();
        main_deinit();
        lib_deinit();