------------------------------------------------------------
revno: 1381
committer: James Hunt <[email protected]>
branch nick: upstart
timestamp: Mon 2012-10-22 14:54:50 +0100
message:
  * init/parse_job.c: stanza_kill(): Actually save parsed
    value to avoid crash if kill signal given as a numeric
    (LP: #1049820).
  * init/tests/test_parse_job.c: test_stanza_kill(): New test:
    "with signal and single numeric argument".
  * init/Makefile.am: test_job_process must now be linked to the
  * 'util'
    library for pty helper functionality.
  * init/tests/test_job_process.c:
    - Compiler appeasement.
    - Conditionally run tests in a pty for build environments such as
      modern versions of sbuild(1) that do not provide a controlling
      terminal (sbuild) (LP: #888910).
modified:
  ChangeLog
  init/Makefile.am
  init/tests/test_job_process.c


--
lp:upstart
https://code.launchpad.net/~upstart-devel/upstart/trunk

Your team Upstart Reviewers is subscribed to branch lp:upstart.
To unsubscribe from this branch go to 
https://code.launchpad.net/~upstart-devel/upstart/trunk/+edit-subscription
=== modified file 'ChangeLog'
--- ChangeLog	2012-10-22 13:29:45 +0000
+++ ChangeLog	2012-10-22 13:54:50 +0000
@@ -5,6 +5,13 @@
 	  (LP: #1049820).
 	* init/tests/test_parse_job.c: test_stanza_kill(): New test:
 	  "with signal and single numeric argument".
+	* init/Makefile.am: test_job_process must now be linked to the 'util'
+	  library for pty helper functionality.
+	* init/tests/test_job_process.c:
+	  - Compiler appeasement.
+	  - Conditionally run tests in a pty for build environments such as
+	    modern versions of sbuild(1) that do not provide a controlling
+	    terminal (sbuild) (LP: #888910).
 
 2012-08-31  Steve Langasek  <[email protected]>
 

=== modified file 'init/Makefile.am'
--- init/Makefile.am	2011-12-09 14:07:11 +0000
+++ init/Makefile.am	2012-10-22 13:54:50 +0000
@@ -190,7 +190,8 @@
 	com.ubuntu.Upstart.Job.o com.ubuntu.Upstart.Instance.o \
 	$(NIH_LIBS) \
 	$(NIH_DBUS_LIBS) \
-	$(DBUS_LIBS)
+	$(DBUS_LIBS) \
+	-lutil
 
 test_job_SOURCES = tests/test_job.c
 test_job_LDADD = \

=== modified file 'init/tests/test_job_process.c'
--- init/tests/test_job_process.c	2012-03-16 21:02:13 +0000
+++ init/tests/test_job_process.c	2012-10-22 13:54:50 +0000
@@ -32,6 +32,7 @@
 
 #include <time.h>
 #include <stdio.h>
+#include <pty.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,6 +52,7 @@
 #include <nih/io.h>
 #include <nih/main.h>
 #include <nih/error.h>
+#include <nih/logging.h>
 
 #include "job_process.h"
 #include "job.h"
@@ -3661,7 +3663,7 @@
 	TEST_EQ (kill (pid, 0), 0);
 
 	{
-		size_t  bytes;
+		size_t  bytes = 0;
 		size_t  expected_bytes = TEST_BLOCKSIZE * EXPECTED_1K_BLOCKS;
 		off_t   filesize = (off_t)-1;
 
@@ -5314,7 +5316,7 @@
 	Job *           job = NULL;
 	Blocked *       blocked = NULL;
 	Event *         event;
-	Event *         bevent;
+	Event *         bevent = NULL;
 	FILE *          output;
 	int             exitcodes[2] = { 100, SIGINT << 8 };
 	int             status;
@@ -8855,6 +8857,174 @@
 	}
 }
 
+void
+run_tests (void)
+{
+	test_run ();
+	test_spawn ();
+	test_log_path ();
+	test_kill ();
+	test_handler ();
+	test_utmp ();
+	test_find ();
+}
+
+/**
+ * io_reader:
+ *
+ * Write data received from child end of pty to stdout and
+ * update the NihIo to reflect the consumed data.
+ *
+ * We could detect and replace the "\r\n" line-end combo added by the
+ * pty line-discipline with a simple '\n', but for now lets leave the
+ * data verbatim so it's clear from the log when pty usage kicks in.
+ **/
+static void
+io_reader (void       *data,
+	   NihIo      *io, 
+	   const char *str,
+	   size_t      len)
+{
+	ssize_t bytes;
+
+	nih_assert (io);
+	nih_assert (str);
+	nih_assert (len);
+
+	bytes = write (STDOUT_FILENO, str, len);
+	TEST_NE (bytes, -1);
+
+	/* consume */
+	nih_io_buffer_shrink (io->recv_buf, bytes);
+}
+
+/**
+ * io_error_handler:
+ *
+ * Deal with errors from child end of pty.
+ **/
+static void
+io_error_handler (void   *data,
+	   	  NihIo  *io)
+{
+	NihError *err;
+
+	nih_assert (io);
+
+	/* Consume */
+	err = nih_error_get ();        
+
+	/* error that's returned when child closes their end of a pty */
+	nih_assert (err->number == EIO);
+
+	nih_free (err);
+
+	nih_free (io);
+	nih_main_loop_exit (EXIT_SUCCESS);
+}
+
+/**
+ * run_tests_in_pty:
+ *
+ * Create a pty and run tests in child process. Parent echoes childs
+ * output.
+ *
+ * This shouldn't be required but for the fact that Upstart needs to
+ * be able to run its test suite even in environments which
+ * don't provide a controlling terminal (such as modern versions of
+ * sbuild).
+ *
+ * See the following for the gory details:
+ *
+ *   - LP: #888910
+ *   - Debian Bug:607844
+ **/
+void
+run_tests_in_pty (void)
+{
+	pid_t             pid;
+	int               pty_master;
+	int               pty_slave;
+	nih_local NihIo  *io = NULL;
+	int               ret;
+	int               status;
+	int               exit_status = 0;
+
+	ret = openpty (&pty_master, &pty_slave, NULL, NULL, NULL);
+	TEST_NE (ret, -1);
+
+	pid = fork ();
+	TEST_NE (pid, (pid_t)-1);
+
+	if (! pid) {
+		int   i;
+		pid_t self;
+
+		/* child */
+		close (pty_master);
+
+		self = getpid ();
+
+		/* Ensure that the child is the process group leader
+		 * such that is responds correctly to SIGTSTP.
+		 */
+		TEST_EQ (setpgid (self, self), 0);
+
+		/* connect standard streams to the child end of the pty */
+		for (i = 0; i < 3; i++)
+			while (dup2(pty_slave, i) == -1 && errno == EBUSY)
+				;
+
+		/* clean up */
+		close (pty_slave);
+
+		/* run tests within the pty */
+		run_tests ();
+
+		exit (EXIT_SUCCESS);
+	}
+
+	/* parent */
+
+	close (pty_slave);
+
+	io = nih_io_reopen (NULL, pty_master,
+			NIH_IO_STREAM,
+			io_reader, NULL,
+			io_error_handler, NULL);
+	TEST_NE_P (io, NULL);
+
+	/* wait for child to finish */
+	TEST_EQ (waitpid (pid, &status, 0), pid);
+
+	/* catch exit status if it failed and return it via parent */
+	exit_status = WIFEXITED (status) ? WEXITSTATUS (status) :
+		      WIFSIGNALED (status) ? WTERMSIG (status) :
+		      WIFSTOPPED (status) ?  WSTOPSIG (status) :
+		      EXIT_FAILURE;
+
+	ret = nih_main_loop ();
+	exit (exit_status ? exit_status : ret);
+}
+
+/**
+ * have_ctty:
+ *
+ * Returns: TRUE if we have a controlling terminal,
+ * else FALSE.
+ **/
+int
+have_ctty (void)
+{
+	int fd;
+
+	fd = open ("/dev/tty", O_RDONLY | O_NOCTTY);
+
+	if (fd < 0)
+		return FALSE;
+	close (fd);
+	return TRUE;
+}
 
 int
 main (int   argc,
@@ -8915,14 +9085,16 @@
 	nih_error_init ();
 	nih_io_init ();
 
-	/* Otherwise run the tests as normal */
-	test_run ();
-	test_spawn ();
-	test_log_path ();
-	test_kill ();
-	test_handler ();
-	test_utmp ();
-	test_find ();
+	if (! have_ctty ()) {
+		fprintf (stderr,
+				"\n\n"
+				"INFO: Running tests in pty since environment "
+				"does not provide needed controlling terminal\n"
+				"\n\n");
+		run_tests_in_pty ();
+	} else {
+		run_tests ();
+	}
 
 	return 0;
 }

-- 
upstart-devel mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/upstart-devel

Reply via email to