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{
13171318 int tests_left ;
13181319 int i ;
@@ -1327,9 +1328,10 @@ wait_for_tests(PID_TYPE * pids, char **names, int num_tests)
13271328 while (tests_left > 0 )
13281329 {
13291330 PID_TYPE p ;
1331+ int exit_status ;
13301332
13311333#ifndef WIN32
1332- p = wait (NULL );
1334+ p = wait (& exit_status );
13331335
13341336 if (p == INVALID_PID )
13351337 {
@@ -1357,9 +1359,11 @@ wait_for_tests(PID_TYPE * pids, char **names, int num_tests)
13571359 if (p == pids [i ])
13581360 {
13591361#ifdef WIN32
1362+ GetExitCodeProcess (pids [i ], & exit_status );
13601363 CloseHandle (pids [i ]);
13611364#endif
13621365 pids [i ] = INVALID_PID ;
1366+ statuses [i ] = exit_status ;
13631367 if (names )
13641368 status (" %s" , names [i ]);
13651369 tests_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 ];
13871420 PID_TYPE pids [MAX_PARALLEL_TESTS ];
1421+ int statuses [MAX_PARALLEL_TESTS ];
13881422 _stringlist * ignorelist = NULL ;
13891423 char scbuf [1024 ];
13901424 FILE * scf ;
@@ -1486,7 +1520,7 @@ run_schedule(const char *schedule, test_function tfunc)
14861520 {
14871521 status (_ ("test %-20s ... " ), tests [0 ]);
14881522 pids [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 }
14921526 else if (max_connections > 0 && max_connections < num_tests )
@@ -1499,12 +1533,14 @@ run_schedule(const char *schedule, test_function tfunc)
14991533 {
15001534 if (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 );
15031538 oldest = i ;
15041539 }
15051540 pids [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 );
15081544 status_end ();
15091545 }
15101546 else
@@ -1514,7 +1550,7 @@ run_schedule(const char *schedule, test_function tfunc)
15141550 {
15151551 pids [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 );
15181554 status_end ();
15191555 }
15201556
@@ -1543,7 +1579,7 @@ run_schedule(const char *schedule, test_function tfunc)
15431579 bool newdiff ;
15441580
15451581 if (tl )
1546- tl = tl -> next ; /* tl has the same lengt has rl and el
1582+ tl = tl -> next ; /* tl has the same length as rl and el
15471583 * if it exists */
15481584
15491585 newdiff = results_differ (tests [i ], rl -> str , el -> str );
@@ -1584,6 +1620,9 @@ run_schedule(const char *schedule, test_function tfunc)
15841620 success_count ++ ;
15851621 }
15861622
1623+ if (statuses [i ] != 0 )
1624+ log_child_failure (statuses [i ]);
1625+
15871626 status_end ();
15881627 }
15891628 }
@@ -1598,6 +1637,7 @@ static void
15981637run_single_test (const char * test , test_function tfunc )
15991638{
16001639 PID_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
16091649 status (_ ("test %-20s ... " ), test );
16101650 pid = (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)
16241664 bool newdiff ;
16251665
16261666 if (tl )
1627- tl = tl -> next ; /* tl has the same lengt has rl and el if it
1667+ tl = tl -> next ; /* tl has the same length as rl and el if it
16281668 * exists */
16291669
16301670 newdiff = results_differ (test , rl -> str , el -> str );
@@ -1645,6 +1685,10 @@ run_single_test(const char *test, test_function tfunc)
16451685 status (_ ("ok" ));
16461686 success_count ++ ;
16471687 }
1688+
1689+ if (exit_status != 0 )
1690+ log_child_failure (exit_status );
1691+
16481692 status_end ();
16491693}
16501694
0 commit comments