[or-cvs] [tor/master 7/8] Add a unit test for tor_spawn_background

nickm at torproject.org nickm at torproject.org
Mon Oct 11 14:58:20 UTC 2010


Author: Steven Murdoch <Steven.Murdoch at cl.cam.ac.uk>
Date: Sun, 10 Oct 2010 18:12:23 +0100
Subject: Add a unit test for tor_spawn_background
Commit: 8a12ce2cf9bb6362e380e7efaee334d82cc3c7c8

- Test sucessfully starting a process
- Test failing to find the executable
---
 .gitignore            |    1 +
 src/common/util.c     |    2 +-
 src/common/util.h     |    2 +
 src/test/Makefile.am  |    2 +-
 src/test/test-child.c |   18 ++++++++++++
 src/test/test_util.c  |   73 +++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 src/test/test-child.c

diff --git a/.gitignore b/.gitignore
index 369d925..6a6c14e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -155,6 +155,7 @@
 /src/test/Makefile
 /src/test/Makefile.in
 /src/test/test
+/src/test/test-child
 
 
 # /src/tools/
diff --git a/src/common/util.c b/src/common/util.c
index 402cfbf..cddc8a9 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2973,7 +2973,7 @@ format_helper_exit_status(unsigned char child_state, int saved_errno,
  * -1.  Some parts of this code are based on the POSIX subprocess module from
  * Python.
  */
-static int
+int
 tor_spawn_background(const char *const filename, int *stdout_read,
                      int *stderr_read, const char **argv)
 {
diff --git a/src/common/util.h b/src/common/util.h
index 86555ee..8c2a9be 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -350,6 +350,8 @@ HANDLE load_windows_system_library(const TCHAR *library_name);
 
 #ifdef UTIL_PRIVATE
 /* Prototypes for private functions only used by util.c (and unit tests) */
+int tor_spawn_background(const char *const filename, int *stdout_read,
+                         int *stderr_read, const char **argv);
 void format_helper_exit_status(unsigned char child_state,
                                int saved_errno, char *hex_errno);
 
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index cfe330c..976c275 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -1,6 +1,6 @@
 TESTS = test
 
-noinst_PROGRAMS = test
+noinst_PROGRAMS = test test-child
 
 AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
         -DLOCALSTATEDIR="\"$(localstatedir)\"" \
diff --git a/src/test/test-child.c b/src/test/test-child.c
new file mode 100644
index 0000000..100e8c0
--- /dev/null
+++ b/src/test/test-child.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+/** Trivial test program which prints out its command line arguments so we can
+ * check if tor_spawn_background() works */
+int
+main(int argc, char **argv)
+{
+  int i;
+
+  fprintf(stdout, "OUT\n");
+  fprintf(stderr, "ERR\n");
+  for (i = 0; i < argc; i++)
+    fprintf(stdout, "%s\n", argv[i]);
+  fprintf(stdout, "DONE\n");
+
+  return 0;
+}
+
diff --git a/src/test/test_util.c b/src/test/test_util.c
index f2744ee..99b7587 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1334,6 +1334,77 @@ test_util_fgets_eagain(void *ptr)
 }
 #endif
 
+#ifndef MS_WINDOWS
+/** Helper function for testing tor_spawn_background */
+static void
+run_util_spawn_background(const char *argv[], const char *expected_out,
+                          const char *expected_err, int expected_exit)
+{
+  int stdout_pipe=-1, stderr_pipe=-1;
+  int retval, stat_loc;
+  pid_t pid;
+  ssize_t pos;
+  char stdout_buf[100], stderr_buf[100];
+
+  /* Start the program */
+  retval = tor_spawn_background(argv[0], &stdout_pipe, &stderr_pipe, argv);
+  tt_int_op(retval, >, 0);
+  tt_int_op(stdout_pipe, >, 0);
+  tt_int_op(stderr_pipe, >, 0);
+  pid = retval;
+
+  /* Check stdout */
+  pos = read(stdout_pipe, stdout_buf, sizeof(stdout_buf) - 1);
+  stdout_buf[pos] = '\0';
+  tt_int_op(pos, ==, strlen(expected_out));
+  tt_str_op(stdout_buf, ==, expected_out);
+
+  /* Check it terminated correctly */
+  retval = waitpid(pid, &stat_loc, 0);
+  tt_int_op(retval, ==, pid);
+  tt_assert(WIFEXITED(stat_loc));
+  tt_int_op(WEXITSTATUS(stat_loc), ==, expected_exit);
+  tt_assert(!WIFSIGNALED(stat_loc));
+  tt_assert(!WIFSTOPPED(stat_loc));
+
+  /* Check stderr */
+  pos = read(stderr_pipe, stderr_buf, sizeof(stderr_buf) - 1);
+  stderr_buf[pos] = '\0';
+  tt_int_op(pos, ==, strlen(expected_err));
+  tt_str_op(stderr_buf, ==, expected_err);
+
+ done:
+  ;
+}
+
+/** Check that we can launch a process and read the output */
+static void
+test_util_spawn_background_ok(void *ptr)
+{
+  const char *argv[] = {"src/test/test-child", "--test", NULL};
+  const char *expected_out = "OUT\nsrc/test/test-child\n--test\nDONE\n";
+  const char *expected_err = "ERR\n";
+
+  (void)ptr;
+
+  run_util_spawn_background(argv, expected_out, expected_err, 0);
+}
+
+/** Check that failing to find the executable works as expected */
+static void
+test_util_spawn_background_fail(void *ptr)
+{
+  const char *argv[] = {"src/test/no-such-file", "--test", NULL};
+  const char *expected_out = "ERR: Failed to spawn background process "
+                             "- code          9/2\n";
+  const char *expected_err = "";
+
+  (void)ptr;
+
+  run_util_spawn_background(argv, expected_out, expected_err, 255);
+}
+#endif
+
 #define UTIL_LEGACY(name)                                               \
   { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
 
@@ -1363,6 +1434,8 @@ struct testcase_t util_tests[] = {
   UTIL_TEST(exit_status, 0),
 #ifndef MS_WINDOWS
   UTIL_TEST(fgets_eagain, 0),
+  UTIL_TEST(spawn_background_ok, 0),
+  UTIL_TEST(spawn_background_fail, 0),
 #endif
   END_OF_TESTCASES
 };
-- 
1.7.1




More information about the tor-commits mailing list