37 #include "pg_config_paths.h"
77 #define TESTNAME_WIDTH 36
83 #define WAIT_TICKS_PER_SECOND 20
147 static void test_status_print(
bool ok,
const char *testname,
double runtime,
bool parallel);
148 static void test_status_ok(
const char *testname,
double runtime,
bool parallel);
162 #define plan(x) emit_tap_output(PLAN, "1..%i", (x))
163 #define note(...) emit_tap_output(NOTE, __VA_ARGS__)
164 #define note_detail(...) emit_tap_output(NOTE_DETAIL, __VA_ARGS__)
165 #define diag(...) emit_tap_output(DIAG, __VA_ARGS__)
166 #define note_end() emit_tap_output(NOTE_END, "\n");
167 #define bail_noatexit(...) bail_out(true, __VA_ARGS__)
168 #define bail(...) bail_out(false, __VA_ARGS__)
173 #if defined(HAVE_GETRLIMIT)
179 getrlimit(RLIMIT_CORE, &lim);
180 if (lim.rlim_max == 0)
182 diag(
"could not set core size: disallowed by hard limit");
185 else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
187 lim.rlim_cur = lim.rlim_max;
188 setrlimit(RLIMIT_CORE, &lim);
204 newentry->
next = NULL;
205 if (*listhead == NULL)
206 *listhead = newentry;
209 for (oldentry = *listhead; oldentry->
next; oldentry = oldentry->
next)
211 oldentry->
next = newentry;
221 if (listhead == NULL || *listhead == NULL)
223 if ((*listhead)->next != NULL)
225 free((*listhead)->str);
292 (ok ? (
int) strlen(
"not ") : 0),
"",
294 (parallel ?
'+' :
'-'),
341 va_list argp_logfile;
376 va_copy(argp_logfile, argp);
440 "\"%s%spg_ctl\" stop -D \"%s/data\" -s",
449 bail_noatexit(
_(
"could not stop postmaster: exit code was %d"), r);
483 raise(postgres_signal_arg);
501 char *
template =
psprintf(
"%s/pg_regress-XXXXXX",
502 getenv(
"TMPDIR") ? getenv(
"TMPDIR") :
"/tmp");
506 bail(
"could not create directory \"%s\": %m",
template);
542 while (*
str && *pattern)
544 if (*pattern ==
'.' && pattern[1] ==
'*')
548 if (*pattern ==
'\0')
561 if (*
str == *pattern || *pattern ==
'.')
575 else if (*pattern !=
'.' && *
str != *pattern)
588 if (*pattern ==
'\0')
592 while (*pattern ==
'.' && pattern[1] ==
'*')
594 if (*pattern ==
'\0')
627 bail(
"could not open file \"%s\" for reading: %m",
buf);
630 while (fgets(
buf,
sizeof(
buf), f))
639 while (
i > 0 && isspace((
unsigned char)
buf[
i - 1]))
643 file_type = strchr(
buf,
':');
646 bail(
"incorrectly formatted resultmap entry: %s",
buf);
650 platform = strchr(file_type,
':');
653 bail(
"incorrectly formatted resultmap entry: %s",
buf);
656 expected = strchr(platform,
'=');
659 bail(
"incorrectly formatted resultmap entry: %s",
buf);
697 if (!file || !(file_type = strrchr(file,
'.')))
704 if (strcmp(testname, rm->
test) == 0 && strcmp(file_type, rm->
type) == 0)
723 setenv(
"PGAPPNAME",
"pg_regress", 1);
731 setenv(
"PG_DLSUFFIX", DLSUFFIX, 1);
753 #if defined(WIN32) || defined(__CYGWIN__) || defined(__darwin__)
766 setenv(
"LC_MESSAGES",
"C", 1);
779 setenv(
"PGTZ",
"America/Los_Angeles", 1);
780 setenv(
"PGDATESTYLE",
"Postgres, MDY", 1);
788 const char *my_pgoptions =
"-c intervalstyle=postgres_verbose";
789 const char *old_pgoptions = getenv(
"PGOPTIONS");
795 old_pgoptions, my_pgoptions);
796 setenv(
"PGOPTIONS", new_pgoptions, 1);
831 unsetenv(
"PGSSLMAXPROTOCOLVERSION");
832 unsetenv(
"PGSSLMINPROTOCOLVERSION");
845 sockdir = getenv(
"PG_REGRESS_SOCK_DIR");
894 pghost = getenv(
"PGHOST");
895 pgport = getenv(
"PGPORT");
908 note(
"using postmaster on %s, default port",
pghost);
910 note(
"using postmaster on Unix socket, port %s",
pgport);
912 note(
"using postmaster on Unix socket, default port");
922 fmtHba(
const char *raw)
928 wp = ret =
pg_realloc(ret, 3 + strlen(raw) * 2);
931 for (rp = raw; *rp; rp++)
948 current_windows_user(
const char **acct,
const char **dom)
953 TOKEN_USER *tokenuser;
955 DWORD accountnamesize =
sizeof(accountname);
956 DWORD domainnamesize =
sizeof(domainname);
957 SID_NAME_USE accountnameuse;
959 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &
token))
961 bail(
"could not open process token: error code %lu", GetLastError());
964 if (!GetTokenInformation(
token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
966 bail(
"could not get token information buffer size: error code %lu",
970 if (!GetTokenInformation(
token, TokenUser, tokenuser, retlen, &retlen))
972 bail(
"could not get token information: error code %lu",
976 if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
977 domainname, &domainnamesize, &accountnameuse))
979 bail(
"could not look up account SID: error code %lu",
998 config_sspi_auth(
const char *pgdata,
const char *superuser_name)
1000 const char *accountname,
1011 current_windows_user(&accountname, &domainname);
1014 if (superuser_name == NULL)
1024 if (superuser_name == NULL)
1035 struct addrinfo *gai_result;
1036 struct addrinfo hints;
1039 hints.ai_flags = AI_NUMERICHOST;
1040 hints.ai_family = AF_UNSPEC;
1041 hints.ai_socktype = 0;
1042 hints.ai_protocol = 0;
1043 hints.ai_addrlen = 0;
1044 hints.ai_canonname = NULL;
1045 hints.ai_addr = NULL;
1046 hints.ai_next = NULL;
1048 have_ipv6 = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0 &&
1049 getaddrinfo(
"::1", NULL, &hints, &gai_result) == 0);
1056 bail("could not write to file \"%s\": %m", fname); \
1059 res =
snprintf(fname,
sizeof(fname),
"%s/pg_hba.conf", pgdata);
1060 if (res < 0 || res >=
sizeof(fname))
1066 bail(
"directory name too long");
1068 hba = fopen(fname,
"w");
1071 bail(
"could not open file \"%s\" for writing: %m", fname);
1073 CW(fputs(
"# Configuration written by config_sspi_auth()\n", hba) >= 0);
1074 CW(fputs(
"host all all 127.0.0.1/32 sspi include_realm=1 map=regress\n",
1077 CW(fputs(
"host all all ::1/128 sspi include_realm=1 map=regress\n",
1079 CW(fclose(hba) == 0);
1081 snprintf(fname,
sizeof(fname),
"%s/pg_ident.conf", pgdata);
1082 ident = fopen(fname,
"w");
1085 bail(
"could not open file \"%s\" for writing: %m", fname);
1087 CW(fputs(
"# Configuration written by config_sspi_auth()\n",
ident) >= 0);
1095 accountname, domainname, fmtHba(superuser_name)) >= 0);
1098 accountname, domainname, fmtHba(sl->
str)) >= 0);
1099 CW(fclose(
ident) == 0);
1119 "\"%s%spsql\" -X -q",
1150 for (cmdptr = cmdbuf.
data; *cmdptr; cmdptr++)
1152 if (strchr(
"\\\"$`", *cmdptr))
1172 if (system(
buf->data) != 0)
1175 bail(
"command failed: %s",
buf->data);
1185 #define psql_command(database, ...) \
1187 StringInfo cmdbuf = psql_start_command(); \
1188 psql_add_command(cmdbuf, __VA_ARGS__); \
1189 psql_end_command(cmdbuf, database); \
1215 bail(
"could not fork: %m");
1228 cmdline2 =
psprintf(
"exec %s", cmdline);
1236 PROCESS_INFORMATION pi;
1238 const char *comspec;
1241 comspec = getenv(
"COMSPEC");
1242 if (comspec == NULL)
1245 memset(&pi, 0,
sizeof(pi));
1246 cmdline2 =
psprintf(
"\"%s\" /c \"%s\"", comspec, cmdline);
1248 if (!CreateRestrictedProcess(cmdline2, &pi))
1251 CloseHandle(pi.hThread);
1263 FILE *f = fopen(file,
"r");
1267 diag(
"could not open file \"%s\" for reading: %m", file);
1270 fseek(f, 0, SEEK_END);
1284 FILE *f = fopen(file,
"r");
1288 diag(
"could not open file \"%s\" for reading: %m", file);
1291 while ((
c = fgetc(f)) != EOF)
1303 FILE *f = fopen(file,
"r");
1316 if (
stat(dir, &st) != 0)
1328 bail(
"could not create directory \"%s\": %m", dir);
1338 int ssize = strlen(expectfile) + 2 + 1;
1342 if (!(tmp = (
char *)
malloc(ssize)))
1345 if (!(s = (
char *)
malloc(ssize)))
1351 strcpy(tmp, expectfile);
1352 last_dot = strrchr(tmp,
'.');
1360 snprintf(s, ssize,
"%s_%d.%s", tmp,
i, last_dot + 1);
1377 bail(
"diff command failed with status %d: %s", r, cmd);
1387 bail(
"diff command not found: %s", cmd);
1401 results_differ(
const char *testname,
const char *resultsfile,
const char *default_expectfile)
1408 int best_line_count;
1411 const char *platform_expectfile;
1419 strlcpy(expectfile, default_expectfile,
sizeof(expectfile));
1420 if (platform_expectfile)
1426 char *p = strrchr(expectfile,
'/');
1429 strcpy(++p, platform_expectfile);
1433 snprintf(diff,
sizeof(diff),
"%s.diff", resultsfile);
1437 "diff %s \"%s\" \"%s\" > \"%s\"",
1449 strcpy(best_expect_file, expectfile);
1451 for (
i = 0;
i <= 9;
i++)
1453 char *alt_expectfile;
1456 if (!alt_expectfile)
1457 bail(
"Unable to check secondary comparison files: %m");
1461 free(alt_expectfile);
1466 "diff %s \"%s\" \"%s\" > \"%s\"",
1472 free(alt_expectfile);
1477 if (l < best_line_count)
1480 best_line_count = l;
1481 strlcpy(best_expect_file, alt_expectfile,
sizeof(best_expect_file));
1483 free(alt_expectfile);
1491 if (platform_expectfile)
1494 "diff %s \"%s\" \"%s\" > \"%s\"",
1505 if (l < best_line_count)
1508 best_line_count = l;
1509 strlcpy(best_expect_file, default_expectfile,
sizeof(best_expect_file));
1530 "diff %s \"%s\" \"%s\" >> \"%s\"",
1548 char **names,
int num_tests)
1556 memcpy(active_pids, pids, num_tests *
sizeof(
PID_TYPE));
1559 tests_left = num_tests;
1560 while (tests_left > 0)
1567 p = wait(&exit_status);
1570 bail(
"failed to wait for subprocesses: %m");
1575 r = WaitForMultipleObjects(tests_left, active_pids, FALSE, INFINITE);
1576 if (r < WAIT_OBJECT_0 || r >= WAIT_OBJECT_0 + tests_left)
1578 bail(
"failed to wait for subprocesses: error code %lu",
1581 p = active_pids[r - WAIT_OBJECT_0];
1583 active_pids[r - WAIT_OBJECT_0] = active_pids[tests_left - 1];
1586 for (
i = 0;
i < num_tests;
i++)
1591 GetExitCodeProcess(pids[
i], &exit_status);
1592 CloseHandle(pids[
i]);
1595 statuses[
i] = (int) exit_status;
1617 diag(
"(test process exited with exit code %d)",
1622 diag(
"(test process was terminated by exception 0x%X)",
1625 diag(
"(test process was terminated by signal %d: %s)",
1630 diag(
"(test process exited with unrecognized status %d)", exitstatus);
1640 #define MAX_PARALLEL_TESTS 100
1653 memset(tests, 0,
sizeof(tests));
1654 memset(resultfiles, 0,
sizeof(resultfiles));
1655 memset(expectfiles, 0,
sizeof(expectfiles));
1656 memset(tags, 0,
sizeof(tags));
1658 scf = fopen(schedule,
"r");
1660 bail(
"could not open file \"%s\" for reading: %m", schedule);
1662 while (fgets(scbuf,
sizeof(scbuf), scf))
1674 while (
i > 0 && isspace((
unsigned char) scbuf[
i - 1]))
1677 if (scbuf[0] ==
'\0' || scbuf[0] ==
'#')
1679 if (strncmp(scbuf,
"test: ", 6) == 0)
1683 bail(
"syntax error in schedule file \"%s\" line %d: %s",
1684 schedule, line_num, scbuf);
1691 if (*
c ==
'\0' || isspace((
unsigned char) *
c))
1700 bail(
"too many parallel tests (more than %d) in schedule file \"%s\" line %d: %s",
1723 bail(
"syntax error in schedule file \"%s\" line %d: %s",
1724 schedule, line_num, scbuf);
1729 pids[0] = (startfunc) (tests[0], &resultfiles[0], &expectfiles[0], &tags[0]);
1736 bail(
"too many parallel tests (more than %d) in schedule file \"%s\" line %d: %s",
1743 note_detail(
"parallel group (%d tests, in groups of %d): ",
1745 for (
i = 0;
i < num_tests;
i++)
1751 tests + oldest,
i - oldest);
1754 pids[
i] = (startfunc) (tests[
i], &resultfiles[
i], &expectfiles[
i], &tags[
i]);
1759 tests + oldest,
i - oldest);
1764 note_detail(
"parallel group (%d tests): ", num_tests);
1765 for (
i = 0;
i < num_tests;
i++)
1767 pids[
i] = (startfunc) (tests[
i], &resultfiles[
i], &expectfiles[
i], &tags[
i]);
1775 for (
i = 0;
i < num_tests;
i++)
1780 bool differ =
false;
1791 for (rl = resultfiles[
i], el = expectfiles[
i], tl = tags[
i];
1794 tl = tl ? tl->
next : NULL)
1799 (*postfunc) (rl->
str);
1808 if (statuses[
i] != 0)
1826 for (
i = 0;
i < num_tests;
i++)
1856 bool differ =
false;
1858 pid = (startfunc) (
test, &resultfiles, &expectfiles, &tags);
1869 for (rl = resultfiles, el = expectfiles, tl = tags;
1872 tl = tl ? tl->
next : NULL)
1877 (*postfunc) (rl->
str);
1888 if (exit_status != 0)
1970 "ALTER DATABASE \"%s\" SET lc_messages TO 'C';"
1971 "ALTER DATABASE \"%s\" SET lc_monetary TO 'C';"
1972 "ALTER DATABASE \"%s\" SET lc_numeric TO 'C';"
1973 "ALTER DATABASE \"%s\" SET lc_time TO 'C';"
1974 "ALTER DATABASE \"%s\" SET bytea_output TO 'hex';"
1975 "ALTER DATABASE \"%s\" SET timezone_abbreviations TO 'Default';",
2004 for (; granted_dbs != NULL; granted_dbs = granted_dbs->
next)
2007 granted_dbs->
str, rolename);
2015 printf(
_(
"PostgreSQL regression test driver\n"));
2020 printf(
_(
" --bindir=BINPATH use BINPATH for programs that are run;\n"));
2021 printf(
_(
" if empty, use PATH from the environment\n"));
2022 printf(
_(
" --config-auth=DATADIR update authentication settings for DATADIR\n"));
2023 printf(
_(
" --create-role=ROLE create the specified role before testing\n"));
2024 printf(
_(
" --dbname=DB use database DB (default \"regression\")\n"));
2025 printf(
_(
" --debug turn on debug mode in programs that are run\n"));
2026 printf(
_(
" --dlpath=DIR look for dynamic libraries in DIR\n"));
2027 printf(
_(
" --encoding=ENCODING use ENCODING as the encoding\n"));
2028 printf(
_(
" --expecteddir=DIR take expected files from DIR (default \".\")\n"));
2029 printf(
_(
" -h, --help show this help, then exit\n"));
2030 printf(
_(
" --inputdir=DIR take input files from DIR (default \".\")\n"));
2031 printf(
_(
" --launcher=CMD use CMD as launcher of psql\n"));
2032 printf(
_(
" --load-extension=EXT load the named extension before running the\n"));
2033 printf(
_(
" tests; can appear multiple times\n"));
2034 printf(
_(
" --max-connections=N maximum number of concurrent connections\n"));
2035 printf(
_(
" (default is 0, meaning unlimited)\n"));
2036 printf(
_(
" --max-concurrent-tests=N maximum number of concurrent tests in schedule\n"));
2037 printf(
_(
" (default is 0, meaning unlimited)\n"));
2038 printf(
_(
" --outputdir=DIR place output files in DIR (default \".\")\n"));
2039 printf(
_(
" --schedule=FILE use test ordering schedule from FILE\n"));
2040 printf(
_(
" (can be used multiple times to concatenate)\n"));
2041 printf(
_(
" --temp-instance=DIR create a temporary instance in DIR\n"));
2042 printf(
_(
" --use-existing use an existing installation\n"));
2043 printf(
_(
" -V, --version output version information, then exit\n"));
2045 printf(
_(
"Options for \"temp-instance\" mode:\n"));
2046 printf(
_(
" --no-locale use C locale\n"));
2047 printf(
_(
" --port=PORT start postmaster on PORT\n"));
2048 printf(
_(
" --temp-config=FILE append contents of FILE to temporary config\n"));
2050 printf(
_(
"Options for using an existing installation:\n"));
2051 printf(
_(
" --host=HOST use postmaster running on HOST\n"));
2052 printf(
_(
" --port=PORT use postmaster running at PORT\n"));
2053 printf(
_(
" --user=USER connect as USER\n"));
2055 printf(
_(
"The exit status is 0 if all tests passed, 1 if some tests failed, and 2\n"));
2056 printf(
_(
"if the tests could not be run for some reason.\n"));
2058 printf(
_(
"Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
2059 printf(
_(
"%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
2068 static struct option long_options[] = {
2096 bool use_unix_sockets;
2117 use_unix_sockets = getenv(
"PG_TEST_USE_UNIX_SOCKETS") ?
true :
false;
2119 use_unix_sockets =
true;
2122 if (!use_unix_sockets)
2131 if (getenv(
"PG_REGRESS_DIFF_OPTS"))
2134 while ((
c =
getopt_long(argc, argv,
"hV", long_options, &option_index)) != -1)
2142 puts(
"pg_regress (PostgreSQL) " PG_VERSION);
2232 while (argc -
optind >= 1)
2244 bail(
"no database name was specified");
2250 if (!use_unix_sockets)
2265 port = 0xC000 | (PG_VERSION_NUM & 0x3FFF);
2279 #if defined(HAVE_GETRLIMIT)
2287 const char *env_wait;
2289 const char *initdb_template_dir;
2290 const char *keywords[4];
2293 const char *initdb_extra_opts_env;
2315 initdb_extra_opts_env = getenv(
"PG_TEST_INITDB_EXTRA_OPTS");
2328 initdb_template_dir = getenv(
"INITDB_TEMPLATE");
2329 if (initdb_template_dir == NULL ||
nolocale ||
debug || initdb_extra_opts_env)
2331 note(
"initializing database system by running initdb");
2334 "\"%s%sinitdb\" -D \"%s/data\" --no-clean --no-sync",
2342 if (initdb_extra_opts_env)
2346 if (system(cmd.
data))
2348 bail(
"initdb failed\n"
2349 "# Examine \"%s/log/initdb.log\" for the reason.\n"
2350 "# Command was: %s",
2357 const char *copycmd =
"cp -RPp \"%s\" \"%s/data\"";
2358 int expected_exitcode = 0;
2360 const char *copycmd =
"robocopy /E /NJS /NJH /NFL /NDL /NP \"%s\" \"%s/data\"";
2361 int expected_exitcode = 1;
2364 note(
"initializing database system by copying initdb template");
2368 initdb_template_dir,
2372 if (system(cmd.
data) != expected_exitcode)
2374 bail(
"copying of initdb template failed\n"
2375 "# Examine \"%s/log/initdb.log\" for the reason.\n"
2376 "# Command was: %s",
2392 pg_conf = fopen(
buf,
"a");
2393 if (pg_conf == NULL)
2394 bail(
"could not open \"%s\" for adding extra config: %m",
buf);
2396 fputs(
"\n# Configuration added by pg_regress\n\n", pg_conf);
2397 fputs(
"log_autovacuum_min_duration = 0\n", pg_conf);
2398 fputs(
"log_checkpoints = on\n", pg_conf);
2399 fputs(
"log_line_prefix = '%m %b[%p] %q%a '\n", pg_conf);
2400 fputs(
"log_lock_waits = on\n", pg_conf);
2401 fputs(
"log_temp_files = 128kB\n", pg_conf);
2402 fputs(
"max_prepared_transactions = 2\n", pg_conf);
2406 char *temp_config = sl->
str;
2408 char line_buf[1024];
2410 extra_conf = fopen(temp_config,
"r");
2411 if (extra_conf == NULL)
2413 bail(
"could not open \"%s\" to read extra config: %m",
2416 while (fgets(line_buf,
sizeof(line_buf), extra_conf) != NULL)
2417 fputs(line_buf, pg_conf);
2424 if (!use_unix_sockets)
2431 config_sspi_auth(
buf, NULL);
2440 keywords[0] =
"dbname";
2442 keywords[1] =
"port";
2444 keywords[2] =
"host";
2452 for (
i = 0;
i < 16;
i++)
2460 note(
"port %d apparently in use",
port);
2462 note(
"could not determine an available port");
2463 bail(
"Specify an unused port using the --port option or shut down any conflicting PostgreSQL servers.");
2466 note(
"port %d apparently in use, trying %d",
port,
port + 1);
2479 "\"%s%spostgres\" -D \"%s/data\" -F%s "
2480 "-c \"listen_addresses=%s\" -k \"%s\" "
2481 "> \"%s/log/postmaster.log\" 2>&1",
2489 bail(
"could not spawn postmaster: %m");
2498 env_wait = getenv(
"PGCTLTIMEOUT");
2499 if (env_wait != NULL)
2524 bail(
"attempting to connect to postmaster failed");
2535 bail(
"postmaster failed, examine \"%s/log/postmaster.log\" for the reason",
2541 diag(
"postmaster did not respond within %d seconds, examine \"%s/log/postmaster.log\" for the reason",
2552 bail(
"could not kill failed postmaster: %m");
2555 bail(
"could not kill failed postmaster: error code %lu",
2558 bail(
"postmaster failed");
2565 #define ULONGPID(x) (unsigned long) (unsigned long long) (x)
2567 #define ULONGPID(x) (unsigned long) (x)
2569 note(
"using temp instance on port %d with PID %lu",
2627 diag(
"could not remove temp instance \"%s\"",
2646 diag(
"The differences that caused some tests to fail can be viewed in the file \"%s\".",
2648 diag(
"A copy of the test summary that you see above is saved in the file \"%s\".",
static Datum values[MAXATTR]
#define Assert(condition)
#define PG_TEXTDOMAIN(domain)
#define pg_attribute_printf(f, a)
void set_pglocale_pgservice(const char *argv0, const char *app)
static void PGresult * res
PGPing PQpingParams(const char *const *keywords, const char *const *values, int expand_dbname)
void * pg_realloc(void *ptr, size_t size)
char * pg_strdup(const char *in)
void * pg_malloc(size_t size)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
#define required_argument
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_SUBTRACT(x, y)
#define INSTR_TIME_GET_MILLISEC(t)
static void const char * fmt
static void const char fflush(stdout)
vfprintf(stderr, fmt, args)
void pg_logging_init(const char *argv0)
#define pg_log_error_hint(...)
void pfree(void *pointer)
#define DEFAULT_PGSOCKET_DIR
PGDLLIMPORT char * optarg
static void open_result_files(void)
static int max_connections
static bool port_specified_by_user
static int file_line_count(const char *file)
static void load_resultmap(void)
static void psql_add_command(StringInfo buf, const char *query,...) pg_attribute_printf(2
static void static void static void static StringInfo psql_start_command(void)
bool file_exists(const char *file)
static void signal_remove_temp(SIGNAL_ARGS)
static void remove_temp(void)
static void stop_postmaster(void)
static int max_concurrent_tests
static void create_database(const char *dbname)
static void free_stringlist(_stringlist **listhead)
static void drop_role_if_exists(const char *rolename)
#define MAX_PARALLEL_TESTS
static void static void psql_end_command(StringInfo buf, const char *database)
static void static void emit_tap_output(TAPtype type, const char *fmt,...) pg_attribute_printf(2
static StringInfo failed_tests
static void unlimit_core_size(void)
static const char * temp_sockdir
static bool directory_exists(const char *dir)
static _stringlist * schedulelist
#define WAIT_TICKS_PER_SECOND
static _stringlist * loadextension
static char * logfilename
static _stringlist * temp_configs
static _stringlist * extra_tests
static void test_status_ok(const char *testname, double runtime, bool parallel)
static void make_directory(const char *dir)
static void split_to_stringlist(const char *s, const char *delim, _stringlist **listhead)
static int run_diff(const char *cmd, const char *filename)
static void run_single_test(const char *test, test_start_function startfunc, postprocess_result_function postfunc)
const char * pretty_diff_opts
static void log_child_failure(int exitstatus)
int regression_main(int argc, char *argv[], init_function ifunc, test_start_function startfunc, postprocess_result_function postfunc)
#define bail_noatexit(...)
static char * difffilename
static const char * get_expectfile(const char *testname, const char *file)
static void bail_out(bool noatexit, const char *fmt,...) pg_attribute_printf(2
static _resultmap * resultmap
struct _resultmap _resultmap
static char * config_auth_datadir
static void drop_database_if_exists(const char *dbname)
static void test_status_failed(const char *testname, double runtime, bool parallel)
const char * basic_diff_opts
static void initialize_environment(void)
static char * temp_instance
static char sockself[MAXPGPATH]
static void wait_for_tests(PID_TYPE *pids, int *statuses, instr_time *stoptimes, char **names, int num_tests)
static const char * sockdir
static long file_size(const char *file)
static bool postmaster_running
static char socklock[MAXPGPATH]
static const char * progname
static _stringlist * extraroles
static bool results_differ(const char *testname, const char *resultsfile, const char *default_expectfile)
static const char * make_temp_sockdir(void)
PID_TYPE spawn_process(const char *cmdline)
static void test_status_print(bool ok, const char *testname, double runtime, bool parallel)
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)
static bool string_matches_pattern(const char *str, const char *pattern)
static void static void static void emit_tap_output_v(TAPtype type, const char *fmt, va_list argp) pg_attribute_printf(2
static char * get_alternative_expectfile(const char *expectfile, int i)
#define psql_command(database,...)
static PID_TYPE postmaster_pid
void(* init_function)(int argc, char **argv)
PID_TYPE(* test_start_function)(const char *testname, _stringlist **resultfiles, _stringlist **expectfiles, _stringlist **tags)
void(* postprocess_result_function)(const char *filename)
static const char * pghost
static const char * pgport
char * make_absolute_path(const char *path)
const char * get_progname(const char *argv0)
pqsigfunc pqsignal(int signo, pqsigfunc func)
const char * pg_strsignal(int signum)
char * strsep(char **stringp, const char *delim)
size_t strlcpy(char *dst, const char *src, size_t siz)
char * mkdtemp(char *path)
#define UNIXSOCK_PATH(path, port, sockdir)
char * psprintf(const char *fmt,...)
void get_restricted_token(void)
bool rmtree(const char *path, bool rmtopdir)
void pg_usleep(long microsec)
int appendStringInfoVA(StringInfo str, const char *fmt, va_list args)
void destroyStringInfo(StringInfo str)
StringInfo makeStringInfo(void)
void appendStringInfo(StringInfo str, const char *fmt,...)
void enlargeStringInfo(StringInfo str, int needed)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
struct _stringlist * next
const char * get_user_name(char **errstr)