PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pg_regress.h File Reference
#include <unistd.h>
Include dependency graph for pg_regress.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  _stringlist
 

Macros

#define PID_TYPE   pid_t
 
#define INVALID_PID   (-1)
 

Typedefs

typedef struct _stringlist _stringlist
 
typedef void(* init_function) (int argc, char **argv)
 
typedef PID_TYPE(* test_start_function) (const char *testname, _stringlist **resultfiles, _stringlist **expectfiles, _stringlist **tags)
 
typedef void(* postprocess_result_function) (const char *filename)
 

Functions

int regression_main (int argc, char *argv[], init_function ifunc, test_start_function startfunc, postprocess_result_function postfunc)
 
void add_stringlist_item (_stringlist **listhead, const char *str)
 
PID_TYPE spawn_process (const char *cmdline)
 
bool file_exists (const char *file)
 

Variables

charbindir
 
charlibdir
 
chardatadir
 
charhost_platform
 
_stringlistdblist
 
bool debug
 
charinputdir
 
charoutputdir
 
charexpecteddir
 
charlauncher
 
const charbasic_diff_opts
 
const charpretty_diff_opts
 

Macro Definition Documentation

◆ INVALID_PID

#define INVALID_PID   (-1)

Definition at line 15 of file pg_regress.h.

◆ PID_TYPE

#define PID_TYPE   pid_t

Definition at line 14 of file pg_regress.h.

Typedef Documentation

◆ _stringlist

◆ init_function

typedef void(* init_function) (int argc, char **argv)

Definition at line 33 of file pg_regress.h.

◆ postprocess_result_function

typedef void(* postprocess_result_function) (const char *filename)

Definition at line 42 of file pg_regress.h.

◆ test_start_function

Definition at line 36 of file pg_regress.h.

Function Documentation

◆ add_stringlist_item()

void add_stringlist_item ( _stringlist **  listhead,
const char str 
)

Definition at line 202 of file pg_regress.c.

203{
206
208 newentry->next = NULL;
209 if (*listhead == NULL)
211 else
212 {
213 for (oldentry = *listhead; oldentry->next; oldentry = oldentry->next)
214 /* skip */ ;
215 oldentry->next = newentry;
216 }
217}
char * pg_strdup(const char *in)
Definition fe_memutils.c:91
#define pg_malloc_object(type)
Definition fe_memutils.h:60
const char * str
static int fb(int x)
char * str
Definition initdb.c:92

References fb(), pg_malloc_object, pg_strdup(), _stringlist::str, and str.

Referenced by regression_main(), and split_to_stringlist().

◆ file_exists()

bool file_exists ( const char file)

Definition at line 1318 of file pg_regress.c.

1319{
1320 FILE *f = fopen(file, "r");
1321
1322 if (!f)
1323 return false;
1324 fclose(f);
1325 return true;
1326}

References fb().

Referenced by isolation_start_test(), psql_start_test(), and results_differ().

◆ regression_main()

int regression_main ( int  argc,
char argv[],
init_function  ifunc,
test_start_function  startfunc,
postprocess_result_function  postfunc 
)

Definition at line 2142 of file pg_regress.c.

