1111 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
1212 * Portions Copyright (c) 1994, Regents of the University of California
1313 *
14- * $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.44 2008/03/31 01:31:43 tgl Exp $
14+ * $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.45 2008/05/17 20:02:01 tgl Exp $
1515 *
1616 *-------------------------------------------------------------------------
1717 */
@@ -1305,14 +1305,15 @@ results_differ(const char *testname, const char *resultsfile, const char *defaul
13051305}
13061306
13071307/*
1308- * Wait for specified subprocesses to finish
1308+ * Wait for specified subprocesses to finish, and return their exit
1309+ * statuses into statuses[]
13091310 *
1310- * If names isn't NULL,report each subprocess as it finishes
1311+ * If names isn't NULL,print each subprocess's name as it finishes
13111312 *
13121313 * Note: it's OK to scribble on the pids array, but not on the names array
13131314 */
13141315static void
1315- wait_for_tests (PID_TYPE * pids ,char * * names ,int num_tests )
1316+ wait_for_tests (PID_TYPE * pids , int * statuses ,char * * names ,int num_tests )
13161317{
13171318int tests_left ;
13181319int i ;
@@ -1327,9 +1328,10 @@ wait_for_tests(PID_TYPE * pids, char **names, int num_tests)
13271328while (tests_left > 0 )
13281329{
13291330PID_TYPE p ;
1331+ int exit_status ;
13301332
13311333#ifndef WIN32
1332- p = wait (NULL );
1334+ p = wait (& exit_status );
13331335
13341336if (p == INVALID_PID )
13351337{
@@ -1357,9 +1359,11 @@ wait_for_tests(PID_TYPE * pids, char **names, int num_tests)
13571359if (p == pids [i ])
13581360{
13591361#ifdef WIN32
1362+ GetExitCodeProcess (pids [i ],& exit_status );
13601363CloseHandle (pids [i ]);
13611364#endif
13621365pids [i ]= INVALID_PID ;
1366+ statuses [i ]= exit_status ;
13631367if (names )
13641368status (" %s" ,names [i ]);
13651369tests_left -- ;
@@ -1373,6 +1377,35 @@ wait_for_tests(PID_TYPE * pids, char **names, int num_tests)
13731377#endif
13741378}
13751379
1380+ /*
1381+ * report nonzero exit code from a test process
1382+ */
1383+ static void
1384+ log_child_failure (int exitstatus )
1385+ {
1386+ if (WIFEXITED (exitstatus ))
1387+ status (_ (" (test process exited with exit code %d)" ),
1388+ WEXITSTATUS (exitstatus ));
1389+ else if (WIFSIGNALED (exitstatus ))
1390+ {
1391+ #if defined(WIN32 )
1392+ status (_ (" (test process was terminated by exception 0x%X)" ),
1393+ WTERMSIG (exitstatus ));
1394+ #elif defined(HAVE_DECL_SYS_SIGLIST )&& HAVE_DECL_SYS_SIGLIST
1395+ status (_ (" (test process was terminated by signal %d: %s)" ),
1396+ WTERMSIG (exitstatus ),
1397+ WTERMSIG (exitstatus )< NSIG ?
1398+ sys_siglist [WTERMSIG (exitstatus )] :"(unknown))" );
1399+ #else
1400+ status (_ (" (test process was terminated by signal %d)" ),
1401+ WTERMSIG (exitstatus ));
1402+ #endif
1403+ }
1404+ else
1405+ status (_ (" (test process exited with unrecognized status %d)" ),
1406+ exitstatus );
1407+ }
1408+
13761409/*
13771410 * Run all the tests specified in one schedule file
13781411 */
@@ -1385,6 +1418,7 @@ run_schedule(const char *schedule, test_function tfunc)
13851418_stringlist * expectfiles [MAX_PARALLEL_TESTS ];
13861419_stringlist * tags [MAX_PARALLEL_TESTS ];
13871420PID_TYPE pids [MAX_PARALLEL_TESTS ];
1421+ int statuses [MAX_PARALLEL_TESTS ];
13881422_stringlist * ignorelist = NULL ;
13891423char scbuf [1024 ];
13901424FILE * scf ;
@@ -1486,7 +1520,7 @@ run_schedule(const char *schedule, test_function tfunc)
14861520{
14871521status (_ ("test %-20s ... " ),tests [0 ]);
14881522pids [0 ]= (tfunc ) (tests [0 ],& resultfiles [0 ],& expectfiles [0 ],& tags [0 ]);
1489- wait_for_tests (pids ,NULL ,1 );
1523+ wait_for_tests (pids ,statuses , NULL ,1 );
14901524/* status line is finished below */
14911525}
14921526else if (max_connections > 0 && max_connections < num_tests )
@@ -1499,12 +1533,14 @@ run_schedule(const char *schedule, test_function tfunc)
14991533{
15001534if (i - oldest >=max_connections )
15011535{
1502- wait_for_tests (pids + oldest ,tests + oldest ,i - oldest );
1536+ wait_for_tests (pids + oldest ,statuses + oldest ,
1537+ tests + oldest ,i - oldest );
15031538oldest = i ;
15041539}
15051540pids [i ]= (tfunc ) (tests [i ],& resultfiles [i ],& expectfiles [i ],& tags [i ]);
15061541}
1507- wait_for_tests (pids + oldest ,tests + oldest ,i - oldest );
1542+ wait_for_tests (pids + oldest ,statuses + oldest ,
1543+ tests + oldest ,i - oldest );
15081544status_end ();
15091545}
15101546else
@@ -1514,7 +1550,7 @@ run_schedule(const char *schedule, test_function tfunc)
15141550{
15151551pids [i ]= (tfunc ) (tests [i ],& resultfiles [i ],& expectfiles [i ],& tags [i ]);
15161552}
1517- wait_for_tests (pids ,tests ,num_tests );
1553+ wait_for_tests (pids ,statuses , tests ,num_tests );
15181554status_end ();
15191555}
15201556
@@ -1543,7 +1579,7 @@ run_schedule(const char *schedule, test_function tfunc)
15431579bool newdiff ;
15441580
15451581if (tl )
1546- tl = tl -> next ;/* tl has the samelengt has rl and el
1582+ tl = tl -> next ;/* tl has the samelength as rl and el
15471583 * if it exists */
15481584
15491585newdiff = results_differ (tests [i ],rl -> str ,el -> str );
@@ -1584,6 +1620,9 @@ run_schedule(const char *schedule, test_function tfunc)
15841620success_count ++ ;
15851621}
15861622
1623+ if (statuses [i ]!= 0 )
1624+ log_child_failure (statuses [i ]);
1625+
15871626status_end ();
15881627}
15891628}
@@ -1598,6 +1637,7 @@ static void
15981637run_single_test (const char * test ,test_function tfunc )
15991638{
16001639PID_TYPE pid ;
1640+ int exit_status ;
16011641_stringlist * resultfiles = NULL ;
16021642_stringlist * expectfiles = NULL ;
16031643_stringlist * tags = NULL ;
@@ -1608,7 +1648,7 @@ run_single_test(const char *test, test_function tfunc)
16081648
16091649status (_ ("test %-20s ... " ),test );
16101650pid = (tfunc ) (test ,& resultfiles ,& expectfiles ,& tags );
1611- wait_for_tests (& pid ,NULL ,1 );
1651+ wait_for_tests (& pid ,& exit_status , NULL ,1 );
16121652
16131653/*
16141654 * Advance over all three lists simultaneously.
@@ -1624,7 +1664,7 @@ run_single_test(const char *test, test_function tfunc)
16241664bool newdiff ;
16251665
16261666if (tl )
1627- tl = tl -> next ;/* tl has the samelengt has rl and el if it
1667+ tl = tl -> next ;/* tl has the samelength as rl and el if it
16281668 * exists */
16291669
16301670newdiff = results_differ (test ,rl -> str ,el -> str );
@@ -1645,6 +1685,10 @@ run_single_test(const char *test, test_function tfunc)
16451685status (_ ("ok" ));
16461686success_count ++ ;
16471687}
1688+
1689+ if (exit_status != 0 )
1690+ log_child_failure (exit_status );
1691+
16481692status_end ();
16491693}
16501694