1 /*-------------------------------------------------------------------------
3 * pg_regress --- regression test driver
5 * This is a C implementation of the previous shell script for running
6 * the regression tests, and should be mostly compatible with it.
7 * Initial author of C translation: Magnus Hagander
9 * This code is released under the terms of the PostgreSQL License.
11 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
14 * src/test/regress/pg_regress.c
16 *-------------------------------------------------------------------------
19 #include "postgres_fe.h"
22 #include <sys/resource.h>
29 #include "common/logging.h"
30 #include "common/restricted_token.h"
31 #include "common/string.h"
32 #include "common/username.h"
33 #include "getopt_long.h"
34 #include "lib/stringinfo.h"
36 #include "libpq/pqcomm.h" /* needed for UNIXSOCK_PATH() */
37 #include "pg_config_paths.h"
38 #include "pg_regress.h"
39 #include "portability/instr_time.h"
41 /* for resultmap we need a list of pairs of strings */
42 typedef struct _resultmap
47 struct _resultmap
*next
;
51 * Values obtained from Makefile.
53 char *host_platform
= HOST_TUPLE
;
55 #ifndef WIN32 /* not used in WIN32 case */
56 static char *shellprog
= SHELLPROG
;
60 * On Windows we use -w in diff switches to avoid problems with inconsistent
61 * newline representation. The actual result files will generally have
62 * Windows-style newlines, but the comparison files might or might not.
65 const char *basic_diff_opts
= "";
66 const char *pretty_diff_opts
= "-U3";
68 const char *basic_diff_opts
= "-w";
69 const char *pretty_diff_opts
= "-w -U3";
73 * The width of the testname field when printing to ensure vertical alignment
74 * of test runtimes. This number is somewhat arbitrarily chosen to match the
75 * older pre-TAP output format.
77 #define TESTNAME_WIDTH 36
80 * The number times per second that pg_regress checks to see if the test
81 * instance server has started and is available for connection.
83 #define WAIT_TICKS_PER_SECOND 20
97 /* options settable from command line */
98 _stringlist
*dblist
= NULL
;
100 char *inputdir
= ".";
101 char *outputdir
= ".";
102 char *expecteddir
= ".";
103 char *bindir
= PGBINDIR
;
104 char *launcher
= NULL
;
105 static _stringlist
*loadextension
= NULL
;
106 static int max_connections
= 0;
107 static int max_concurrent_tests
= 0;
108 static char *encoding
= NULL
;
109 static _stringlist
*schedulelist
= NULL
;
110 static _stringlist
*extra_tests
= NULL
;
111 static char *temp_instance
= NULL
;
112 static _stringlist
*temp_configs
= NULL
;
113 static bool nolocale
= false;
114 static bool use_existing
= false;
115 static char *hostname
= NULL
;
116 static int port
= -1;
117 static char portstr
[16];
118 static bool port_specified_by_user
= false;
119 static char *dlpath
= PKGLIBDIR
;
120 static char *user
= NULL
;
121 static _stringlist
*extraroles
= NULL
;
122 static char *config_auth_datadir
= NULL
;
124 /* internal variables */
125 static const char *progname
;
126 static char *logfilename
;
127 static FILE *logfile
;
128 static char *difffilename
;
129 static const char *sockdir
;
130 static const char *temp_sockdir
;
131 static char sockself
[MAXPGPATH
];
132 static char socklock
[MAXPGPATH
];
133 static StringInfo failed_tests
= NULL
;
134 static bool in_note
= false;
136 static _resultmap
*resultmap
= NULL
;
138 static PID_TYPE postmaster_pid
= INVALID_PID
;
139 static bool postmaster_running
= false;
141 static int success_count
= 0;
142 static int fail_count
= 0;
144 static bool directory_exists(const char *dir
);
145 static void make_directory(const char *dir
);
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
);
149 static void test_status_failed(const char *testname
, double runtime
, bool parallel
);
150 static void bail_out(bool noatexit
, const char *fmt
,...) pg_attribute_printf(2, 3);
151 static void emit_tap_output(TAPtype type
, const char *fmt
,...) pg_attribute_printf(2, 3);
152 static void emit_tap_output_v(TAPtype type
, const char *fmt
, va_list argp
) pg_attribute_printf(2, 0);
154 static StringInfo
psql_start_command(void);
155 static void psql_add_command(StringInfo buf
, const char *query
,...) pg_attribute_printf(2, 3);
156 static void psql_end_command(StringInfo buf
, const char *database
);
159 * Convenience macros for printing TAP output with a more shorthand syntax
160 * aimed at making the code more readable.
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__)
171 * allow core files if possible.
173 #if defined(HAVE_GETRLIMIT)
175 unlimit_core_size(void)
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
);
195 * Add an item at the end of a stringlist.
198 add_stringlist_item(_stringlist
**listhead
, const char *str
)
200 _stringlist
*newentry
= pg_malloc(sizeof(_stringlist
));
201 _stringlist
*oldentry
;
203 newentry
->str
= pg_strdup(str
);
204 newentry
->next
= NULL
;
205 if (*listhead
== NULL
)
206 *listhead
= newentry
;
209 for (oldentry
= *listhead
; oldentry
->next
; oldentry
= oldentry
->next
)
211 oldentry
->next
= newentry
;
219 free_stringlist(_stringlist
**listhead
)
221 if (listhead
== NULL
|| *listhead
== NULL
)
223 if ((*listhead
)->next
!= NULL
)
224 free_stringlist(&((*listhead
)->next
));
225 free((*listhead
)->str
);
231 * Split a delimited string into a stringlist
234 split_to_stringlist(const char *s
, const char *delim
, _stringlist
**listhead
)
236 char *sc
= pg_strdup(s
);
237 char *token
= strtok(sc
, delim
);
241 add_stringlist_item(listhead
, token
);
242 token
= strtok(NULL
, delim
);
248 * Bailing out is for unrecoverable errors which prevents further testing to
249 * occur and after which the test run should be aborted. By passing noatexit
250 * as true the process will terminate with _exit(2) and skipping registered
251 * exit handlers, thus avoid any risk of bottomless recursion calls to exit.
254 bail_out(bool noatexit
, const char *fmt
,...)
259 emit_tap_output_v(BAIL
, fmt
, ap
);
269 * Print the result of a test run and associated metadata like runtime. Care
270 * is taken to align testnames and runtimes vertically to ensure the output
271 * is human readable while still TAP compliant. Tests run in parallel are
272 * prefixed with a '+' and sequential tests with a '-'. This distinction was
273 * previously indicated by 'test' prefixing sequential tests while parallel
274 * tests were indented by four leading spaces. The meson TAP parser consumes
275 * leading space however, so a non-whitespace prefix of the same length is
279 test_status_print(bool ok
, const char *testname
, double runtime
, bool parallel
)
281 int testnumber
= fail_count
+ success_count
;
284 * Testnumbers are padded to 5 characters to ensure that testnames align
285 * vertically (assuming at most 9999 tests). Testnames are prefixed with
286 * a leading character to indicate being run in parallel or not. A leading
287 * '+' indicates a parallel test, '-' indicates a single test.
289 emit_tap_output(TEST_STATUS
, "%sok %-5i%*s %c %-*s %8.0f ms",
292 /* If ok, indent with four spaces matching "not " */
293 (ok
? (int) strlen("not ") : 0), "",
294 /* Prefix a parallel test '+' and a single test with '-' */
295 (parallel
? '+' : '-'),
296 /* Testnames are padded to align runtimes */
297 TESTNAME_WIDTH
, testname
,
302 test_status_ok(const char *testname
, double runtime
, bool parallel
)
306 test_status_print(true, testname
, runtime
, parallel
);
310 test_status_failed(const char *testname
, double runtime
, bool parallel
)
313 * Save failed tests in a buffer such that we can print a summary at the
314 * end with diag() to ensure it's shown even under test harnesses.
317 failed_tests
= makeStringInfo();
319 appendStringInfoChar(failed_tests
, ',');
321 appendStringInfo(failed_tests
, " %s", testname
);
325 test_status_print(false, testname
, runtime
, parallel
);
330 emit_tap_output(TAPtype type
, const char *fmt
,...)
335 emit_tap_output_v(type
, fmt
, argp
);
340 emit_tap_output_v(TAPtype type
, const char *fmt
, va_list argp
)
342 va_list argp_logfile
;
347 * The fprintf() calls used to output TAP-protocol elements might clobber
348 * errno, so save it here and restore it before vfprintf()-ing the user's
349 * format string, in case it contains %m placeholders.
354 * Diagnostic output will be hidden by prove unless printed to stderr. The
355 * Bail message is also printed to stderr to aid debugging under a harness
356 * which might otherwise not emit such an important message.
358 if (type
== DIAG
|| type
== BAIL
)
364 * If we are ending a note_detail line we can avoid further processing and
365 * immediately return following a newline.
367 if (type
== NOTE_END
)
372 fprintf(logfile
, "\n");
376 /* Make a copy of the va args for printing to the logfile */
377 va_copy(argp_logfile
, argp
);
380 * Non-protocol output such as diagnostics or notes must be prefixed by a
381 * '#' character. We print the Bail message like this too.
383 if ((type
== NOTE
|| type
== DIAG
|| type
== BAIL
)
384 || (type
== NOTE_DETAIL
&& !in_note
))
388 fprintf(logfile
, "# ");
391 vfprintf(fp
, fmt
, argp
);
395 vfprintf(logfile
, fmt
, argp_logfile
);
399 * If we are entering into a note with more details to follow, register
400 * that the leading '#' has been printed such that subsequent details
401 * aren't prefixed as well.
403 if (type
== NOTE_DETAIL
)
407 * If this was a Bail message, the bail protocol message must go to stdout
412 fprintf(stdout
, "Bail out!");
414 fprintf(logfile
, "Bail out!");
417 va_end(argp_logfile
);
419 if (type
!= NOTE_DETAIL
)
423 fprintf(logfile
, "\n");
429 * shut down temp postmaster
432 stop_postmaster(void)
434 if (postmaster_running
)
436 /* We use pg_ctl to issue the kill and wait for stop */
437 char buf
[MAXPGPATH
* 2];
440 snprintf(buf
, sizeof(buf
),
441 "\"%s%spg_ctl\" stop -D \"%s/data\" -s",
442 bindir
? bindir
: "",
449 /* Not using the normal bail() as we want _exit */
450 bail_noatexit(_("could not stop postmaster: exit code was %d"), r
);
453 postmaster_running
= false;
458 * Remove the socket temporary directory. pg_regress never waits for a
459 * postmaster exit, so it is indeterminate whether the postmaster has yet to
460 * unlink the socket and lock file. Unlink them here so we can proceed to
461 * remove the directory. Ignore errors; leaking a temporary directory is
462 * unimportant. This can run from a signal handler. The code is not
463 * acceptable in a Windows signal handler (see initdb.c:trapsig()), but
464 * on Windows, pg_regress does not use Unix sockets by default.
469 Assert(temp_sockdir
);
476 * Signal handler that calls remove_temp() and reraises the signal.
479 signal_remove_temp(SIGNAL_ARGS
)
483 pqsignal(postgres_signal_arg
, SIG_DFL
);
484 raise(postgres_signal_arg
);
488 * Create a temporary directory suitable for the server's Unix-domain socket.
489 * The directory will have mode 0700 or stricter, so no other OS user can open
490 * our socket to exploit our use of trust authentication. Most systems
491 * constrain the length of socket paths well below _POSIX_PATH_MAX, so we
492 * place the directory under /tmp rather than relative to the possibly-deep
493 * current working directory.
495 * Compared to using the compiled-in DEFAULT_PGSOCKET_DIR, this also permits
496 * testing to work in builds that relocate it to a directory not writable to
497 * the build/test user.
500 make_temp_sockdir(void)
502 char *template = psprintf("%s/pg_regress-XXXXXX",
503 getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
505 temp_sockdir
= mkdtemp(template);
506 if (temp_sockdir
== NULL
)
507 bail("could not create directory \"%s\": %m", template);
509 /* Stage file names for remove_temp(). Unsafe in a signal handler. */
510 UNIXSOCK_PATH(sockself
, port
, temp_sockdir
);
511 snprintf(socklock
, sizeof(socklock
), "%s.lock", sockself
);
513 /* Remove the directory during clean exit. */
517 * Remove the directory before dying to the usual signals. Omit SIGQUIT,
518 * preserving it as a quick, untidy exit.
520 pqsignal(SIGHUP
, signal_remove_temp
);
521 pqsignal(SIGINT
, signal_remove_temp
);
522 pqsignal(SIGPIPE
, signal_remove_temp
);
523 pqsignal(SIGTERM
, signal_remove_temp
);
529 * Check whether string matches pattern
531 * In the original shell script, this function was implemented using expr(1),
532 * which provides basic regular expressions restricted to match starting at
533 * the string start (in conventional regex terms, there's an implicit "^"
534 * at the start of the pattern --- but no implicit "$" at the end).
536 * For now, we only support "." and ".*" as non-literal metacharacters,
537 * because that's all that anyone has found use for in resultmap. This
538 * code could be extended if more functionality is needed.
541 string_matches_pattern(const char *str
, const char *pattern
)
543 while (*str
&& *pattern
)
545 if (*pattern
== '.' && pattern
[1] == '*')
548 /* Trailing .* matches everything. */
549 if (*pattern
== '\0')
553 * Otherwise, scan for a text position at which we can match the
554 * rest of the pattern.
559 * Optimization to prevent most recursion: don't recurse
560 * unless first pattern char might match this text char.
562 if (*str
== *pattern
|| *pattern
== '.')
564 if (string_matches_pattern(str
, pattern
))
572 * End of text with no match.
576 else if (*pattern
!= '.' && *str
!= *pattern
)
579 * Not the single-character wildcard and no explicit match? Then
589 if (*pattern
== '\0')
590 return true; /* end of pattern, so declare match */
592 /* End of input string. Do we have matching pattern remaining? */
593 while (*pattern
== '.' && pattern
[1] == '*')
595 if (*pattern
== '\0')
596 return true; /* end of pattern, so declare match */
602 * Scan resultmap file to find which platform-specific expected files to use.
604 * The format of each line of the file is
605 * testname/hostplatformpattern=substitutefile
606 * where the hostplatformpattern is evaluated per the rules of expr(1),
607 * namely, it is a standard regular expression with an implicit ^ at the start.
608 * (We currently support only a very limited subset of regular expressions,
609 * see string_matches_pattern() above.) What hostplatformpattern will be
610 * matched against is the config.guess output. (In the shell-script version,
611 * we also provided an indication of whether gcc or another compiler was in
612 * use, but that facility isn't used anymore.)
620 /* scan the file ... */
621 snprintf(buf
, sizeof(buf
), "%s/resultmap", inputdir
);
625 /* OK if it doesn't exist, else complain */
628 bail("could not open file \"%s\" for reading: %m", buf
);
631 while (fgets(buf
, sizeof(buf
), f
))
638 /* strip trailing whitespace, especially the newline */
640 while (i
> 0 && isspace((unsigned char) buf
[i
- 1]))
643 /* parse out the line fields */
644 file_type
= strchr(buf
, ':');
647 bail("incorrectly formatted resultmap entry: %s", buf
);
651 platform
= strchr(file_type
, ':');
654 bail("incorrectly formatted resultmap entry: %s", buf
);
657 expected
= strchr(platform
, '=');
660 bail("incorrectly formatted resultmap entry: %s", buf
);
665 * if it's for current platform, save it in resultmap list. Note: by
666 * adding at the front of the list, we ensure that in ambiguous cases,
667 * the last match in the resultmap file is used. This mimics the
668 * behavior of the old shell script.
670 if (string_matches_pattern(host_platform
, platform
))
672 _resultmap
*entry
= pg_malloc(sizeof(_resultmap
));
674 entry
->test
= pg_strdup(buf
);
675 entry
->type
= pg_strdup(file_type
);
676 entry
->resultfile
= pg_strdup(expected
);
677 entry
->next
= resultmap
;
685 * Check in resultmap if we should be looking at a different file
689 get_expectfile(const char *testname
, const char *file
)
695 * Determine the file type from the file name. This is just what is
696 * following the last dot in the file name.
698 if (!file
|| !(file_type
= strrchr(file
, '.')))
703 for (rm
= resultmap
; rm
!= NULL
; rm
= rm
->next
)
705 if (strcmp(testname
, rm
->test
) == 0 && strcmp(file_type
, rm
->type
) == 0)
707 return rm
->resultfile
;
715 * Prepare environment variables for running regression tests
718 initialize_environment(void)
721 * Set default application_name. (The test_start_function may choose to
722 * override this, but if it doesn't, we have something useful in place.)
724 setenv("PGAPPNAME", "pg_regress", 1);
727 * Set variables that the test scripts may need to refer to.
729 setenv("PG_ABS_SRCDIR", inputdir
, 1);
730 setenv("PG_ABS_BUILDDIR", outputdir
, 1);
731 setenv("PG_LIBDIR", dlpath
, 1);
732 setenv("PG_DLSUFFIX", DLSUFFIX
, 1);
737 * Clear out any non-C locale settings
739 unsetenv("LC_COLLATE");
740 unsetenv("LC_CTYPE");
741 unsetenv("LC_MONETARY");
742 unsetenv("LC_NUMERIC");
747 * Most platforms have adopted the POSIX locale as their
748 * implementation-defined default locale. Exceptions include native
749 * Windows, macOS with --enable-nls, and Cygwin with --enable-nls.
750 * (Use of --enable-nls matters because libintl replaces setlocale().)
751 * Also, PostgreSQL does not support macOS with locale environment
752 * variables unset; see PostmasterMain().
754 #if defined(WIN32) || defined(__CYGWIN__) || defined(__darwin__)
755 setenv("LANG", "C", 1);
760 * Set translation-related settings to English; otherwise psql will
761 * produce translated messages and produce diffs. (XXX If we ever support
762 * translation of pg_regress, this needs to be moved elsewhere, where psql
763 * is actually called.)
765 unsetenv("LANGUAGE");
767 setenv("LC_MESSAGES", "C", 1);
770 * Set encoding as requested
773 setenv("PGCLIENTENCODING", encoding
, 1);
775 unsetenv("PGCLIENTENCODING");
778 * Set timezone and datestyle for datetime-related tests
780 setenv("PGTZ", "PST8PDT", 1);
781 setenv("PGDATESTYLE", "Postgres, MDY", 1);
784 * Likewise set intervalstyle to ensure consistent results. This is a bit
785 * more painful because we must use PGOPTIONS, and we want to preserve the
786 * user's ability to set other variables through that.
789 const char *my_pgoptions
= "-c intervalstyle=postgres_verbose";
790 const char *old_pgoptions
= getenv("PGOPTIONS");
795 new_pgoptions
= psprintf("%s %s",
796 old_pgoptions
, my_pgoptions
);
797 setenv("PGOPTIONS", new_pgoptions
, 1);
804 * Clear out any environment vars that might cause psql to connect to
805 * the wrong postmaster, or otherwise behave in nondefault ways. (Note
806 * we also use psql's -X switch consistently, so that ~/.psqlrc files
807 * won't mess things up.) Also, set PGPORT to the temp port, and set
808 * PGHOST depending on whether we are using TCP or Unix sockets.
810 * This list should be kept in sync with PostgreSQL/Test/Utils.pm.
812 unsetenv("PGCHANNELBINDING");
813 /* PGCLIENTENCODING, see above */
814 unsetenv("PGCONNECT_TIMEOUT");
816 unsetenv("PGDATABASE");
817 unsetenv("PGGSSDELEGATION");
818 unsetenv("PGGSSENCMODE");
819 unsetenv("PGGSSLIB");
820 /* PGHOSTADDR, see below */
821 unsetenv("PGKRBSRVNAME");
822 unsetenv("PGPASSFILE");
823 unsetenv("PGPASSWORD");
824 unsetenv("PGREQUIREPEER");
825 unsetenv("PGREQUIRESSL");
826 unsetenv("PGSERVICE");
827 unsetenv("PGSERVICEFILE");
828 unsetenv("PGSSLCERT");
829 unsetenv("PGSSLCRL");
830 unsetenv("PGSSLCRLDIR");
831 unsetenv("PGSSLKEY");
832 unsetenv("PGSSLMAXPROTOCOLVERSION");
833 unsetenv("PGSSLMINPROTOCOLVERSION");
834 unsetenv("PGSSLMODE");
835 unsetenv("PGSSLROOTCERT");
836 unsetenv("PGSSLSNI");
837 unsetenv("PGTARGETSESSIONATTRS");
839 /* PGPORT, see below */
840 /* PGHOST, see below */
842 if (hostname
!= NULL
)
843 setenv("PGHOST", hostname
, 1);
846 sockdir
= getenv("PG_REGRESS_SOCK_DIR");
848 sockdir
= make_temp_sockdir();
849 setenv("PGHOST", sockdir
, 1);
851 unsetenv("PGHOSTADDR");
856 snprintf(s
, sizeof(s
), "%d", port
);
857 setenv("PGPORT", s
, 1);
866 * When testing an existing install, we honor existing environment
867 * variables, except if they're overridden by command line options.
869 if (hostname
!= NULL
)
871 setenv("PGHOST", hostname
, 1);
872 unsetenv("PGHOSTADDR");
878 snprintf(s
, sizeof(s
), "%d", port
);
879 setenv("PGPORT", s
, 1);
882 setenv("PGUSER", user
, 1);
885 * However, we *don't* honor PGDATABASE, since we certainly don't wish
886 * to connect to whatever database the user might like as default.
887 * (Most tests override PGDATABASE anyway, but there are some ECPG
888 * test cases that don't.)
890 unsetenv("PGDATABASE");
893 * Report what we're connecting to
895 pghost
= getenv("PGHOST");
896 pgport
= getenv("PGPORT");
899 /* Keep this bit in sync with libpq's default host location: */
900 if (DEFAULT_PGSOCKET_DIR
[0])
901 /* do nothing, we'll print "Unix socket" below */ ;
903 pghost
= "localhost"; /* DefaultHost in fe-connect.c */
906 if (pghost
&& pgport
)
907 note("using postmaster on %s, port %s", pghost
, pgport
);
908 if (pghost
&& !pgport
)
909 note("using postmaster on %s, default port", pghost
);
910 if (!pghost
&& pgport
)
911 note("using postmaster on Unix socket, port %s", pgport
);
912 if (!pghost
&& !pgport
)
913 note("using postmaster on Unix socket, default port");
921 /* support for config_sspi_auth() */
923 fmtHba(const char *raw
)
929 wp
= ret
= pg_realloc(ret
, 3 + strlen(raw
) * 2);
932 for (rp
= raw
; *rp
; rp
++)
945 * Get account and domain/realm names for the current user. This is based on
946 * pg_SSPI_recvauth(). The returned strings use static storage.
949 current_windows_user(const char **acct
, const char **dom
)
951 static char accountname
[MAXPGPATH
];
952 static char domainname
[MAXPGPATH
];
954 TOKEN_USER
*tokenuser
;
956 DWORD accountnamesize
= sizeof(accountname
);
957 DWORD domainnamesize
= sizeof(domainname
);
958 SID_NAME_USE accountnameuse
;
960 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ
, &token
))
962 bail("could not open process token: error code %lu", GetLastError());
965 if (!GetTokenInformation(token
, TokenUser
, NULL
, 0, &retlen
) && GetLastError() != 122)
967 bail("could not get token information buffer size: error code %lu",
970 tokenuser
= pg_malloc(retlen
);
971 if (!GetTokenInformation(token
, TokenUser
, tokenuser
, retlen
, &retlen
))
973 bail("could not get token information: error code %lu",
977 if (!LookupAccountSid(NULL
, tokenuser
->User
.Sid
, accountname
, &accountnamesize
,
978 domainname
, &domainnamesize
, &accountnameuse
))
980 bail("could not look up account SID: error code %lu",
991 * Rewrite pg_hba.conf and pg_ident.conf to use SSPI authentication. Permit
992 * the current OS user to authenticate as the bootstrap superuser and as any
993 * user named in a --create-role option.
995 * In --config-auth mode, the --user switch can be used to specify the
996 * bootstrap superuser's name, otherwise we assume it is the default.
999 config_sspi_auth(const char *pgdata
, const char *superuser_name
)
1001 const char *accountname
,
1005 char fname
[MAXPGPATH
];
1011 /* Find out the name of the current OS user */
1012 current_windows_user(&accountname
, &domainname
);
1014 /* Determine the bootstrap superuser's name */
1015 if (superuser_name
== NULL
)
1018 * Compute the default superuser name the same way initdb does.
1020 * It's possible that this result always matches "accountname", the
1021 * value SSPI authentication discovers. But the underlying system
1022 * functions do not clearly guarantee that.
1024 superuser_name
= get_user_name(&errstr
);
1025 if (superuser_name
== NULL
)
1032 * Like initdb.c:setup_config(), determine whether the platform recognizes
1033 * ::1 (IPv6 loopback) as a numeric host address string.
1036 struct addrinfo
*gai_result
;
1037 struct addrinfo hints
;
1040 hints
.ai_flags
= AI_NUMERICHOST
;
1041 hints
.ai_family
= AF_UNSPEC
;
1042 hints
.ai_socktype
= 0;
1043 hints
.ai_protocol
= 0;
1044 hints
.ai_addrlen
= 0;
1045 hints
.ai_canonname
= NULL
;
1046 hints
.ai_addr
= NULL
;
1047 hints
.ai_next
= NULL
;
1049 have_ipv6
= (WSAStartup(MAKEWORD(2, 2), &wsaData
) == 0 &&
1050 getaddrinfo("::1", NULL
, &hints
, &gai_result
) == 0);
1053 /* Check a Write outcome and report any error. */
1057 bail("could not write to file \"%s\": %m", fname); \
1060 res
= snprintf(fname
, sizeof(fname
), "%s/pg_hba.conf", pgdata
);
1061 if (res
< 0 || res
>= sizeof(fname
))
1064 * Truncating this name is a fatal error, because we must not fail to
1065 * overwrite an original trust-authentication pg_hba.conf.
1067 bail("directory name too long");
1069 hba
= fopen(fname
, "w");
1072 bail("could not open file \"%s\" for writing: %m", fname
);
1074 CW(fputs("# Configuration written by config_sspi_auth()\n", hba
) >= 0);
1075 CW(fputs("host all all 127.0.0.1/32 sspi include_realm=1 map=regress\n",
1078 CW(fputs("host all all ::1/128 sspi include_realm=1 map=regress\n",
1080 CW(fclose(hba
) == 0);
1082 snprintf(fname
, sizeof(fname
), "%s/pg_ident.conf", pgdata
);
1083 ident
= fopen(fname
, "w");
1086 bail("could not open file \"%s\" for writing: %m", fname
);
1088 CW(fputs("# Configuration written by config_sspi_auth()\n", ident
) >= 0);
1091 * Double-quote for the benefit of account names containing whitespace or
1092 * '#'. Windows forbids the double-quote character itself, so don't
1093 * bother escaping embedded double-quote characters.
1095 CW(fprintf(ident
, "regress \"%s@%s\" %s\n",
1096 accountname
, domainname
, fmtHba(superuser_name
)) >= 0);
1097 for (sl
= extraroles
; sl
; sl
= sl
->next
)
1098 CW(fprintf(ident
, "regress \"%s@%s\" %s\n",
1099 accountname
, domainname
, fmtHba(sl
->str
)) >= 0);
1100 CW(fclose(ident
) == 0);
1103 #endif /* ENABLE_SSPI */
1106 * psql_start_command, psql_add_command, psql_end_command
1108 * Issue one or more commands within one psql call.
1109 * Set up with psql_start_command, then add commands one at a time
1110 * with psql_add_command, and finally execute with psql_end_command.
1112 * Since we use system(), this doesn't return until the operation finishes
1115 psql_start_command(void)
1117 StringInfo buf
= makeStringInfo();
1119 appendStringInfo(buf
,
1120 "\"%s%spsql\" -X -q",
1121 bindir
? bindir
: "",
1127 psql_add_command(StringInfo buf
, const char *query
,...)
1129 StringInfoData cmdbuf
;
1132 /* Add each command as a -c argument in the psql call */
1133 appendStringInfoString(buf
, " -c \"");
1135 /* Generate the query with insertion of sprintf arguments */
1136 initStringInfo(&cmdbuf
);
1142 va_start(args
, query
);
1143 needed
= appendStringInfoVA(&cmdbuf
, query
, args
);
1146 break; /* success */
1147 enlargeStringInfo(&cmdbuf
, needed
);
1150 /* Now escape any shell double-quote metacharacters */
1151 for (cmdptr
= cmdbuf
.data
; *cmdptr
; cmdptr
++)
1153 if (strchr("\\\"$`", *cmdptr
))
1154 appendStringInfoChar(buf
, '\\');
1155 appendStringInfoChar(buf
, *cmdptr
);
1158 appendStringInfoChar(buf
, '"');
1164 psql_end_command(StringInfo buf
, const char *database
)
1166 /* Add the database name --- assume it needs no extra escaping */
1167 appendStringInfo(buf
,
1171 /* And now we can execute the shell command */
1173 if (system(buf
->data
) != 0)
1175 /* psql probably already reported the error */
1176 bail("command failed: %s", buf
->data
);
1180 destroyStringInfo(buf
);
1184 * Shorthand macro for the common case of a single command
1186 #define psql_command(database, ...) \
1188 StringInfo cmdbuf = psql_start_command(); \
1189 psql_add_command(cmdbuf, __VA_ARGS__); \
1190 psql_end_command(cmdbuf, database); \
1194 * Spawn a process to execute the given shell command; don't wait for it
1196 * Returns the process ID (or HANDLE) so we can wait for it later
1199 spawn_process(const char *cmdline
)
1205 * Must flush I/O buffers before fork.
1216 bail("could not fork: %m");
1223 * Instead of using system(), exec the shell directly, and tell it to
1224 * "exec" the command too. This saves two useless processes per
1225 * parallel test case.
1229 cmdline2
= psprintf("exec %s", cmdline
);
1230 execl(shellprog
, shellprog
, "-c", cmdline2
, (char *) NULL
);
1231 /* Not using the normal bail() here as we want _exit */
1232 bail_noatexit("could not exec \"%s\": %m", shellprog
);
1237 PROCESS_INFORMATION pi
;
1239 const char *comspec
;
1241 /* Find CMD.EXE location using COMSPEC, if it's set */
1242 comspec
= getenv("COMSPEC");
1243 if (comspec
== NULL
)
1246 memset(&pi
, 0, sizeof(pi
));
1247 cmdline2
= psprintf("\"%s\" /d /c \"%s\"", comspec
, cmdline
);
1249 if (!CreateRestrictedProcess(cmdline2
, &pi
))
1252 CloseHandle(pi
.hThread
);
1258 * Count bytes in file
1261 file_size(const char *file
)
1264 FILE *f
= fopen(file
, "r");
1268 diag("could not open file \"%s\" for reading: %m", file
);
1271 fseek(f
, 0, SEEK_END
);
1278 * Count lines in file
1281 file_line_count(const char *file
)
1285 FILE *f
= fopen(file
, "r");
1289 diag("could not open file \"%s\" for reading: %m", file
);
1292 while ((c
= fgetc(f
)) != EOF
)
1302 file_exists(const char *file
)
1304 FILE *f
= fopen(file
, "r");
1313 directory_exists(const char *dir
)
1317 if (stat(dir
, &st
) != 0)
1319 if (S_ISDIR(st
.st_mode
))
1324 /* Create a directory */
1326 make_directory(const char *dir
)
1328 if (mkdir(dir
, S_IRWXU
| S_IRWXG
| S_IRWXO
) < 0)
1329 bail("could not create directory \"%s\": %m", dir
);
1333 * In: filename.ext, Return: filename_i.ext, where 0 < i <= 9
1336 get_alternative_expectfile(const char *expectfile
, int i
)
1339 int ssize
= strlen(expectfile
) + 2 + 1;
1343 if (!(tmp
= (char *) malloc(ssize
)))
1346 if (!(s
= (char *) malloc(ssize
)))
1352 strcpy(tmp
, expectfile
);
1353 last_dot
= strrchr(tmp
, '.');
1361 snprintf(s
, ssize
, "%s_%d.%s", tmp
, i
, last_dot
+ 1);
1367 * Run a "diff" command and also check that it didn't crash
1370 run_diff(const char *cmd
, const char *filename
)
1376 if (!WIFEXITED(r
) || WEXITSTATUS(r
) > 1)
1378 bail("diff command failed with status %d: %s", r
, cmd
);
1383 * On WIN32, if the 'diff' command cannot be found, system() returns 1,
1384 * but produces nothing to stdout, so we check for that here.
1386 if (WEXITSTATUS(r
) == 1 && file_size(filename
) <= 0)
1388 bail("diff command not found: %s", cmd
);
1392 return WEXITSTATUS(r
);
1396 * Check the actual result file for the given test against expected results
1398 * Returns true if different (failure), false if correct match found.
1399 * In the true case, the diff is appended to the diffs file.
1402 results_differ(const char *testname
, const char *resultsfile
, const char *default_expectfile
)
1404 char expectfile
[MAXPGPATH
];
1405 char diff
[MAXPGPATH
];
1406 char cmd
[MAXPGPATH
* 3];
1407 char best_expect_file
[MAXPGPATH
];
1409 int best_line_count
;
1412 const char *platform_expectfile
;
1415 * We can pass either the resultsfile or the expectfile, they should have
1416 * the same type (filename.type) anyway.
1418 platform_expectfile
= get_expectfile(testname
, resultsfile
);
1420 strlcpy(expectfile
, default_expectfile
, sizeof(expectfile
));
1421 if (platform_expectfile
)
1424 * Replace everything after the last slash in expectfile with what the
1425 * platform_expectfile contains.
1427 char *p
= strrchr(expectfile
, '/');
1430 strcpy(++p
, platform_expectfile
);
1433 /* Name to use for temporary diff file */
1434 snprintf(diff
, sizeof(diff
), "%s.diff", resultsfile
);
1436 /* OK, run the diff */
1437 snprintf(cmd
, sizeof(cmd
),
1438 "diff %s \"%s\" \"%s\" > \"%s\"",
1439 basic_diff_opts
, expectfile
, resultsfile
, diff
);
1441 /* Is the diff file empty? */
1442 if (run_diff(cmd
, diff
) == 0)
1448 /* There may be secondary comparison files that match better */
1449 best_line_count
= file_line_count(diff
);
1450 strcpy(best_expect_file
, expectfile
);
1452 for (i
= 0; i
<= 9; i
++)
1454 char *alt_expectfile
;
1456 alt_expectfile
= get_alternative_expectfile(expectfile
, i
);
1457 if (!alt_expectfile
)
1458 bail("Unable to check secondary comparison files: %m");
1460 if (!file_exists(alt_expectfile
))
1462 free(alt_expectfile
);
1466 snprintf(cmd
, sizeof(cmd
),
1467 "diff %s \"%s\" \"%s\" > \"%s\"",
1468 basic_diff_opts
, alt_expectfile
, resultsfile
, diff
);
1470 if (run_diff(cmd
, diff
) == 0)
1473 free(alt_expectfile
);
1477 l
= file_line_count(diff
);
1478 if (l
< best_line_count
)
1480 /* This diff was a better match than the last one */
1481 best_line_count
= l
;
1482 strlcpy(best_expect_file
, alt_expectfile
, sizeof(best_expect_file
));
1484 free(alt_expectfile
);
1488 * fall back on the canonical results file if we haven't tried it yet and
1489 * haven't found a complete match yet.
1492 if (platform_expectfile
)
1494 snprintf(cmd
, sizeof(cmd
),
1495 "diff %s \"%s\" \"%s\" > \"%s\"",
1496 basic_diff_opts
, default_expectfile
, resultsfile
, diff
);
1498 if (run_diff(cmd
, diff
) == 0)
1500 /* No diff = no changes = good */
1505 l
= file_line_count(diff
);
1506 if (l
< best_line_count
)
1508 /* This diff was a better match than the last one */
1509 best_line_count
= l
;
1510 strlcpy(best_expect_file
, default_expectfile
, sizeof(best_expect_file
));
1515 * Use the best comparison file to generate the "pretty" diff, which we
1516 * append to the diffs summary file.
1519 /* Write diff header */
1520 difffile
= fopen(difffilename
, "a");
1525 pretty_diff_opts
, best_expect_file
, resultsfile
);
1530 snprintf(cmd
, sizeof(cmd
),
1531 "diff %s \"%s\" \"%s\" >> \"%s\"",
1532 pretty_diff_opts
, best_expect_file
, resultsfile
, difffilename
);
1533 run_diff(cmd
, difffilename
);
1540 * Wait for specified subprocesses to finish, and return their exit
1541 * statuses into statuses[] and stop times into stoptimes[]
1543 * If names isn't NULL, print each subprocess's name as it finishes
1545 * Note: it's OK to scribble on the pids array, but not on the names array
1548 wait_for_tests(PID_TYPE
* pids
, int *statuses
, instr_time
*stoptimes
,
1549 char **names
, int num_tests
)
1555 PID_TYPE
*active_pids
= pg_malloc(num_tests
* sizeof(PID_TYPE
));
1557 memcpy(active_pids
, pids
, num_tests
* sizeof(PID_TYPE
));
1560 tests_left
= num_tests
;
1561 while (tests_left
> 0)
1568 p
= wait(&exit_status
);
1570 if (p
== INVALID_PID
)
1571 bail("failed to wait for subprocesses: %m");
1576 r
= WaitForMultipleObjects(tests_left
, active_pids
, FALSE
, INFINITE
);
1577 if (r
< WAIT_OBJECT_0
|| r
>= WAIT_OBJECT_0
+ tests_left
)
1579 bail("failed to wait for subprocesses: error code %lu",
1582 p
= active_pids
[r
- WAIT_OBJECT_0
];
1583 /* compact the active_pids array */
1584 active_pids
[r
- WAIT_OBJECT_0
] = active_pids
[tests_left
- 1];
1587 for (i
= 0; i
< num_tests
; i
++)
1592 GetExitCodeProcess(pids
[i
], &exit_status
);
1593 CloseHandle(pids
[i
]);
1595 pids
[i
] = INVALID_PID
;
1596 statuses
[i
] = (int) exit_status
;
1597 INSTR_TIME_SET_CURRENT(stoptimes
[i
]);
1599 note_detail(" %s", names
[i
]);
1612 * report nonzero exit code from a test process
1615 log_child_failure(int exitstatus
)
1617 if (WIFEXITED(exitstatus
))
1618 diag("(test process exited with exit code %d)",
1619 WEXITSTATUS(exitstatus
));
1620 else if (WIFSIGNALED(exitstatus
))
1623 diag("(test process was terminated by exception 0x%X)",
1624 WTERMSIG(exitstatus
));
1626 diag("(test process was terminated by signal %d: %s)",
1627 WTERMSIG(exitstatus
), pg_strsignal(WTERMSIG(exitstatus
)));
1631 diag("(test process exited with unrecognized status %d)", exitstatus
);
1635 * Run all the tests specified in one schedule file
1638 run_schedule(const char *schedule
, test_start_function startfunc
,
1639 postprocess_result_function postfunc
)
1641 #define MAX_PARALLEL_TESTS 100
1642 char *tests
[MAX_PARALLEL_TESTS
];
1643 _stringlist
*resultfiles
[MAX_PARALLEL_TESTS
];
1644 _stringlist
*expectfiles
[MAX_PARALLEL_TESTS
];
1645 _stringlist
*tags
[MAX_PARALLEL_TESTS
];
1646 PID_TYPE pids
[MAX_PARALLEL_TESTS
];
1647 instr_time starttimes
[MAX_PARALLEL_TESTS
];
1648 instr_time stoptimes
[MAX_PARALLEL_TESTS
];
1649 int statuses
[MAX_PARALLEL_TESTS
];
1654 memset(tests
, 0, sizeof(tests
));
1655 memset(resultfiles
, 0, sizeof(resultfiles
));
1656 memset(expectfiles
, 0, sizeof(expectfiles
));
1657 memset(tags
, 0, sizeof(tags
));
1659 scf
= fopen(schedule
, "r");
1661 bail("could not open file \"%s\" for reading: %m", schedule
);
1663 while (fgets(scbuf
, sizeof(scbuf
), scf
))
1673 /* strip trailing whitespace, especially the newline */
1675 while (i
> 0 && isspace((unsigned char) scbuf
[i
- 1]))
1678 if (scbuf
[0] == '\0' || scbuf
[0] == '#')
1680 if (strncmp(scbuf
, "test: ", 6) == 0)
1684 bail("syntax error in schedule file \"%s\" line %d: %s",
1685 schedule
, line_num
, scbuf
);
1690 for (c
= test
;; c
++)
1692 if (*c
== '\0' || isspace((unsigned char) *c
))
1696 /* Reached end of a test name */
1699 if (num_tests
>= MAX_PARALLEL_TESTS
)
1701 bail("too many parallel tests (more than %d) in schedule file \"%s\" line %d: %s",
1702 MAX_PARALLEL_TESTS
, schedule
, line_num
, scbuf
);
1706 tests
[num_tests
] = pg_strdup(test
);
1712 break; /* loop exit is here */
1716 /* Start of a test name */
1724 bail("syntax error in schedule file \"%s\" line %d: %s",
1725 schedule
, line_num
, scbuf
);
1730 pids
[0] = (startfunc
) (tests
[0], &resultfiles
[0], &expectfiles
[0], &tags
[0]);
1731 INSTR_TIME_SET_CURRENT(starttimes
[0]);
1732 wait_for_tests(pids
, statuses
, stoptimes
, NULL
, 1);
1733 /* status line is finished below */
1735 else if (max_concurrent_tests
> 0 && max_concurrent_tests
< num_tests
)
1737 bail("too many parallel tests (more than %d) in schedule file \"%s\" line %d: %s",
1738 max_concurrent_tests
, schedule
, line_num
, scbuf
);
1740 else if (max_connections
> 0 && max_connections
< num_tests
)
1744 note_detail("parallel group (%d tests, in groups of %d): ",
1745 num_tests
, max_connections
);
1746 for (i
= 0; i
< num_tests
; i
++)
1748 if (i
- oldest
>= max_connections
)
1750 wait_for_tests(pids
+ oldest
, statuses
+ oldest
,
1752 tests
+ oldest
, i
- oldest
);
1755 pids
[i
] = (startfunc
) (tests
[i
], &resultfiles
[i
], &expectfiles
[i
], &tags
[i
]);
1756 INSTR_TIME_SET_CURRENT(starttimes
[i
]);
1758 wait_for_tests(pids
+ oldest
, statuses
+ oldest
,
1760 tests
+ oldest
, i
- oldest
);
1765 note_detail("parallel group (%d tests): ", num_tests
);
1766 for (i
= 0; i
< num_tests
; i
++)
1768 pids
[i
] = (startfunc
) (tests
[i
], &resultfiles
[i
], &expectfiles
[i
], &tags
[i
]);
1769 INSTR_TIME_SET_CURRENT(starttimes
[i
]);
1771 wait_for_tests(pids
, statuses
, stoptimes
, tests
, num_tests
);
1775 /* Check results for all tests */
1776 for (i
= 0; i
< num_tests
; i
++)
1781 bool differ
= false;
1783 INSTR_TIME_SUBTRACT(stoptimes
[i
], starttimes
[i
]);
1786 * Advance over all three lists simultaneously.
1788 * Compare resultfiles[j] with expectfiles[j] always. Tags are
1789 * optional but if there are tags, the tag list has the same
1790 * length as the other two lists.
1792 for (rl
= resultfiles
[i
], el
= expectfiles
[i
], tl
= tags
[i
];
1793 rl
!= NULL
; /* rl and el have the same length */
1794 rl
= rl
->next
, el
= el
->next
,
1795 tl
= tl
? tl
->next
: NULL
)
1800 (*postfunc
) (rl
->str
);
1801 newdiff
= results_differ(tests
[i
], rl
->str
, el
->str
);
1804 diag("tag: %s", tl
->str
);
1809 if (statuses
[i
] != 0)
1811 test_status_failed(tests
[i
], INSTR_TIME_GET_MILLISEC(stoptimes
[i
]), (num_tests
> 1));
1812 log_child_failure(statuses
[i
]);
1818 test_status_failed(tests
[i
], INSTR_TIME_GET_MILLISEC(stoptimes
[i
]), (num_tests
> 1));
1822 test_status_ok(tests
[i
], INSTR_TIME_GET_MILLISEC(stoptimes
[i
]), (num_tests
> 1));
1827 for (i
= 0; i
< num_tests
; i
++)
1831 free_stringlist(&resultfiles
[i
]);
1832 free_stringlist(&expectfiles
[i
]);
1833 free_stringlist(&tags
[i
]);
1844 run_single_test(const char *test
, test_start_function startfunc
,
1845 postprocess_result_function postfunc
)
1848 instr_time starttime
;
1849 instr_time stoptime
;
1851 _stringlist
*resultfiles
= NULL
;
1852 _stringlist
*expectfiles
= NULL
;
1853 _stringlist
*tags
= NULL
;
1857 bool differ
= false;
1859 pid
= (startfunc
) (test
, &resultfiles
, &expectfiles
, &tags
);
1860 INSTR_TIME_SET_CURRENT(starttime
);
1861 wait_for_tests(&pid
, &exit_status
, &stoptime
, NULL
, 1);
1864 * Advance over all three lists simultaneously.
1866 * Compare resultfiles[j] with expectfiles[j] always. Tags are optional
1867 * but if there are tags, the tag list has the same length as the other
1870 for (rl
= resultfiles
, el
= expectfiles
, tl
= tags
;
1871 rl
!= NULL
; /* rl and el have the same length */
1872 rl
= rl
->next
, el
= el
->next
,
1873 tl
= tl
? tl
->next
: NULL
)
1878 (*postfunc
) (rl
->str
);
1879 newdiff
= results_differ(test
, rl
->str
, el
->str
);
1882 diag("tag: %s", tl
->str
);
1887 INSTR_TIME_SUBTRACT(stoptime
, starttime
);
1889 if (exit_status
!= 0)
1891 test_status_failed(test
, INSTR_TIME_GET_MILLISEC(stoptime
), false);
1892 log_child_failure(exit_status
);
1898 test_status_failed(test
, INSTR_TIME_GET_MILLISEC(stoptime
), false);
1902 test_status_ok(test
, INSTR_TIME_GET_MILLISEC(stoptime
), false);
1908 * Create the summary-output files (making them empty if already existing)
1911 open_result_files(void)
1913 char file
[MAXPGPATH
];
1916 /* create outputdir directory if not present */
1917 if (!directory_exists(outputdir
))
1918 make_directory(outputdir
);
1920 /* create the log file (copy of running status output) */
1921 snprintf(file
, sizeof(file
), "%s/regression.out", outputdir
);
1922 logfilename
= pg_strdup(file
);
1923 logfile
= fopen(logfilename
, "w");
1925 bail("could not open file \"%s\" for writing: %m", logfilename
);
1927 /* create the diffs file as empty */
1928 snprintf(file
, sizeof(file
), "%s/regression.diffs", outputdir
);
1929 difffilename
= pg_strdup(file
);
1930 difffile
= fopen(difffilename
, "w");
1932 bail("could not open file \"%s\" for writing: %m", difffilename
);
1934 /* we don't keep the diffs file open continuously */
1937 /* also create the results directory if not present */
1938 snprintf(file
, sizeof(file
), "%s/results", outputdir
);
1939 if (!directory_exists(file
))
1940 make_directory(file
);
1944 drop_database_if_exists(const char *dbname
)
1946 StringInfo buf
= psql_start_command();
1948 /* Set warning level so we don't see chatter about nonexistent DB */
1949 psql_add_command(buf
, "SET client_min_messages = warning");
1950 psql_add_command(buf
, "DROP DATABASE IF EXISTS \"%s\"", dbname
);
1951 psql_end_command(buf
, "postgres");
1955 create_database(const char *dbname
)
1957 StringInfo buf
= psql_start_command();
1961 * We use template0 so that any installation-local cruft in template1 will
1962 * not mess up the tests.
1965 psql_add_command(buf
, "CREATE DATABASE \"%s\" TEMPLATE=template0 ENCODING='%s'%s", dbname
, encoding
,
1966 (nolocale
) ? " LOCALE='C'" : "");
1968 psql_add_command(buf
, "CREATE DATABASE \"%s\" TEMPLATE=template0%s", dbname
,
1969 (nolocale
) ? " LOCALE='C'" : "");
1970 psql_add_command(buf
,
1971 "ALTER DATABASE \"%s\" SET lc_messages TO 'C';"
1972 "ALTER DATABASE \"%s\" SET lc_monetary TO 'C';"
1973 "ALTER DATABASE \"%s\" SET lc_numeric TO 'C';"
1974 "ALTER DATABASE \"%s\" SET lc_time TO 'C';"
1975 "ALTER DATABASE \"%s\" SET bytea_output TO 'hex';"
1976 "ALTER DATABASE \"%s\" SET timezone_abbreviations TO 'Default';",
1977 dbname
, dbname
, dbname
, dbname
, dbname
, dbname
);
1978 psql_end_command(buf
, "postgres");
1981 * Install any requested extensions. We use CREATE IF NOT EXISTS so that
1982 * this will work whether or not the extension is preinstalled.
1984 for (sl
= loadextension
; sl
!= NULL
; sl
= sl
->next
)
1985 psql_command(dbname
, "CREATE EXTENSION IF NOT EXISTS \"%s\"", sl
->str
);
1989 drop_role_if_exists(const char *rolename
)
1991 StringInfo buf
= psql_start_command();
1993 /* Set warning level so we don't see chatter about nonexistent role */
1994 psql_add_command(buf
, "SET client_min_messages = warning");
1995 psql_add_command(buf
, "DROP ROLE IF EXISTS \"%s\"", rolename
);
1996 psql_end_command(buf
, "postgres");
2000 create_role(const char *rolename
, const _stringlist
*granted_dbs
)
2002 StringInfo buf
= psql_start_command();
2004 psql_add_command(buf
, "CREATE ROLE \"%s\" WITH LOGIN", rolename
);
2005 for (; granted_dbs
!= NULL
; granted_dbs
= granted_dbs
->next
)
2007 psql_add_command(buf
, "GRANT ALL ON DATABASE \"%s\" TO \"%s\"",
2008 granted_dbs
->str
, rolename
);
2010 psql_end_command(buf
, "postgres");
2016 printf(_("PostgreSQL regression test driver\n"));
2018 printf(_("Usage:\n %s [OPTION]... [EXTRA-TEST]...\n"), progname
);
2020 printf(_("Options:\n"));
2021 printf(_(" --bindir=BINPATH use BINPATH for programs that are run;\n"));
2022 printf(_(" if empty, use PATH from the environment\n"));
2023 printf(_(" --config-auth=DATADIR update authentication settings for DATADIR\n"));
2024 printf(_(" --create-role=ROLE create the specified role before testing\n"));
2025 printf(_(" --dbname=DB use database DB (default \"regression\")\n"));
2026 printf(_(" --debug turn on debug mode in programs that are run\n"));
2027 printf(_(" --dlpath=DIR look for dynamic libraries in DIR\n"));
2028 printf(_(" --encoding=ENCODING use ENCODING as the encoding\n"));
2029 printf(_(" --expecteddir=DIR take expected files from DIR (default \".\")\n"));
2030 printf(_(" -h, --help show this help, then exit\n"));
2031 printf(_(" --inputdir=DIR take input files from DIR (default \".\")\n"));
2032 printf(_(" --launcher=CMD use CMD as launcher of psql\n"));
2033 printf(_(" --load-extension=EXT load the named extension before running the\n"));
2034 printf(_(" tests; can appear multiple times\n"));
2035 printf(_(" --max-connections=N maximum number of concurrent connections\n"));
2036 printf(_(" (default is 0, meaning unlimited)\n"));
2037 printf(_(" --max-concurrent-tests=N maximum number of concurrent tests in schedule\n"));
2038 printf(_(" (default is 0, meaning unlimited)\n"));
2039 printf(_(" --outputdir=DIR place output files in DIR (default \".\")\n"));
2040 printf(_(" --schedule=FILE use test ordering schedule from FILE\n"));
2041 printf(_(" (can be used multiple times to concatenate)\n"));
2042 printf(_(" --temp-instance=DIR create a temporary instance in DIR\n"));
2043 printf(_(" --use-existing use an existing installation\n"));
2044 printf(_(" -V, --version output version information, then exit\n"));
2046 printf(_("Options for \"temp-instance\" mode:\n"));
2047 printf(_(" --no-locale use C locale\n"));
2048 printf(_(" --port=PORT start postmaster on PORT\n"));
2049 printf(_(" --temp-config=FILE append contents of FILE to temporary config\n"));
2051 printf(_("Options for using an existing installation:\n"));
2052 printf(_(" --host=HOST use postmaster running on HOST\n"));
2053 printf(_(" --port=PORT use postmaster running at PORT\n"));
2054 printf(_(" --user=USER connect as USER\n"));
2056 printf(_("The exit status is 0 if all tests passed, 1 if some tests failed, and 2\n"));
2057 printf(_("if the tests could not be run for some reason.\n"));
2059 printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
2060 printf(_("%s home page: <%s>\n"), PACKAGE_NAME
, PACKAGE_URL
);
2064 regression_main(int argc
, char *argv
[],
2065 init_function ifunc
,
2066 test_start_function startfunc
,
2067 postprocess_result_function postfunc
)
2069 static struct option long_options
[] = {
2070 {"help", no_argument
, NULL
, 'h'},
2071 {"version", no_argument
, NULL
, 'V'},
2072 {"dbname", required_argument
, NULL
, 1},
2073 {"debug", no_argument
, NULL
, 2},
2074 {"inputdir", required_argument
, NULL
, 3},
2075 {"max-connections", required_argument
, NULL
, 5},
2076 {"encoding", required_argument
, NULL
, 6},
2077 {"outputdir", required_argument
, NULL
, 7},
2078 {"schedule", required_argument
, NULL
, 8},
2079 {"temp-instance", required_argument
, NULL
, 9},
2080 {"no-locale", no_argument
, NULL
, 10},
2081 {"host", required_argument
, NULL
, 13},
2082 {"port", required_argument
, NULL
, 14},
2083 {"user", required_argument
, NULL
, 15},
2084 {"bindir", required_argument
, NULL
, 16},
2085 {"dlpath", required_argument
, NULL
, 17},
2086 {"create-role", required_argument
, NULL
, 18},
2087 {"temp-config", required_argument
, NULL
, 19},
2088 {"use-existing", no_argument
, NULL
, 20},
2089 {"launcher", required_argument
, NULL
, 21},
2090 {"load-extension", required_argument
, NULL
, 22},
2091 {"config-auth", required_argument
, NULL
, 24},
2092 {"max-concurrent-tests", required_argument
, NULL
, 25},
2093 {"expecteddir", required_argument
, NULL
, 26},
2097 bool use_unix_sockets
;
2102 char buf
[MAXPGPATH
* 4];
2104 pg_logging_init(argv
[0]);
2105 progname
= get_progname(argv
[0]);
2106 set_pglocale_pgservice(argv
[0], PG_TEXTDOMAIN("pg_regress"));
2108 get_restricted_token();
2110 atexit(stop_postmaster
);
2115 * We don't use Unix-domain sockets on Windows by default (see comment at
2116 * remove_temp() for a reason). Override at your own risk.
2118 use_unix_sockets
= getenv("PG_TEST_USE_UNIX_SOCKETS") ? true : false;
2120 use_unix_sockets
= true;
2123 if (!use_unix_sockets
)
2124 hostname
= "localhost";
2127 * We call the initialization function here because that way we can set
2128 * default parameters and let them be overwritten by the commandline.
2132 if (getenv("PG_REGRESS_DIFF_OPTS"))
2133 pretty_diff_opts
= getenv("PG_REGRESS_DIFF_OPTS");
2135 while ((c
= getopt_long(argc
, argv
, "hV", long_options
, &option_index
)) != -1)
2143 puts("pg_regress (PostgreSQL) " PG_VERSION
);
2148 * If a default database was specified, we need to remove it
2149 * before we add the specified one.
2151 free_stringlist(&dblist
);
2152 split_to_stringlist(optarg
, ",", &dblist
);
2158 inputdir
= pg_strdup(optarg
);
2161 max_connections
= atoi(optarg
);
2164 encoding
= pg_strdup(optarg
);
2167 outputdir
= pg_strdup(optarg
);
2170 add_stringlist_item(&schedulelist
, optarg
);
2173 temp_instance
= make_absolute_path(optarg
);
2179 hostname
= pg_strdup(optarg
);
2182 port
= atoi(optarg
);
2183 port_specified_by_user
= true;
2186 user
= pg_strdup(optarg
);
2189 /* "--bindir=" means to use PATH */
2191 bindir
= pg_strdup(optarg
);
2196 dlpath
= pg_strdup(optarg
);
2199 split_to_stringlist(optarg
, ",", &extraroles
);
2202 add_stringlist_item(&temp_configs
, optarg
);
2205 use_existing
= true;
2208 launcher
= pg_strdup(optarg
);
2211 add_stringlist_item(&loadextension
, optarg
);
2214 config_auth_datadir
= pg_strdup(optarg
);
2217 max_concurrent_tests
= atoi(optarg
);
2220 expecteddir
= pg_strdup(optarg
);
2223 /* getopt_long already emitted a complaint */
2224 pg_log_error_hint("Try \"%s --help\" for more information.",
2231 * if we still have arguments, they are extra tests to run
2233 while (argc
- optind
>= 1)
2235 add_stringlist_item(&extra_tests
, argv
[optind
]);
2240 * We must have a database to run the tests in; either a default name, or
2241 * one supplied by the --dbname switch.
2243 if (!(dblist
&& dblist
->str
&& dblist
->str
[0]))
2245 bail("no database name was specified");
2248 if (config_auth_datadir
)
2251 if (!use_unix_sockets
)
2252 config_sspi_auth(config_auth_datadir
, user
);
2257 if (temp_instance
&& !port_specified_by_user
)
2260 * To reduce chances of interference with parallel installations, use
2261 * a port number starting in the private range (49152-65535)
2262 * calculated from the version number. This aids non-Unix socket mode
2263 * systems; elsewhere, the use of a private socket directory already
2264 * prevents interference.
2266 port
= 0xC000 | (PG_VERSION_NUM
& 0x3FFF);
2268 inputdir
= make_absolute_path(inputdir
);
2269 outputdir
= make_absolute_path(outputdir
);
2270 expecteddir
= make_absolute_path(expecteddir
);
2271 dlpath
= make_absolute_path(dlpath
);
2276 open_result_files();
2278 initialize_environment();
2280 #if defined(HAVE_GETRLIMIT)
2281 unlimit_core_size();
2288 const char *env_wait
;
2290 const char *initdb_template_dir
;
2291 const char *keywords
[4];
2292 const char *values
[4];
2294 const char *initdb_extra_opts_env
;
2297 * Prepare the temp instance
2300 if (directory_exists(temp_instance
))
2302 if (!rmtree(temp_instance
, true))
2304 bail("could not remove temp instance \"%s\"", temp_instance
);
2308 /* make the temp instance top directory */
2309 make_directory(temp_instance
);
2311 /* and a directory for log files */
2312 snprintf(buf
, sizeof(buf
), "%s/log", outputdir
);
2313 if (!directory_exists(buf
))
2314 make_directory(buf
);
2316 initdb_extra_opts_env
= getenv("PG_TEST_INITDB_EXTRA_OPTS");
2318 initStringInfo(&cmd
);
2321 * Create data directory.
2323 * If available, use a previously initdb'd cluster as a template by
2324 * copying it. For a lot of tests, that's substantially cheaper.
2326 * There's very similar code in Cluster.pm, but we can't easily de
2327 * duplicate it until we require perl at build time.
2329 initdb_template_dir
= getenv("INITDB_TEMPLATE");
2330 if (initdb_template_dir
== NULL
|| nolocale
|| debug
|| initdb_extra_opts_env
)
2332 note("initializing database system by running initdb");
2334 appendStringInfo(&cmd
,
2335 "\"%s%sinitdb\" -D \"%s/data\" --no-clean --no-sync",
2336 bindir
? bindir
: "",
2340 appendStringInfoString(&cmd
, " --debug");
2342 appendStringInfoString(&cmd
, " --no-locale");
2343 if (initdb_extra_opts_env
)
2344 appendStringInfo(&cmd
, " %s", initdb_extra_opts_env
);
2345 appendStringInfo(&cmd
, " > \"%s/log/initdb.log\" 2>&1", outputdir
);
2347 if (system(cmd
.data
))
2349 bail("initdb failed\n"
2350 "# Examine \"%s/log/initdb.log\" for the reason.\n"
2351 "# Command was: %s",
2352 outputdir
, cmd
.data
);
2358 const char *copycmd
= "cp -RPp \"%s\" \"%s/data\"";
2359 int expected_exitcode
= 0;
2361 const char *copycmd
= "robocopy /E /NJS /NJH /NFL /NDL /NP \"%s\" \"%s/data\"";
2362 int expected_exitcode
= 1; /* 1 denotes files were copied */
2365 note("initializing database system by copying initdb template");
2367 appendStringInfo(&cmd
,
2369 initdb_template_dir
,
2371 appendStringInfo(&cmd
, " > \"%s/log/initdb.log\" 2>&1", outputdir
);
2373 if (system(cmd
.data
) != expected_exitcode
)
2375 bail("copying of initdb template failed\n"
2376 "# Examine \"%s/log/initdb.log\" for the reason.\n"
2377 "# Command was: %s",
2378 outputdir
, cmd
.data
);
2385 * Adjust the default postgresql.conf for regression testing. The user
2386 * can specify a file to be appended; in any case we expand logging
2387 * and set max_prepared_transactions to enable testing of prepared
2388 * xacts. (Note: to reduce the probability of unexpected shmmax
2389 * failures, don't set max_prepared_transactions any higher than
2390 * actually needed by the prepared_xacts regression test.)
2392 snprintf(buf
, sizeof(buf
), "%s/data/postgresql.conf", temp_instance
);
2393 pg_conf
= fopen(buf
, "a");
2394 if (pg_conf
== NULL
)
2395 bail("could not open \"%s\" for adding extra config: %m", buf
);
2397 fputs("\n# Configuration added by pg_regress\n\n", pg_conf
);
2398 fputs("log_autovacuum_min_duration = 0\n", pg_conf
);
2399 fputs("log_checkpoints = on\n", pg_conf
);
2400 fputs("log_line_prefix = '%m %b[%p] %q%a '\n", pg_conf
);
2401 fputs("log_lock_waits = on\n", pg_conf
);
2402 fputs("log_temp_files = 128kB\n", pg_conf
);
2403 fputs("max_prepared_transactions = 2\n", pg_conf
);
2405 for (sl
= temp_configs
; sl
!= NULL
; sl
= sl
->next
)
2407 char *temp_config
= sl
->str
;
2409 char line_buf
[1024];
2411 extra_conf
= fopen(temp_config
, "r");
2412 if (extra_conf
== NULL
)
2414 bail("could not open \"%s\" to read extra config: %m",
2417 while (fgets(line_buf
, sizeof(line_buf
), extra_conf
) != NULL
)
2418 fputs(line_buf
, pg_conf
);
2425 if (!use_unix_sockets
)
2428 * Since we successfully used the same buffer for the much-longer
2429 * "initdb" command, this can't truncate.
2431 snprintf(buf
, sizeof(buf
), "%s/data", temp_instance
);
2432 config_sspi_auth(buf
, NULL
);
2437 * Prepare the connection params for checking the state of the server
2438 * before starting the tests.
2440 sprintf(portstr
, "%d", port
);
2441 keywords
[0] = "dbname";
2442 values
[0] = "postgres";
2443 keywords
[1] = "port";
2444 values
[1] = portstr
;
2445 keywords
[2] = "host";
2446 values
[2] = hostname
? hostname
: sockdir
;
2451 * Check if there is a postmaster running already.
2453 for (i
= 0; i
< 16; i
++)
2455 rv
= PQpingParams(keywords
, values
, 1);
2457 if (rv
== PQPING_OK
)
2459 if (port_specified_by_user
|| i
== 15)
2461 note("port %d apparently in use", port
);
2462 if (!port_specified_by_user
)
2463 note("could not determine an available port");
2464 bail("Specify an unused port using the --port option or shut down any conflicting PostgreSQL servers.");
2467 note("port %d apparently in use, trying %d", port
, port
+ 1);
2469 sprintf(portstr
, "%d", port
);
2470 setenv("PGPORT", portstr
, 1);
2477 * Start the temp postmaster
2479 snprintf(buf
, sizeof(buf
),
2480 "\"%s%spostgres\" -D \"%s/data\" -F%s "
2481 "-c \"listen_addresses=%s\" -k \"%s\" "
2482 "> \"%s/log/postmaster.log\" 2>&1",
2483 bindir
? bindir
: "",
2485 temp_instance
, debug
? " -d 5" : "",
2486 hostname
? hostname
: "", sockdir
? sockdir
: "",
2488 postmaster_pid
= spawn_process(buf
);
2489 if (postmaster_pid
== INVALID_PID
)
2490 bail("could not spawn postmaster: %m");
2493 * Wait till postmaster is able to accept connections; normally takes
2494 * only a fraction of a second or so, but Cygwin is reportedly *much*
2495 * slower, and test builds using Valgrind or similar tools might be
2496 * too. Hence, allow the default timeout of 60 seconds to be
2497 * overridden from the PGCTLTIMEOUT environment variable.
2499 env_wait
= getenv("PGCTLTIMEOUT");
2500 if (env_wait
!= NULL
)
2502 wait_seconds
= atoi(env_wait
);
2503 if (wait_seconds
<= 0)
2509 for (i
= 0; i
< wait_seconds
* WAIT_TICKS_PER_SECOND
; i
++)
2512 * It's fairly unlikely that the server is responding immediately
2513 * so we start with sleeping before checking instead of the other
2516 pg_usleep(1000000L / WAIT_TICKS_PER_SECOND
);
2518 rv
= PQpingParams(keywords
, values
, 1);
2520 /* Done if the server is running and accepts connections */
2521 if (rv
== PQPING_OK
)
2524 if (rv
== PQPING_NO_ATTEMPT
)
2525 bail("attempting to connect to postmaster failed");
2528 * Fail immediately if postmaster has exited
2531 if (waitpid(postmaster_pid
, NULL
, WNOHANG
) == postmaster_pid
)
2533 if (WaitForSingleObject(postmaster_pid
, 0) == WAIT_OBJECT_0
)
2536 bail("postmaster failed, examine \"%s/log/postmaster.log\" for the reason",
2540 if (i
>= wait_seconds
* WAIT_TICKS_PER_SECOND
)
2542 diag("postmaster did not respond within %d seconds, examine \"%s/log/postmaster.log\" for the reason",
2543 wait_seconds
, outputdir
);
2546 * If we get here, the postmaster is probably wedged somewhere in
2547 * startup. Try to kill it ungracefully rather than leaving a
2548 * stuck postmaster that might interfere with subsequent test
2552 if (kill(postmaster_pid
, SIGKILL
) != 0 && errno
!= ESRCH
)
2553 bail("could not kill failed postmaster: %m");
2555 if (TerminateProcess(postmaster_pid
, 255) == 0)
2556 bail("could not kill failed postmaster: error code %lu",
2559 bail("postmaster failed");
2562 postmaster_running
= true;
2565 /* need a series of two casts to convert HANDLE without compiler warning */
2566 #define ULONGPID(x) (unsigned long) (unsigned long long) (x)
2568 #define ULONGPID(x) (unsigned long) (x)
2570 note("using temp instance on port %d with PID %lu",
2571 port
, ULONGPID(postmaster_pid
));
2576 * Using an existing installation, so may need to get rid of
2577 * pre-existing database(s) and role(s)
2581 for (sl
= dblist
; sl
; sl
= sl
->next
)
2582 drop_database_if_exists(sl
->str
);
2583 for (sl
= extraroles
; sl
; sl
= sl
->next
)
2584 drop_role_if_exists(sl
->str
);
2589 * Create the test database(s) and role(s)
2593 for (sl
= dblist
; sl
; sl
= sl
->next
)
2594 create_database(sl
->str
);
2595 for (sl
= extraroles
; sl
; sl
= sl
->next
)
2596 create_role(sl
->str
, dblist
);
2600 * Ready to run the tests
2602 for (sl
= schedulelist
; sl
!= NULL
; sl
= sl
->next
)
2604 run_schedule(sl
->str
, startfunc
, postfunc
);
2607 for (sl
= extra_tests
; sl
!= NULL
; sl
= sl
->next
)
2609 run_single_test(sl
->str
, startfunc
, postfunc
);
2613 * Shut down temp installation's postmaster
2621 * If there were no errors, remove the temp instance immediately to
2622 * conserve disk space. (If there were errors, we leave the instance in
2623 * place for possible manual investigation.)
2625 if (temp_instance
&& fail_count
== 0)
2627 if (!rmtree(temp_instance
, true))
2628 diag("could not remove temp instance \"%s\"",
2633 * Emit a TAP compliant Plan
2635 plan(fail_count
+ success_count
);
2638 * Emit nice-looking summary message
2640 if (fail_count
== 0)
2641 note("All %d tests passed.", success_count
);
2643 diag("%d of %d tests failed.", fail_count
, success_count
+ fail_count
);
2645 if (file_size(difffilename
) > 0)
2647 diag("The differences that caused some tests to fail can be viewed in the file \"%s\".",
2649 diag("A copy of the test summary that you see above is saved in the file \"%s\".",
2654 unlink(difffilename
);
2655 unlink(logfilename
);
2661 if (fail_count
!= 0)