2146{
2147 static struct option long_options[] = {
2148 {"help", no_argument, NULL, 'h'},
2149 {"version", no_argument, NULL, 'V'},
2150 {"dbname", required_argument, NULL, 1},
2151 {"debug", no_argument, NULL, 2},
2152 {"inputdir", required_argument, NULL, 3},
2153 {"max-connections", required_argument, NULL, 5},
2154 {"encoding", required_argument, NULL, 6},
2155 {"outputdir", required_argument, NULL, 7},
2156 {"schedule", required_argument, NULL, 8},
2157 {"temp-instance", required_argument, NULL, 9},
2158 {"no-locale", no_argument, NULL, 10},
2159 {"host", required_argument, NULL, 13},
2160 {"port", required_argument, NULL, 14},
2161 {"user", required_argument, NULL, 15},
2162 {"bindir", required_argument, NULL, 16},
2163 {"dlpath", required_argument, NULL, 17},
2164 {"create-role", required_argument, NULL, 18},
2165 {"temp-config", required_argument, NULL, 19},
2166 {"use-existing", no_argument, NULL, 20},
2167 {"launcher", required_argument, NULL, 21},
2168 {"load-extension", required_argument, NULL, 22},
2169 {"config-auth", required_argument, NULL, 24},
2170 {"max-concurrent-tests", required_argument, NULL, 25},
2171 {"expecteddir", required_argument, NULL, 26},
2172 {NULL, 0, NULL, 0}
2173 };
2174
2175 bool use_unix_sockets;
2176 _stringlist *sl;
2177 int c;
2178 int i;
2179 int option_index;
2180 char buf[MAXPGPATH * 4];
2181
2182 pg_logging_init(argv[0]);
2183 progname = get_progname(argv[0]);
2184 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_regress"));
2185
2187
2189
2191
2192#if defined(WIN32)
2193
2194 /*
2195 * We don't use Unix-domain sockets on Windows by default (see comment at
2196 * remove_temp() for a reason). Override at your own risk.
2197 */
2198 use_unix_sockets = getenv("PG_TEST_USE_UNIX_SOCKETS") ? true : false;
2199#else
2200 use_unix_sockets = true;
2201#endif
2202
2203 if (!use_unix_sockets)
2204 hostname = "localhost";
2205
2206 /*
2207 * We call the initialization function here because that way we can set
2208 * default parameters and let them be overwritten by the commandline.
2209 */
2210 ifunc(argc, argv);
2211
2212 if (getenv("PG_REGRESS_DIFF_OPTS"))
2213 pretty_diff_opts = getenv("PG_REGRESS_DIFF_OPTS");
2214
2215 while ((c = getopt_long(argc, argv, "hV", long_options, &option_index)) != -1)
2216 {
2217 switch (c)
2218 {
2219 case 'h':
2220 help();
2221 exit(0);
2222 case 'V':
2223 puts("pg_regress (PostgreSQL) " PG_VERSION);
2224 exit(0);
2225 case 1:
2226
2227 /*
2228 * If a default database was specified, we need to remove it
2229 * before we add the specified one.
2230 */
2233 break;
2234 case 2:
2235 debug = true;
2236 break;
2237 case 3:
2239 break;
2240 case 5:
2242 break;
2243 case 6:
2245 break;
2246 case 7:
2248 break;
2249 case 8:
2251 break;
2252 case 9:
2254 break;
2255 case 10:
2256 nolocale = true;
2257 break;
2258 case 13:
2260 break;
2261 case 14:
2262 port = atoi(optarg);
2264 break;
2265 case 15:
2267 break;
2268 case 16:
2269 /* "--bindir=" means to use PATH */
2270 if (strlen(optarg))
2272 else
2273 bindir = NULL;
2274 break;
2275 case 17:
2277 break;
2278 case 18:
2280 break;
2281 case 19:
2283 break;
2284 case 20:
2285 use_existing = true;
2286 break;
2287 case 21:
2289 break;
2290 case 22:
2292 break;
2293 case 24:
2295 break;
2296 case 25:
2298 break;
2299 case 26:
2301 break;
2302 default:
2303 /* getopt_long already emitted a complaint */
2304 pg_log_error_hint("Try \"%s --help\" for more information.",
2305 progname);
2306 exit(2);
2307 }
2308 }
2309
2310 /*
2311 * if we still have arguments, they are extra tests to run
2312 */
2313 while (argc - optind >= 1)
2314 {
2316 optind++;
2317 }
2318
2319 /*
2320 * We must have a database to run the tests in; either a default name, or
2321 * one supplied by the --dbname switch.
2322 */
2323 if (!(dblist && dblist->str && dblist->str[0]))
2324 {
2325 bail("no database name was specified");
2326 }
2327
2329 {
2330#ifdef ENABLE_SSPI
2331 if (!use_unix_sockets)
2333#endif
2334 exit(0);
2335 }
2336
2338
2339 /*
2340 * To reduce chances of interference with parallel installations, use
2341 * a port number starting in the private range (49152-65535)
2342 * calculated from the version number. This aids non-Unix socket mode
2343 * systems; elsewhere, the use of a private socket directory already
2344 * prevents interference.
2345 */
2346 port = 0xC000 | (PG_VERSION_NUM & 0x3FFF);
2347
2352
2353 /*
2354 * Initialization
2355 */
2357
2359
2360#if defined(HAVE_GETRLIMIT)
2362#endif
2363
2364 if (temp_instance)
2365 {
2366 StringInfoData cmd;
2367 FILE *pg_conf;
2368 const char *env_wait;
2369 int wait_seconds;
2370 const char *initdb_template_dir;
2371 const char *keywords[4];
2372 const char *values[4];
2373 PGPing rv;
2374 const char *initdb_extra_opts_env;
2375
2376 /*
2377 * Prepare the temp instance
2378 */
2379
2381 {
2382 if (!rmtree(temp_instance, true))
2383 {
2384 bail("could not remove temp instance \"%s\"", temp_instance);
2385 }
2386 }
2387
2388 /* make the temp instance top directory */
2390
2391 /* and a directory for log files */
2392 snprintf(buf, sizeof(buf), "%s/log", outputdir);
2393 if (!directory_exists(buf))
2395
2396 initdb_extra_opts_env = getenv("PG_TEST_INITDB_EXTRA_OPTS");
2397
2398 initStringInfo(&cmd);
2399
2400 /*
2401 * Create data directory.
2402 *
2403 * If available, use a previously initdb'd cluster as a template by
2404 * copying it. For a lot of tests, that's substantially cheaper.
2405 *
2406 * There's very similar code in Cluster.pm, but we can't easily de
2407 * duplicate it until we require perl at build time.
2408 */
2409 initdb_template_dir = getenv("INITDB_TEMPLATE");
2411 {
2412 note("initializing database system by running initdb");
2413
2414 appendStringInfo(&cmd,
2415 "\"%s%sinitdb\" -D \"%s/data\" --no-clean --no-sync",
2416 bindir ? bindir : "",
2417 bindir ? "/" : "",
2419 if (debug)
2420 appendStringInfoString(&cmd, " --debug");
2421 if (nolocale)
2422 appendStringInfoString(&cmd, " --no-locale");
2425 appendStringInfo(&cmd, " > \"%s/log/initdb.log\" 2>&1", outputdir);
2426 fflush(NULL);
2427 if (system(cmd.data))
2428 {
2429 bail("initdb failed\n"
2430 "# Examine \"%s/log/initdb.log\" for the reason.\n"
2431 "# Command was: %s",
2432 outputdir, cmd.data);
2433 }
2434 }
2435 else
2436 {
2437#ifndef WIN32
2438 const char *copycmd = "cp -RPp \"%s\" \"%s/data\"";
2439 int expected_exitcode = 0;
2440#else
2441 const char *copycmd = "robocopy /E /NJS /NJH /NFL /NDL /NP \"%s\" \"%s/data\"";
2442 int expected_exitcode = 1; /* 1 denotes files were copied */
2443#endif
2444
2445 note("initializing database system by copying initdb template");
2446
2447 appendStringInfo(&cmd,
2448 copycmd,
2451 appendStringInfo(&cmd, " > \"%s/log/initdb.log\" 2>&1", outputdir);
2452 fflush(NULL);
2453 if (system(cmd.data) != expected_exitcode)
2454 {
2455 bail("copying of initdb template failed\n"
2456 "# Examine \"%s/log/initdb.log\" for the reason.\n"
2457 "# Command was: %s",
2458 outputdir, cmd.data);
2459 }
2460 }
2461
2462 pfree(cmd.data);
2463
2464 /*
2465 * Adjust the default postgresql.conf for regression testing. The user
2466 * can specify a file to be appended; in any case we expand logging
2467 * and set max_prepared_transactions to enable testing of prepared
2468 * xacts. (Note: to reduce the probability of unexpected shmmax
2469 * failures, don't set max_prepared_transactions any higher than
2470 * actually needed by the prepared_xacts regression test.)
2471 */
2472 snprintf(buf, sizeof(buf), "%s/data/postgresql.conf", temp_instance);
2473 pg_conf = fopen(buf, "a");
2474 if (pg_conf == NULL)
2475 bail("could not open \"%s\" for adding extra config: %m", buf);
2476
2477 fputs("\n# Configuration added by pg_regress\n\n", pg_conf);
2478 fputs("log_autovacuum_min_duration = 0\n", pg_conf);
2479 fputs("log_autoanalyze_min_duration = 0\n", pg_conf);
2480 fputs("log_checkpoints = on\n", pg_conf);
2481 fputs("log_line_prefix = '%m %b[%p] %q%a '\n", pg_conf);
2482 fputs("log_lock_waits = on\n", pg_conf);
2483 fputs("log_temp_files = 128kB\n", pg_conf);
2484 fputs("max_prepared_transactions = 2\n", pg_conf);
2485
2486 for (sl = temp_configs; sl != NULL; sl = sl->next)
2487 {
2488 char *temp_config = sl->str;
2490 char line_buf[1024];
2491
2493 if (extra_conf == NULL)
2494 {
2495 bail("could not open \"%s\" to read extra config: %m",
2496 temp_config);
2497 }
2498 while (fgets(line_buf, sizeof(line_buf), extra_conf) != NULL)
2499 fputs(line_buf, pg_conf);
2501 }
2502
2503 fclose(pg_conf);
2504
2505#ifdef ENABLE_SSPI
2506 if (!use_unix_sockets)
2507 {
2508 /*
2509 * Since we successfully used the same buffer for the much-longer
2510 * "initdb" command, this can't truncate.
2511 */
2512 snprintf(buf, sizeof(buf), "%s/data", temp_instance);
2514 }
2515#endif
2516
2517 /*
2518 * Prepare the connection params for checking the state of the server
2519 * before starting the tests.
2520 */
2521 sprintf(portstr, "%d", port);
2522 keywords[0] = "dbname";
2523 values[0] = "postgres";
2524 keywords[1] = "port";
2525 values[1] = portstr;
2526 keywords[2] = "host";
2528 keywords[3] = NULL;
2529 values[3] = NULL;
2530
2531 /*
2532 * Check if there is a postmaster running already.
2533 */
2534 for (i = 0; i < 16; i++)
2535 {
2536 rv = PQpingParams(keywords, values, 1);
2537
2538 if (rv == PQPING_OK)
2539 {
2540 if (port_specified_by_user || i == 15)
2541 {
2542 note("port %d apparently in use", port);
2544 note("could not determine an available port");
2545 bail("Specify an unused port using the --port option or shut down any conflicting PostgreSQL servers.");
2546 }
2547
2548 note("port %d apparently in use, trying %d", port, port + 1);
2549 port++;
2550 sprintf(portstr, "%d", port);
2551 setenv("PGPORT", portstr, 1);
2552 }
2553 else
2554 break;
2555 }
2556
2557 /*
2558 * Start the temp postmaster
2559 */
2560 snprintf(buf, sizeof(buf),
2561 "\"%s%spostgres\" -D \"%s/data\" -F%s "
2562 "-c \"listen_addresses=%s\" -k \"%s\" "
2563 "> \"%s/log/postmaster.log\" 2>&1",
2564 bindir ? bindir : "",
2565 bindir ? "/" : "",
2566 temp_instance, debug ? " -d 5" : "",
2567 hostname ? hostname : "", sockdir ? sockdir : "",
2568 outputdir);
2571 bail("could not spawn postmaster: %m");
2572
2573 /*
2574 * Wait till postmaster is able to accept connections; normally takes
2575 * only a fraction of a second or so, but Cygwin is reportedly *much*
2576 * slower, and test builds using Valgrind or similar tools might be
2577 * too. Hence, allow the default timeout of 60 seconds to be
2578 * overridden from the PGCTLTIMEOUT environment variable.
2579 */
2580 env_wait = getenv("PGCTLTIMEOUT");
2581 if (env_wait != NULL)
2582 {
2584 if (wait_seconds <= 0)
2585 wait_seconds = 60;
2586 }
2587 else
2588 wait_seconds = 60;
2589
2590 for (i = 0; i < wait_seconds * WAIT_TICKS_PER_SECOND; i++)
2591 {
2592 /*
2593 * It's fairly unlikely that the server is responding immediately
2594 * so we start with sleeping before checking instead of the other
2595 * way around.
2596 */
2597 pg_usleep(1000000L / WAIT_TICKS_PER_SECOND);
2598
2599 rv = PQpingParams(keywords, values, 1);
2600
2601 /* Done if the server is running and accepts connections */
2602 if (rv == PQPING_OK)
2603 break;
2604
2605 if (rv == PQPING_NO_ATTEMPT)
2606 bail("attempting to connect to postmaster failed");
2607
2608 /*
2609 * Fail immediately if postmaster has exited
2610 */
2611#ifndef WIN32
2613#else
2615#endif
2616 {
2617 bail("postmaster failed, examine \"%s/log/postmaster.log\" for the reason",
2618 outputdir);
2619 }
2620 }
2622 {
2623 diag("postmaster did not respond within %d seconds, examine \"%s/log/postmaster.log\" for the reason",
2625
2626 /*
2627 * If we get here, the postmaster is probably wedged somewhere in
2628 * startup. Try to kill it ungracefully rather than leaving a
2629 * stuck postmaster that might interfere with subsequent test
2630 * attempts.
2631 */
2632#ifndef WIN32
2633 if (kill(postmaster_pid, SIGKILL) != 0 && errno != ESRCH)
2634 bail("could not kill failed postmaster: %m");
2635#else
2636 if (TerminateProcess(postmaster_pid, 255) == 0)
2637 bail("could not kill failed postmaster: error code %lu",
2638 GetLastError());
2639#endif
2640 bail("postmaster failed");
2641 }
2642
2643 postmaster_running = true;
2644
2645#ifdef _WIN64
2646/* need a series of two casts to convert HANDLE without compiler warning */
2647#define ULONGPID(x) (unsigned long) (unsigned long long) (x)
2648#else
2649#define ULONGPID(x) (unsigned long) (x)
2650#endif
2651 note("using temp instance on port %d with PID %lu",
2653 }
2654 else
2655 {
2656 /*
2657 * Using an existing installation, so may need to get rid of
2658 * pre-existing database(s) and role(s)
2659 */
2660 if (!use_existing)
2661 {
2662 for (sl = dblist; sl; sl = sl->next)
2664 for (sl = extraroles; sl; sl = sl->next)
2665 drop_role_if_exists(sl->str);
2666 }
2667 }
2668
2669 /*
2670 * Create the test database(s) and role(s)
2671 */
2672 if (!use_existing)
2673 {
2674 for (sl = dblist; sl; sl = sl->next)
2675 create_database(sl->str);
2676 for (sl = extraroles; sl; sl = sl->next)
2677 create_role(sl->str, dblist);
2678 }
2679
2680 /*
2681 * Ready to run the tests
2682 */
2683 for (sl = schedulelist; sl != NULL; sl = sl->next)
2684 {
2686 }
2687
2688 for (sl = extra_tests; sl != NULL; sl = sl->next)
2689 {
2691 }
2692
2693 /*
2694 * Shut down temp installation's postmaster
2695 */
2696 if (temp_instance)
2697 {
2699 }
2700
2701 /*
2702 * If there were no errors, remove the temp instance immediately to
2703 * conserve disk space. (If there were errors, we leave the instance in
2704 * place for possible manual investigation.)
2705 */
2706 if (temp_instance && fail_count == 0)
2707 {
2708 if (!rmtree(temp_instance, true))
2709 diag("could not remove temp instance \"%s\"",
2711 }
2712
2713 /*
2714 * Emit a TAP compliant Plan
2715 */
2717
2718 /*
2719 * Emit nice-looking summary message
2720 */
2721 if (fail_count == 0)
2722 note("All %d tests passed.", success_count);
2723 else
2724 diag("%d of %d tests failed.", fail_count, success_count + fail_count);
2725
2726 if (file_size(difffilename) > 0)
2727 {
2728 diag("The differences that caused some tests to fail can be viewed in the file \"%s\".",
2729 difffilename);
2730 diag("A copy of the test summary that you see above is saved in the file \"%s\".",
2731 logfilename);
2732 }
2733 else
2734 {
2737 }
2738
2739 fclose(logfile);
2740 logfile = NULL;
2741
2742 if (fail_count != 0)
2743 exit(1);
2744
2745 return 0;
2746}
static Datum values[MAXATTR]
Definition bootstrap.c:190
#define PG_TEXTDOMAIN(domain)
Definition c.h:1359
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition exec.c:430
PGPing PQpingParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition fe-connect.c:793
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition getopt_long.c:60
#define no_argument
Definition getopt_long.h:25
#define required_argument
Definition getopt_long.h:26
void pg_initialize_timing(void)
Definition instr_time.c:84
return true
Definition isn.c:130
int i
Definition isn.c:77
static const JsonPathKeyword keywords[]
PGPing
Definition libpq-fe.h:181
@ PQPING_OK
Definition libpq-fe.h:182
@ PQPING_NO_ATTEMPT
Definition libpq-fe.h:185
void pg_logging_init(const char *argv0)
Definition logging.c:85
#define pg_log_error_hint(...)
Definition logging.h:114
void pfree(void *pointer)
Definition mcxt.c:1619
#define MAXPGPATH
static int wait_seconds
Definition pg_ctl.c:77
PGDLLIMPORT int optind
Definition getopt.c:47
PGDLLIMPORT char * optarg
Definition getopt.c:49
#define plan(x)
Definition pg_regress.c:164
static bool use_existing
Definition pg_regress.c:115
static void open_result_files(void)
static int max_connections
Definition pg_regress.c:107
static char * user
Definition pg_regress.c:121
static bool port_specified_by_user
Definition pg_regress.c:119
static bool nolocale
Definition pg_regress.c:114
#define diag(...)
Definition pg_regress.c:167
static void stop_postmaster(void)
Definition pg_regress.c:444
static int max_concurrent_tests
Definition pg_regress.c:108
static void create_database(const char *dbname)
static void free_stringlist(_stringlist **listhead)
Definition pg_regress.c:223
static void drop_role_if_exists(const char *rolename)
bool debug
Definition pg_regress.c:100
static void unlimit_core_size(void)
Definition pg_regress.c:179
static bool directory_exists(const char *dir)
static _stringlist * schedulelist
Definition pg_regress.c:110
#define WAIT_TICKS_PER_SECOND
Definition pg_regress.c:82
static _stringlist * loadextension
Definition pg_regress.c:106
static char * logfilename
Definition pg_regress.c:127
static _stringlist * temp_configs
Definition pg_regress.c:113
static _stringlist * extra_tests
Definition pg_regress.c:111
static int port
Definition pg_regress.c:117
char * outputdir
Definition pg_regress.c:102
static void make_directory(const char *dir)
static void split_to_stringlist(const char *s, const char *delim, _stringlist **listhead)
Definition pg_regress.c:238
#define note(...)
Definition pg_regress.c:165
static void run_single_test(const char *test, test_start_function startfunc, postprocess_result_function postfunc)
char * launcher
Definition pg_regress.c:105
const char * pretty_diff_opts
Definition pg_regress.c:65
char * inputdir
Definition pg_regress.c:101
static char * difffilename
Definition pg_regress.c:129
char * expecteddir
Definition pg_regress.c:103
static char * config_auth_datadir
Definition pg_regress.c:123
static void drop_database_if_exists(const char *dbname)
static FILE * logfile
Definition pg_regress.c:128
static char portstr[16]
Definition pg_regress.c:118
static void initialize_environment(void)
Definition pg_regress.c:734
static char * temp_instance
Definition pg_regress.c:112
static char * encoding
Definition pg_regress.c:109
static void help(void)
static const char * sockdir
Definition pg_regress.c:130
static long file_size(const char *file)
static bool postmaster_running
Definition pg_regress.c:141
_stringlist * dblist
Definition pg_regress.c:99
static const char * progname
Definition pg_regress.c:126
static char * dlpath
Definition pg_regress.c:120
static _stringlist * extraroles
Definition pg_regress.c:122
PID_TYPE spawn_process(const char *cmdline)
char * bindir
Definition pg_regress.c:104
#define bail(...)
Definition pg_regress.c:172
static void create_role(const char *rolename, const _stringlist *granted_dbs)
static void run_schedule(const char *schedule, test_start_function startfunc, postprocess_result_function postfunc)
void add_stringlist_item(_stringlist **listhead, const char *str)
Definition pg_regress.c:202
static int success_count
Definition pg_regress.c:143
#define ULONGPID(x)
static char * hostname
Definition pg_regress.c:116
static int fail_count
Definition pg_regress.c:144
static PID_TYPE postmaster_pid
Definition pg_regress.c:140
#define INVALID_PID
Definition pg_regress.h:15
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define sprintf
Definition port.h:263
#define snprintf
Definition port.h:261
char * make_absolute_path(const char *path)
Definition path.c:824
const char * get_progname(const char *argv0)
Definition path.c:669
char * c
void get_restricted_token(void)
bool rmtree(const char *path, bool rmtopdir)
Definition rmtree.c:50
void pg_usleep(long microsec)
Definition signal.c:53
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
struct _stringlist * next
Definition initdb.c:93
#define kill(pid, sig)
Definition win32_port.h:490
#define setenv(x, y, z)
Definition win32_port.h:542
#define SIGKILL
Definition win32_port.h:162

References add_stringlist_item(), appendStringInfo(), appendStringInfoString(), bail, bindir, buf, config_auth_datadir, create_database(), create_role(), StringInfoData::data, dblist, debug, diag, difffilename, directory_exists(), dlpath, drop_database_if_exists(), drop_role_if_exists(), encoding, expecteddir, extra_tests, extraroles, fail_count, fb(), file_size(), free_stringlist(), get_progname(), get_restricted_token(), getopt_long(), help(), hostname, i, initialize_environment(), initStringInfo(), inputdir, INVALID_PID, keywords, kill, launcher, loadextension, logfile, logfilename, make_absolute_path(), make_directory(), max_concurrent_tests, max_connections, MAXPGPATH, _stringlist::next, no_argument, nolocale, note, open_result_files(), optarg, optind, outputdir, pfree(), pg_initialize_timing(), pg_log_error_hint, pg_logging_init(), pg_strdup(), PG_TEXTDOMAIN, pg_usleep(), plan, port, port_specified_by_user, portstr, postmaster_pid, postmaster_running, PQPING_NO_ATTEMPT, PQPING_OK, PQpingParams(), pretty_diff_opts, progname, required_argument, rmtree(), run_schedule(), run_single_test(), schedulelist, set_pglocale_pgservice(), setenv, SIGKILL, snprintf, sockdir, spawn_process(), split_to_stringlist(), sprintf, stop_postmaster(), _stringlist::str, success_count, temp_configs, temp_instance, true, ULONGPID, unlimit_core_size(), use_existing, user, values, wait_seconds, and WAIT_TICKS_PER_SECOND.

Referenced by main().

◆ spawn_process()

PID_TYPE spawn_process ( const char cmdline)

Definition at line 1215 of file pg_regress.c.

1216{
1217#ifndef WIN32
1218 pid_t pid;
1219
1220 /*
1221 * Must flush I/O buffers before fork.
1222 */
1223 fflush(NULL);
1224
1225#ifdef EXEC_BACKEND
1227#endif
1228
1229 pid = fork();
1230 if (pid == -1)
1231 {
1232 bail("could not fork: %m");
1233 }
1234 if (pid == 0)
1235 {
1236 /*
1237 * In child
1238 *
1239 * Instead of using system(), exec the shell directly, and tell it to
1240 * "exec" the command too. This saves two useless processes per
1241 * parallel test case.
1242 */
1243 char *cmdline2;
1244
1245 cmdline2 = psprintf("exec %s", cmdline);
1246 execl(shellprog, shellprog, "-c", cmdline2, (char *) NULL);
1247 /* Not using the normal bail() here as we want _exit */
1248 bail_noatexit("could not exec \"%s\": %m", shellprog);
1249 }
1250 /* in parent */
1251 return pid;
1252#else
1254 char *cmdline2;
1255 const char *comspec;
1256
1257 /* Find CMD.EXE location using COMSPEC, if it's set */
1258 comspec = getenv("COMSPEC");
1259 if (comspec == NULL)
1260 comspec = "CMD";
1261
1262 memset(&pi, 0, sizeof(pi));
1263 cmdline2 = psprintf("\"%s\" /c \"%s\"", comspec, cmdline);
1264
1266 exit(2);
1267
1268 CloseHandle(pi.hThread);
1269 return pi.hProcess;
1270#endif
1271}
static char * shellprog
Definition pg_regress.c:55
#define bail_noatexit(...)
Definition pg_regress.c:171
char * psprintf(const char *fmt,...)
Definition psprintf.c:43

References bail, bail_noatexit, fb(), psprintf(), and shellprog.

Referenced by ecpg_start_test(), isolation_start_test(), psql_start_test(), and regression_main().

Variable Documentation

◆ basic_diff_opts

const char* basic_diff_opts
extern

Definition at line 64 of file pg_regress.c.

Referenced by results_differ().

◆ bindir

char* bindir
extern

◆ datadir

◆ dblist

◆ debug

bool debug
extern

Definition at line 100 of file pg_regress.c.

Referenced by regression_main().

◆ expecteddir

char* expecteddir
extern

Definition at line 103 of file pg_regress.c.

Referenced by ecpg_start_test(), psql_start_test(), and regression_main().

◆ host_platform

char* host_platform
extern

Definition at line 52 of file pg_regress.c.

Referenced by load_resultmap().

◆ inputdir

◆ launcher

char* launcher
extern

Definition at line 105 of file pg_regress.c.

Referenced by isolation_start_test(), psql_start_test(), and regression_main().

◆ libdir

char* libdir
extern

◆ outputdir

◆ pretty_diff_opts

const char* pretty_diff_opts
extern

Definition at line 65 of file pg_regress.c.

Referenced by regression_main(), and results_differ().