mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
Allow pg_regress.c wrappers to postprocess test result files.
Add an optional callback to regression_main() that, if provided, is invoked on each test output file before we try to compare it to the expected-result file. The main and isolation test programs don't need this (yet). In pg_regress_ecpg, add a filter that eliminates target-host details from "could not connect" error reports. This filter doesn't do anything as of this commit, but it will be needed by the next one. In the long run we might want to provide some more general, perhaps pattern-based, filtering mechanism for test output. For now, this will solve the immediate problem. Discussion: https://postgr.es/m/BN6PR05MB3492948E4FD76C156E747E8BC9160@BN6PR05MB3492.namprd05.prod.outlook.com
This commit is contained in:
@ -23,13 +23,16 @@
|
||||
#include "lib/stringinfo.h"
|
||||
|
||||
|
||||
/*
|
||||
* Create a filtered copy of sourcefile, removing any path
|
||||
* appearing in #line directives; for example, replace
|
||||
* #line x "./../bla/foo.h" with #line x "foo.h".
|
||||
* This is needed because the path part can vary depending
|
||||
* on compiler, platform, build options, etc.
|
||||
*/
|
||||
static void
|
||||
ecpg_filter(const char *sourcefile, const char *outfile)
|
||||
ecpg_filter_source(const char *sourcefile, const char *outfile)
|
||||
{
|
||||
/*
|
||||
* Create a filtered copy of sourcefile, replacing #line x
|
||||
* "./../bla/foo.h" with #line x "foo.h"
|
||||
*/
|
||||
FILE *s,
|
||||
*t;
|
||||
StringInfoData linebuf;
|
||||
@ -76,6 +79,66 @@ ecpg_filter(const char *sourcefile, const char *outfile)
|
||||
fclose(t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the details of "could not connect to ...: " error messages
|
||||
* in a test result file, since the target host/pathname and/or port
|
||||
* can vary. Rewrite the result file in-place.
|
||||
*
|
||||
* At some point it might be interesting to unify this with
|
||||
* ecpg_filter_source, but building a general pattern matcher
|
||||
* is no fun, nor does it seem desirable to introduce a
|
||||
* dependency on an external one.
|
||||
*/
|
||||
static void
|
||||
ecpg_filter_stderr(const char *resultfile, const char *tmpfile)
|
||||
{
|
||||
FILE *s,
|
||||
*t;
|
||||
StringInfoData linebuf;
|
||||
|
||||
s = fopen(resultfile, "r");
|
||||
if (!s)
|
||||
{
|
||||
fprintf(stderr, "Could not open file %s for reading\n", resultfile);
|
||||
exit(2);
|
||||
}
|
||||
t = fopen(tmpfile, "w");
|
||||
if (!t)
|
||||
{
|
||||
fprintf(stderr, "Could not open file %s for writing\n", tmpfile);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
initStringInfo(&linebuf);
|
||||
|
||||
while (pg_get_line_buf(s, &linebuf))
|
||||
{
|
||||
char *p1 = strstr(linebuf.data, "could not connect to ");
|
||||
|
||||
if (p1)
|
||||
{
|
||||
char *p2 = strstr(p1, ": ");
|
||||
|
||||
if (p2)
|
||||
{
|
||||
memmove(p1 + 17, p2, strlen(p2) + 1);
|
||||
/* we don't bother to fix up linebuf.len */
|
||||
}
|
||||
}
|
||||
fputs(linebuf.data, t);
|
||||
}
|
||||
|
||||
pfree(linebuf.data);
|
||||
fclose(s);
|
||||
fclose(t);
|
||||
if (rename(tmpfile, resultfile) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not overwrite file %s with %s\n",
|
||||
resultfile, tmpfile);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* start an ecpg test process for specified file (including redirection),
|
||||
* and return process ID
|
||||
@ -139,7 +202,7 @@ ecpg_start_test(const char *testname,
|
||||
add_stringlist_item(expectfiles, expectfile_source);
|
||||
add_stringlist_item(tags, "source");
|
||||
|
||||
ecpg_filter(insource, outfile_source);
|
||||
ecpg_filter_source(insource, outfile_source);
|
||||
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"\"%s\" >\"%s\" 2>\"%s\"",
|
||||
@ -167,6 +230,21 @@ ecpg_start_test(const char *testname,
|
||||
return pid;
|
||||
}
|
||||
|
||||
static void
|
||||
ecpg_postprocess_result(const char *filename)
|
||||
{
|
||||
int nlen = strlen(filename);
|
||||
|
||||
/* Only stderr files require filtering, at the moment */
|
||||
if (nlen > 7 && strcmp(filename + nlen - 7, ".stderr") == 0)
|
||||
{
|
||||
char *tmpfile = psprintf("%s.tmp", filename);
|
||||
|
||||
ecpg_filter_stderr(filename, tmpfile);
|
||||
pfree(tmpfile);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ecpg_init(int argc, char *argv[])
|
||||
{
|
||||
@ -176,5 +254,8 @@ ecpg_init(int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
return regression_main(argc, argv, ecpg_init, ecpg_start_test);
|
||||
return regression_main(argc, argv,
|
||||
ecpg_init,
|
||||
ecpg_start_test,
|
||||
ecpg_postprocess_result);
|
||||
}
|
||||
|
Reference in New Issue
Block a user