@ -32,6 +32,7 @@
# include "common/username.h"
# include "common/username.h"
# include "getopt_long.h"
# include "getopt_long.h"
# include "lib/stringinfo.h"
# include "lib/stringinfo.h"
# include "libpq-fe.h"
# include "libpq/pqcomm.h" /* needed for UNIXSOCK_PATH() */
# include "libpq/pqcomm.h" /* needed for UNIXSOCK_PATH() */
# include "pg_config_paths.h"
# include "pg_config_paths.h"
# include "pg_regress.h"
# include "pg_regress.h"
@ -75,6 +76,12 @@ const char *pretty_diff_opts = "-w -U3";
*/
*/
# define TESTNAME_WIDTH 36
# define TESTNAME_WIDTH 36
/*
* The number times per second that pg_regress checks to see if the test
* instance server has started and is available for connection .
*/
# define WAIT_TICKS_PER_SECOND 20
typedef enum TAPtype
typedef enum TAPtype
{
{
DIAG = 0 ,
DIAG = 0 ,
@ -107,6 +114,7 @@ static bool nolocale = false;
static bool use_existing = false ;
static bool use_existing = false ;
static char * hostname = NULL ;
static char * hostname = NULL ;
static int port = - 1 ;
static int port = - 1 ;
static char portstr [ 16 ] ;
static bool port_specified_by_user = false ;
static bool port_specified_by_user = false ;
static char * dlpath = PKGLIBDIR ;
static char * dlpath = PKGLIBDIR ;
static char * user = NULL ;
static char * user = NULL ;
@ -2107,7 +2115,6 @@ regression_main(int argc, char *argv[],
int i ;
int i ;
int option_index ;
int option_index ;
char buf [ MAXPGPATH * 4 ] ;
char buf [ MAXPGPATH * 4 ] ;
char buf2 [ MAXPGPATH * 4 ] ;
pg_logging_init ( argv [ 0 ] ) ;
pg_logging_init ( argv [ 0 ] ) ;
progname = get_progname ( argv [ 0 ] ) ;
progname = get_progname ( argv [ 0 ] ) ;
@ -2296,6 +2303,9 @@ regression_main(int argc, char *argv[],
const char * env_wait ;
const char * env_wait ;
int wait_seconds ;
int wait_seconds ;
const char * initdb_template_dir ;
const char * initdb_template_dir ;
const char * keywords [ 4 ] ;
const char * values [ 4 ] ;
PGPing rv ;
/*
/*
* Prepare the temp instance
* Prepare the temp instance
@ -2436,21 +2446,28 @@ regression_main(int argc, char *argv[],
# endif
# endif
/*
/*
* Check if there is a postmaster running already .
* Prepare the connection params for checking the state of the server
* before starting the tests .
*/
*/
snprintf ( buf2 , sizeof ( buf2 ) ,
sprintf ( portstr , " %d " , port ) ;
" \" %s%spsql \" -X postgres <%s 2>%s " ,
keywords [ 0 ] = " dbname " ;
bindir ? bindir : " " ,
values [ 0 ] = " postgres " ;
bindir ? " / " : " " ,
keywords [ 1 ] = " port " ;
DEVNULL , DEVNULL ) ;
values [ 1 ] = portstr ;
keywords [ 2 ] = " host " ;
values [ 2 ] = hostname ? hostname : sockdir ;
keywords [ 3 ] = NULL ;
values [ 3 ] = NULL ;
/*
* Check if there is a postmaster running already .
*/
for ( i = 0 ; i < 16 ; i + + )
for ( i = 0 ; i < 16 ; i + + )
{
{
fflush ( NULL ) ;
rv = PQpingParams ( keywords , values , 1 ) ;
if ( system ( buf2 ) = = 0 )
{
char s [ 16 ] ;
if ( rv = = PQPING_OK )
{
if ( port_specified_by_user | | i = = 15 )
if ( port_specified_by_user | | i = = 15 )
{
{
note ( " port %d apparently in use " , port ) ;
note ( " port %d apparently in use " , port ) ;
@ -2461,8 +2478,8 @@ regression_main(int argc, char *argv[],
note ( " port %d apparently in use, trying %d " , port , port + 1 ) ;
note ( " port %d apparently in use, trying %d " , port , port + 1 ) ;
port + + ;
port + + ;
sprintf ( s , " %d " , port ) ;
sprintf ( port str , " %d " , port ) ;
setenv ( " PGPORT " , s , 1 ) ;
setenv ( " PGPORT " , port str , 1 ) ;
}
}
else
else
break ;
break ;
@ -2485,11 +2502,11 @@ regression_main(int argc, char *argv[],
bail ( " could not spawn postmaster: %s " , strerror ( errno ) ) ;
bail ( " could not spawn postmaster: %s " , strerror ( errno ) ) ;
/*
/*
* Wait till postmaster is able to accept connections ; normally thi s
* Wait till postmaster is able to accept connections ; normally take s
* is only a second or so , but Cygwin is reportedly * much * slower , and
* only a fraction of a second or so , but Cygwin is reportedly * much *
* test builds using Valgrind or similar tools might be too . Hence ,
* slower , and test builds using Valgrind or similar tools might be
* allow the default timeout of 60 seconds to be overridden from th e
* too . Hence , allow the default timeout of 60 seconds to be
* PGCTLTIMEOUT environment variable .
* overridden from the PGCTLTIMEOUT environment variable .
*/
*/
env_wait = getenv ( " PGCTLTIMEOUT " ) ;
env_wait = getenv ( " PGCTLTIMEOUT " ) ;
if ( env_wait ! = NULL )
if ( env_wait ! = NULL )
@ -2501,13 +2518,24 @@ regression_main(int argc, char *argv[],
else
else
wait_seconds = 60 ;
wait_seconds = 60 ;
for ( i = 0 ; i < wait_seconds ; i + + )
for ( i = 0 ; i < wait_seconds * WAIT_TICKS_PER_SECOND ; i + + )
{
{
/* Done if psql succeeds */
/*
fflush ( NULL ) ;
* It ' s fairly unlikely that the server is responding immediately
if ( system ( buf2 ) = = 0 )
* so we start with sleeping before checking instead of the other
* way around .
*/
pg_usleep ( 1000000L / WAIT_TICKS_PER_SECOND ) ;
rv = PQpingParams ( keywords , values , 1 ) ;
/* Done if the server is running and accepts connections */
if ( rv = = PQPING_OK )
break ;
break ;
if ( rv = = PQPING_NO_ATTEMPT )
bail ( " attempting to connect to postmaster failed " ) ;
/*
/*
* Fail immediately if postmaster has exited
* Fail immediately if postmaster has exited
*/
*/
@ -2520,10 +2548,8 @@ regression_main(int argc, char *argv[],
bail ( " postmaster failed, examine \" %s/log/postmaster.log \" for the reason " ,
bail ( " postmaster failed, examine \" %s/log/postmaster.log \" for the reason " ,
outputdir ) ;
outputdir ) ;
}
}
pg_usleep ( 1000000L ) ;
}
}
if ( i > = wait_seconds )
if ( i > = wait_seconds * WAIT_TICKS_PER_SECOND )
{
{
diag ( " postmaster did not respond within %d seconds, examine \" %s/log/postmaster.log \" for the reason " ,
diag ( " postmaster did not respond within %d seconds, examine \" %s/log/postmaster.log \" for the reason " ,
wait_seconds , outputdir ) ;
wait_seconds , outputdir ) ;