diff --git a/tests/wait-for-child-processes.c b/tests/wait-for-child-processes.c
index f99606b5bbe9adf63f7a758fbded99415f10f4cf..f00c88c241fe267d1f267d805bbc18c66771b64d 100644
--- a/tests/wait-for-child-processes.c
+++ b/tests/wait-for-child-processes.c
@@ -24,6 +24,9 @@
  */
 
 #include <stdlib.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <unistd.h>
 
 #include <glib.h>
@@ -50,6 +53,9 @@ setup (Fixture *f,
        gconstpointer context)
 {
   G_GNUC_UNUSED const Config *config = context;
+
+  /* Assert we initially have no child processes */
+  g_assert_cmpint (waitpid (-1, NULL, WNOHANG) >= 0 ? 0 : errno, ==, ECHILD);
 }
 
 static void
@@ -57,6 +63,9 @@ teardown (Fixture *f,
           gconstpointer context)
 {
   G_GNUC_UNUSED const Config *config = context;
+
+  /* Assert we end up with no child processes */
+  g_assert_cmpint (waitpid (-1, NULL, WNOHANG) >= 0 ? 0 : errno, ==, ECHILD);
 }
 
 #define SPAWN_FLAGS \
@@ -64,6 +73,108 @@ teardown (Fixture *f,
    | G_SPAWN_LEAVE_DESCRIPTORS_OPEN \
    | G_SPAWN_DO_NOT_REAP_CHILD)
 
+static void
+test_terminate_nothing (Fixture *f,
+                        gconstpointer context)
+{
+  g_autoptr(GError) error = NULL;
+  gboolean ret;
+
+  ret = pv_terminate_all_child_processes (0, 0, &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+
+  ret = pv_terminate_all_child_processes (0, 100 * G_TIME_SPAN_MILLISECOND, &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+
+  ret = pv_terminate_all_child_processes (100 * G_TIME_SPAN_MILLISECOND, 0, &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+
+  ret = pv_terminate_all_child_processes (100 * G_TIME_SPAN_MILLISECOND,
+                                          100 * G_TIME_SPAN_MILLISECOND, &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+}
+
+static void
+test_terminate_sigterm (Fixture *f,
+                        gconstpointer context)
+{
+  g_autoptr(GError) error = NULL;
+  gboolean ret;
+  const char * const argv[] = { "sh", "-c", "sleep 3600", NULL };
+
+  ret = g_spawn_async (NULL,  /* cwd */
+                       (char **) argv,
+                       NULL,  /* envp */
+                       SPAWN_FLAGS,
+                       NULL, NULL,    /* child setup */
+                       NULL,  /* pid */
+                       &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+
+  ret = pv_terminate_all_child_processes (0, 60 * G_TIME_SPAN_SECOND, &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+}
+
+static void
+test_terminate_sigkill (Fixture *f,
+                        gconstpointer context)
+{
+  g_autoptr(GError) error = NULL;
+  gboolean ret;
+  const char * const argv[] =
+  {
+    "sh", "-c", "trap 'echo Ignoring SIGTERM >&2' TERM; sleep 3600", NULL
+  };
+
+  ret = g_spawn_async (NULL,  /* cwd */
+                       (char **) argv,
+                       NULL,  /* envp */
+                       SPAWN_FLAGS,
+                       NULL, NULL,    /* child setup */
+                       NULL,  /* pid */
+                       &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+
+  /* We give it 100ms before SIGTERM to let it put the trap in place */
+  ret = pv_terminate_all_child_processes (100 * G_TIME_SPAN_MILLISECOND,
+                                          100 * G_TIME_SPAN_MILLISECOND, &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+}
+
+static void
+test_terminate_sigkill_immediately (Fixture *f,
+                                    gconstpointer context)
+{
+  g_autoptr(GError) error = NULL;
+  gboolean ret;
+  const char * const argv[] =
+  {
+    "sh", "-c", "trap 'echo Ignoring SIGTERM >&2' TERM; sleep 3600", NULL
+  };
+
+  ret = g_spawn_async (NULL,  /* cwd */
+                       (char **) argv,
+                       NULL,  /* envp */
+                       SPAWN_FLAGS,
+                       NULL, NULL,    /* child setup */
+                       NULL,  /* pid */
+                       &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+
+  ret = pv_terminate_all_child_processes (0, 0, &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
+}
+
 static void
 test_wait_for_all (Fixture *f,
                    gconstpointer context)
@@ -163,6 +274,11 @@ test_wait_for_main_plus (Fixture *f,
   g_assert_true (ret);
   g_assert_true (WIFSIGNALED (wstat));
   g_assert_cmpint (WTERMSIG (wstat), ==, SIGTERM);
+
+  /* Don't leak the other processes, if any (probably after_argv) */
+  ret = pv_wait_for_child_processes (0, &wstat, &error);
+  g_assert_no_error (error);
+  g_assert_true (ret);
 }
 
 static void
@@ -197,9 +313,27 @@ int
 main (int argc,
       char **argv)
 {
+  sigset_t mask;
+
+  sigemptyset (&mask);
+  sigaddset (&mask, SIGCHLD);
+
+  /* Must be called before we start any threads */
+  if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
+    g_error ("pthread_sigmask: %s", g_strerror (errno));
+
+  prctl (PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
   pv_avoid_gvfs ();
 
   g_test_init (&argc, &argv, NULL);
+  g_test_add ("/terminate/nothing", Fixture, NULL,
+              setup, test_terminate_nothing, teardown);
+  g_test_add ("/terminate/sigterm", Fixture, NULL,
+              setup, test_terminate_sigterm, teardown);
+  g_test_add ("/terminate/sigkill", Fixture, NULL,
+              setup, test_terminate_sigkill, teardown);
+  g_test_add ("/terminate/sigkill-immediately", Fixture, NULL,
+              setup, test_terminate_sigkill_immediately, teardown);
   g_test_add ("/wait/for-all", Fixture, NULL,
               setup, test_wait_for_all, teardown);
   g_test_add ("/wait/for-main", Fixture, NULL,