Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oOddX-0002cL-JA for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Aug 2022 11:24:32 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1oOddU-0007BM-Qf for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Aug 2022 11:24:28 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oOddU-0007BD-D3 for pgsql-hackers@lists.postgresql.org; Thu, 18 Aug 2022 11:24:28 +0000 Received: from smtp.outgoing.loopia.se ([93.188.3.37]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oOddQ-0000dF-0l for pgsql-hackers@lists.postgresql.org; Thu, 18 Aug 2022 11:24:27 +0000 Received: from s807.loopia.se (localhost [127.0.0.1]) by s807.loopia.se (Postfix) with ESMTP id 7F4F52F13194 for ; Thu, 18 Aug 2022 13:24:22 +0200 (CEST) Received: from s981.loopia.se (unknown [172.22.191.6]) by s807.loopia.se (Postfix) with ESMTP id 6D89C2E2807D; Thu, 18 Aug 2022 13:24:22 +0200 (CEST) Received: from s898.loopia.se (unknown [172.22.191.6]) by s981.loopia.se (Postfix) with ESMTP id 68CED22B1740; Thu, 18 Aug 2022 13:24:22 +0200 (CEST) X-Virus-Scanned: amavisd-new at amavis.loopia.se X-Spam-Flag: NO X-Spam-Score: -1.01 X-Spam-Level: X-Spam-Status: No, score=-1.01 tagged_above=-999 required=6.2 tests=[ALL_TRUSTED=-1, T_SCC_BODY_TEXT_LINE=-0.01] autolearn=disabled Received: from s934.loopia.se ([172.22.191.6]) by s898.loopia.se (s898.loopia.se [172.22.190.17]) (amavisd-new, port 10024) with LMTP id ewutUA642RJQ; Thu, 18 Aug 2022 13:24:21 +0200 (CEST) X-Loopia-Auth: user X-Loopia-User: daniel@yesql.se X-Loopia-Originating-IP: 89.255.232.193 Received: from smtpclient.apple (customer-89-255-232-193.stosn.net [89.255.232.193]) (Authenticated sender: daniel@yesql.se) by s934.loopia.se (Postfix) with ESMTPSA id B42F77CEA50; Thu, 18 Aug 2022 13:24:21 +0200 (CEST) From: Daniel Gustafsson Message-Id: <04784F1A-1EE1-48C9-B443-0ACC32D16F3A@yesql.se> Content-Type: multipart/mixed; boundary="Apple-Mail=_D15C0D38-B755-4BDF-A6AF-DE3C07F7DEE0" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.100.31\)) Subject: Re: TAP output format in pg_regress Date: Thu, 18 Aug 2022 13:24:20 +0200 In-Reply-To: <20220817224949.jp7yftjv7ltfi2q6@awork3.anarazel.de> Cc: Tom Lane , Peter Eisentraut , PostgreSQL Developers To: Andres Freund References: <49A54862-C682-4B60-9155-05F178FA79DC@yesql.se> <20220321234924.kcc3q26o7sx6rnfa@alap3.anarazel.de> <489D2B5A-B26F-4918-BC07-B426329169E3@yesql.se> <5e6bc6a6-0a4e-109d-2b7d-c286dc58d609@enterprisedb.com> <461F8D8E-77D8-4F15-84C6-F7FD239018C0@yesql.se> <20220704225831.peh3a3afdgf6b5rj@awork3.anarazel.de> <1803389.1656986184@sss.pgh.pa.us> <20220705024011.nsvsfdedvridfhgc@awork3.anarazel.de> <2784249C-C92F-45A0-A6B4-5EE5925208FC@yesql.se> <20220817224949.jp7yftjv7ltfi2q6@awork3.anarazel.de> X-Mailer: Apple Mail (2.3696.100.31) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_D15C0D38-B755-4BDF-A6AF-DE3C07F7DEE0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On 18 Aug 2022, at 00:49, Andres Freund wrote: >> while still be TAP compliant enough that running it with prove (with = a tiny >> Perl wrapper) works. >=20 > Wonder if we could utilize that for making failures of = 002_pg_upgrade.pl and > 027_stream_regress.pl easier to understand, by reporting pg_regress' = steps as > part of the outer test. But that'd probably be at least somewhat hard, = due to > the embedded test count etc. I have a feeling it might require some quite bespoke logic to tie it = together (which may not be worth it in the end) but I'll have a look. >> A normal "make check" with this patch applied now looks like this: >>=20 >> ... >=20 > I'm happy with that compared to our current output. Great! Once this thread has settled on a format, maybe it should go to = a separate -hackers thread to get more visibility and (hopefully) buy-in = for such a change. One thing I haven't researched yet is if the Buildfarm or CFBot parses = the current output in any way or just check the exit status of the testrun. >> The ending comment isn't currently shown when executed via prove as = it has to >> go to STDERR for that to work, and I'm not sure that's something we = want to do >> in the general case. I don't expect running the pg_regress tests via = prove is >> going to be the common case. How does the meson TAP ingestion handle >> stdout/stderr? >=20 > It'll parse stdout for tap output and log stderr output separately. Then I think this patch will be compatible with that. >> There is a slight reduction in information, for example around tests = run >> serially vs in a parallel group. This could perhaps be handled by = marking the >> test name in some way like "tablespace (serial) or prefixing with a = symbol or >> somerthing. I can take a stab at that in case we think that level of = detail is >> important to preserve. >=20 > I think we could just indent the test "description" for tests in = parallel > groups: >=20 > I.e. instead of >=20 > ok 6 - varchar 68 ms > ... > ok 6 - varchar 68 ms >=20 > that'd make it sufficiently clear, and is a bit more similar to the = current > format? Thats a better option, done that way. > I wonder if we should indent the test name so that the number doesn't = cause > wrapping? The tricky part there is that we don't know beforehands how many tests = will be run. We could add a first pass over the schedule, which seems excessive = for this, or align with a fixed max such that 9999 number of tests is the = maximum number of tests which will print neatly aligned. > And perhaps we can skip the - in that case? The dash is listed as "Recommended" but not required in the TAP spec = (including up to v14) so we can skip it. With these changes, the "worst case" output in terms of testnames = alignment would be something like this (assuming at most 9999 tests): ok 211 stats 852 ms # parallel group (2 tests): event_trigger oidjoins ok 212 event_trigger 149 ms not ok 213 oidjoins 194 ms ok 214 fast_default 178 ms 1..214 I think that's fairly readable, and not that much different from today. -- Daniel Gustafsson https://vmware.com/ --Apple-Mail=_D15C0D38-B755-4BDF-A6AF-DE3C07F7DEE0 Content-Disposition: attachment; filename=v7-0001-Make-pg_regress-output-format-TAP-compliant.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v7-0001-Make-pg_regress-output-format-TAP-compliant.patch" Content-Transfer-Encoding: quoted-printable =46rom=20fe168dae50622989a60c51ba4076f6c3f4297c31=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Daniel=20Gustafsson=20= =0ADate:=20Wed,=2017=20Aug=202022=2022:53:48=20= +0200=0ASubject:=20[PATCH=20v7]=20Make=20pg_regress=20output=20format=20= TAP=20compliant=0A=0AThis=20converts=20pg_regress=20output=20format=20to=20= emit=20TAP=20complient=20output=0Awhile=20keeping=20it=20as=20human=20= readable=20as=20possible=20for=20use=20without=20TAP=0Atest=20harnesses.=20= As=20verbose=20harness=20related=20information=20isn't=20really=0A= supported=20by=20TAP=20this=20also=20reduces=20the=20verbosity=20of=20= pg_regress=20runs=0Awhich=20makes=20scrolling=20through=20log=20output=20= in=20buildfarm/CI=20runs=20a=20bit=0Aeasier=20as=20well.=0A=0AAs=20all=20= output=20from=20pg_regress=20had=20to=20be=20addressed,=20=20the=20= frontend=20log=0Aframework=20was=20also=20brought=20to=20use=20as=20it=20= was=20already=20being=20set=20up=20but=0Anot=20used.=0A---=0A=20= src/test/regress/pg_regress.c=20|=20447=20= ++++++++++++++++++----------------=0A=201=20file=20changed,=20232=20= insertions(+),=20215=20deletions(-)=0A=0Adiff=20--git=20= a/src/test/regress/pg_regress.c=20b/src/test/regress/pg_regress.c=0A= index=209ca1a8d906..f2effe06f8=20100644=0A---=20= a/src/test/regress/pg_regress.c=0A+++=20b/src/test/regress/pg_regress.c=0A= @@=20-92,6=20+92,7=20@@=20static=20char=20*dlpath=20=3D=20PKGLIBDIR;=0A=20= static=20char=20*user=20=3D=20NULL;=0A=20static=20_stringlist=20= *extraroles=20=3D=20NULL;=0A=20static=20char=20*config_auth_datadir=20=3D=20= NULL;=0A+static=20bool=20has_status=20=3D=20false;=0A=20=0A=20/*=20= internal=20variables=20*/=0A=20static=20const=20char=20*progname;=0A@@=20= -115,11=20+116,15=20@@=20static=20int=09fail_ignore_count=20=3D=200;=0A=20= static=20bool=20directory_exists(const=20char=20*dir);=0A=20static=20= void=20make_directory(const=20char=20*dir);=0A=20=0A-static=20void=20= header(const=20char=20*fmt,...)=20pg_attribute_printf(1,=202);=0A+static=20= void=20test_status_ok(const=20char=20*testname,=20double=20runtime,=20= bool=20parallel);=0A+static=20void=20test_status_failed(const=20char=20= *testname,=20bool=20ignore,=20char=20*tags,=20double=20runtime,=20bool=20= parallel);=0A+static=20void=20bail(const=20char=20*fmt,...);=0A+=0A=20= static=20void=20status(const=20char=20*fmt,...)=20pg_attribute_printf(1,=20= 2);=0A=20static=20StringInfo=20psql_start_command(void);=0A=20static=20= void=20psql_add_command(StringInfo=20buf,=20const=20char=20*query,...)=20= pg_attribute_printf(2,=203);=0A=20static=20void=20= psql_end_command(StringInfo=20buf,=20const=20char=20*database);=0A= +static=20void=20status_end(void);=0A=20=0A=20/*=0A=20=20*=20allow=20= core=20files=20if=20possible.=0A@@=20-133,9=20+138,7=20@@=20= unlimit_core_size(void)=0A=20=09getrlimit(RLIMIT_CORE,=20&lim);=0A=20=09= if=20(lim.rlim_max=20=3D=3D=200)=0A=20=09{=0A-=09=09fprintf(stderr,=0A-=09= =09=09=09_("%s:=20could=20not=20set=20core=20size:=20disallowed=20by=20= hard=20limit\n"),=0A-=09=09=09=09progname);=0A+=09=09= pg_log_error(_("could=20not=20set=20core=20size:=20disallowed=20by=20= hard=20limit"));=0A=20=09=09return;=0A=20=09}=0A=20=09else=20if=20= (lim.rlim_max=20=3D=3D=20RLIM_INFINITY=20||=20lim.rlim_cur=20<=20= lim.rlim_max)=0A@@=20-201,20=20+204,87=20@@=20split_to_stringlist(const=20= char=20*s,=20const=20char=20*delim,=20_stringlist=20**listhead)=0A=20}=0A= =20=0A=20/*=0A-=20*=20Print=20a=20progress=20banner=20on=20stdout.=0A+=20= *=20Bailing=20out=20is=20for=20unrecoverable=20errors=20which=20prevents=20= further=20testing=20to=0A+=20*=20occur=20and=20after=20which=20the=20= test=20run=20should=20be=20aborted.=0A=20=20*/=0A=20static=20void=0A= -header(const=20char=20*fmt,...)=0A+bail(const=20char=20*fmt,...)=0A=20{=0A= -=09char=09=09tmp[64];=0A+=09char=09=09tmp[256];=0A=20=09va_list=09=09= ap;=0A=20=0A=20=09va_start(ap,=20fmt);=0A=20=09vsnprintf(tmp,=20= sizeof(tmp),=20fmt,=20ap);=0A=20=09va_end(ap);=0A=20=0A-=09= fprintf(stdout,=20"=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=20%-38s=20= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n",=20tmp);=0A-=09= fflush(stdout);=0A+=09status("\nBail=20out!=20%s",=20tmp);=0A+=0A+=09= status_end();=0A+=09exit(2);=0A+}=0A+=0A+/*=0A+=20*=20Testnumbers=20are=20= padded=20to=205=20characters=20to=20ensure=20that=20a=20base=2010=20= increase=0A+=20*=20doesn't=20alter=20testname=20alignment=20(assuming=20= at=20most=209999=20tests).=20Testnames=0A+=20*=20are=20indented=208=20= spaces=20in=20case=20they=20run=20as=20part=20of=20a=20parallel=20group.=20= The=0A+=20*=20position=20for=20the=20runtime=20is=20then=20calculated=20= based=20on=20the=20horizontal=20space=0A+=20*=20consumed=20by=20testname=20= and=20testnumber.=0A+=20*/=0A+static=20void=0A+test_status_ok(const=20= char=20*testname,=20double=20runtime,=20bool=20parallel)=0A+{=0A+=09int=09= =09testnumber;=0A+=09int=20=09indent;=0A+=0A+=09success_count++;=0A+=0A+=09= testnumber=20=3D=20fail_count=20+=20fail_ignore_count=20+=20= success_count;=0A+=09/*=20Calculate=20an=20offset=20to=20align=20= runtimes=20vertically=20*/=0A+=09indent=20=3D=2036=20-=20(parallel=20?=20= 8=20:=200)=20-=20floor(log10(testnumber)=20+=201);=0A+=0A+=09/*=20There=20= is=20no=20NLS=20translation=20here=20as=20"ok"=20is=20a=20protocol=20= message=20*/=0A+=09status("ok=20%-5i=20=20=20=20=20%s%-*s=20%8.0f=20ms",=0A= +=09=09=20=20=20testnumber,=20(parallel=20?=20"=20=20=20=20=20=20=20=20"=20= :=20""),=20indent,=0A+=09=09=20=20=20testname,=0A+=09=09=20=20=20= runtime);=0A+}=0A+=0A+/*=0A+=20*=20For=20indentation=20rules,=20see=20= test_status_ok.=0A+=20*/=0A+static=20void=0A+test_status_failed(const=20= char=20*testname,=20bool=20ignore,=20char=20*tags,=20double=20runtime,=20= bool=20parallel)=0A+{=0A+=09int=09=09testnumber;=0A+=09int=09=09indent;=0A= +=0A+=09if=20(ignore)=0A+=09=09fail_ignore_count++;=0A+=09else=0A+=09=09= fail_count++;=0A+=0A+=09testnumber=20=3D=20fail_count=20+=20= fail_ignore_count=20+=20success_count;=0A+=09/*=20Calculate=20an=20= offset=20to=20align=20runtimes=20vertically=20*/=0A+=09indent=20=3D=2036=20= -=20(parallel=20?=208=20:=200)=20-=20floor(log10(testnumber)=20+=201);=0A= +=0A+=09/*=20There=20is=20no=20NLS=20translation=20here=20as=20"(not)=20= ok"=20are=20protocol=20messages=20*/=0A+=09if=20(ignore)=0A+=09{=0A+=09=09= status("ok=20%-5i=20=20=20=20=20%s%-*s=20%8.0f=20ms=20#=20SKIP=20= (ignored)",=0A+=09=09=09=20=20=20testnumber,=20(parallel=20?=20"=20=20=20= =20=20=20=20=20"=20:=20""),=20indent,=0A+=09=09=09=20=20=20testname,=0A+=09= =09=09=20=20=20runtime);=0A+=09}=0A+=09else=0A+=09{=0A+=09=09status("not=20= ok=20%-5i=20%s%-*s=20%8.0f=20ms",=0A+=09=09=09=20=20=20testnumber,=20= (parallel=20?=20"=20=20=20=20=20=20=20=20"=20:=20""),=20indent,=0A+=09=09= =09=20=20=20testname,=0A+=09=09=09=20=20=20runtime);=0A+=09}=0A+=0A+=09= if=20(tags=20&&=20strlen(tags)=20>=200)=0A+=09=09status("\n#=20tags:=20= %s",=20tags);=0A=20}=0A=20=0A=20/*=0A@@=20-225,6=20+295,7=20@@=20= status(const=20char=20*fmt,...)=0A=20{=0A=20=09va_list=09=09ap;=0A=20=0A= +=09has_status=20=3D=20true;=0A=20=09va_start(ap,=20fmt);=0A=20=09= vfprintf(stdout,=20fmt,=20ap);=0A=20=09fflush(stdout);=0A@@=20-244,6=20= +315,10=20@@=20status(const=20char=20*fmt,...)=0A=20static=20void=0A=20= status_end(void)=0A=20{=0A+=09if=20(!has_status)=0A+=09=09return;=0A+=0A= +=09has_status=20=3D=20false;=0A=20=09fprintf(stdout,=20"\n");=0A=20=09= fflush(stdout);=0A=20=09if=20(logfile)=0A@@=20-274,8=20+349,9=20@@=20= stop_postmaster(void)=0A=20=09=09r=20=3D=20system(buf);=0A=20=09=09if=20= (r=20!=3D=200)=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20_("\n%s:=20= could=20not=20stop=20postmaster:=20exit=20code=20was=20%d\n"),=0A-=09=09=09= =09=09progname,=20r);=0A+=09=09=09/*=20Not=20using=20the=20normal=20= bail()=20as=20we=20want=20_exit=20*/=0A+=09=09=09status("\nBail=20out!=20= ");=0A+=09=09=09status(_("could=20not=20stop=20postmaster:=20exit=20code=20= was=20%d"),=20r);=0A=20=09=09=09_exit(2);=09=09=09/*=20not=20exit(),=20= that=20could=20be=20recursive=20*/=0A=20=09=09}=0A=20=0A@@=20-334,9=20= +410,8=20@@=20make_temp_sockdir(void)=0A=20=09temp_sockdir=20=3D=20= mkdtemp(template);=0A=20=09if=20(temp_sockdir=20=3D=3D=20NULL)=0A=20=09{=0A= -=09=09fprintf(stderr,=20_("%s:=20could=20not=20create=20directory=20= \"%s\":=20%s\n"),=0A-=09=09=09=09progname,=20template,=20= strerror(errno));=0A-=09=09exit(2);=0A+=09=09bail(_("could=20not=20= create=20directory=20\"%s\":=20%s"),=0A+=09=09=09=20template,=20= strerror(errno));=0A=20=09}=0A=20=0A=20=09/*=20Stage=20file=20names=20= for=20remove_temp().=20=20Unsafe=20in=20a=20signal=20handler.=20*/=0A@@=20= -458,9=20+533,8=20@@=20load_resultmap(void)=0A=20=09=09/*=20OK=20if=20it=20= doesn't=20exist,=20else=20complain=20*/=0A=20=09=09if=20(errno=20=3D=3D=20= ENOENT)=0A=20=09=09=09return;=0A-=09=09fprintf(stderr,=20_("%s:=20could=20= not=20open=20file=20\"%s\"=20for=20reading:=20%s\n"),=0A-=09=09=09=09= progname,=20buf,=20strerror(errno));=0A-=09=09exit(2);=0A+=09=09= bail(_("could=20not=20open=20file=20\"%s\"=20for=20reading:=20%s"),=0A+=09= =09=09=20buf,=20strerror(errno));=0A=20=09}=0A=20=0A=20=09while=20= (fgets(buf,=20sizeof(buf),=20f))=0A@@=20-479,26=20+553,20=20@@=20= load_resultmap(void)=0A=20=09=09file_type=20=3D=20strchr(buf,=20':');=0A=20= =09=09if=20(!file_type)=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20= _("incorrectly=20formatted=20resultmap=20entry:=20%s\n"),=0A-=09=09=09=09= =09buf);=0A-=09=09=09exit(2);=0A+=09=09=09bail(_("incorrectly=20= formatted=20resultmap=20entry:=20%s"),=20buf);=0A=20=09=09}=0A=20=09=09= *file_type++=20=3D=20'\0';=0A=20=0A=20=09=09platform=20=3D=20= strchr(file_type,=20':');=0A=20=09=09if=20(!platform)=0A=20=09=09{=0A-=09= =09=09fprintf(stderr,=20_("incorrectly=20formatted=20resultmap=20entry:=20= %s\n"),=0A-=09=09=09=09=09buf);=0A-=09=09=09exit(2);=0A+=09=09=09= bail(_("incorrectly=20formatted=20resultmap=20entry:=20%s"),=20buf);=0A=20= =09=09}=0A=20=09=09*platform++=20=3D=20'\0';=0A=20=09=09expected=20=3D=20= strchr(platform,=20'=3D');=0A=20=09=09if=20(!expected)=0A=20=09=09{=0A-=09= =09=09fprintf(stderr,=20_("incorrectly=20formatted=20resultmap=20entry:=20= %s\n"),=0A-=09=09=09=09=09buf);=0A-=09=09=09exit(2);=0A+=09=09=09= bail(_("incorrectly=20formatted=20resultmap=20entry:=20%s"),=20buf);=0A=20= =09=09}=0A=20=09=09*expected++=20=3D=20'\0';=0A=20=0A@@=20-744,13=20= +812,13=20@@=20initialize_environment(void)=0A=20=09=09}=0A=20=0A=20=09=09= if=20(pghost=20&&=20pgport)=0A-=09=09=09printf(_("(using=20postmaster=20= on=20%s,=20port=20%s)\n"),=20pghost,=20pgport);=0A+=09=09=09status(_("#=20= (using=20postmaster=20on=20%s,=20port=20%s)\n"),=20pghost,=20pgport);=0A=20= =09=09if=20(pghost=20&&=20!pgport)=0A-=09=09=09printf(_("(using=20= postmaster=20on=20%s,=20default=20port)\n"),=20pghost);=0A+=09=09=09= status(_("#=20(using=20postmaster=20on=20%s,=20default=20port)\n"),=20= pghost);=0A=20=09=09if=20(!pghost=20&&=20pgport)=0A-=09=09=09= printf(_("(using=20postmaster=20on=20Unix=20socket,=20port=20%s)\n"),=20= pgport);=0A+=09=09=09status(_("#=20(using=20postmaster=20on=20Unix=20= socket,=20port=20%s)\n"),=20pgport);=0A=20=09=09if=20(!pghost=20&&=20= !pgport)=0A-=09=09=09printf(_("(using=20postmaster=20on=20Unix=20socket,=20= default=20port)\n"));=0A+=09=09=09status(_("#=20(using=20postmaster=20on=20= Unix=20socket,=20default=20port)\n"));=0A=20=09}=0A=20=0A=20=09= load_resultmap();=0A@@=20-799,34=20+867,30=20@@=20= current_windows_user(const=20char=20**acct,=20const=20char=20**dom)=0A=20= =0A=20=09if=20(!OpenProcessToken(GetCurrentProcess(),=20TOKEN_READ,=20= &token))=0A=20=09{=0A-=09=09fprintf(stderr,=0A-=09=09=09=09_("%s:=20= could=20not=20open=20process=20token:=20error=20code=20%lu\n"),=0A-=09=09= =09=09progname,=20GetLastError());=0A+=09=09pg_log_error("could=20not=20= open=20process=20token:=20error=20code=20%lu",=0A+=09=09=09=09=09=20= GetLastError());=0A=20=09=09exit(2);=0A=20=09}=0A=20=0A=20=09if=20= (!GetTokenInformation(token,=20TokenUser,=20NULL,=200,=20&retlen)=20&&=20= GetLastError()=20!=3D=20122)=0A=20=09{=0A-=09=09fprintf(stderr,=0A-=09=09= =09=09_("%s:=20could=20not=20get=20token=20information=20buffer=20size:=20= error=20code=20%lu\n"),=0A-=09=09=09=09progname,=20GetLastError());=0A+=09= =09pg_log_error("could=20not=20get=20token=20information=20buffer=20= size:=20error=20code=20%lu",=0A+=09=09=09=09=09=20GetLastError());=0A=20=09= =09exit(2);=0A=20=09}=0A=20=09tokenuser=20=3D=20pg_malloc(retlen);=0A=20=09= if=20(!GetTokenInformation(token,=20TokenUser,=20tokenuser,=20retlen,=20= &retlen))=0A=20=09{=0A-=09=09fprintf(stderr,=0A-=09=09=09=09_("%s:=20= could=20not=20get=20token=20information:=20error=20code=20%lu\n"),=0A-=09= =09=09=09progname,=20GetLastError());=0A+=09=09pg_log_error("could=20not=20= get=20token=20information:=20error=20code=20%lu",=0A+=09=09=09=09=09=20= GetLastError());=0A=20=09=09exit(2);=0A=20=09}=0A=20=0A=20=09if=20= (!LookupAccountSid(NULL,=20tokenuser->User.Sid,=20accountname,=20= &accountnamesize,=0A=20=09=09=09=09=09=09=20=20domainname,=20= &domainnamesize,=20&accountnameuse))=0A=20=09{=0A-=09=09fprintf(stderr,=0A= -=09=09=09=09_("%s:=20could=20not=20look=20up=20account=20SID:=20error=20= code=20%lu\n"),=0A-=09=09=09=09progname,=20GetLastError());=0A+=09=09= pg_log_error("could=20not=20look=20up=20account=20SID:=20error=20code=20= %lu",=0A+=09=09=09=09=09=20GetLastError());=0A=20=09=09exit(2);=0A=20=09= }=0A=20=0A@@=20-976,7=20+1040,7=20@@=20psql_start_command(void)=0A=20=09= StringInfo=09buf=20=3D=20makeStringInfo();=0A=20=0A=20=09= appendStringInfo(buf,=0A-=09=09=09=09=09=20"\"%s%spsql\"=20-X",=0A+=09=09= =09=09=09=20"\"%s%spsql\"=20-X=20-q",=0A=20=09=09=09=09=09=20bindir=20?=20= bindir=20:=20"",=0A=20=09=09=09=09=09=20bindir=20?=20"/"=20:=20"");=0A=20= =09return=20buf;=0A@@=20-1031,8=20+1095,7=20@@=20= psql_end_command(StringInfo=20buf,=20const=20char=20*database)=0A=20=09= if=20(system(buf->data)=20!=3D=200)=0A=20=09{=0A=20=09=09/*=20psql=20= probably=20already=20reported=20the=20error=20*/=0A-=09=09= fprintf(stderr,=20_("command=20failed:=20%s\n"),=20buf->data);=0A-=09=09= exit(2);=0A+=09=09bail(_("command=20failed:=20%s"),=20buf->data);=0A=20=09= }=0A=20=0A=20=09/*=20Clean=20up=20*/=0A@@=20-1077,9=20+1140,7=20@@=20= spawn_process(const=20char=20*cmdline)=0A=20=09pid=20=3D=20fork();=0A=20=09= if=20(pid=20=3D=3D=20-1)=0A=20=09{=0A-=09=09fprintf(stderr,=20_("%s:=20= could=20not=20fork:=20%s\n"),=0A-=09=09=09=09progname,=20= strerror(errno));=0A-=09=09exit(2);=0A+=09=09bail(_("could=20not=20fork:=20= %s"),=20strerror(errno));=0A=20=09}=0A=20=09if=20(pid=20=3D=3D=200)=0A=20= =09{=0A@@=20-1094,8=20+1155,9=20@@=20spawn_process(const=20char=20= *cmdline)=0A=20=0A=20=09=09cmdline2=20=3D=20psprintf("exec=20%s",=20= cmdline);=0A=20=09=09execl(shellprog,=20shellprog,=20"-c",=20cmdline2,=20= (char=20*)=20NULL);=0A-=09=09fprintf(stderr,=20_("%s:=20could=20not=20= exec=20\"%s\":=20%s\n"),=0A-=09=09=09=09progname,=20shellprog,=20= strerror(errno));=0A+=09=09/*=20Not=20using=20the=20normal=20bail()=20= here=20as=20we=20want=20_exit=20*/=0A+=09=09status("\nBail=20out!=20");=0A= +=09=09status(_("could=20not=20exec=20\"%s\":=20%s"),=20shellprog,=20= strerror(errno));=0A=20=09=09_exit(1);=09=09=09=09/*=20not=20exit()=20= here...=20*/=0A=20=09}=0A=20=09/*=20in=20parent=20*/=0A@@=20-1134,8=20= +1196,8=20@@=20file_size(const=20char=20*file)=0A=20=0A=20=09if=20(!f)=0A= =20=09{=0A-=09=09fprintf(stderr,=20_("%s:=20could=20not=20open=20file=20= \"%s\"=20for=20reading:=20%s\n"),=0A-=09=09=09=09progname,=20file,=20= strerror(errno));=0A+=09=09pg_log_error(_("#=20could=20not=20open=20file=20= \"%s\"=20for=20reading:=20%s"),=0A+=09=09=09=09=09=20file,=20= strerror(errno));=0A=20=09=09return=20-1;=0A=20=09}=0A=20=09fseek(f,=20= 0,=20SEEK_END);=0A@@=20-1156,8=20+1218,8=20@@=20file_line_count(const=20= char=20*file)=0A=20=0A=20=09if=20(!f)=0A=20=09{=0A-=09=09fprintf(stderr,=20= _("%s:=20could=20not=20open=20file=20\"%s\"=20for=20reading:=20%s\n"),=0A= -=09=09=09=09progname,=20file,=20strerror(errno));=0A+=09=09= pg_log_error(_("#=20could=20not=20open=20file=20\"%s\"=20for=20reading:=20= %s"),=0A+=09=09=09=09file,=20strerror(errno));=0A=20=09=09return=20-1;=0A= =20=09}=0A=20=09while=20((c=20=3D=20fgetc(f))=20!=3D=20EOF)=0A@@=20= -1198,9=20+1260,8=20@@=20make_directory(const=20char=20*dir)=0A=20{=0A=20= =09if=20(mkdir(dir,=20S_IRWXU=20|=20S_IRWXG=20|=20S_IRWXO)=20<=200)=0A=20= =09{=0A-=09=09fprintf(stderr,=20_("%s:=20could=20not=20create=20= directory=20\"%s\":=20%s\n"),=0A-=09=09=09=09progname,=20dir,=20= strerror(errno));=0A-=09=09exit(2);=0A+=09=09bail(_("could=20not=20= create=20directory=20\"%s\":=20%s"),=0A+=09=09=09=20dir,=20= strerror(errno));=0A=20=09}=0A=20}=0A=20=0A@@=20-1249,8=20+1310,7=20@@=20= run_diff(const=20char=20*cmd,=20const=20char=20*filename)=0A=20=09r=20=3D=20= system(cmd);=0A=20=09if=20(!WIFEXITED(r)=20||=20WEXITSTATUS(r)=20>=201)=0A= =20=09{=0A-=09=09fprintf(stderr,=20_("diff=20command=20failed=20with=20= status=20%d:=20%s\n"),=20r,=20cmd);=0A-=09=09exit(2);=0A+=09=09= bail(_("diff=20command=20failed=20with=20status=20%d:=20%s"),=20r,=20= cmd);=0A=20=09}=0A=20#ifdef=20WIN32=0A=20=0A@@=20-1260,8=20+1320,7=20@@=20= run_diff(const=20char=20*cmd,=20const=20char=20*filename)=0A=20=09=20*/=0A= =20=09if=20(WEXITSTATUS(r)=20=3D=3D=201=20&&=20file_size(filename)=20<=3D=20= 0)=0A=20=09{=0A-=09=09fprintf(stderr,=20_("diff=20command=20not=20found:=20= %s\n"),=20cmd);=0A-=09=09exit(2);=0A+=09=09bail(_("diff=20command=20not=20= found:=20%s"),=20cmd);=0A=20=09}=0A=20#endif=0A=20=0A@@=20-1332,9=20= +1391,8=20@@=20results_differ(const=20char=20*testname,=20const=20char=20= *resultsfile,=20const=20char=20*defaul=0A=20=09=09alt_expectfile=20=3D=20= get_alternative_expectfile(expectfile,=20i);=0A=20=09=09if=20= (!alt_expectfile)=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20_("Unable=20= to=20check=20secondary=20comparison=20files:=20%s\n"),=0A-=09=09=09=09=09= strerror(errno));=0A-=09=09=09exit(2);=0A+=09=09=09bail(_("Unable=20to=20= check=20secondary=20comparison=20files:=20%s"),=0A+=09=09=09=09=20= strerror(errno));=0A=20=09=09}=0A=20=0A=20=09=09if=20= (!file_exists(alt_expectfile))=0A@@=20-1449,9=20+1507,8=20@@=20= wait_for_tests(PID_TYPE=20*=20pids,=20int=20*statuses,=20instr_time=20= *stoptimes,=0A=20=0A=20=09=09if=20(p=20=3D=3D=20INVALID_PID)=0A=20=09=09= {=0A-=09=09=09fprintf(stderr,=20_("failed=20to=20wait=20for=20= subprocesses:=20%s\n"),=0A-=09=09=09=09=09strerror(errno));=0A-=09=09=09= exit(2);=0A+=09=09=09bail(_("failed=20to=20wait=20for=20subprocesses:=20= %s"),=0A+=09=09=09=09=20strerror(errno));=0A=20=09=09}=0A=20#else=0A=20=09= =09DWORD=09=09exit_status;=0A@@=20-1460,9=20+1517,8=20@@=20= wait_for_tests(PID_TYPE=20*=20pids,=20int=20*statuses,=20instr_time=20= *stoptimes,=0A=20=09=09r=20=3D=20WaitForMultipleObjects(tests_left,=20= active_pids,=20FALSE,=20INFINITE);=0A=20=09=09if=20(r=20<=20= WAIT_OBJECT_0=20||=20r=20>=3D=20WAIT_OBJECT_0=20+=20tests_left)=0A=20=09=09= {=0A-=09=09=09fprintf(stderr,=20_("failed=20to=20wait=20for=20= subprocesses:=20error=20code=20%lu\n"),=0A-=09=09=09=09=09= GetLastError());=0A-=09=09=09exit(2);=0A+=09=09=09bail(_("failed=20to=20= wait=20for=20subprocesses:=20error=20code=20%lu"),=0A+=09=09=09=09=20= GetLastError());=0A=20=09=09}=0A=20=09=09p=20=3D=20active_pids[r=20-=20= WAIT_OBJECT_0];=0A=20=09=09/*=20compact=20the=20active_pids=20array=20*/=0A= @@=20-1500,20=20+1556,20=20@@=20static=20void=0A=20log_child_failure(int=20= exitstatus)=0A=20{=0A=20=09if=20(WIFEXITED(exitstatus))=0A-=09=09= status(_("=20(test=20process=20exited=20with=20exit=20code=20%d)"),=0A+=09= =09status(_("#=20(test=20process=20exited=20with=20exit=20code=20%d)"),=0A= =20=09=09=09=20=20=20WEXITSTATUS(exitstatus));=0A=20=09else=20if=20= (WIFSIGNALED(exitstatus))=0A=20=09{=0A=20#if=20defined(WIN32)=0A-=09=09= status(_("=20(test=20process=20was=20terminated=20by=20exception=20= 0x%X)"),=0A+=09=09status(_("#=20(test=20process=20was=20terminated=20by=20= exception=200x%X)"),=0A=20=09=09=09=20=20=20WTERMSIG(exitstatus));=0A=20= #else=0A-=09=09status(_("=20(test=20process=20was=20terminated=20by=20= signal=20%d:=20%s)"),=0A+=09=09status(_("#=20(test=20process=20was=20= terminated=20by=20signal=20%d:=20%s)"),=0A=20=09=09=09=20=20=20= WTERMSIG(exitstatus),=20pg_strsignal(WTERMSIG(exitstatus)));=0A=20#endif=0A= =20=09}=0A=20=09else=0A-=09=09status(_("=20(test=20process=20exited=20= with=20unrecognized=20status=20%d)"),=0A+=09=09status(_("#=20(test=20= process=20exited=20with=20unrecognized=20status=20%d)"),=0A=20=09=09=09=20= =20=20exitstatus);=0A=20}=0A=20=0A@@=20-1537,18=20+1593,20=20@@=20= run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09char=09=09scbuf[1024];=0A=20=09FILE=09=20=20=20*scf;=0A= =20=09int=09=09=09line_num=20=3D=200;=0A+=09StringInfoData=20tagbuf;=0A=20= =0A=20=09memset(tests,=200,=20sizeof(tests));=0A=20=09= memset(resultfiles,=200,=20sizeof(resultfiles));=0A=20=09= memset(expectfiles,=200,=20sizeof(expectfiles));=0A=20=09memset(tags,=20= 0,=20sizeof(tags));=0A=20=0A+=09initStringInfo(&tagbuf);=0A+=0A=20=09scf=20= =3D=20fopen(schedule,=20"r");=0A=20=09if=20(!scf)=0A=20=09{=0A-=09=09= fprintf(stderr,=20_("%s:=20could=20not=20open=20file=20\"%s\"=20for=20= reading:=20%s\n"),=0A-=09=09=09=09progname,=20schedule,=20= strerror(errno));=0A-=09=09exit(2);=0A+=09=09bail(_("could=20not=20open=20= file=20\"%s\"=20for=20reading:=20%s"),=0A+=09=09=09=20schedule,=20= strerror(errno));=0A=20=09}=0A=20=0A=20=09while=20(fgets(scbuf,=20= sizeof(scbuf),=20scf))=0A@@=20-1586,9=20+1644,8=20@@=20= run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09=09}=0A=20=09=09else=0A=20=09=09{=0A-=09=09=09= fprintf(stderr,=20_("syntax=20error=20in=20schedule=20file=20\"%s\"=20= line=20%d:=20%s\n"),=0A-=09=09=09=09=09schedule,=20line_num,=20scbuf);=0A= -=09=09=09exit(2);=0A+=09=09=09bail(_("syntax=20error=20in=20schedule=20= file=20\"%s\"=20line=20%d:=20%s\n"),=0A+=09=09=09=09=20schedule,=20= line_num,=20scbuf);=0A=20=09=09}=0A=20=0A=20=09=09num_tests=20=3D=200;=0A= @@=20-1604,9=20+1661,8=20@@=20run_schedule(const=20char=20*schedule,=20= test_start_function=20startfunc,=0A=20=0A=20=09=09=09=09=09if=20= (num_tests=20>=3D=20MAX_PARALLEL_TESTS)=0A=20=09=09=09=09=09{=0A-=09=09=09= =09=09=09fprintf(stderr,=20_("too=20many=20parallel=20tests=20(more=20= than=20%d)=20in=20schedule=20file=20\"%s\"=20line=20%d:=20%s\n"),=0A-=09=09= =09=09=09=09=09=09MAX_PARALLEL_TESTS,=20schedule,=20line_num,=20scbuf);=0A= -=09=09=09=09=09=09exit(2);=0A+=09=09=09=09=09=09bail(_("too=20many=20= parallel=20tests=20(more=20than=20%d)=20in=20schedule=20file=20\"%s\"=20= line=20%d:=20%s\n"),=0A+=09=09=09=09=09=09=09=20MAX_PARALLEL_TESTS,=20= schedule,=20line_num,=20scbuf);=0A=20=09=09=09=09=09}=0A=20=09=09=09=09=09= sav=20=3D=20*c;=0A=20=09=09=09=09=09*c=20=3D=20'\0';=0A@@=20-1628,14=20= +1684,12=20@@=20run_schedule(const=20char=20*schedule,=20= test_start_function=20startfunc,=0A=20=0A=20=09=09if=20(num_tests=20=3D=3D= =200)=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20_("syntax=20error=20in=20= schedule=20file=20\"%s\"=20line=20%d:=20%s\n"),=0A-=09=09=09=09=09= schedule,=20line_num,=20scbuf);=0A-=09=09=09exit(2);=0A+=09=09=09= bail(_("syntax=20error=20in=20schedule=20file=20\"%s\"=20line=20%d:=20= %s\n"),=0A+=09=09=09=09=20schedule,=20line_num,=20scbuf);=0A=20=09=09}=0A= =20=0A=20=09=09if=20(num_tests=20=3D=3D=201)=0A=20=09=09{=0A-=09=09=09= status(_("test=20%-28s=20...=20"),=20tests[0]);=0A=20=09=09=09pids[0]=20= =3D=20(startfunc)=20(tests[0],=20&resultfiles[0],=20&expectfiles[0],=20= &tags[0]);=0A=20=09=09=09INSTR_TIME_SET_CURRENT(starttimes[0]);=0A=20=09=09= =09wait_for_tests(pids,=20statuses,=20stoptimes,=20NULL,=201);=0A@@=20= -1643,16=20+1697,15=20@@=20run_schedule(const=20char=20*schedule,=20= test_start_function=20startfunc,=0A=20=09=09}=0A=20=09=09else=20if=20= (max_concurrent_tests=20>=200=20&&=20max_concurrent_tests=20<=20= num_tests)=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20_("too=20many=20= parallel=20tests=20(more=20than=20%d)=20in=20schedule=20file=20\"%s\"=20= line=20%d:=20%s\n"),=0A-=09=09=09=09=09max_concurrent_tests,=20schedule,=20= line_num,=20scbuf);=0A-=09=09=09exit(2);=0A+=09=09=09bail(_("too=20many=20= parallel=20tests=20(more=20than=20%d)=20in=20schedule=20file=20\"%s\"=20= line=20%d:=20%s\n"),=0A+=09=09=09=09=20max_concurrent_tests,=20schedule,=20= line_num,=20scbuf);=0A=20=09=09}=0A=20=09=09else=20if=20(max_connections=20= >=200=20&&=20max_connections=20<=20num_tests)=0A=20=09=09{=0A=20=09=09=09= int=09=09=09oldest=20=3D=200;=0A=20=0A-=09=09=09status(_("parallel=20= group=20(%d=20tests,=20in=20groups=20of=20%d):=20"),=0A-=09=09=09=09=20=20= =20num_tests,=20max_connections);=0A+=09=09=09status(_("#=20parallel=20= group=20(%d=20tests,=20in=20groups=20of=20%d):=20"),=0A+=09=09=09=09=09=20= =20num_tests,=20max_connections);=0A=20=09=09=09for=20(i=20=3D=200;=20i=20= <=20num_tests;=20i++)=0A=20=09=09=09{=0A=20=09=09=09=09if=20(i=20-=20= oldest=20>=3D=20max_connections)=0A@@=20-1672,7=20+1725,7=20@@=20= run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09=09}=0A=20=09=09else=0A=20=09=09{=0A-=09=09=09= status(_("parallel=20group=20(%d=20tests):=20"),=20num_tests);=0A+=09=09=09= status(_("#=20parallel=20group=20(%d=20tests):=20"),=20num_tests);=0A=20=09= =09=09for=20(i=20=3D=200;=20i=20<=20num_tests;=20i++)=0A=20=09=09=09{=0A=20= =09=09=09=09pids[i]=20=3D=20(startfunc)=20(tests[i],=20&resultfiles[i],=20= &expectfiles[i],=20&tags[i]);=0A@@=20-1690,8=20+1743,9=20@@=20= run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09=09=09=09=09=20=20=20*tl;=0A=20=09=09=09bool=09=09= differ=20=3D=20false;=0A=20=0A-=09=09=09if=20(num_tests=20>=201)=0A-=09=09= =09=09status(_("=20=20=20=20=20%-28s=20...=20"),=20tests[i]);=0A+=09=09=09= resetStringInfo(&tagbuf);=0A+=0A+=09=09=09= INSTR_TIME_SUBTRACT(stoptimes[i],=20starttimes[i]);=0A=20=0A=20=09=09=09= /*=0A=20=09=09=09=20*=20Advance=20over=20all=20three=20lists=20= simultaneously.=0A@@=20-1712,7=20+1766,7=20@@=20run_schedule(const=20= char=20*schedule,=20test_start_function=20startfunc,=0A=20=09=09=09=09= newdiff=20=3D=20results_differ(tests[i],=20rl->str,=20el->str);=0A=20=09=09= =09=09if=20(newdiff=20&&=20tl)=0A=20=09=09=09=09{=0A-=09=09=09=09=09= printf("%s=20",=20tl->str);=0A+=09=09=09=09=09appendStringInfo(&tagbuf,=20= "%s=20",=20tl->str);=0A=20=09=09=09=09}=0A=20=09=09=09=09differ=20|=3D=20= newdiff;=0A=20=09=09=09}=0A@@=20-1730,29=20+1784,15=20@@=20= run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09=09=09=09=09=09break;=0A=20=09=09=09=09=09}=0A=20=09=09= =09=09}=0A-=09=09=09=09if=20(ignore)=0A-=09=09=09=09{=0A-=09=09=09=09=09= status(_("failed=20(ignored)"));=0A-=09=09=09=09=09fail_ignore_count++;=0A= -=09=09=09=09}=0A-=09=09=09=09else=0A-=09=09=09=09{=0A-=09=09=09=09=09= status(_("FAILED"));=0A-=09=09=09=09=09fail_count++;=0A-=09=09=09=09}=0A= +=0A+=09=09=09=09test_status_failed(tests[i],=20ignore,=20tagbuf.data,=20= INSTR_TIME_GET_MILLISEC(stoptimes[i]),=20(num_tests=20>=201));=0A=20=09=09= =09}=0A=20=09=09=09else=0A-=09=09=09{=0A-=09=09=09=09status(_("ok=20=20=20= =20"));=09/*=20align=20with=20FAILED=20*/=0A-=09=09=09=09= success_count++;=0A-=09=09=09}=0A+=09=09=09=09test_status_ok(tests[i],=20= INSTR_TIME_GET_MILLISEC(stoptimes[i]),=20(num_tests=20>=201));=0A=20=0A=20= =09=09=09if=20(statuses[i]=20!=3D=200)=0A=20=09=09=09=09= log_child_failure(statuses[i]);=0A=20=0A-=09=09=09= INSTR_TIME_SUBTRACT(stoptimes[i],=20starttimes[i]);=0A-=09=09=09= status(_("=20%8.0f=20ms"),=20INSTR_TIME_GET_MILLISEC(stoptimes[i]));=0A-=0A= =20=09=09=09status_end();=0A=20=09=09}=0A=20=0A@@=20-1766,6=20+1806,7=20= @@=20run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09=09}=0A=20=09}=0A=20=0A+=09pg_free(tagbuf.data);=0A=20= =09free_stringlist(&ignorelist);=0A=20=0A=20=09fclose(scf);=0A@@=20= -1789,11=20+1830,12=20@@=20run_single_test(const=20char=20*test,=20= test_start_function=20startfunc,=0A=20=09=09=09=20=20=20*el,=0A=20=09=09=09= =20=20=20*tl;=0A=20=09bool=09=09differ=20=3D=20false;=0A+=09= StringInfoData=20tagbuf;=0A=20=0A-=09status(_("test=20%-28s=20...=20"),=20= test);=0A=20=09pid=20=3D=20(startfunc)=20(test,=20&resultfiles,=20= &expectfiles,=20&tags);=0A=20=09INSTR_TIME_SET_CURRENT(starttime);=0A=20=09= wait_for_tests(&pid,=20&exit_status,=20&stoptime,=20NULL,=201);=0A+=09= initStringInfo(&tagbuf);=0A=20=0A=20=09/*=0A=20=09=20*=20Advance=20over=20= all=20three=20lists=20simultaneously.=0A@@=20-1814,27=20+1856,22=20@@=20= run_single_test(const=20char=20*test,=20test_start_function=20startfunc,=0A= =20=09=09newdiff=20=3D=20results_differ(test,=20rl->str,=20el->str);=0A=20= =09=09if=20(newdiff=20&&=20tl)=0A=20=09=09{=0A-=09=09=09printf("%s=20",=20= tl->str);=0A+=09=09=09appendStringInfo(&tagbuf,=20"%s=20",=20tl->str);=0A= =20=09=09}=0A=20=09=09differ=20|=3D=20newdiff;=0A=20=09}=0A=20=0A+=09= INSTR_TIME_SUBTRACT(stoptime,=20starttime);=0A+=0A=20=09if=20(differ)=0A= -=09{=0A-=09=09status(_("FAILED"));=0A-=09=09fail_count++;=0A-=09}=0A+=09= =09test_status_failed(test,=20false,=20tagbuf.data,=20= INSTR_TIME_GET_MILLISEC(stoptime),=20false);=0A=20=09else=0A-=09{=0A-=09=09= status(_("ok=20=20=20=20"));=09/*=20align=20with=20FAILED=20*/=0A-=09=09= success_count++;=0A-=09}=0A+=09=09test_status_ok(test,=20= INSTR_TIME_GET_MILLISEC(stoptime),=20false);=0A=20=0A=20=09if=20= (exit_status=20!=3D=200)=0A=20=09=09log_child_failure(exit_status);=0A=20= =0A-=09INSTR_TIME_SUBTRACT(stoptime,=20starttime);=0A-=09status(_("=20= %8.0f=20ms"),=20INSTR_TIME_GET_MILLISEC(stoptime));=0A+=09= pg_free(tagbuf.data);=0A=20=0A=20=09status_end();=0A=20}=0A@@=20-1858,9=20= +1895,8=20@@=20open_result_files(void)=0A=20=09logfile=20=3D=20= fopen(logfilename,=20"w");=0A=20=09if=20(!logfile)=0A=20=09{=0A-=09=09= fprintf(stderr,=20_("%s:=20could=20not=20open=20file=20\"%s\"=20for=20= writing:=20%s\n"),=0A-=09=09=09=09progname,=20logfilename,=20= strerror(errno));=0A-=09=09exit(2);=0A+=09=09bail(_("%s:=20could=20not=20= open=20file=20\"%s\"=20for=20writing:=20%s"),=0A+=09=09=09=20progname,=20= logfilename,=20strerror(errno));=0A=20=09}=0A=20=0A=20=09/*=20create=20= the=20diffs=20file=20as=20empty=20*/=0A@@=20-1869,9=20+1905,8=20@@=20= open_result_files(void)=0A=20=09difffile=20=3D=20fopen(difffilename,=20= "w");=0A=20=09if=20(!difffile)=0A=20=09{=0A-=09=09fprintf(stderr,=20= _("%s:=20could=20not=20open=20file=20\"%s\"=20for=20writing:=20%s\n"),=0A= -=09=09=09=09progname,=20difffilename,=20strerror(errno));=0A-=09=09= exit(2);=0A+=09=09bail(_("%s:=20could=20not=20open=20file=20\"%s\"=20for=20= writing:=20%s"),=0A+=09=09=09=20progname,=20difffilename,=20= strerror(errno));=0A=20=09}=0A=20=09/*=20we=20don't=20keep=20the=20diffs=20= file=20open=20continuously=20*/=0A=20=09fclose(difffile);=0A@@=20-1887,7=20= +1922,6=20@@=20drop_database_if_exists(const=20char=20*dbname)=0A=20{=0A=20= =09StringInfo=09buf=20=3D=20psql_start_command();=0A=20=0A-=09= header(_("dropping=20database=20\"%s\""),=20dbname);=0A=20=09/*=20Set=20= warning=20level=20so=20we=20don't=20see=20chatter=20about=20nonexistent=20= DB=20*/=0A=20=09psql_add_command(buf,=20"SET=20client_min_messages=20=3D=20= warning");=0A=20=09psql_add_command(buf,=20"DROP=20DATABASE=20IF=20= EXISTS=20\"%s\"",=20dbname);=0A@@=20-1904,7=20+1938,6=20@@=20= create_database(const=20char=20*dbname)=0A=20=09=20*=20We=20use=20= template0=20so=20that=20any=20installation-local=20cruft=20in=20= template1=20will=0A=20=09=20*=20not=20mess=20up=20the=20tests.=0A=20=09=20= */=0A-=09header(_("creating=20database=20\"%s\""),=20dbname);=0A=20=09if=20= (encoding)=0A=20=09=09psql_add_command(buf,=20"CREATE=20DATABASE=20= \"%s\"=20TEMPLATE=3Dtemplate0=20ENCODING=3D'%s'%s",=20dbname,=20= encoding,=0A=20=09=09=09=09=09=09=20(nolocale)=20?=20"=20LC_COLLATE=3D'C'=20= LC_CTYPE=3D'C'"=20:=20"");=0A@@=20-1926,10=20+1959,7=20@@=20= create_database(const=20char=20*dbname)=0A=20=09=20*=20this=20will=20= work=20whether=20or=20not=20the=20extension=20is=20preinstalled.=0A=20=09= =20*/=0A=20=09for=20(sl=20=3D=20loadextension;=20sl=20!=3D=20NULL;=20sl=20= =3D=20sl->next)=0A-=09{=0A-=09=09header(_("installing=20%s"),=20= sl->str);=0A=20=09=09psql_command(dbname,=20"CREATE=20EXTENSION=20IF=20= NOT=20EXISTS=20\"%s\"",=20sl->str);=0A-=09}=0A=20}=0A=20=0A=20static=20= void=0A@@=20-1937,7=20+1967,6=20@@=20drop_role_if_exists(const=20char=20= *rolename)=0A=20{=0A=20=09StringInfo=09buf=20=3D=20psql_start_command();=0A= =20=0A-=09header(_("dropping=20role=20\"%s\""),=20rolename);=0A=20=09/*=20= Set=20warning=20level=20so=20we=20don't=20see=20chatter=20about=20= nonexistent=20role=20*/=0A=20=09psql_add_command(buf,=20"SET=20= client_min_messages=20=3D=20warning");=0A=20=09psql_add_command(buf,=20= "DROP=20ROLE=20IF=20EXISTS=20\"%s\"",=20rolename);=0A@@=20-1949,7=20= +1978,6=20@@=20create_role(const=20char=20*rolename,=20const=20= _stringlist=20*granted_dbs)=0A=20{=0A=20=09StringInfo=09buf=20=3D=20= psql_start_command();=0A=20=0A-=09header(_("creating=20role=20\"%s\""),=20= rolename);=0A=20=09psql_add_command(buf,=20"CREATE=20ROLE=20\"%s\"=20= WITH=20LOGIN",=20rolename);=0A=20=09for=20(;=20granted_dbs=20!=3D=20= NULL;=20granted_dbs=20=3D=20granted_dbs->next)=0A=20=09{=0A@@=20-2166,7=20= +2194,7=20@@=20regression_main(int=20argc,=20char=20*argv[],=0A=20=09=09=09= =09break;=0A=20=09=09=09default:=0A=20=09=09=09=09/*=20getopt_long=20= already=20emitted=20a=20complaint=20*/=0A-=09=09=09=09fprintf(stderr,=20= _("\nTry=20\"%s=20-h\"=20for=20more=20information.\n"),=0A+=09=09=09=09= pg_log_error_hint("Try=20\"%s=20--help\"=20for=20more=20information.",=0A= =20=09=09=09=09=09=09progname);=0A=20=09=09=09=09exit(2);=0A=20=09=09}=0A= @@=20-2228,17=20+2256,13=20@@=20regression_main(int=20argc,=20char=20= *argv[],=0A=20=0A=20=09=09if=20(directory_exists(temp_instance))=0A=20=09= =09{=0A-=09=09=09header(_("removing=20existing=20temp=20instance"));=0A=20= =09=09=09if=20(!rmtree(temp_instance,=20true))=0A=20=09=09=09{=0A-=09=09=09= =09fprintf(stderr,=20_("\n%s:=20could=20not=20remove=20temp=20instance=20= \"%s\"\n"),=0A-=09=09=09=09=09=09progname,=20temp_instance);=0A-=09=09=09= =09exit(2);=0A+=09=09=09=09bail(_("%s:=20could=20not=20remove=20temp=20= instance=20\"%s\""),=0A+=09=09=09=09=09=09=09=20progname,=20= temp_instance);=0A=20=09=09=09}=0A=20=09=09}=0A=20=0A-=09=09= header(_("creating=20temporary=20instance"));=0A-=0A=20=09=09/*=20make=20= the=20temp=20instance=20top=20directory=20*/=0A=20=09=09= make_directory(temp_instance);=0A=20=0A@@=20-2248,7=20+2272,6=20@@=20= regression_main(int=20argc,=20char=20*argv[],=0A=20=09=09=09= make_directory(buf);=0A=20=0A=20=09=09/*=20initdb=20*/=0A-=09=09= header(_("initializing=20database=20system"));=0A=20=09=09snprintf(buf,=20= sizeof(buf),=0A=20=09=09=09=09=20"\"%s%sinitdb\"=20-D=20\"%s/data\"=20= --no-clean=20--no-sync%s%s=20>=20\"%s/log/initdb.log\"=202>&1",=0A=20=09=09= =09=09=20bindir=20?=20bindir=20:=20"",=0A@@=20-2259,8=20+2282,8=20@@=20= regression_main(int=20argc,=20char=20*argv[],=0A=20=09=09=09=09=20= outputdir);=0A=20=09=09if=20(system(buf))=0A=20=09=09{=0A-=09=09=09= fprintf(stderr,=20_("\n%s:=20initdb=20failed\nExamine=20= %s/log/initdb.log=20for=20the=20reason.\nCommand=20was:=20%s\n"),=20= progname,=20outputdir,=20buf);=0A-=09=09=09exit(2);=0A+=09=09=09= bail(_("%s:=20initdb=20failed\nExamine=20%s/log/initdb.log=20for=20the=20= reason.\nCommand=20was:=20%s"),=0A+=09=09=09=09=20progname,=20outputdir,=20= buf);=0A=20=09=09}=0A=20=0A=20=09=09/*=0A@@=20-2275,8=20+2298,8=20@@=20= regression_main(int=20argc,=20char=20*argv[],=0A=20=09=09pg_conf=20=3D=20= fopen(buf,=20"a");=0A=20=09=09if=20(pg_conf=20=3D=3D=20NULL)=0A=20=09=09= {=0A-=09=09=09fprintf(stderr,=20_("\n%s:=20could=20not=20open=20\"%s\"=20= for=20adding=20extra=20config:=20%s\n"),=20progname,=20buf,=20= strerror(errno));=0A-=09=09=09exit(2);=0A+=09=09=09bail(=20_("%s:=20= could=20not=20open=20\"%s\"=20for=20adding=20extra=20config:=20%s"),=0A+=09= =09=09=09=20progname,=20buf,=20strerror(errno));=0A=20=09=09}=0A=20=09=09= fputs("\n#=20Configuration=20added=20by=20pg_regress\n\n",=20pg_conf);=0A= =20=09=09fputs("log_autovacuum_min_duration=20=3D=200\n",=20pg_conf);=0A= @@=20-2295,8=20+2318,8=20@@=20regression_main(int=20argc,=20char=20= *argv[],=0A=20=09=09=09extra_conf=20=3D=20fopen(temp_config,=20"r");=0A=20= =09=09=09if=20(extra_conf=20=3D=3D=20NULL)=0A=20=09=09=09{=0A-=09=09=09=09= fprintf(stderr,=20_("\n%s:=20could=20not=20open=20\"%s\"=20to=20read=20= extra=20config:=20%s\n"),=20progname,=20temp_config,=20strerror(errno));=0A= -=09=09=09=09exit(2);=0A+=09=09=09=09bail(_("%s:=20could=20not=20open=20= \"%s\"=20to=20read=20extra=20config:=20%s"),=0A+=09=09=09=09=09=20= progname,=20temp_config,=20strerror(errno));=0A=20=09=09=09}=0A=20=09=09=09= while=20(fgets(line_buf,=20sizeof(line_buf),=20extra_conf)=20!=3D=20= NULL)=0A=20=09=09=09=09fputs(line_buf,=20pg_conf);=0A@@=20-2334,14=20= +2357,14=20@@=20regression_main(int=20argc,=20char=20*argv[],=0A=20=0A=20= =09=09=09=09if=20(port_specified_by_user=20||=20i=20=3D=3D=2015)=0A=20=09= =09=09=09{=0A-=09=09=09=09=09fprintf(stderr,=20_("port=20%d=20apparently=20= in=20use\n"),=20port);=0A+=09=09=09=09=09status(_("#=20port=20%d=20= apparently=20in=20use\n"),=20port);=0A=20=09=09=09=09=09if=20= (!port_specified_by_user)=0A-=09=09=09=09=09=09fprintf(stderr,=20_("%s:=20= could=20not=20determine=20an=20available=20port\n"),=20progname);=0A-=09=09= =09=09=09fprintf(stderr,=20_("Specify=20an=20unused=20port=20using=20the=20= --port=20option=20or=20shut=20down=20any=20conflicting=20PostgreSQL=20= servers.\n"));=0A-=09=09=09=09=09exit(2);=0A+=09=09=09=09=09=09= status(_("#=20could=20not=20determine=20an=20available=20port\n"));=0A+=09= =09=09=09=09bail(_("Specify=20an=20unused=20port=20using=20the=20--port=20= option=20or=20shut=20down=20any=20conflicting=20PostgreSQL=20= servers."));=0A=20=09=09=09=09}=0A=20=0A-=09=09=09=09fprintf(stderr,=20= _("port=20%d=20apparently=20in=20use,=20trying=20%d\n"),=20port,=20port=20= +=201);=0A+=09=09=09=09status(_("#=20port=20%d=20apparently=20in=20use,=20= trying=20%d\n"),=0A+=09=09=09=09=09=09port,=20port=20+=201);=0A=20=09=09=09= =09port++;=0A=20=09=09=09=09sprintf(s,=20"%d",=20port);=0A=20=09=09=09=09= setenv("PGPORT",=20s,=201);=0A@@=20-2353,7=20+2376,6=20@@=20= regression_main(int=20argc,=20char=20*argv[],=0A=20=09=09/*=0A=20=09=09=20= *=20Start=20the=20temp=20postmaster=0A=20=09=09=20*/=0A-=09=09= header(_("starting=20postmaster"));=0A=20=09=09snprintf(buf,=20= sizeof(buf),=0A=20=09=09=09=09=20"\"%s%spostgres\"=20-D=20\"%s/data\"=20= -F%s=20"=0A=20=09=09=09=09=20"-c=20\"listen_addresses=3D%s\"=20-k=20= \"%s\"=20"=0A@@=20-2365,11=20+2387,7=20@@=20regression_main(int=20argc,=20= char=20*argv[],=0A=20=09=09=09=09=20outputdir);=0A=20=09=09= postmaster_pid=20=3D=20spawn_process(buf);=0A=20=09=09if=20= (postmaster_pid=20=3D=3D=20INVALID_PID)=0A-=09=09{=0A-=09=09=09= fprintf(stderr,=20_("\n%s:=20could=20not=20spawn=20postmaster:=20%s\n"),=0A= -=09=09=09=09=09progname,=20strerror(errno));=0A-=09=09=09exit(2);=0A-=09= =09}=0A+=09=09=09bail(_("could=20not=20spawn=20postmaster:=20%s\n"),=20= strerror(errno));=0A=20=0A=20=09=09/*=0A=20=09=09=20*=20Wait=20till=20= postmaster=20is=20able=20to=20accept=20connections;=20normally=20this=0A= @@=20-2403,16=20+2421,16=20@@=20regression_main(int=20argc,=20char=20= *argv[],=0A=20=09=09=09if=20(WaitForSingleObject(postmaster_pid,=200)=20= =3D=3D=20WAIT_OBJECT_0)=0A=20#endif=0A=20=09=09=09{=0A-=09=09=09=09= fprintf(stderr,=20_("\n%s:=20postmaster=20failed\nExamine=20= %s/log/postmaster.log=20for=20the=20reason\n"),=20progname,=20= outputdir);=0A-=09=09=09=09exit(2);=0A+=09=09=09=09bail(_("postmaster=20= failed\nExamine=20%s/log/postmaster.log=20for=20the=20reason\n"),=0A+=09=09= =09=09=09=20outputdir);=0A=20=09=09=09}=0A=20=0A=20=09=09=09= pg_usleep(1000000L);=0A=20=09=09}=0A=20=09=09if=20(i=20>=3D=20= wait_seconds)=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20_("\n%s:=20= postmaster=20did=20not=20respond=20within=20%d=20seconds\nExamine=20= %s/log/postmaster.log=20for=20the=20reason\n"),=0A-=09=09=09=09=09= progname,=20wait_seconds,=20outputdir);=0A+=09=09=09status(_("#=20= postmaster=20did=20not=20respond=20within=20%d=20seconds\nExamine=20= %s/log/postmaster.log=20for=20the=20reason\n"),=0A+=09=09=09=09=09= wait_seconds,=20outputdir);=0A=20=0A=20=09=09=09/*=0A=20=09=09=09=20*=20= If=20we=20get=20here,=20the=20postmaster=20is=20probably=20wedged=20= somewhere=20in=0A@@=20-2421,17=20+2439,14=20@@=20regression_main(int=20= argc,=20char=20*argv[],=0A=20=09=09=09=20*=20attempts.=0A=20=09=09=09=20= */=0A=20#ifndef=20WIN32=0A-=09=09=09if=20(kill(postmaster_pid,=20= SIGKILL)=20!=3D=200=20&&=0A-=09=09=09=09errno=20!=3D=20ESRCH)=0A-=09=09=09= =09fprintf(stderr,=20_("\n%s:=20could=20not=20kill=20failed=20= postmaster:=20%s\n"),=0A-=09=09=09=09=09=09progname,=20strerror(errno));=0A= +=09=09=09if=20(kill(postmaster_pid,=20SIGKILL)=20!=3D=200=20&&=20errno=20= !=3D=20ESRCH)=0A+=09=09=09=09bail(_("could=20not=20kill=20failed=20= postmaster:=20%s"),=20strerror(errno));=0A=20#else=0A=20=09=09=09if=20= (TerminateProcess(postmaster_pid,=20255)=20=3D=3D=200)=0A-=09=09=09=09= fprintf(stderr,=20_("\n%s:=20could=20not=20kill=20failed=20postmaster:=20= error=20code=20%lu\n"),=0A-=09=09=09=09=09=09progname,=20= GetLastError());=0A+=09=09=09=09bail(_("could=20not=20kill=20failed=20= postmaster:=20error=20code=20%lu"),=0A+=09=09=09=09=09=20= GetLastError());=0A=20#endif=0A-=0A-=09=09=09exit(2);=0A+=09=09=09= bail(_("postmaster=20failed"));=0A=20=09=09}=0A=20=0A=20=09=09= postmaster_running=20=3D=20true;=0A@@=20-2442,7=20+2457,7=20@@=20= regression_main(int=20argc,=20char=20*argv[],=0A=20#else=0A=20#define=20= ULONGPID(x)=20(unsigned=20long)=20(x)=0A=20#endif=0A-=09=09= printf(_("running=20on=20port=20%d=20with=20PID=20%lu\n"),=0A+=09=09= status(_("#=20running=20on=20port=20%d=20with=20PID=20%lu\n"),=0A=20=09=09= =09=20=20=20port,=20ULONGPID(postmaster_pid));=0A=20=09}=0A=20=09else=0A= @@=20-2474,8=20+2489,6=20@@=20regression_main(int=20argc,=20char=20= *argv[],=0A=20=09/*=0A=20=09=20*=20Ready=20to=20run=20the=20tests=0A=20=09= =20*/=0A-=09header(_("running=20regression=20test=20queries"));=0A-=0A=20= =09for=20(sl=20=3D=20schedulelist;=20sl=20!=3D=20NULL;=20sl=20=3D=20= sl->next)=0A=20=09{=0A=20=09=09run_schedule(sl->str,=20startfunc,=20= postfunc);=0A@@=20-2491,7=20+2504,6=20@@=20regression_main(int=20argc,=20= char=20*argv[],=0A=20=09=20*/=0A=20=09if=20(temp_instance)=0A=20=09{=0A-=09= =09header(_("shutting=20down=20postmaster"));=0A=20=09=09= stop_postmaster();=0A=20=09}=0A=20=0A@@=20-2502,62=20+2514,67=20@@=20= regression_main(int=20argc,=20char=20*argv[],=0A=20=09=20*/=0A=20=09if=20= (temp_instance=20&&=20fail_count=20=3D=3D=200=20&&=20fail_ignore_count=20= =3D=3D=200)=0A=20=09{=0A-=09=09header(_("removing=20temporary=20= instance"));=0A=20=09=09if=20(!rmtree(temp_instance,=20true))=0A-=09=09=09= fprintf(stderr,=20_("\n%s:=20could=20not=20remove=20temp=20instance=20= \"%s\"\n"),=0A-=09=09=09=09=09progname,=20temp_instance);=0A+=09=09=09= pg_log_error("could=20not=20remove=20temp=20instance=20\"%s\"",=0A+=09=09= =09=09=09=09=20temp_instance);=0A=20=09}=0A=20=0A-=09fclose(logfile);=0A= +=09/*=0A+=09=20*=20Emit=20a=20TAP=20compliant=20Plan=0A+=09=20*/=0A+=09= status("1..%i\n",=20(fail_count=20+=20fail_ignore_count=20+=20= success_count));=0A=20=0A=20=09/*=0A=20=09=20*=20Emit=20nice-looking=20= summary=20message=0A=20=09=20*/=0A=20=09if=20(fail_count=20=3D=3D=200=20= &&=20fail_ignore_count=20=3D=3D=200)=0A-=09=09snprintf(buf,=20= sizeof(buf),=0A-=09=09=09=09=20_("=20All=20%d=20tests=20passed.=20"),=0A= -=09=09=09=09=20success_count);=0A-=09else=20if=20(fail_count=20=3D=3D=20= 0)=09/*=20fail_count=3D0,=20fail_ignore_count>0=20*/=0A-=09=09= snprintf(buf,=20sizeof(buf),=0A-=09=09=09=09=20_("=20%d=20of=20%d=20= tests=20passed,=20%d=20failed=20test(s)=20ignored.=20"),=0A-=09=09=09=09=20= success_count,=0A-=09=09=09=09=20success_count=20+=20fail_ignore_count,=0A= -=09=09=09=09=20fail_ignore_count);=0A-=09else=20if=20(fail_ignore_count=20= =3D=3D=200)=09/*=20fail_count>0=20&&=20fail_ignore_count=3D0=20*/=0A-=09=09= snprintf(buf,=20sizeof(buf),=0A-=09=09=09=09=20_("=20%d=20of=20%d=20= tests=20failed.=20"),=0A-=09=09=09=09=20fail_count,=0A-=09=09=09=09=20= success_count=20+=20fail_count);=0A+=09=09status(_("#=20All=20%d=20tests=20= passed."),=20success_count);=0A+=09/*=20fail_count=3D0,=20= fail_ignore_count>0=20*/=0A+=09else=20if=20(fail_count=20=3D=3D=200)=0A+=09= =09status(_("#=20%d=20of=20%d=20tests=20passed,=20%d=20failed=20test(s)=20= ignored."),=0A+=09=09=09=20=20=20success_count,=0A+=09=09=09=20=20=20= success_count=20+=20fail_ignore_count,=0A+=09=09=09=20=20=20= fail_ignore_count);=0A+=09/*=20fail_count>0=20&&=20fail_ignore_count=3D0=20= */=0A+=09else=20if=20(fail_ignore_count=20=3D=3D=200)=0A+=09=09= status(_("#=20%d=20of=20%d=20tests=20failed."),=0A+=09=09=09=20=20=20= fail_count,=0A+=09=09=09=20=20=20success_count=20+=20fail_count);=0A+=09= /*=20fail_count>0=20&&=20fail_ignore_count>0=20*/=0A=20=09else=0A-=09=09= /*=20fail_count>0=20&&=20fail_ignore_count>0=20*/=0A-=09=09snprintf(buf,=20= sizeof(buf),=0A-=09=09=09=09=20_("=20%d=20of=20%d=20tests=20failed,=20%d=20= of=20these=20failures=20ignored.=20"),=0A-=09=09=09=09=20fail_count=20+=20= fail_ignore_count,=0A-=09=09=09=09=20success_count=20+=20fail_count=20+=20= fail_ignore_count,=0A-=09=09=09=09=20fail_ignore_count);=0A-=0A-=09= putchar('\n');=0A-=09for=20(i=20=3D=20strlen(buf);=20i=20>=200;=20i--)=0A= -=09=09putchar('=3D');=0A-=09printf("\n%s\n",=20buf);=0A-=09for=20(i=20=3D= =20strlen(buf);=20i=20>=200;=20i--)=0A-=09=09putchar('=3D');=0A-=09= putchar('\n');=0A-=09putchar('\n');=0A+=09=09status(_("#=20%d=20of=20%d=20= tests=20failed,=20%d=20of=20these=20failures=20ignored."),=0A+=09=09=09=20= =20=20fail_count=20+=20fail_ignore_count,=0A+=09=09=09=20=20=20= success_count=20+=20fail_count=20+=20fail_ignore_count,=0A+=09=09=09=20=20= =20fail_ignore_count);=0A=20=0A+=09/*=0A+=09=20*=20In=20order=20for=20= this=20information=20(or=20any=20error=20information)=20to=20be=20shown=0A= +=09=20*=20when=20running=20pg_regress=20test=20suites=20under=20prove=20= it=20needs=20to=20be=20emitted=0A+=09=20*=20stderr=20instead=20of=20= stdout.=0A+=09=20*/=0A=20=09if=20(file_size(difffilename)=20>=200)=0A=20=09= {=0A-=09=09printf(_("The=20differences=20that=20caused=20some=20tests=20= to=20fail=20can=20be=20viewed=20in=20the\n"=0A-=09=09=09=09=20"file=20= \"%s\".=20=20A=20copy=20of=20the=20test=20summary=20that=20you=20see\n"=0A= -=09=09=09=09=20"above=20is=20saved=20in=20the=20file=20\"%s\".\n\n"),=0A= +=09=09status(_("\n#=20The=20differences=20that=20caused=20some=20tests=20= to=20fail=20can=20be=20viewed=20in=20the\n"=0A+=09=09=09=09=20=20"#=20= file=20\"%s\".=20=20A=20copy=20of=20the=20test=20summary=20that=20you=20= see\n"=0A+=09=09=09=09=20=20"#=20above=20is=20saved=20in=20the=20file=20= \"%s\".\n\n"),=0A=20=09=09=09=20=20=20difffilename,=20logfilename);=0A=20= =09}=0A=20=09else=0A=20=09{=0A=20=09=09unlink(difffilename);=0A=20=09=09= unlink(logfilename);=0A+=0A+=09=09free(difffilename);=0A+=09=09= difffilename=20=3D=20NULL;=0A+=09=09free(logfilename);=0A+=09=09= logfilename=20=3D=20NULL;=0A=20=09}=0A=20=0A+=09status_end();=0A+=0A+=09= fclose(logfile);=0A+=09logfile=20=3D=20NULL;=0A+=0A=20=09if=20= (fail_count=20!=3D=200)=0A=20=09=09exit(1);=0A=20=0A--=20=0A2.32.1=20= (Apple=20Git-133)=0A=0A= --Apple-Mail=_D15C0D38-B755-4BDF-A6AF-DE3C07F7DEE0--