1 /*-------------------------------------------------------------------------
3 * isolation_main --- pg_regress test launcher for isolation tests
5 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
8 * src/test/isolation/isolation_main.c
10 *-------------------------------------------------------------------------
13 #include "postgres_fe.h"
15 #include "pg_regress.h"
17 char saved_argv0
[MAXPGPATH
];
18 char isolation_exec
[MAXPGPATH
];
19 bool looked_up_isolation_exec
= false;
21 #define PG_ISOLATION_VERSIONSTR "isolationtester (PostgreSQL) " PG_VERSION "\n"
24 * start an isolation tester process for specified file (including
25 * redirection), and return process ID
28 isolation_start_test(const char *testname
,
29 _stringlist
**resultfiles
,
30 _stringlist
**expectfiles
,
34 char infile
[MAXPGPATH
];
35 char outfile
[MAXPGPATH
];
36 char expectfile
[MAXPGPATH
];
37 char psql_cmd
[MAXPGPATH
* 3];
41 /* need to do the path lookup here, check isolation_init() for details */
42 if (!looked_up_isolation_exec
)
44 /* look for isolationtester binary */
45 if (find_other_exec(saved_argv0
, "isolationtester",
46 PG_ISOLATION_VERSIONSTR
, isolation_exec
) != 0)
48 fprintf(stderr
, _("could not find proper isolationtester binary\n"));
51 looked_up_isolation_exec
= true;
55 * Look for files in the output dir first, consistent with a vpath search.
56 * This is mainly to create more reasonable error messages if the file is
57 * not found. It also allows local test overrides when running pg_regress
58 * outside of the source tree.
60 snprintf(infile
, sizeof(infile
), "%s/specs/%s.spec",
62 if (!file_exists(infile
))
63 snprintf(infile
, sizeof(infile
), "%s/specs/%s.spec",
66 snprintf(outfile
, sizeof(outfile
), "%s/results/%s.out",
69 snprintf(expectfile
, sizeof(expectfile
), "%s/expected/%s.out",
71 if (!file_exists(expectfile
))
72 snprintf(expectfile
, sizeof(expectfile
), "%s/expected/%s.out",
75 add_stringlist_item(resultfiles
, outfile
);
76 add_stringlist_item(expectfiles
, expectfile
);
80 offset
+= snprintf(psql_cmd
+ offset
, sizeof(psql_cmd
) - offset
,
82 if (offset
>= sizeof(psql_cmd
))
84 fprintf(stderr
, _("command too long\n"));
89 offset
+= snprintf(psql_cmd
+ offset
, sizeof(psql_cmd
) - offset
,
90 "\"%s\" \"dbname=%s\" < \"%s\" > \"%s\" 2>&1",
95 if (offset
>= sizeof(psql_cmd
))
97 fprintf(stderr
, _("command too long\n"));
101 appnameenv
= psprintf("isolation/%s", testname
);
102 setenv("PGAPPNAME", appnameenv
, 1);
105 pid
= spawn_process(psql_cmd
);
107 if (pid
== INVALID_PID
)
109 fprintf(stderr
, _("could not start process for test %s\n"),
114 unsetenv("PGAPPNAME");
120 isolation_init(int argc
, char **argv
)
125 * We unfortunately cannot do the find_other_exec() lookup to find the
126 * "isolationtester" binary here. regression_main() calls the
127 * initialization functions before parsing the commandline arguments and
128 * thus hasn't changed the library search path at this point which in turn
129 * can cause the "isolationtester -V" invocation that find_other_exec()
130 * does to fail since it's linked to libpq. So we instead copy argv[0]
131 * and do the lookup the first time through isolation_start_test().
133 argv0_len
= strlcpy(saved_argv0
, argv
[0], MAXPGPATH
);
134 if (argv0_len
>= MAXPGPATH
)
136 fprintf(stderr
, _("path for isolationtester executable is longer than %d bytes\n"),
137 (int) (MAXPGPATH
- 1));
141 /* set default regression database name */
142 add_stringlist_item(&dblist
, "isolation_regression");
146 main(int argc
, char *argv
[])
148 return regression_main(argc
, argv
,
150 isolation_start_test
,
151 NULL
/* no postfunc needed */ );