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
;
346 * Diagnostic output will be hidden by prove unless printed to stderr. The
347 * Bail message is also printed to stderr to aid debugging under a harness
348 * which might otherwise not emit such an important message.
350 if (type
== DIAG
|| type
== BAIL
)
356 * If we are ending a note_detail line we can avoid further processing and
357 * immediately return following a newline.
359 if (type
== NOTE_END
)
364 fprintf(logfile
, "\n");
368 /* Make a copy of the va args for printing to the logfile */
369 va_copy(argp_logfile
, argp
);
372 * Non-protocol output such as diagnostics or notes must be prefixed by a
373 * '#' character. We print the Bail message like this too.
375 if ((type
== NOTE
|| type
== DIAG
|| type
== BAIL
)
376 || (type
== NOTE_DETAIL
&& !in_note
))
380 fprintf(logfile
, "# ");
382 vfprintf(fp
, fmt
, argp
);
384 vfprintf(logfile
, fmt
, argp_logfile
);
387 * If we are entering into a note with more details to follow, register
388 * that the leading '#' has been printed such that subsequent details
389 * aren't prefixed as well.
391 if (type
== NOTE_DETAIL
)
395 * If this was a Bail message, the bail protocol message must go to stdout
400 fprintf(stdout
, "Bail out!");
402 fprintf(logfile
, "Bail out!");
405 va_end(argp_logfile
);
407 if (type
!= NOTE_DETAIL
)
411 fprintf(logfile
, "\n");
417 * shut down temp postmaster
420 stop_postmaster(void)
422 if (postmaster_running
)
424 /* We use pg_ctl to issue the kill and wait for stop */
425 char buf
[MAXPGPATH
* 2];
428 snprintf(buf
, sizeof(buf
),
429 "\"%s%spg_ctl\" stop -D \"%s/data\" -s",
430 bindir
? bindir
: "",
437 /* Not using the normal bail() as we want _exit */
438 bail_noatexit(_("could not stop postmaster: exit code was %d"), r
);
441 postmaster_running
= false;
446 * Remove the socket temporary directory. pg_regress never waits for a
447 * postmaster exit, so it is indeterminate whether the postmaster has yet to
448 * unlink the socket and lock file. Unlink them here so we can proceed to
449 * remove the directory. Ignore errors; leaking a temporary directory is
450 * unimportant. This can run from a signal handler. The code is not
451 * acceptable in a Windows signal handler (see initdb.c:trapsig()), but
452 * on Windows, pg_regress does not use Unix sockets by default.
457 Assert(temp_sockdir
);
464 * Signal handler that calls remove_temp() and reraises the signal.
467 signal_remove_temp(SIGNAL_ARGS
)
471 pqsignal(postgres_signal_arg
, SIG_DFL
);
472 raise(postgres_signal_arg
);
476 * Create a temporary directory suitable for the server's Unix-domain socket.
477 * The directory will have mode 0700 or stricter, so no other OS user can open
478 * our socket to exploit our use of trust authentication. Most systems
479 * constrain the length of socket paths well below _POSIX_PATH_MAX, so we
480 * place the directory under /tmp rather than relative to the possibly-deep
481 * current working directory.
483 * Compared to using the compiled-in DEFAULT_PGSOCKET_DIR, this also permits
484 * testing to work in builds that relocate it to a directory not writable to
485 * the build/test user.
488 make_temp_sockdir(void)
490 char *template = psprintf("%s/pg_regress-XXXXXX",
491 getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
493 temp_sockdir
= mkdtemp(template);
494 if (temp_sockdir
== NULL
)
496 bail("could not create directory \"%s\": %s",
497 template, strerror(errno
));
500 /* Stage file names for remove_temp(). Unsafe in a signal handler. */
501 UNIXSOCK_PATH(sockself
, port
, temp_sockdir
);
502 snprintf(socklock
, sizeof(socklock
), "%s.lock", sockself
);
504 /* Remove the directory during clean exit. */
508 * Remove the directory before dying to the usual signals. Omit SIGQUIT,
509 * preserving it as a quick, untidy exit.
511 pqsignal(SIGHUP
, signal_remove_temp
);
512 pqsignal(SIGINT
, signal_remove_temp
);
513 pqsignal(SIGPIPE
, signal_remove_temp
);
514 pqsignal(SIGTERM
, signal_remove_temp
);
520 * Check whether string matches pattern
522 * In the original shell script, this function was implemented using expr(1),
523 * which provides basic regular expressions restricted to match starting at
524 * the string start (in conventional regex terms, there's an implicit "^"
525 * at the start of the pattern --- but no implicit "$" at the end).
527 * For now, we only support "." and ".*" as non-literal metacharacters,
528 * because that's all that anyone has found use for in resultmap. This
529 * code could be extended if more functionality is needed.
532 string_matches_pattern(const char *str
, const char *pattern
)
534 while (*str
&& *pattern
)
536 if (*pattern
== '.' && pattern
[1] == '*')
539 /* Trailing .* matches everything. */
540 if (*pattern
== '\0')
544 * Otherwise, scan for a text position at which we can match the
545 * rest of the pattern.
550 * Optimization to prevent most recursion: don't recurse
551 * unless first pattern char might match this text char.
553 if (*str
== *pattern
|| *pattern
== '.')
555 if (string_matches_pattern(str
, pattern
))
563 * End of text with no match.
567 else if (*pattern
!= '.' && *str
!= *pattern
)
570 * Not the single-character wildcard and no explicit match? Then
580 if (*pattern
== '\0')
581 return true; /* end of pattern, so declare match */
583 /* End of input string. Do we have matching pattern remaining? */
584 while (*pattern
== '.' && pattern
[1] == '*')
586 if (*pattern
== '\0')
587 return true; /* end of pattern, so declare match */
593 * Scan resultmap file to find which platform-specific expected files to use.
595 * The format of each line of the file is
596 * testname/hostplatformpattern=substitutefile
597 * where the hostplatformpattern is evaluated per the rules of expr(1),
598 * namely, it is a standard regular expression with an implicit ^ at the start.
599 * (We currently support only a very limited subset of regular expressions,
600 * see string_matches_pattern() above.) What hostplatformpattern will be
601 * matched against is the config.guess output. (In the shell-script version,
602 * we also provided an indication of whether gcc or another compiler was in
603 * use, but that facility isn't used anymore.)
611 /* scan the file ... */
612 snprintf(buf
, sizeof(buf
), "%s/resultmap", inputdir
);
616 /* OK if it doesn't exist, else complain */
619 bail("could not open file \"%s\" for reading: %s",
620 buf
, strerror(errno
));
623 while (fgets(buf
, sizeof(buf
), f
))
630 /* strip trailing whitespace, especially the newline */
632 while (i
> 0 && isspace((unsigned char) buf
[i
- 1]))
635 /* parse out the line fields */
636 file_type
= strchr(buf
, ':');
639 bail("incorrectly formatted resultmap entry: %s", buf
);
643 platform
= strchr(file_type
, ':');
646 bail("incorrectly formatted resultmap entry: %s", buf
);
649 expected
= strchr(platform
, '=');
652 bail("incorrectly formatted resultmap entry: %s", buf
);
657 * if it's for current platform, save it in resultmap list. Note: by
658 * adding at the front of the list, we ensure that in ambiguous cases,
659 * the last match in the resultmap file is used. This mimics the
660 * behavior of the old shell script.
662 if (string_matches_pattern(host_platform
, platform
))
664 _resultmap
*entry
= pg_malloc(sizeof(_resultmap
));
666 entry
->test
= pg_strdup(buf
);
667 entry
->type
= pg_strdup(file_type
);
668 entry
->resultfile
= pg_strdup(expected
);
669 entry
->next
= resultmap
;
677 * Check in resultmap if we should be looking at a different file
681 get_expectfile(const char *testname
, const char *file
)
687 * Determine the file type from the file name. This is just what is
688 * following the last dot in the file name.
690 if (!file
|| !(file_type
= strrchr(file
, '.')))
695 for (rm
= resultmap
; rm
!= NULL
; rm
= rm
->next
)
697 if (strcmp(testname
, rm
->test
) == 0 && strcmp(file_type
, rm
->type
) == 0)
699 return rm
->resultfile
;
707 * Prepare environment variables for running regression tests
710 initialize_environment(void)
713 * Set default application_name. (The test_start_function may choose to
714 * override this, but if it doesn't, we have something useful in place.)
716 setenv("PGAPPNAME", "pg_regress", 1);
719 * Set variables that the test scripts may need to refer to.
721 setenv("PG_ABS_SRCDIR", inputdir
, 1);
722 setenv("PG_ABS_BUILDDIR", outputdir
, 1);
723 setenv("PG_LIBDIR", dlpath
, 1);
724 setenv("PG_DLSUFFIX", DLSUFFIX
, 1);
729 * Clear out any non-C locale settings
731 unsetenv("LC_COLLATE");
732 unsetenv("LC_CTYPE");
733 unsetenv("LC_MONETARY");
734 unsetenv("LC_NUMERIC");
739 * Most platforms have adopted the POSIX locale as their
740 * implementation-defined default locale. Exceptions include native
741 * Windows, macOS with --enable-nls, and Cygwin with --enable-nls.
742 * (Use of --enable-nls matters because libintl replaces setlocale().)
743 * Also, PostgreSQL does not support macOS with locale environment
744 * variables unset; see PostmasterMain().
746 #if defined(WIN32) || defined(__CYGWIN__) || defined(__darwin__)
747 setenv("LANG", "C", 1);
752 * Set translation-related settings to English; otherwise psql will
753 * produce translated messages and produce diffs. (XXX If we ever support
754 * translation of pg_regress, this needs to be moved elsewhere, where psql
755 * is actually called.)
757 unsetenv("LANGUAGE");
759 setenv("LC_MESSAGES", "C", 1);
762 * Set encoding as requested
765 setenv("PGCLIENTENCODING", encoding
, 1);
767 unsetenv("PGCLIENTENCODING");
770 * Set timezone and datestyle for datetime-related tests
772 setenv("PGTZ", "PST8PDT", 1);
773 setenv("PGDATESTYLE", "Postgres, MDY", 1);
776 * Likewise set intervalstyle to ensure consistent results. This is a bit
777 * more painful because we must use PGOPTIONS, and we want to preserve the
778 * user's ability to set other variables through that.
781 const char *my_pgoptions
= "-c intervalstyle=postgres_verbose";
782 const char *old_pgoptions
= getenv("PGOPTIONS");
787 new_pgoptions
= psprintf("%s %s",
788 old_pgoptions
, my_pgoptions
);
789 setenv("PGOPTIONS", new_pgoptions
, 1);
796 * Clear out any environment vars that might cause psql to connect to
797 * the wrong postmaster, or otherwise behave in nondefault ways. (Note
798 * we also use psql's -X switch consistently, so that ~/.psqlrc files
799 * won't mess things up.) Also, set PGPORT to the temp port, and set
800 * PGHOST depending on whether we are using TCP or Unix sockets.
802 * This list should be kept in sync with PostgreSQL/Test/Utils.pm.
804 unsetenv("PGCHANNELBINDING");
805 /* PGCLIENTENCODING, see above */
806 unsetenv("PGCONNECT_TIMEOUT");
808 unsetenv("PGDATABASE");
809 unsetenv("PGGSSDELEGATION");
810 unsetenv("PGGSSENCMODE");
811 unsetenv("PGGSSLIB");
812 /* PGHOSTADDR, see below */
813 unsetenv("PGKRBSRVNAME");
814 unsetenv("PGPASSFILE");
815 unsetenv("PGPASSWORD");
816 unsetenv("PGREQUIREPEER");
817 unsetenv("PGREQUIRESSL");
818 unsetenv("PGSERVICE");
819 unsetenv("PGSERVICEFILE");
820 unsetenv("PGSSLCERT");
821 unsetenv("PGSSLCRL");
822 unsetenv("PGSSLCRLDIR");
823 unsetenv("PGSSLKEY");
824 unsetenv("PGSSLMAXPROTOCOLVERSION");
825 unsetenv("PGSSLMINPROTOCOLVERSION");
826 unsetenv("PGSSLMODE");
827 unsetenv("PGSSLROOTCERT");
828 unsetenv("PGSSLSNI");
829 unsetenv("PGTARGETSESSIONATTRS");
831 /* PGPORT, see below */
832 /* PGHOST, see below */
834 if (hostname
!= NULL
)
835 setenv("PGHOST", hostname
, 1);
838 sockdir
= getenv("PG_REGRESS_SOCK_DIR");
840 sockdir
= make_temp_sockdir();
841 setenv("PGHOST", sockdir
, 1);
843 unsetenv("PGHOSTADDR");
848 snprintf(s
, sizeof(s
), "%d", port
);
849 setenv("PGPORT", s
, 1);
858 * When testing an existing install, we honor existing environment
859 * variables, except if they're overridden by command line options.
861 if (hostname
!= NULL
)
863 setenv("PGHOST", hostname
, 1);
864 unsetenv("PGHOSTADDR");
870 snprintf(s
, sizeof(s
), "%d", port
);
871 setenv("PGPORT", s
, 1);
874 setenv("PGUSER", user
, 1);
877 * However, we *don't* honor PGDATABASE, since we certainly don't wish
878 * to connect to whatever database the user might like as default.
879 * (Most tests override PGDATABASE anyway, but there are some ECPG
880 * test cases that don't.)
882 unsetenv("PGDATABASE");
885 * Report what we're connecting to
887 pghost
= getenv("PGHOST");
888 pgport
= getenv("PGPORT");
891 /* Keep this bit in sync with libpq's default host location: */
892 if (DEFAULT_PGSOCKET_DIR
[0])
893 /* do nothing, we'll print "Unix socket" below */ ;
895 pghost
= "localhost"; /* DefaultHost in fe-connect.c */
898 if (pghost
&& pgport
)
899 note("using postmaster on %s, port %s", pghost
, pgport
);
900 if (pghost
&& !pgport
)
901 note("using postmaster on %s, default port", pghost
);
902 if (!pghost
&& pgport
)
903 note("using postmaster on Unix socket, port %s", pgport
);
904 if (!pghost
&& !pgport
)
905 note("using postmaster on Unix socket, default port");
913 /* support for config_sspi_auth() */
915 fmtHba(const char *raw
)
921 wp
= ret
= pg_realloc(ret
, 3 + strlen(raw
) * 2);
924 for (rp
= raw
; *rp
; rp
++)
937 * Get account and domain/realm names for the current user. This is based on
938 * pg_SSPI_recvauth(). The returned strings use static storage.
941 current_windows_user(const char **acct
, const char **dom
)
943 static char accountname
[MAXPGPATH
];
944 static char domainname
[MAXPGPATH
];
946 TOKEN_USER
*tokenuser
;
948 DWORD accountnamesize
= sizeof(accountname
);
949 DWORD domainnamesize
= sizeof(domainname
);
950 SID_NAME_USE accountnameuse
;
952 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ
, &token
))
954 bail("could not open process token: error code %lu", GetLastError());
957 if (!GetTokenInformation(token
, TokenUser
, NULL
, 0, &retlen
) && GetLastError() != 122)
959 bail("could not get token information buffer size: error code %lu",
962 tokenuser
= pg_malloc(retlen
);
963 if (!GetTokenInformation(token
, TokenUser
, tokenuser
, retlen
, &retlen
))
965 bail("could not get token information: error code %lu",
969 if (!LookupAccountSid(NULL
, tokenuser
->User
.Sid
, accountname
, &accountnamesize
,
970 domainname
, &domainnamesize
, &accountnameuse
))
972 bail("could not look up account SID: error code %lu",
983 * Rewrite pg_hba.conf and pg_ident.conf to use SSPI authentication. Permit
984 * the current OS user to authenticate as the bootstrap superuser and as any
985 * user named in a --create-role option.
987 * In --config-auth mode, the --user switch can be used to specify the
988 * bootstrap superuser's name, otherwise we assume it is the default.
991 config_sspi_auth(const char *pgdata
, const char *superuser_name
)
993 const char *accountname
,
997 char fname
[MAXPGPATH
];
1003 /* Find out the name of the current OS user */
1004 current_windows_user(&accountname
, &domainname
);
1006 /* Determine the bootstrap superuser's name */
1007 if (superuser_name
== NULL
)
1010 * Compute the default superuser name the same way initdb does.
1012 * It's possible that this result always matches "accountname", the
1013 * value SSPI authentication discovers. But the underlying system
1014 * functions do not clearly guarantee that.
1016 superuser_name
= get_user_name(&errstr
);
1017 if (superuser_name
== NULL
)
1024 * Like initdb.c:setup_config(), determine whether the platform recognizes
1025 * ::1 (IPv6 loopback) as a numeric host address string.
1028 struct addrinfo
*gai_result
;
1029 struct addrinfo hints
;
1032 hints
.ai_flags
= AI_NUMERICHOST
;
1033 hints
.ai_family
= AF_UNSPEC
;
1034 hints
.ai_socktype
= 0;
1035 hints
.ai_protocol
= 0;
1036 hints
.ai_addrlen
= 0;
1037 hints
.ai_canonname
= NULL
;
1038 hints
.ai_addr
= NULL
;
1039 hints
.ai_next
= NULL
;
1041 have_ipv6
= (WSAStartup(MAKEWORD(2, 2), &wsaData
) == 0 &&
1042 getaddrinfo("::1", NULL
, &hints
, &gai_result
) == 0);
1045 /* Check a Write outcome and report any error. */
1050 bail("could not write to file \"%s\": %s", \
1051 fname, strerror(errno)); \
1055 res
= snprintf(fname
, sizeof(fname
), "%s/pg_hba.conf", pgdata
);
1056 if (res
< 0 || res
>= sizeof(fname
))
1059 * Truncating this name is a fatal error, because we must not fail to
1060 * overwrite an original trust-authentication pg_hba.conf.
1062 bail("directory name too long");
1064 hba
= fopen(fname
, "w");
1067 bail("could not open file \"%s\" for writing: %s",
1068 fname
, strerror(errno
));
1070 CW(fputs("# Configuration written by config_sspi_auth()\n", hba
) >= 0);
1071 CW(fputs("host all all 127.0.0.1/32 sspi include_realm=1 map=regress\n",
1074 CW(fputs("host all all ::1/128 sspi include_realm=1 map=regress\n",
1076 CW(fclose(hba
) == 0);
1078 snprintf(fname
, sizeof(fname
), "%s/pg_ident.conf", pgdata
);
1079 ident
= fopen(fname
, "w");
1082 bail("could not open file \"%s\" for writing: %s",
1083 fname
, strerror(errno
));
1085 CW(fputs("# Configuration written by config_sspi_auth()\n", ident
) >= 0);
1088 * Double-quote for the benefit of account names containing whitespace or
1089 * '#'. Windows forbids the double-quote character itself, so don't
1090 * bother escaping embedded double-quote characters.
1092 CW(fprintf(ident
, "regress \"%s@%s\" %s\n",
1093 accountname
, domainname
, fmtHba(superuser_name
)) >= 0);
1094 for (sl
= extraroles
; sl
; sl
= sl
->next
)
1095 CW(fprintf(ident
, "regress \"%s@%s\" %s\n",
1096 accountname
, domainname
, fmtHba(sl
->str
)) >= 0);
1097 CW(fclose(ident
) == 0);
1100 #endif /* ENABLE_SSPI */
1103 * psql_start_command, psql_add_command, psql_end_command
1105 * Issue one or more commands within one psql call.
1106 * Set up with psql_start_command, then add commands one at a time
1107 * with psql_add_command, and finally execute with psql_end_command.
1109 * Since we use system(), this doesn't return until the operation finishes
1112 psql_start_command(void)
1114 StringInfo buf
= makeStringInfo();
1116 appendStringInfo(buf
,
1117 "\"%s%spsql\" -X -q",
1118 bindir
? bindir
: "",
1124 psql_add_command(StringInfo buf
, const char *query
,...)
1126 StringInfoData cmdbuf
;
1129 /* Add each command as a -c argument in the psql call */
1130 appendStringInfoString(buf
, " -c \"");
1132 /* Generate the query with insertion of sprintf arguments */
1133 initStringInfo(&cmdbuf
);
1139 va_start(args
, query
);
1140 needed
= appendStringInfoVA(&cmdbuf
, query
, args
);
1143 break; /* success */
1144 enlargeStringInfo(&cmdbuf
, needed
);
1147 /* Now escape any shell double-quote metacharacters */
1148 for (cmdptr
= cmdbuf
.data
; *cmdptr
; cmdptr
++)
1150 if (strchr("\\\"$`", *cmdptr
))
1151 appendStringInfoChar(buf
, '\\');
1152 appendStringInfoChar(buf
, *cmdptr
);
1155 appendStringInfoChar(buf
, '"');
1161 psql_end_command(StringInfo buf
, const char *database
)
1163 /* Add the database name --- assume it needs no extra escaping */
1164 appendStringInfo(buf
,
1168 /* And now we can execute the shell command */
1170 if (system(buf
->data
) != 0)
1172 /* psql probably already reported the error */
1173 bail("command failed: %s", buf
->data
);
1182 * Shorthand macro for the common case of a single command
1184 #define psql_command(database, ...) \
1186 StringInfo cmdbuf = psql_start_command(); \
1187 psql_add_command(cmdbuf, __VA_ARGS__); \
1188 psql_end_command(cmdbuf, database); \
1192 * Spawn a process to execute the given shell command; don't wait for it
1194 * Returns the process ID (or HANDLE) so we can wait for it later
1197 spawn_process(const char *cmdline
)
1203 * Must flush I/O buffers before fork.
1214 bail("could not fork: %s", strerror(errno
));
1221 * Instead of using system(), exec the shell directly, and tell it to
1222 * "exec" the command too. This saves two useless processes per
1223 * parallel test case.
1227 cmdline2
= psprintf("exec %s", cmdline
);
1228 execl(shellprog
, shellprog
, "-c", cmdline2
, (char *) NULL
);
1229 /* Not using the normal bail() here as we want _exit */
1230 bail_noatexit("could not exec \"%s\": %s", shellprog
, strerror(errno
));
1235 PROCESS_INFORMATION pi
;
1237 const char *comspec
;
1239 /* Find CMD.EXE location using COMSPEC, if it's set */
1240 comspec
= getenv("COMSPEC");
1241 if (comspec
== NULL
)
1244 memset(&pi
, 0, sizeof(pi
));
1245 cmdline2
= psprintf("\"%s\" /d /c \"%s\"", comspec
, cmdline
);
1247 if (!CreateRestrictedProcess(cmdline2
, &pi
))
1250 CloseHandle(pi
.hThread
);
1256 * Count bytes in file
1259 file_size(const char *file
)
1262 FILE *f
= fopen(file
, "r");
1266 diag("could not open file \"%s\" for reading: %s",
1267 file
, strerror(errno
));
1270 fseek(f
, 0, SEEK_END
);
1277 * Count lines in file
1280 file_line_count(const char *file
)
1284 FILE *f
= fopen(file
, "r");
1288 diag("could not open file \"%s\" for reading: %s",
1289 file
, strerror(errno
));
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)
1330 bail("could not create directory \"%s\": %s", dir
, strerror(errno
));
1335 * In: filename.ext, Return: filename_i.ext, where 0 < i <= 9
1338 get_alternative_expectfile(const char *expectfile
, int i
)
1341 int ssize
= strlen(expectfile
) + 2 + 1;
1345 if (!(tmp
= (char *) malloc(ssize
)))
1348 if (!(s
= (char *) malloc(ssize
)))
1354 strcpy(tmp
, expectfile
);
1355 last_dot
= strrchr(tmp
, '.');
1363 snprintf(s
, ssize
, "%s_%d.%s", tmp
, i
, last_dot
+ 1);
1369 * Run a "diff" command and also check that it didn't crash
1372 run_diff(const char *cmd
, const char *filename
)
1378 if (!WIFEXITED(r
) || WEXITSTATUS(r
) > 1)
1380 bail("diff command failed with status %d: %s", r
, cmd
);
1385 * On WIN32, if the 'diff' command cannot be found, system() returns 1,
1386 * but produces nothing to stdout, so we check for that here.
1388 if (WEXITSTATUS(r
) == 1 && file_size(filename
) <= 0)
1390 bail("diff command not found: %s", cmd
);
1394 return WEXITSTATUS(r
);
1398 * Check the actual result file for the given test against expected results
1400 * Returns true if different (failure), false if correct match found.
1401 * In the true case, the diff is appended to the diffs file.
1404 results_differ(const char *testname
, const char *resultsfile
, const char *default_expectfile
)
1406 char expectfile
[MAXPGPATH
];
1407 char diff
[MAXPGPATH
];
1408 char cmd
[MAXPGPATH
* 3];
1409 char best_expect_file
[MAXPGPATH
];
1411 int best_line_count
;
1414 const char *platform_expectfile
;
1417 * We can pass either the resultsfile or the expectfile, they should have
1418 * the same type (filename.type) anyway.
1420 platform_expectfile
= get_expectfile(testname
, resultsfile
);
1422 strlcpy(expectfile
, default_expectfile
, sizeof(expectfile
));
1423 if (platform_expectfile
)
1426 * Replace everything after the last slash in expectfile with what the
1427 * platform_expectfile contains.
1429 char *p
= strrchr(expectfile
, '/');
1432 strcpy(++p
, platform_expectfile
);
1435 /* Name to use for temporary diff file */
1436 snprintf(diff
, sizeof(diff
), "%s.diff", resultsfile
);
1438 /* OK, run the diff */
1439 snprintf(cmd
, sizeof(cmd
),
1440 "diff %s \"%s\" \"%s\" > \"%s\"",
1441 basic_diff_opts
, expectfile
, resultsfile
, diff
);
1443 /* Is the diff file empty? */
1444 if (run_diff(cmd
, diff
) == 0)
1450 /* There may be secondary comparison files that match better */
1451 best_line_count
= file_line_count(diff
);
1452 strcpy(best_expect_file
, expectfile
);
1454 for (i
= 0; i
<= 9; i
++)
1456 char *alt_expectfile
;
1458 alt_expectfile
= get_alternative_expectfile(expectfile
, i
);
1459 if (!alt_expectfile
)
1461 bail("Unable to check secondary comparison files: %s",
1465 if (!file_exists(alt_expectfile
))
1467 free(alt_expectfile
);
1471 snprintf(cmd
, sizeof(cmd
),
1472 "diff %s \"%s\" \"%s\" > \"%s\"",
1473 basic_diff_opts
, alt_expectfile
, resultsfile
, diff
);
1475 if (run_diff(cmd
, diff
) == 0)
1478 free(alt_expectfile
);
1482 l
= file_line_count(diff
);
1483 if (l
< best_line_count
)
1485 /* This diff was a better match than the last one */
1486 best_line_count
= l
;
1487 strlcpy(best_expect_file
, alt_expectfile
, sizeof(best_expect_file
));
1489 free(alt_expectfile
);
1493 * fall back on the canonical results file if we haven't tried it yet and
1494 * haven't found a complete match yet.
1497 if (platform_expectfile
)
1499 snprintf(cmd
, sizeof(cmd
),
1500 "diff %s \"%s\" \"%s\" > \"%s\"",
1501 basic_diff_opts
, default_expectfile
, resultsfile
, diff
);
1503 if (run_diff(cmd
, diff
) == 0)
1505 /* No diff = no changes = good */
1510 l
= file_line_count(diff
);
1511 if (l
< best_line_count
)
1513 /* This diff was a better match than the last one */
1514 best_line_count
= l
;
1515 strlcpy(best_expect_file
, default_expectfile
, sizeof(best_expect_file
));
1520 * Use the best comparison file to generate the "pretty" diff, which we
1521 * append to the diffs summary file.
1524 /* Write diff header */
1525 difffile
= fopen(difffilename
, "a");
1530 pretty_diff_opts
, best_expect_file
, resultsfile
);
1535 snprintf(cmd
, sizeof(cmd
),
1536 "diff %s \"%s\" \"%s\" >> \"%s\"",
1537 pretty_diff_opts
, best_expect_file
, resultsfile
, difffilename
);
1538 run_diff(cmd
, difffilename
);
1545 * Wait for specified subprocesses to finish, and return their exit
1546 * statuses into statuses[] and stop times into stoptimes[]
1548 * If names isn't NULL, print each subprocess's name as it finishes
1550 * Note: it's OK to scribble on the pids array, but not on the names array
1553 wait_for_tests(PID_TYPE
* pids
, int *statuses
, instr_time
*stoptimes
,
1554 char **names
, int num_tests
)
1560 PID_TYPE
*active_pids
= pg_malloc(num_tests
* sizeof(PID_TYPE
));
1562 memcpy(active_pids
, pids
, num_tests
* sizeof(PID_TYPE
));
1565 tests_left
= num_tests
;
1566 while (tests_left
> 0)
1573 p
= wait(&exit_status
);
1575 if (p
== INVALID_PID
)
1577 bail("failed to wait for subprocesses: %s", strerror(errno
));
1583 r
= WaitForMultipleObjects(tests_left
, active_pids
, FALSE
, INFINITE
);
1584 if (r
< WAIT_OBJECT_0
|| r
>= WAIT_OBJECT_0
+ tests_left
)
1586 bail("failed to wait for subprocesses: error code %lu",
1589 p
= active_pids
[r
- WAIT_OBJECT_0
];
1590 /* compact the active_pids array */
1591 active_pids
[r
- WAIT_OBJECT_0
] = active_pids
[tests_left
- 1];
1594 for (i
= 0; i
< num_tests
; i
++)
1599 GetExitCodeProcess(pids
[i
], &exit_status
);
1600 CloseHandle(pids
[i
]);
1602 pids
[i
] = INVALID_PID
;
1603 statuses
[i
] = (int) exit_status
;
1604 INSTR_TIME_SET_CURRENT(stoptimes
[i
]);
1606 note_detail(" %s", names
[i
]);
1619 * report nonzero exit code from a test process
1622 log_child_failure(int exitstatus
)
1624 if (WIFEXITED(exitstatus
))
1625 diag("(test process exited with exit code %d)",
1626 WEXITSTATUS(exitstatus
));
1627 else if (WIFSIGNALED(exitstatus
))
1630 diag("(test process was terminated by exception 0x%X)",
1631 WTERMSIG(exitstatus
));
1633 diag("(test process was terminated by signal %d: %s)",
1634 WTERMSIG(exitstatus
), pg_strsignal(WTERMSIG(exitstatus
)));
1638 diag("(test process exited with unrecognized status %d)", exitstatus
);
1642 * Run all the tests specified in one schedule file
1645 run_schedule(const char *schedule
, test_start_function startfunc
,
1646 postprocess_result_function postfunc
)
1648 #define MAX_PARALLEL_TESTS 100
1649 char *tests
[MAX_PARALLEL_TESTS
];
1650 _stringlist
*resultfiles
[MAX_PARALLEL_TESTS
];
1651 _stringlist
*expectfiles
[MAX_PARALLEL_TESTS
];
1652 _stringlist
*tags
[MAX_PARALLEL_TESTS
];
1653 PID_TYPE pids
[MAX_PARALLEL_TESTS
];
1654 instr_time starttimes
[MAX_PARALLEL_TESTS
];
1655 instr_time stoptimes
[MAX_PARALLEL_TESTS
];
1656 int statuses
[MAX_PARALLEL_TESTS
];
1661 memset(tests
, 0, sizeof(tests
));
1662 memset(resultfiles
, 0, sizeof(resultfiles
));
1663 memset(expectfiles
, 0, sizeof(expectfiles
));
1664 memset(tags
, 0, sizeof(tags
));
1666 scf
= fopen(schedule
, "r");
1669 bail("could not open file \"%s\" for reading: %s",
1670 schedule
, strerror(errno
));
1673 while (fgets(scbuf
, sizeof(scbuf
), scf
))
1683 /* strip trailing whitespace, especially the newline */
1685 while (i
> 0 && isspace((unsigned char) scbuf
[i
- 1]))
1688 if (scbuf
[0] == '\0' || scbuf
[0] == '#')
1690 if (strncmp(scbuf
, "test: ", 6) == 0)
1694 bail("syntax error in schedule file \"%s\" line %d: %s",
1695 schedule
, line_num
, scbuf
);
1700 for (c
= test
;; c
++)
1702 if (*c
== '\0' || isspace((unsigned char) *c
))
1706 /* Reached end of a test name */
1709 if (num_tests
>= MAX_PARALLEL_TESTS
)
1711 bail("too many parallel tests (more than %d) in schedule file \"%s\" line %d: %s",
1712 MAX_PARALLEL_TESTS
, schedule
, line_num
, scbuf
);
1716 tests
[num_tests
] = pg_strdup(test
);
1722 break; /* loop exit is here */
1726 /* Start of a test name */
1734 bail("syntax error in schedule file \"%s\" line %d: %s",
1735 schedule
, line_num
, scbuf
);
1740 pids
[0] = (startfunc
) (tests
[0], &resultfiles
[0], &expectfiles
[0], &tags
[0]);
1741 INSTR_TIME_SET_CURRENT(starttimes
[0]);
1742 wait_for_tests(pids
, statuses
, stoptimes
, NULL
, 1);
1743 /* status line is finished below */
1745 else if (max_concurrent_tests
> 0 && max_concurrent_tests
< num_tests
)
1747 bail("too many parallel tests (more than %d) in schedule file \"%s\" line %d: %s",
1748 max_concurrent_tests
, schedule
, line_num
, scbuf
);
1750 else if (max_connections
> 0 && max_connections
< num_tests
)
1754 note_detail("parallel group (%d tests, in groups of %d): ",
1755 num_tests
, max_connections
);
1756 for (i
= 0; i
< num_tests
; i
++)
1758 if (i
- oldest
>= max_connections
)
1760 wait_for_tests(pids
+ oldest
, statuses
+ oldest
,
1762 tests
+ oldest
, i
- oldest
);
1765 pids
[i
] = (startfunc
) (tests
[i
], &resultfiles
[i
], &expectfiles
[i
], &tags
[i
]);
1766 INSTR_TIME_SET_CURRENT(starttimes
[i
]);
1768 wait_for_tests(pids
+ oldest
, statuses
+ oldest
,
1770 tests
+ oldest
, i
- oldest
);
1775 note_detail("parallel group (%d tests): ", num_tests
);
1776 for (i
= 0; i
< num_tests
; i
++)
1778 pids
[i
] = (startfunc
) (tests
[i
], &resultfiles
[i
], &expectfiles
[i
], &tags
[i
]);
1779 INSTR_TIME_SET_CURRENT(starttimes
[i
]);
1781 wait_for_tests(pids
, statuses
, stoptimes
, tests
, num_tests
);
1785 /* Check results for all tests */
1786 for (i
= 0; i
< num_tests
; i
++)
1791 bool differ
= false;
1793 INSTR_TIME_SUBTRACT(stoptimes
[i
], starttimes
[i
]);
1796 * Advance over all three lists simultaneously.
1798 * Compare resultfiles[j] with expectfiles[j] always. Tags are
1799 * optional but if there are tags, the tag list has the same
1800 * length as the other two lists.
1802 for (rl
= resultfiles
[i
], el
= expectfiles
[i
], tl
= tags
[i
];
1803 rl
!= NULL
; /* rl and el have the same length */
1804 rl
= rl
->next
, el
= el
->next
,
1805 tl
= tl
? tl
->next
: NULL
)
1810 (*postfunc
) (rl
->str
);
1811 newdiff
= results_differ(tests
[i
], rl
->str
, el
->str
);
1814 diag("tag: %s", tl
->str
);
1819 if (statuses
[i
] != 0)
1821 test_status_failed(tests
[i
], INSTR_TIME_GET_MILLISEC(stoptimes
[i
]), (num_tests
> 1));
1822 log_child_failure(statuses
[i
]);
1828 test_status_failed(tests
[i
], INSTR_TIME_GET_MILLISEC(stoptimes
[i
]), (num_tests
> 1));
1832 test_status_ok(tests
[i
], INSTR_TIME_GET_MILLISEC(stoptimes
[i
]), (num_tests
> 1));
1837 for (i
= 0; i
< num_tests
; i
++)
1841 free_stringlist(&resultfiles
[i
]);
1842 free_stringlist(&expectfiles
[i
]);
1843 free_stringlist(&tags
[i
]);
1854 run_single_test(const char *test
, test_start_function startfunc
,
1855 postprocess_result_function postfunc
)
1858 instr_time starttime
;
1859 instr_time stoptime
;
1861 _stringlist
*resultfiles
= NULL
;
1862 _stringlist
*expectfiles
= NULL
;
1863 _stringlist
*tags
= NULL
;
1867 bool differ
= false;
1869 pid
= (startfunc
) (test
, &resultfiles
, &expectfiles
, &tags
);
1870 INSTR_TIME_SET_CURRENT(starttime
);
1871 wait_for_tests(&pid
, &exit_status
, &stoptime
, NULL
, 1);
1874 * Advance over all three lists simultaneously.
1876 * Compare resultfiles[j] with expectfiles[j] always. Tags are optional
1877 * but if there are tags, the tag list has the same length as the other
1880 for (rl
= resultfiles
, el
= expectfiles
, tl
= tags
;
1881 rl
!= NULL
; /* rl and el have the same length */
1882 rl
= rl
->next
, el
= el
->next
,
1883 tl
= tl
? tl
->next
: NULL
)
1888 (*postfunc
) (rl
->str
);
1889 newdiff
= results_differ(test
, rl
->str
, el
->str
);
1892 diag("tag: %s", tl
->str
);
1897 INSTR_TIME_SUBTRACT(stoptime
, starttime
);
1899 if (exit_status
!= 0)
1901 test_status_failed(test
, INSTR_TIME_GET_MILLISEC(stoptime
), false);
1902 log_child_failure(exit_status
);
1908 test_status_failed(test
, INSTR_TIME_GET_MILLISEC(stoptime
), false);
1912 test_status_ok(test
, INSTR_TIME_GET_MILLISEC(stoptime
), false);
1918 * Create the summary-output files (making them empty if already existing)
1921 open_result_files(void)
1923 char file
[MAXPGPATH
];
1926 /* create outputdir directory if not present */
1927 if (!directory_exists(outputdir
))
1928 make_directory(outputdir
);
1930 /* create the log file (copy of running status output) */
1931 snprintf(file
, sizeof(file
), "%s/regression.out", outputdir
);
1932 logfilename
= pg_strdup(file
);
1933 logfile
= fopen(logfilename
, "w");
1936 bail("could not open file \"%s\" for writing: %s",
1937 logfilename
, strerror(errno
));
1940 /* create the diffs file as empty */
1941 snprintf(file
, sizeof(file
), "%s/regression.diffs", outputdir
);
1942 difffilename
= pg_strdup(file
);
1943 difffile
= fopen(difffilename
, "w");
1946 bail("could not open file \"%s\" for writing: %s",
1947 difffilename
, strerror(errno
));
1949 /* we don't keep the diffs file open continuously */
1952 /* also create the results directory if not present */
1953 snprintf(file
, sizeof(file
), "%s/results", outputdir
);
1954 if (!directory_exists(file
))
1955 make_directory(file
);
1959 drop_database_if_exists(const char *dbname
)
1961 StringInfo buf
= psql_start_command();
1963 /* Set warning level so we don't see chatter about nonexistent DB */
1964 psql_add_command(buf
, "SET client_min_messages = warning");
1965 psql_add_command(buf
, "DROP DATABASE IF EXISTS \"%s\"", dbname
);
1966 psql_end_command(buf
, "postgres");
1970 create_database(const char *dbname
)
1972 StringInfo buf
= psql_start_command();
1976 * We use template0 so that any installation-local cruft in template1 will
1977 * not mess up the tests.
1980 psql_add_command(buf
, "CREATE DATABASE \"%s\" TEMPLATE=template0 ENCODING='%s'%s", dbname
, encoding
,
1981 (nolocale
) ? " LOCALE='C'" : "");
1983 psql_add_command(buf
, "CREATE DATABASE \"%s\" TEMPLATE=template0%s", dbname
,
1984 (nolocale
) ? " LOCALE='C'" : "");
1985 psql_add_command(buf
,
1986 "ALTER DATABASE \"%s\" SET lc_messages TO 'C';"
1987 "ALTER DATABASE \"%s\" SET lc_monetary TO 'C';"
1988 "ALTER DATABASE \"%s\" SET lc_numeric TO 'C';"
1989 "ALTER DATABASE \"%s\" SET lc_time TO 'C';"
1990 "ALTER DATABASE \"%s\" SET bytea_output TO 'hex';"
1991 "ALTER DATABASE \"%s\" SET timezone_abbreviations TO 'Default';",
1992 dbname
, dbname
, dbname
, dbname
, dbname
, dbname
);
1993 psql_end_command(buf
, "postgres");
1996 * Install any requested extensions. We use CREATE IF NOT EXISTS so that
1997 * this will work whether or not the extension is preinstalled.
1999 for (sl
= loadextension
; sl
!= NULL
; sl
= sl
->next
)
2000 psql_command(dbname
, "CREATE EXTENSION IF NOT EXISTS \"%s\"", sl
->str
);
2004 drop_role_if_exists(const char *rolename
)
2006 StringInfo buf
= psql_start_command();
2008 /* Set warning level so we don't see chatter about nonexistent role */
2009 psql_add_command(buf
, "SET client_min_messages = warning");
2010 psql_add_command(buf
, "DROP ROLE IF EXISTS \"%s\"", rolename
);
2011 psql_end_command(buf
, "postgres");
2015 create_role(const char *rolename
, const _stringlist
*granted_dbs
)
2017 StringInfo buf
= psql_start_command();
2019 psql_add_command(buf
, "CREATE ROLE \"%s\" WITH LOGIN", rolename
);
2020 for (; granted_dbs
!= NULL
; granted_dbs
= granted_dbs
->next
)
2022 psql_add_command(buf
, "GRANT ALL ON DATABASE \"%s\" TO \"%s\"",
2023 granted_dbs
->str
, rolename
);
2025 psql_end_command(buf
, "postgres");
2031 printf(_("PostgreSQL regression test driver\n"));
2033 printf(_("Usage:\n %s [OPTION]... [EXTRA-TEST]...\n"), progname
);
2035 printf(_("Options:\n"));
2036 printf(_(" --bindir=BINPATH use BINPATH for programs that are run;\n"));
2037 printf(_(" if empty, use PATH from the environment\n"));
2038 printf(_(" --config-auth=DATADIR update authentication settings for DATADIR\n"));
2039 printf(_(" --create-role=ROLE create the specified role before testing\n"));
2040 printf(_(" --dbname=DB use database DB (default \"regression\")\n"));
2041 printf(_(" --debug turn on debug mode in programs that are run\n"));
2042 printf(_(" --dlpath=DIR look for dynamic libraries in DIR\n"));
2043 printf(_(" --encoding=ENCODING use ENCODING as the encoding\n"));
2044 printf(_(" --expecteddir=DIR take expected files from DIR (default \".\")\n"));
2045 printf(_(" -h, --help show this help, then exit\n"));
2046 printf(_(" --inputdir=DIR take input files from DIR (default \".\")\n"));
2047 printf(_(" --launcher=CMD use CMD as launcher of psql\n"));
2048 printf(_(" --load-extension=EXT load the named extension before running the\n"));
2049 printf(_(" tests; can appear multiple times\n"));
2050 printf(_(" --max-connections=N maximum number of concurrent connections\n"));
2051 printf(_(" (default is 0, meaning unlimited)\n"));
2052 printf(_(" --max-concurrent-tests=N maximum number of concurrent tests in schedule\n"));
2053 printf(_(" (default is 0, meaning unlimited)\n"));
2054 printf(_(" --outputdir=DIR place output files in DIR (default \".\")\n"));
2055 printf(_(" --schedule=FILE use test ordering schedule from FILE\n"));
2056 printf(_(" (can be used multiple times to concatenate)\n"));
2057 printf(_(" --temp-instance=DIR create a temporary instance in DIR\n"));
2058 printf(_(" --use-existing use an existing installation\n"));
2059 printf(_(" -V, --version output version information, then exit\n"));
2061 printf(_("Options for \"temp-instance\" mode:\n"));
2062 printf(_(" --no-locale use C locale\n"));
2063 printf(_(" --port=PORT start postmaster on PORT\n"));
2064 printf(_(" --temp-config=FILE append contents of FILE to temporary config\n"));
2066 printf(_("Options for using an existing installation:\n"));
2067 printf(_(" --host=HOST use postmaster running on HOST\n"));
2068 printf(_(" --port=PORT use postmaster running at PORT\n"));
2069 printf(_(" --user=USER connect as USER\n"));
2071 printf(_("The exit status is 0 if all tests passed, 1 if some tests failed, and 2\n"));
2072 printf(_("if the tests could not be run for some reason.\n"));
2074 printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
2075 printf(_("%s home page: <%s>\n"), PACKAGE_NAME
, PACKAGE_URL
);
2079 regression_main(int argc
, char *argv
[],
2080 init_function ifunc
,
2081 test_start_function startfunc
,
2082 postprocess_result_function postfunc
)
2084 static struct option long_options
[] = {
2085 {"help", no_argument
, NULL
, 'h'},
2086 {"version", no_argument
, NULL
, 'V'},
2087 {"dbname", required_argument
, NULL
, 1},
2088 {"debug", no_argument
, NULL
, 2},
2089 {"inputdir", required_argument
, NULL
, 3},
2090 {"max-connections", required_argument
, NULL
, 5},
2091 {"encoding", required_argument
, NULL
, 6},
2092 {"outputdir", required_argument
, NULL
, 7},
2093 {"schedule", required_argument
, NULL
, 8},
2094 {"temp-instance", required_argument
, NULL
, 9},
2095 {"no-locale", no_argument
, NULL
, 10},
2096 {"host", required_argument
, NULL
, 13},
2097 {"port", required_argument
, NULL
, 14},
2098 {"user", required_argument
, NULL
, 15},
2099 {"bindir", required_argument
, NULL
, 16},
2100 {"dlpath", required_argument
, NULL
, 17},
2101 {"create-role", required_argument
, NULL
, 18},
2102 {"temp-config", required_argument
, NULL
, 19},
2103 {"use-existing", no_argument
, NULL
, 20},
2104 {"launcher", required_argument
, NULL
, 21},
2105 {"load-extension", required_argument
, NULL
, 22},
2106 {"config-auth", required_argument
, NULL
, 24},
2107 {"max-concurrent-tests", required_argument
, NULL
, 25},
2108 {"expecteddir", required_argument
, NULL
, 26},
2112 bool use_unix_sockets
;
2117 char buf
[MAXPGPATH
* 4];
2119 pg_logging_init(argv
[0]);
2120 progname
= get_progname(argv
[0]);
2121 set_pglocale_pgservice(argv
[0], PG_TEXTDOMAIN("pg_regress"));
2123 get_restricted_token();
2125 atexit(stop_postmaster
);
2130 * We don't use Unix-domain sockets on Windows by default (see comment at
2131 * remove_temp() for a reason). Override at your own risk.
2133 use_unix_sockets
= getenv("PG_TEST_USE_UNIX_SOCKETS") ? true : false;
2135 use_unix_sockets
= true;
2138 if (!use_unix_sockets
)
2139 hostname
= "localhost";
2142 * We call the initialization function here because that way we can set
2143 * default parameters and let them be overwritten by the commandline.
2147 if (getenv("PG_REGRESS_DIFF_OPTS"))
2148 pretty_diff_opts
= getenv("PG_REGRESS_DIFF_OPTS");
2150 while ((c
= getopt_long(argc
, argv
, "hV", long_options
, &option_index
)) != -1)
2158 puts("pg_regress (PostgreSQL) " PG_VERSION
);
2163 * If a default database was specified, we need to remove it
2164 * before we add the specified one.
2166 free_stringlist(&dblist
);
2167 split_to_stringlist(optarg
, ",", &dblist
);
2173 inputdir
= pg_strdup(optarg
);
2176 max_connections
= atoi(optarg
);
2179 encoding
= pg_strdup(optarg
);
2182 outputdir
= pg_strdup(optarg
);
2185 add_stringlist_item(&schedulelist
, optarg
);
2188 temp_instance
= make_absolute_path(optarg
);
2194 hostname
= pg_strdup(optarg
);
2197 port
= atoi(optarg
);
2198 port_specified_by_user
= true;
2201 user
= pg_strdup(optarg
);
2204 /* "--bindir=" means to use PATH */
2206 bindir
= pg_strdup(optarg
);
2211 dlpath
= pg_strdup(optarg
);
2214 split_to_stringlist(optarg
, ",", &extraroles
);
2217 add_stringlist_item(&temp_configs
, optarg
);
2220 use_existing
= true;
2223 launcher
= pg_strdup(optarg
);
2226 add_stringlist_item(&loadextension
, optarg
);
2229 config_auth_datadir
= pg_strdup(optarg
);
2232 max_concurrent_tests
= atoi(optarg
);
2235 expecteddir
= pg_strdup(optarg
);
2238 /* getopt_long already emitted a complaint */
2239 pg_log_error_hint("Try \"%s --help\" for more information.",
2246 * if we still have arguments, they are extra tests to run
2248 while (argc
- optind
>= 1)
2250 add_stringlist_item(&extra_tests
, argv
[optind
]);
2255 * We must have a database to run the tests in; either a default name, or
2256 * one supplied by the --dbname switch.
2258 if (!(dblist
&& dblist
->str
&& dblist
->str
[0]))
2260 bail("no database name was specified");
2263 if (config_auth_datadir
)
2266 if (!use_unix_sockets
)
2267 config_sspi_auth(config_auth_datadir
, user
);
2272 if (temp_instance
&& !port_specified_by_user
)
2275 * To reduce chances of interference with parallel installations, use
2276 * a port number starting in the private range (49152-65535)
2277 * calculated from the version number. This aids non-Unix socket mode
2278 * systems; elsewhere, the use of a private socket directory already
2279 * prevents interference.
2281 port
= 0xC000 | (PG_VERSION_NUM
& 0x3FFF);
2283 inputdir
= make_absolute_path(inputdir
);
2284 outputdir
= make_absolute_path(outputdir
);
2285 expecteddir
= make_absolute_path(expecteddir
);
2286 dlpath
= make_absolute_path(dlpath
);
2291 open_result_files();
2293 initialize_environment();
2295 #if defined(HAVE_GETRLIMIT)
2296 unlimit_core_size();
2303 const char *env_wait
;
2305 const char *initdb_template_dir
;
2306 const char *keywords
[4];
2307 const char *values
[4];
2311 * Prepare the temp instance
2314 if (directory_exists(temp_instance
))
2316 if (!rmtree(temp_instance
, true))
2318 bail("could not remove temp instance \"%s\"", temp_instance
);
2322 /* make the temp instance top directory */
2323 make_directory(temp_instance
);
2325 /* and a directory for log files */
2326 snprintf(buf
, sizeof(buf
), "%s/log", outputdir
);
2327 if (!directory_exists(buf
))
2328 make_directory(buf
);
2330 initStringInfo(&cmd
);
2333 * Create data directory.
2335 * If available, use a previously initdb'd cluster as a template by
2336 * copying it. For a lot of tests, that's substantially cheaper.
2338 * There's very similar code in Cluster.pm, but we can't easily de
2339 * duplicate it until we require perl at build time.
2341 initdb_template_dir
= getenv("INITDB_TEMPLATE");
2342 if (initdb_template_dir
== NULL
|| nolocale
|| debug
)
2344 note("initializing database system by running initdb");
2346 appendStringInfo(&cmd
,
2347 "\"%s%sinitdb\" -D \"%s/data\" --no-clean --no-sync",
2348 bindir
? bindir
: "",
2352 appendStringInfoString(&cmd
, " --debug");
2354 appendStringInfoString(&cmd
, " --no-locale");
2355 appendStringInfo(&cmd
, " > \"%s/log/initdb.log\" 2>&1", outputdir
);
2357 if (system(cmd
.data
))
2359 bail("initdb failed\n"
2360 "# Examine \"%s/log/initdb.log\" for the reason.\n"
2361 "# Command was: %s",
2362 outputdir
, cmd
.data
);
2368 const char *copycmd
= "cp -RPp \"%s\" \"%s/data\"";
2369 int expected_exitcode
= 0;
2371 const char *copycmd
= "robocopy /E /NJS /NJH /NFL /NDL /NP \"%s\" \"%s/data\"";
2372 int expected_exitcode
= 1; /* 1 denotes files were copied */
2375 note("initializing database system by copying initdb template");
2377 appendStringInfo(&cmd
,
2379 initdb_template_dir
,
2381 appendStringInfo(&cmd
, " > \"%s/log/initdb.log\" 2>&1", outputdir
);
2383 if (system(cmd
.data
) != expected_exitcode
)
2385 bail("copying of initdb template failed\n"
2386 "# Examine \"%s/log/initdb.log\" for the reason.\n"
2387 "# Command was: %s",
2388 outputdir
, cmd
.data
);
2395 * Adjust the default postgresql.conf for regression testing. The user
2396 * can specify a file to be appended; in any case we expand logging
2397 * and set max_prepared_transactions to enable testing of prepared
2398 * xacts. (Note: to reduce the probability of unexpected shmmax
2399 * failures, don't set max_prepared_transactions any higher than
2400 * actually needed by the prepared_xacts regression test.)
2402 snprintf(buf
, sizeof(buf
), "%s/data/postgresql.conf", temp_instance
);
2403 pg_conf
= fopen(buf
, "a");
2404 if (pg_conf
== NULL
)
2406 bail("could not open \"%s\" for adding extra config: %s",
2407 buf
, strerror(errno
));
2409 fputs("\n# Configuration added by pg_regress\n\n", pg_conf
);
2410 fputs("log_autovacuum_min_duration = 0\n", pg_conf
);
2411 fputs("log_checkpoints = on\n", pg_conf
);
2412 fputs("log_line_prefix = '%m %b[%p] %q%a '\n", pg_conf
);
2413 fputs("log_lock_waits = on\n", pg_conf
);
2414 fputs("log_temp_files = 128kB\n", pg_conf
);
2415 fputs("max_prepared_transactions = 2\n", pg_conf
);
2417 for (sl
= temp_configs
; sl
!= NULL
; sl
= sl
->next
)
2419 char *temp_config
= sl
->str
;
2421 char line_buf
[1024];
2423 extra_conf
= fopen(temp_config
, "r");
2424 if (extra_conf
== NULL
)
2426 bail("could not open \"%s\" to read extra config: %s",
2427 temp_config
, strerror(errno
));
2429 while (fgets(line_buf
, sizeof(line_buf
), extra_conf
) != NULL
)
2430 fputs(line_buf
, pg_conf
);
2437 if (!use_unix_sockets
)
2440 * Since we successfully used the same buffer for the much-longer
2441 * "initdb" command, this can't truncate.
2443 snprintf(buf
, sizeof(buf
), "%s/data", temp_instance
);
2444 config_sspi_auth(buf
, NULL
);
2449 * Prepare the connection params for checking the state of the server
2450 * before starting the tests.
2452 sprintf(portstr
, "%d", port
);
2453 keywords
[0] = "dbname";
2454 values
[0] = "postgres";
2455 keywords
[1] = "port";
2456 values
[1] = portstr
;
2457 keywords
[2] = "host";
2458 values
[2] = hostname
? hostname
: sockdir
;
2463 * Check if there is a postmaster running already.
2465 for (i
= 0; i
< 16; i
++)
2467 rv
= PQpingParams(keywords
, values
, 1);
2469 if (rv
== PQPING_OK
)
2471 if (port_specified_by_user
|| i
== 15)
2473 note("port %d apparently in use", port
);
2474 if (!port_specified_by_user
)
2475 note("could not determine an available port");
2476 bail("Specify an unused port using the --port option or shut down any conflicting PostgreSQL servers.");
2479 note("port %d apparently in use, trying %d", port
, port
+ 1);
2481 sprintf(portstr
, "%d", port
);
2482 setenv("PGPORT", portstr
, 1);
2489 * Start the temp postmaster
2491 snprintf(buf
, sizeof(buf
),
2492 "\"%s%spostgres\" -D \"%s/data\" -F%s "
2493 "-c \"listen_addresses=%s\" -k \"%s\" "
2494 "> \"%s/log/postmaster.log\" 2>&1",
2495 bindir
? bindir
: "",
2497 temp_instance
, debug
? " -d 5" : "",
2498 hostname
? hostname
: "", sockdir
? sockdir
: "",
2500 postmaster_pid
= spawn_process(buf
);
2501 if (postmaster_pid
== INVALID_PID
)
2502 bail("could not spawn postmaster: %s", strerror(errno
));
2505 * Wait till postmaster is able to accept connections; normally takes
2506 * only a fraction of a second or so, but Cygwin is reportedly *much*
2507 * slower, and test builds using Valgrind or similar tools might be
2508 * too. Hence, allow the default timeout of 60 seconds to be
2509 * overridden from the PGCTLTIMEOUT environment variable.
2511 env_wait
= getenv("PGCTLTIMEOUT");
2512 if (env_wait
!= NULL
)
2514 wait_seconds
= atoi(env_wait
);
2515 if (wait_seconds
<= 0)
2521 for (i
= 0; i
< wait_seconds
* WAIT_TICKS_PER_SECOND
; i
++)
2524 * It's fairly unlikely that the server is responding immediately
2525 * so we start with sleeping before checking instead of the other
2528 pg_usleep(1000000L / WAIT_TICKS_PER_SECOND
);
2530 rv
= PQpingParams(keywords
, values
, 1);
2532 /* Done if the server is running and accepts connections */
2533 if (rv
== PQPING_OK
)
2536 if (rv
== PQPING_NO_ATTEMPT
)
2537 bail("attempting to connect to postmaster failed");
2540 * Fail immediately if postmaster has exited
2543 if (waitpid(postmaster_pid
, NULL
, WNOHANG
) == postmaster_pid
)
2545 if (WaitForSingleObject(postmaster_pid
, 0) == WAIT_OBJECT_0
)
2548 bail("postmaster failed, examine \"%s/log/postmaster.log\" for the reason",
2552 if (i
>= wait_seconds
* WAIT_TICKS_PER_SECOND
)
2554 diag("postmaster did not respond within %d seconds, examine \"%s/log/postmaster.log\" for the reason",
2555 wait_seconds
, outputdir
);
2558 * If we get here, the postmaster is probably wedged somewhere in
2559 * startup. Try to kill it ungracefully rather than leaving a
2560 * stuck postmaster that might interfere with subsequent test
2564 if (kill(postmaster_pid
, SIGKILL
) != 0 && errno
!= ESRCH
)
2565 bail("could not kill failed postmaster: %s", strerror(errno
));
2567 if (TerminateProcess(postmaster_pid
, 255) == 0)
2568 bail("could not kill failed postmaster: error code %lu",
2571 bail("postmaster failed");
2574 postmaster_running
= true;
2577 /* need a series of two casts to convert HANDLE without compiler warning */
2578 #define ULONGPID(x) (unsigned long) (unsigned long long) (x)
2580 #define ULONGPID(x) (unsigned long) (x)
2582 note("using temp instance on port %d with PID %lu",
2583 port
, ULONGPID(postmaster_pid
));
2588 * Using an existing installation, so may need to get rid of
2589 * pre-existing database(s) and role(s)
2593 for (sl
= dblist
; sl
; sl
= sl
->next
)
2594 drop_database_if_exists(sl
->str
);
2595 for (sl
= extraroles
; sl
; sl
= sl
->next
)
2596 drop_role_if_exists(sl
->str
);
2601 * Create the test database(s) and role(s)
2605 for (sl
= dblist
; sl
; sl
= sl
->next
)
2606 create_database(sl
->str
);
2607 for (sl
= extraroles
; sl
; sl
= sl
->next
)
2608 create_role(sl
->str
, dblist
);
2612 * Ready to run the tests
2614 for (sl
= schedulelist
; sl
!= NULL
; sl
= sl
->next
)
2616 run_schedule(sl
->str
, startfunc
, postfunc
);
2619 for (sl
= extra_tests
; sl
!= NULL
; sl
= sl
->next
)
2621 run_single_test(sl
->str
, startfunc
, postfunc
);
2625 * Shut down temp installation's postmaster
2633 * If there were no errors, remove the temp instance immediately to
2634 * conserve disk space. (If there were errors, we leave the instance in
2635 * place for possible manual investigation.)
2637 if (temp_instance
&& fail_count
== 0)
2639 if (!rmtree(temp_instance
, true))
2640 diag("could not remove temp instance \"%s\"",
2645 * Emit a TAP compliant Plan
2647 plan(fail_count
+ success_count
);
2650 * Emit nice-looking summary message
2652 if (fail_count
== 0)
2653 note("All %d tests passed.", success_count
);
2655 diag("%d of %d tests failed.", fail_count
, success_count
+ fail_count
);
2657 if (file_size(difffilename
) > 0)
2659 diag("The differences that caused some tests to fail can be viewed in the file \"%s\".",
2661 diag("A copy of the test summary that you see above is saved in the file \"%s\".",
2666 unlink(difffilename
);
2667 unlink(logfilename
);
2673 if (fail_count
!= 0)