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 1phbFh-0007bk-52 for pgsql-hackers@arkaria.postgresql.org; Wed, 29 Mar 2023 19:14:33 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1phbFg-0002pm-47 for pgsql-hackers@arkaria.postgresql.org; Wed, 29 Mar 2023 19:14:32 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1phbFf-0002lM-Dw for pgsql-hackers@lists.postgresql.org; Wed, 29 Mar 2023 19:14:31 +0000 Received: from smtp.outgoing.loopia.se ([93.188.3.37]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1phbFb-0001gE-Qd for pgsql-hackers@lists.postgresql.org; Wed, 29 Mar 2023 19:14:30 +0000 Received: from s807.loopia.se (localhost [127.0.0.1]) by s807.loopia.se (Postfix) with ESMTP id 0D5D52F78584 for ; Wed, 29 Mar 2023 21:14:25 +0200 (CEST) Received: from s899.loopia.se (unknown [172.22.191.6]) by s807.loopia.se (Postfix) with ESMTP id EFA6F2E292CC; Wed, 29 Mar 2023 21:14:24 +0200 (CEST) Received: from s476.loopia.se (unknown [172.22.191.6]) by s899.loopia.se (Postfix) with ESMTP id E648C2C8BA6F; Wed, 29 Mar 2023 21:14:24 +0200 (CEST) X-Virus-Scanned: amavisd-new at amavis.loopia.se X-Spam-Flag: NO X-Spam-Score: -1 X-Spam-Level: X-Spam-Status: No, score=-1 tagged_above=-999 required=6.2 tests=[ALL_TRUSTED=-1] autolearn=disabled Received: from s980.loopia.se ([172.22.191.6]) by s476.loopia.se (s476.loopia.se [172.22.190.16]) (amavisd-new, port 10024) with LMTP id AeDY64c__UCp; Wed, 29 Mar 2023 21:14:24 +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 s980.loopia.se (Postfix) with ESMTPSA id 05A5122015BB; Wed, 29 Mar 2023 21:14:24 +0200 (CEST) From: Daniel Gustafsson Message-Id: <424F65D5-CDB2-4120-BB59-1E562BBADD17@yesql.se> Content-Type: multipart/mixed; boundary="Apple-Mail=_34FA7BDF-0C7E-41EC-A25B-2DACD98660DA" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.2\)) Subject: Re: TAP output format in pg_regress Date: Wed, 29 Mar 2023 21:14:23 +0200 In-Reply-To: <28cced17-a21b-84c0-2de2-e470d97089e5@enterprisedb.com> Cc: vignesh C , Nikolay Shaplov , Andres Freund , =?utf-8?Q?Dagfinn_Ilmari_Manns=C3=A5ker?= , PostgreSQL Developers , Andrew Dunstan , Tom Lane To: Peter Eisentraut References: <5e6bc6a6-0a4e-109d-2b7d-c286dc58d609@enterprisedb.com> <20221128182848.rxcmaxtw3mclmyr4@awork3.anarazel.de> <5348601.u5redSiXY4@thinkpad-pgpro> <655E7296-24A1-4481-A992-B5CD55B7F7DB@yesql.se> <4B2CBB72-9B1D-4028-9CAD-E53DF303AB8D@yesql.se> <0CBE542D-F333-45DE-9D6B-533CCDB13CDE@yesql.se> <42883A10-AA8C-4044-B559-3E741F011B4E@yesql.se> <34735bb9-ca5e-8b3d-1ccd-c4ba252bbfa4@enterprisedb.com> <66CE8D6C-1344-4B55-9CB5-2E144DD3CCF1@yesql.se> <28cced17-a21b-84c0-2de2-e470d97089e5@enterprisedb.com> X-Mailer: Apple Mail (2.3696.120.41.1.2) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_34FA7BDF-0C7E-41EC-A25B-2DACD98660DA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On 29 Mar 2023, at 09:08, Peter Eisentraut = wrote: >=20 > On 28.03.23 15:56, Daniel Gustafsson wrote: >>> On 28 Mar 2023, at 15:26, Daniel Gustafsson wrote: >>> I think the attached is a good candidate for going in, but I would = like to see it >>> for another spin in the CF bot first. >> Another candidate due to a thinko which raised a compiler warning. >=20 > This is incorrect: >=20 > -echo "+++ tap install-check in $(subdir) +++" && \ > +echo "\# +++ tap install-check in $(subdir) +++" && \ >=20 > It actually prints the backslash. >=20 > But this appears to be correct: >=20 > pg_regress_check =3D \ > - echo "+++ regress check in $(subdir) +++" && \ > + echo "\# +++ regress check in $(subdir) +++" && \ >=20 > (Maybe because it's in a variable definition?) Copy paste error, fixed. > I'm confused why all the messages at the end lost their period ("All = tests passed", "A copy of the test summary ...", etc.). As long as they = are written as sentences, they should have a period. Fixed. I also made sure that all messages printing the output directory = wrap it in quotes like how we print paths generally. > There is a comment "Testnames are indented 8 spaces" but you made that = into a macro now, which is currently defined to 3. As explained below, this is removed. I've also removed a comment on NLS = which no longer makes sense. > There is an unexplained #if 0. Ugh, I clearly should've stayed on the couch yesterday. > The additions of >=20 > + free(difffilename); > + difffilename =3D NULL; > + free(logfilename); > + logfilename =3D NULL; >=20 > in the success case are not clear. The program is going to end soon = anyway. Fair enough, removed. > On the indentation of the test names: If you look at the output of = meson test verbose mode (e.g., meson test -C _build --suite regress = --verbose), it reproduces the indentation in a weirdly backwards way, = e.g., >=20 > =E2=96=B6 1/1 stats 981 ms OK > =E2=96=B6 1/1 event_trigger 122 ms OK > =E2=96=B6 1/1 oidjoins 172 ms OK > =E2=96=B6 1/1 fast_default 137 ms OK > =E2=96=B6 1/1 tablespace 285 ms OK >=20 > Not sure by which logic it arrives at that, but you can clearly see 3 = additional spaces for the single tests. I'm not sure what meson does actually. It seems to strip the leading = padding and line up the testname, but then add the stripped padding on the right = side? Removing the padding for parallel tests solves it, so I have in the = attached moved to indicating parallel tests with a leading '+' and single tests = with '-'. Not sure if this is clear enough, but it's not worse than padding = IMO. > One thing I have noticed while playing around with this is that it's = quite hard to tell casually whether a test run has failed or is failing, = if you just keep half an eye on it in another Window. The display of = "ok"/"not ok" as well as the summaries at the end are much less = prominent than the previous "ok"/"FAILED" and the summary box at the = end. I'm not sure what to do about that, or if it's just something to = get used to. meson already presents the results in a box, so if we bring back the =3D=3D= =3D box it gets quite verbose there. To some extent I think it is something to get = used to, but if there is discontent with what it looks like reported when = more hackers gets exposed to this we need to fix it. -- Daniel Gustafsson --Apple-Mail=_34FA7BDF-0C7E-41EC-A25B-2DACD98660DA Content-Disposition: attachment; filename=v20-0001-pg_regress-Emit-TAP-compliant-output.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v20-0001-pg_regress-Emit-TAP-compliant-output.patch" Content-Transfer-Encoding: quoted-printable =46rom=20786750d6e6ccddade942c6df2abb5eef41c17aba=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Daniel=20Gustafsson=20=0A= Date:=20Tue,=2028=20Mar=202023=2015:20:19=20+0200=0ASubject:=20[PATCH=20= v20]=20pg_regress:=20Emit=20TAP=20compliant=20output=0AMIME-Version:=20= 1.0=0AContent-Type:=20text/plain;=20charset=3DUTF-8=0A= Content-Transfer-Encoding:=208bit=0A=0AThis=20converts=20pg_regress=20= output=20format=20to=20emit=20TAP=20compliant=20output=0Awhile=20keeping=20= it=20as=20human=20readable=20as=20possible=20for=20use=20without=20TAP=0A= test=20harnesses.=20As=20verbose=20harness=20related=20information=20= isn't=20really=0Asupported=20by=20TAP=20this=20also=20reduces=20the=20= verbosity=20of=20pg_regress=20runs=0Awhich=20makes=20scrolling=20through=20= log=20output=20in=20buildfarm/CI=20runs=20a=20bit=0Aeasier=20as=20well.=0A= =0ATAP=20format=20testing=20is=20also=20enabled=20in=20Meson=20as=20of=20= this.=0A=0AReviewed-by:=20Andres=20Freund=20=0A= Reviewed-by:=20Tom=20Lane=20=0AReviewed-by:=20Nikolay=20= Shaplov=20=0AReviewed-by:=20Dagfinn=20Ilmari=20= Manns=C3=A5ker=20=0AReviewed-by:=20Peter=20Eisentraut=20= =0ADiscussion:=20= https://postgr.es/m/BD4B107D-7E53-4794-ACBA-275BEB4327C9@yesql.se=0A= Discussion:=20= https://postgr.es/m/20220221164736.rq3ornzjdkmwk2wo@alap3.anarazel.de=0A= ---=0A=20meson.build=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20|=20=20=201=20+=0A=20src/Makefile.global.in=20=20=20=20=20=20=20=20|=20= =2014=20+-=0A=20src/test/regress/pg_regress.c=20|=20558=20= ++++++++++++++++++----------------=0A=203=20files=20changed,=20312=20= insertions(+),=20261=20deletions(-)=0A=0Adiff=20--git=20a/meson.build=20= b/meson.build=0Aindex=2061e94be864..dd23acee54=20100644=0A---=20= a/meson.build=0A+++=20b/meson.build=0A@@=20-3118,6=20+3118,7=20@@=20= foreach=20test_dir=20:=20tests=0A=20=20=20=20=20=20=20= env.prepend('PATH',=20temp_install_bindir,=20test_dir['bd'])=0A=20=0A=20=20= =20=20=20=20=20test_kwargs=20=3D=20{=0A+=20=20=20=20=20=20=20=20= 'protocol':=20'tap',=0A=20=20=20=20=20=20=20=20=20'priority':=2010,=0A=20= =20=20=20=20=20=20=20=20'timeout':=201000,=0A=20=20=20=20=20=20=20=20=20= 'depends':=20test_deps=20+=20t.get('deps',=20[]),=0Adiff=20--git=20= a/src/Makefile.global.in=20b/src/Makefile.global.in=0Aindex=20= fb3e197fc0..736dd1ed5e=20100644=0A---=20a/src/Makefile.global.in=0A+++=20= b/src/Makefile.global.in=0A@@=20-444,7=20+444,7=20@@=20ifeq=20= ($(enable_tap_tests),yes)=0A=20=0A=20ifndef=20PGXS=0A=20define=20= prove_installcheck=0A-echo=20"+++=20tap=20install-check=20in=20$(subdir)=20= +++"=20&&=20\=0A+echo=20"#=20+++=20tap=20install-check=20in=20$(subdir)=20= +++"=20&&=20\=0A=20rm=20-rf=20'$(CURDIR)'/tmp_check=20&&=20\=0A=20= $(MKDIR_P)=20'$(CURDIR)'/tmp_check=20&&=20\=0A=20cd=20$(srcdir)=20&&=20\=0A= @@=20-457,7=20+457,7=20@@=20cd=20$(srcdir)=20&&=20\=0A=20endef=0A=20else=20= #=20PGXS=20case=0A=20define=20prove_installcheck=0A-echo=20"+++=20tap=20= install-check=20in=20$(subdir)=20+++"=20&&=20\=0A+echo=20"#=20+++=20tap=20= install-check=20in=20$(subdir)=20+++"=20&&=20\=0A=20rm=20-rf=20= '$(CURDIR)'/tmp_check=20&&=20\=0A=20$(MKDIR_P)=20'$(CURDIR)'/tmp_check=20= &&=20\=0A=20cd=20$(srcdir)=20&&=20\=0A@@=20-471,7=20+471,7=20@@=20endef=0A= =20endif=20#=20PGXS=0A=20=0A=20define=20prove_check=0A-echo=20"+++=20tap=20= check=20in=20$(subdir)=20+++"=20&&=20\=0A+echo=20"#=20+++=20tap=20check=20= in=20$(subdir)=20+++"=20&&=20\=0A=20rm=20-rf=20'$(CURDIR)'/tmp_check=20= &&=20\=0A=20$(MKDIR_P)=20'$(CURDIR)'/tmp_check=20&&=20\=0A=20cd=20= $(srcdir)=20&&=20\=0A@@=20-665,7=20+665,7=20@@=20pg_regress_locale_flags=20= =3D=20$(if=20$(ENCODING),--encoding=3D$(ENCODING))=20$(NOLOCALE)=0A=20= pg_regress_clean_files=20=3D=20results/=20regression.diffs=20= regression.out=20tmp_check/=20tmp_check_iso/=20log/=20output_iso/=0A=20=0A= =20pg_regress_check=20=3D=20\=0A-=20=20=20=20echo=20"+++=20regress=20= check=20in=20$(subdir)=20+++"=20&&=20\=0A+=20=20=20=20echo=20"\#=20+++=20= regress=20check=20in=20$(subdir)=20+++"=20&&=20\=0A=20=20=20=20=20= $(with_temp_install)=20\=0A=20=20=20=20=20= $(top_builddir)/src/test/regress/pg_regress=20\=0A=20=20=20=20=20= --temp-instance=3D./tmp_check=20\=0A@@=20-674,14=20+674,14=20@@=20= pg_regress_check=20=3D=20\=0A=20=20=20=20=20$(TEMP_CONF)=20\=0A=20=20=20=20= =20$(pg_regress_locale_flags)=20$(EXTRA_REGRESS_OPTS)=0A=20= pg_regress_installcheck=20=3D=20\=0A-=20=20=20=20echo=20"+++=20regress=20= install-check=20in=20$(subdir)=20+++"=20&&=20\=0A+=20=20=20=20echo=20"\#=20= +++=20regress=20install-check=20in=20$(subdir)=20+++"=20&&=20\=0A=20=20=20= =20=20$(top_builddir)/src/test/regress/pg_regress=20\=0A=20=20=20=20=20= --inputdir=3D$(srcdir)=20\=0A=20=20=20=20=20--bindir=3D'$(bindir)'=20\=0A= =20=20=20=20=20$(pg_regress_locale_flags)=20$(EXTRA_REGRESS_OPTS)=0A=20=0A= =20pg_isolation_regress_check=20=3D=20\=0A-=20=20=20=20echo=20"+++=20= isolation=20check=20in=20$(subdir)=20+++"=20&&=20\=0A+=20=20=20=20echo=20= "\#=20+++=20isolation=20check=20in=20$(subdir)=20+++"=20&&=20\=0A=20=20=20= =20=20$(with_temp_install)=20\=0A=20=20=20=20=20= $(top_builddir)/src/test/isolation/pg_isolation_regress=20\=0A=20=20=20=20= =20--temp-instance=3D./tmp_check_iso=20\=0A@@=20-690,7=20+690,7=20@@=20= pg_isolation_regress_check=20=3D=20\=0A=20=20=20=20=20$(TEMP_CONF)=20\=0A= =20=20=20=20=20$(pg_regress_locale_flags)=20$(EXTRA_REGRESS_OPTS)=0A=20= pg_isolation_regress_installcheck=20=3D=20\=0A-=20=20=20=20echo=20"+++=20= isolation=20install-check=20in=20$(subdir)=20+++"=20&&=20\=0A+=20=20=20=20= echo=20"\#=20+++=20isolation=20install-check=20in=20$(subdir)=20+++"=20= &&=20\=0A=20=20=20=20=20= $(top_builddir)/src/test/isolation/pg_isolation_regress=20\=0A=20=20=20=20= =20--inputdir=3D$(srcdir)=20--outputdir=3Doutput_iso=20\=0A=20=20=20=20=20= --bindir=3D'$(bindir)'=20\=0Adiff=20--git=20= a/src/test/regress/pg_regress.c=20b/src/test/regress/pg_regress.c=0A= index=207b23cc80dc..7c642519b6=20100644=0A---=20= a/src/test/regress/pg_regress.c=0A+++=20b/src/test/regress/pg_regress.c=0A= @@=20-68,6=20+68,25=20@@=20const=20char=20*basic_diff_opts=20=3D=20"-w";=0A= =20const=20char=20*pretty_diff_opts=20=3D=20"-w=20-U3";=0A=20#endif=0A=20= =0A+/*=0A+=20*=20The=20width=20of=20the=20testname=20field=20when=20= printing=20to=20ensure=20vertical=20alignment=0A+=20*=20of=20test=20= runtimes.=20This=20number=20is=20somewhat=20arbitrarily=20chosen=20to=20= match=20the=0A+=20*=20older=20pre-TAP=20output=20format.=0A+=20*/=0A= +#define=20TESTNAME_WIDTH=2036=0A+=0A+typedef=20enum=20TAPtype=0A+{=0A+=09= DIAG=20=3D=200,=0A+=09BAIL,=0A+=09NOTE,=0A+=09NOTE_DETAIL,=0A+=09= NOTE_END,=0A+=09TEST_STATUS,=0A+=09PLAN,=0A+=09NONE=0A+}=09=09=09= TAPtype;=0A+=0A=20/*=20options=20settable=20from=20command=20line=20*/=0A= =20_stringlist=20*dblist=20=3D=20NULL;=0A=20bool=09=09debug=20=3D=20= false;=0A@@=20-103,6=20+122,8=20@@=20static=20const=20char=20*sockdir;=0A= =20static=20const=20char=20*temp_sockdir;=0A=20static=20char=20= sockself[MAXPGPATH];=0A=20static=20char=20socklock[MAXPGPATH];=0A+static=20= StringInfo=20failed_tests=20=3D=20NULL;=0A+static=20bool=20in_note=20=3D=20= false;=0A=20=0A=20static=20_resultmap=20*resultmap=20=3D=20NULL;=0A=20=0A= @@=20-115,12=20+136,29=20@@=20static=20int=09fail_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=20status(const=20char=20*fmt,...)=20pg_attribute_printf(1,=202);=0A= +static=20void=20test_status_print(bool=20ok,=20const=20char=20= *testname,=20double=20runtime,=20bool=20parallel);=0A+static=20void=20= test_status_ok(const=20char=20*testname,=20double=20runtime,=20bool=20= parallel);=0A+static=20void=20test_status_failed(const=20char=20= *testname,=20double=20runtime,=20bool=20parallel);=0A+static=20void=20= bail_out(bool=20noatexit,=20const=20char=20*fmt,...)=20= pg_attribute_printf(2,=203);=0A+static=20void=20emit_tap_output(TAPtype=20= type,=20const=20char=20*fmt,...)=20pg_attribute_printf(2,=203);=0A= +static=20void=20emit_tap_output_v(TAPtype=20type,=20const=20char=20= *fmt,=20va_list=20argp)=20pg_attribute_printf(2,=200);=0A+=0A=20static=20= StringInfo=20psql_start_command(void);=0A=20static=20void=20= psql_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=20=0A= +/*=0A+=20*=20Convenience=20macros=20for=20printing=20TAP=20output=20= with=20a=20more=20shorthand=20syntax=0A+=20*=20aimed=20at=20making=20the=20= code=20more=20readable.=0A+=20*/=0A+#define=20plan(x)=09=09=09=09= emit_tap_output(PLAN,=20"1..%i",=20(x))=0A+#define=20note(...)=09=09=09= emit_tap_output(NOTE,=20__VA_ARGS__)=0A+#define=20note_detail(...)=09= emit_tap_output(NOTE_DETAIL,=20__VA_ARGS__)=0A+#define=20diag(...)=09=09=09= emit_tap_output(DIAG,=20__VA_ARGS__)=0A+#define=20note_end()=09=09=09= emit_tap_output(NOTE_END,=20"\n");=0A+#define=20bail_noatexit(...)=09= bail_out(true,=20__VA_ARGS__)=0A+#define=20bail(...)=09=09=09= bail_out(false,=20__VA_ARGS__)=0A+=0A=20/*=0A=20=20*=20allow=20core=20= files=20if=20possible.=0A=20=20*/=0A@@=20-133,9=20+171,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=09diag("could=20not=20= set=20core=20size:=20disallowed=20by=20hard=20limit");=0A=20=09=09= return;=0A=20=09}=0A=20=09else=20if=20(lim.rlim_max=20=3D=3D=20= RLIM_INFINITY=20||=20lim.rlim_cur=20<=20lim.rlim_max)=0A@@=20-201,53=20= +237,162=20@@=20split_to_stringlist(const=20char=20*s,=20const=20char=20= *delim,=20_stringlist=20**listhead)=0A=20}=0A=20=0A=20/*=0A-=20*=20Print=20= a=20progress=20banner=20on=20stdout.=0A+=20*=20Bailing=20out=20is=20for=20= unrecoverable=20errors=20which=20prevents=20further=20testing=20to=0A+=20= *=20occur=20and=20after=20which=20the=20test=20run=20should=20be=20= aborted.=20By=20passing=20noatexit=0A+=20*=20as=20true=20the=20process=20= will=20terminate=20with=20_exit(2)=20and=20skipping=20registered=0A+=20*=20= exit=20handlers,=20thus=20avoid=20any=20risk=20of=20bottomless=20= recursion=20calls=20to=20exit.=0A=20=20*/=0A=20static=20void=0A= -header(const=20char=20*fmt,...)=0A+bail_out(bool=20noatexit,=20const=20= char=20*fmt,...)=0A=20{=0A-=09char=09=09tmp[64];=0A=20=09va_list=09=09= ap;=0A=20=0A=20=09va_start(ap,=20fmt);=0A-=09vsnprintf(tmp,=20= sizeof(tmp),=20fmt,=20ap);=0A+=09emit_tap_output_v(BAIL,=20fmt,=20ap);=0A= =20=09va_end(ap);=0A=20=0A-=09fprintf(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",=20= tmp);=0A-=09fflush(stdout);=0A+=09if=20(noatexit)=0A+=09=09_exit(2);=0A+=0A= +=09exit(2);=0A=20}=0A=20=0A-/*=0A-=20*=20Print=20"doing=20something=20= ..."=20---=20supplied=20text=20should=20not=20end=20with=20newline=0A-=20= */=0A=20static=20void=0A-status(const=20char=20*fmt,...)=0A= +test_status_print(bool=20ok,=20const=20char=20*testname,=20double=20= runtime,=20bool=20parallel)=0A=20{=0A-=09va_list=09=09ap;=0A+=09int=09=09= =09testnumber=20=3D=20fail_count=20+=20success_count;=0A=20=0A-=09= va_start(ap,=20fmt);=0A-=09vfprintf(stdout,=20fmt,=20ap);=0A-=09= fflush(stdout);=0A-=09va_end(ap);=0A+=09/*=0A+=09=20*=20Testnumbers=20= are=20padded=20to=205=20characters=20to=20ensure=20that=20testnames=20= align=0A+=09=20*=20vertically=20(assuming=20at=20most=209999=20tests).=20= =20Testnames=20are=20prefixed=20with=0A+=09=20*=20a=20leading=20= character=20to=20indicate=20being=20run=20in=20parallel=20or=20not.=20A=20= leading=0A+=09=20*=20'+'=20indicates=20a=20parellel=20test,=20'-'=20= indicates=20a=20single=20test.=0A+=09=20*/=0A+=09= emit_tap_output(TEST_STATUS,=20"%sok=20%-5i%*s=20%c=20%-*s=20%8.0f=20= ms",=0A+=09=09=09=09=09(ok=20?=20""=20:=20"not=20"),=0A+=09=09=09=09=09= testnumber,=0A+=09/*=20If=20ok,=20indent=20with=20four=20spaces=20= matching=20"not=20"=20*/=0A+=09=09=09=09=09(ok=20?=20(int)=20strlen("not=20= ")=20:=200),=20"",=0A+=09/*=20Prefix=20a=20parallel=20test=20'+'=20and=20= a=20single=20test=20with=20'-'=20*/=0A+=09=09=09=09=09(parallel=20?=20= '+'=20:=20'-'),=0A+=09/*=20Testnames=20are=20padded=20to=20align=20= runtimes=20*/=0A+=09=09=09=09=09TESTNAME_WIDTH,=20testname,=0A+=09=09=09=09= =09runtime);=0A+}=0A=20=0A-=09if=20(logfile)=0A-=09{=0A-=09=09= va_start(ap,=20fmt);=0A-=09=09vfprintf(logfile,=20fmt,=20ap);=0A-=09=09= va_end(ap);=0A-=09}=0A+static=20void=0A+test_status_ok(const=20char=20= *testname,=20double=20runtime,=20bool=20parallel)=0A+{=0A+=09= success_count++;=0A+=0A+=09test_status_print(true,=20testname,=20= runtime,=20parallel);=0A=20}=0A=20=0A-/*=0A-=20*=20Done=20"doing=20= something=20..."=0A-=20*/=0A=20static=20void=0A-status_end(void)=0A= +test_status_failed(const=20char=20*testname,=20double=20runtime,=20bool=20= parallel)=0A=20{=0A-=09fprintf(stdout,=20"\n");=0A-=09fflush(stdout);=0A= +=09/*=0A+=09=20*=20Save=20failed=20tests=20in=20a=20buffer=20such=20= that=20we=20can=20print=20a=20summary=20at=20the=0A+=09=20*=20end=20with=20= diag()=20to=20ensure=20it's=20shown=20even=20under=20test=20harnesses.=0A= +=09=20*/=0A+=09if=20(!failed_tests)=0A+=09=09failed_tests=20=3D=20= makeStringInfo();=0A+=09else=0A+=09=09appendStringInfoChar(failed_tests,=20= ',');=0A+=0A+=09appendStringInfo(failed_tests,=20"=20%s",=20testname);=0A= +=0A+=09fail_count++;=0A+=0A+=09test_status_print(false,=20testname,=20= runtime,=20parallel);=0A+}=0A+=0A+=0A+static=20void=0A= +emit_tap_output(TAPtype=20type,=20const=20char=20*fmt,...)=0A+{=0A+=09= va_list=09=09argp;=0A+=0A+=09va_start(argp,=20fmt);=0A+=09= emit_tap_output_v(type,=20fmt,=20argp);=0A+=09va_end(argp);=0A+}=0A+=0A= +static=20void=0A+emit_tap_output_v(TAPtype=20type,=20const=20char=20= *fmt,=20va_list=20argp)=0A+{=0A+=09va_list=09=09argp_logfile;=0A+=09FILE=09= =20=20=20*fp;=0A+=0A+=09/*=0A+=09=20*=20Diagnostic=20output=20will=20be=20= hidden=20by=20prove=20unless=20printed=20to=20stderr.=20The=0A+=09=20*=20= Bail=20message=20is=20also=20printed=20to=20stderr=20to=20aid=20= debugging=20under=20a=20harness=0A+=09=20*=20which=20might=20otherwise=20= not=20emit=20such=20an=20important=20message.=0A+=09=20*/=0A+=09if=20= (type=20=3D=3D=20DIAG=20||=20type=20=3D=3D=20BAIL)=0A+=09=09fp=20=3D=20= stderr;=0A+=09else=0A+=09=09fp=20=3D=20stdout;=0A+=0A+=09/*=0A+=09=20*=20= If=20we=20are=20ending=20a=20note_detail=20line=20we=20can=20avoid=20= further=20processing=20and=0A+=09=20*=20immediately=20return=20following=20= a=20newline.=0A+=09=20*/=0A+=09if=20(type=20=3D=3D=20NOTE_END)=0A+=09{=0A= +=09=09in_note=20=3D=20false;=0A+=09=09fprintf(fp,=20"\n");=0A+=09=09if=20= (logfile)=0A+=09=09=09fprintf(logfile,=20"\n");=0A+=09=09return;=0A+=09}=0A= +=0A+=09/*=20Make=20a=20copy=20of=20the=20va=20args=20for=20printing=20= to=20the=20logfile=20*/=0A+=09va_copy(argp_logfile,=20argp);=0A+=0A+=09= /*=0A+=09=20*=20Non-protocol=20output=20such=20as=20diagnostics=20or=20= notes=20must=20be=20prefixed=20by=20a=0A+=09=20*=20'#'=20character.=20We=20= print=20the=20Bail=20message=20like=20this=20too.=0A+=09=20*/=0A+=09if=20= ((type=20=3D=3D=20NOTE=20||=20type=20=3D=3D=20DIAG=20||=20type=20=3D=3D=20= BAIL)=0A+=09=09||=20(type=20=3D=3D=20NOTE_DETAIL=20&&=20!in_note))=0A+=09= {=0A+=09=09fprintf(fp,=20"#=20");=0A+=09=09if=20(logfile)=0A+=09=09=09= fprintf(logfile,=20"#=20");=0A+=09}=0A+=09vfprintf(fp,=20fmt,=20argp);=0A= =20=09if=20(logfile)=0A-=09=09fprintf(logfile,=20"\n");=0A+=09=09= vfprintf(logfile,=20fmt,=20argp_logfile);=0A+=0A+=09/*=0A+=09=20*=20If=20= we=20are=20entering=20into=20a=20note=20with=20more=20details=20to=20= follow,=20register=0A+=09=20*=20that=20the=20leading=20'#'=20has=20been=20= printed=20such=20that=20subsequent=20details=0A+=09=20*=20aren't=20= prefixed=20as=20well.=0A+=09=20*/=0A+=09if=20(type=20=3D=3D=20= NOTE_DETAIL)=0A+=09=09in_note=20=3D=20true;=0A+=0A+=09/*=0A+=09=20*=20If=20= this=20was=20a=20Bail=20message,=20the=20bail=20protocol=20message=20= must=20go=20to=20stdout=0A+=09=20*=20separately.=0A+=09=20*/=0A+=09if=20= (type=20=3D=3D=20BAIL)=0A+=09{=0A+=09=09fprintf(stdout,=20"Bail=20= out!");=0A+=09=09if=20(logfile)=0A+=09=09=09fprintf(logfile,=20"Bail=20= out!");=0A+=09}=0A+=0A+=09va_end(argp_logfile);=0A+=0A+=09if=20(type=20= !=3D=20NOTE_DETAIL)=0A+=09{=0A+=09=09fprintf(fp,=20"\n");=0A+=09=09if=20= (logfile)=0A+=09=09=09fprintf(logfile,=20"\n");=0A+=09}=0A+=09= fflush(NULL);=0A=20}=0A=20=0A=20/*=0A@@=20-271,9=20+416,8=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_exit(2);=09=09=09/*=20not=20exit(),=20= that=20could=20be=20recursive=20*/=0A+=09=09=09/*=20Not=20using=20the=20= normal=20bail()=20as=20we=20want=20_exit=20*/=0A+=09=09=09= bail_noatexit(_("could=20not=20stop=20postmaster:=20exit=20code=20was=20= %d"),=20r);=0A=20=09=09}=0A=20=0A=20=09=09postmaster_running=20=3D=20= false;=0A@@=20-331,9=20+475,8=20@@=20make_temp_sockdir(void)=0A=20=09= temp_sockdir=20=3D=20mkdtemp(template);=0A=20=09if=20(temp_sockdir=20=3D=3D= =20NULL)=0A=20=09{=0A-=09=09fprintf(stderr,=20_("%s:=20could=20not=20= create=20directory=20\"%s\":=20%s\n"),=0A-=09=09=09=09progname,=20= template,=20strerror(errno));=0A-=09=09exit(2);=0A+=09=09bail("could=20= not=20create=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= -455,9=20+598,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-476,26=20+618,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=20formatted=20= resultmap=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=20strchr(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=09bail("incorrectly=20formatted=20= resultmap=20entry:=20%s",=20buf);=0A=20=09=09}=0A=20=09=09*platform++=20= =3D=20'\0';=0A=20=09=09expected=20=3D=20strchr(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=09bail("incorrectly=20formatted=20= resultmap=20entry:=20%s",=20buf);=0A=20=09=09}=0A=20=09=09*expected++=20= =3D=20'\0';=0A=20=0A@@=20-741,13=20+877,13=20@@=20= initialize_environment(void)=0A=20=09=09}=0A=20=0A=20=09=09if=20(pghost=20= &&=20pgport)=0A-=09=09=09printf(_("(using=20postmaster=20on=20%s,=20port=20= %s)\n"),=20pghost,=20pgport);=0A+=09=09=09note("using=20postmaster=20on=20= %s,=20port=20%s",=20pghost,=20pgport);=0A=20=09=09if=20(pghost=20&&=20= !pgport)=0A-=09=09=09printf(_("(using=20postmaster=20on=20%s,=20default=20= port)\n"),=20pghost);=0A+=09=09=09note("using=20postmaster=20on=20%s,=20= default=20port",=20pghost);=0A=20=09=09if=20(!pghost=20&&=20pgport)=0A-=09= =09=09printf(_("(using=20postmaster=20on=20Unix=20socket,=20port=20= %s)\n"),=20pgport);=0A+=09=09=09note("using=20postmaster=20on=20Unix=20= socket,=20port=20%s",=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=09note("using=20postmaster=20on=20Unix=20= socket,=20default=20port");=0A=20=09}=0A=20=0A=20=09load_resultmap();=0A= @@=20-796,35=20+932,26=20@@=20current_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:=20could=20not=20open=20= process=20token:=20error=20code=20%lu\n"),=0A-=09=09=09=09progname,=20= GetLastError());=0A-=09=09exit(2);=0A+=09=09bail("could=20not=20open=20= process=20token:=20error=20code=20%lu",=20GetLastError());=0A=20=09}=0A=20= =0A=20=09if=20(!GetTokenInformation(token,=20TokenUser,=20NULL,=200,=20= &retlen)=20&&=20GetLastError()=20!=3D=20122)=0A=20=09{=0A-=09=09= fprintf(stderr,=0A-=09=09=09=09_("%s:=20could=20not=20get=20token=20= information=20buffer=20size:=20error=20code=20%lu\n"),=0A-=09=09=09=09= progname,=20GetLastError());=0A-=09=09exit(2);=0A+=09=09bail("could=20= not=20get=20token=20information=20buffer=20size:=20error=20code=20%lu",=0A= +=09=09=09=20GetLastError());=0A=20=09}=0A=20=09tokenuser=20=3D=20= pg_malloc(retlen);=0A=20=09if=20(!GetTokenInformation(token,=20= TokenUser,=20tokenuser,=20retlen,=20&retlen))=0A=20=09{=0A-=09=09= fprintf(stderr,=0A-=09=09=09=09_("%s:=20could=20not=20get=20token=20= information:=20error=20code=20%lu\n"),=0A-=09=09=09=09progname,=20= GetLastError());=0A-=09=09exit(2);=0A+=09=09bail("could=20not=20get=20= token=20information:=20error=20code=20%lu",=0A+=09=09=09=20= GetLastError());=0A=20=09}=0A=20=0A=20=09if=20(!LookupAccountSid(NULL,=20= tokenuser->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=20= account=20SID:=20error=20code=20%lu\n"),=0A-=09=09=09=09progname,=20= GetLastError());=0A-=09=09exit(2);=0A+=09=09bail("could=20not=20look=20= up=20account=20SID:=20error=20code=20%lu",=0A+=09=09=09=20= GetLastError());=0A=20=09}=0A=20=0A=20=09free(tokenuser);=0A@@=20-870,8=20= +997,7=20@@=20config_sspi_auth(const=20char=20*pgdata,=20const=20char=20= *superuser_name)=0A=20=09=09superuser_name=20=3D=20= get_user_name(&errstr);=0A=20=09=09if=20(superuser_name=20=3D=3D=20NULL)=0A= =20=09=09{=0A-=09=09=09fprintf(stderr,=20"%s:=20%s\n",=20progname,=20= errstr);=0A-=09=09=09exit(2);=0A+=09=09=09bail("%s",=20errstr);=0A=20=09=09= }=0A=20=09}=0A=20=0A@@=20-902,9=20+1028,8=20@@=20config_sspi_auth(const=20= char=20*pgdata,=20const=20char=20*superuser_name)=0A=20=09do=20{=20\=0A=20= =09=09if=20(!(cond))=20\=0A=20=09=09{=20\=0A-=09=09=09fprintf(stderr,=20= _("%s:=20could=20not=20write=20to=20file=20\"%s\":=20%s\n"),=20\=0A-=09=09= =09=09=09progname,=20fname,=20strerror(errno));=20\=0A-=09=09=09exit(2);=20= \=0A+=09=09=09bail("could=20not=20write=20to=20file=20\"%s\":=20%s",=20\=0A= +=09=09=09=09=20fname,=20strerror(errno));=20\=0A=20=09=09}=20\=0A=20=09= }=20while=20(0)=0A=20=0A@@=20-915,15=20+1040,13=20@@=20= config_sspi_auth(const=20char=20*pgdata,=20const=20char=20= *superuser_name)=0A=20=09=09=20*=20Truncating=20this=20name=20is=20a=20= fatal=20error,=20because=20we=20must=20not=20fail=20to=0A=20=09=09=20*=20= overwrite=20an=20original=20trust-authentication=20pg_hba.conf.=0A=20=09=09= =20*/=0A-=09=09fprintf(stderr,=20_("%s:=20directory=20name=20too=20= long\n"),=20progname);=0A-=09=09exit(2);=0A+=09=09bail("directory=20name=20= too=20long");=0A=20=09}=0A=20=09hba=20=3D=20fopen(fname,=20"w");=0A=20=09= if=20(hba=20=3D=3D=20NULL)=0A=20=09{=0A-=09=09fprintf(stderr,=20_("%s:=20= could=20not=20open=20file=20\"%s\"=20for=20writing:=20%s\n"),=0A-=09=09=09= =09progname,=20fname,=20strerror(errno));=0A-=09=09exit(2);=0A+=09=09= bail("could=20not=20open=20file=20\"%s\"=20for=20writing:=20%s",=0A+=09=09= =09=20fname,=20strerror(errno));=0A=20=09}=0A=20=09CW(fputs("#=20= Configuration=20written=20by=20config_sspi_auth()\n",=20hba)=20>=3D=20= 0);=0A=20=09CW(fputs("host=20all=20all=20127.0.0.1/32=20=20sspi=20= include_realm=3D1=20map=3Dregress\n",=0A@@=20-937,9=20+1060,8=20@@=20= config_sspi_auth(const=20char=20*pgdata,=20const=20char=20= *superuser_name)=0A=20=09ident=20=3D=20fopen(fname,=20"w");=0A=20=09if=20= (ident=20=3D=3D=20NULL)=0A=20=09{=0A-=09=09fprintf(stderr,=20_("%s:=20= could=20not=20open=20file=20\"%s\"=20for=20writing:=20%s\n"),=0A-=09=09=09= =09progname,=20fname,=20strerror(errno));=0A-=09=09exit(2);=0A+=09=09= bail("could=20not=20open=20file=20\"%s\"=20for=20writing:=20%s",=0A+=09=09= =09=20fname,=20strerror(errno));=0A=20=09}=0A=20=09CW(fputs("#=20= Configuration=20written=20by=20config_sspi_auth()\n",=20ident)=20>=3D=20= 0);=0A=20=0A@@=20-973,7=20+1095,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-1029,8=20+1151,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-1071,9=20+1192,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-1088,9=20+1207,8=20@@=20spawn_process(const=20char=20*cmdline)=0A= =20=0A=20=09=09cmdline2=20=3D=20psprintf("exec=20%s",=20cmdline);=0A=20=09= =09execl(shellprog,=20shellprog,=20"-c",=20cmdline2,=20(char=20*)=20= NULL);=0A-=09=09fprintf(stderr,=20_("%s:=20could=20not=20exec=20\"%s\":=20= %s\n"),=0A-=09=09=09=09progname,=20shellprog,=20strerror(errno));=0A-=09=09= _exit(1);=09=09=09=09/*=20not=20exit()=20here...=20*/=0A+=09=09/*=20Not=20= using=20the=20normal=20bail()=20here=20as=20we=20want=20_exit=20*/=0A+=09= =09bail_noatexit("could=20not=20exec=20\"%s\":=20%s",=20shellprog,=20= strerror(errno));=0A=20=09}=0A=20=09/*=20in=20parent=20*/=0A=20=09return=20= pid;=0A@@=20-1128,8=20+1246,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=20= not=20open=20file=20\"%s\"=20for=20reading:=20%s\n"),=0A-=09=09=09=09= progname,=20file,=20strerror(errno));=0A+=09=09diag("could=20not=20open=20= file=20\"%s\"=20for=20reading:=20%s",=0A+=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-1150,8=20+1268,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=09diag("could=20= not=20open=20file=20\"%s\"=20for=20reading:=20%s",=0A+=09=09=09=20file,=20= strerror(errno));=0A=20=09=09return=20-1;=0A=20=09}=0A=20=09while=20((c=20= =3D=20fgetc(f))=20!=3D=20EOF)=0A@@=20-1192,9=20+1310,7=20@@=20= make_directory(const=20char=20*dir)=0A=20{=0A=20=09if=20(mkdir(dir,=20= S_IRWXU=20|=20S_IRWXG=20|=20S_IRWXO)=20<=200)=0A=20=09{=0A-=09=09= fprintf(stderr,=20_("%s:=20could=20not=20create=20directory=20\"%s\":=20= %s\n"),=0A-=09=09=09=09progname,=20dir,=20strerror(errno));=0A-=09=09= exit(2);=0A+=09=09bail("could=20not=20create=20directory=20\"%s\":=20= %s",=20dir,=20strerror(errno));=0A=20=09}=0A=20}=0A=20=0A@@=20-1244,8=20= +1360,7=20@@=20run_diff(const=20char=20*cmd,=20const=20char=20*filename)=0A= =20=09r=20=3D=20system(cmd);=0A=20=09if=20(!WIFEXITED(r)=20||=20= WEXITSTATUS(r)=20>=201)=0A=20=09{=0A-=09=09fprintf(stderr,=20_("diff=20= command=20failed=20with=20status=20%d:=20%s\n"),=20r,=20cmd);=0A-=09=09= exit(2);=0A+=09=09bail("diff=20command=20failed=20with=20status=20%d:=20= %s",=20r,=20cmd);=0A=20=09}=0A=20#ifdef=20WIN32=0A=20=0A@@=20-1255,8=20= +1370,7=20@@=20run_diff(const=20char=20*cmd,=20const=20char=20*filename)=0A= =20=09=20*/=0A=20=09if=20(WEXITSTATUS(r)=20=3D=3D=201=20&&=20= file_size(filename)=20<=3D=200)=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=20found:=20%s",=20cmd);=0A=20=09}=0A=20= #endif=0A=20=0A@@=20-1327,9=20+1441,8=20@@=20results_differ(const=20char=20= *testname,=20const=20char=20*resultsfile,=20const=20char=20*defaul=0A=20=09= =09alt_expectfile=20=3D=20get_alternative_expectfile(expectfile,=20i);=0A= =20=09=09if=20(!alt_expectfile)=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20= _("Unable=20to=20check=20secondary=20comparison=20files:=20%s\n"),=0A-=09= =09=09=09=09strerror(errno));=0A-=09=09=09exit(2);=0A+=09=09=09= bail("Unable=20to=20check=20secondary=20comparison=20files:=20%s",=0A+=09= =09=09=09=20strerror(errno));=0A=20=09=09}=0A=20=0A=20=09=09if=20= (!file_exists(alt_expectfile))=0A@@=20-1444,9=20+1557,7=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",=20strerror(errno));=0A=20=09=09}=0A=20#else=0A=20=09=09DWORD=09=09= exit_status;=0A@@=20-1455,9=20+1566,8=20@@=20wait_for_tests(PID_TYPE=20*=20= pids,=20int=20*statuses,=20instr_time=20*stoptimes,=0A=20=09=09r=20=3D=20= WaitForMultipleObjects(tests_left,=20active_pids,=20FALSE,=20INFINITE);=0A= =20=09=09if=20(r=20<=20WAIT_OBJECT_0=20||=20r=20>=3D=20WAIT_OBJECT_0=20+=20= tests_left)=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20_("failed=20to=20= wait=20for=20subprocesses:=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-1476,7=20+1586,7=20@@=20wait_for_tests(PID_TYPE=20*=20pids,=20int=20= *statuses,=20instr_time=20*stoptimes,=0A=20=09=09=09=09statuses[i]=20=3D=20= (int)=20exit_status;=0A=20=09=09=09=09= INSTR_TIME_SET_CURRENT(stoptimes[i]);=0A=20=09=09=09=09if=20(names)=0A-=09= =09=09=09=09status("=20%s",=20names[i]);=0A+=09=09=09=09=09note_detail("=20= %s",=20names[i]);=0A=20=09=09=09=09tests_left--;=0A=20=09=09=09=09break;=0A= =20=09=09=09}=0A@@=20-1495,21=20+1605,20=20@@=20static=20void=0A=20= log_child_failure(int=20exitstatus)=0A=20{=0A=20=09if=20= (WIFEXITED(exitstatus))=0A-=09=09status(_("=20(test=20process=20exited=20= with=20exit=20code=20%d)"),=0A-=09=09=09=20=20=20= WEXITSTATUS(exitstatus));=0A+=09=09diag("(test=20process=20exited=20with=20= exit=20code=20%d)",=0A+=09=09=09=20WEXITSTATUS(exitstatus));=0A=20=09= else=20if=20(WIFSIGNALED(exitstatus))=0A=20=09{=0A=20#if=20= defined(WIN32)=0A-=09=09status(_("=20(test=20process=20was=20terminated=20= by=20exception=200x%X)"),=0A-=09=09=09=20=20=20WTERMSIG(exitstatus));=0A= +=09=09diag("(test=20process=20was=20terminated=20by=20exception=20= 0x%X)",=0A+=09=09=09=20WTERMSIG(exitstatus));=0A=20#else=0A-=09=09= status(_("=20(test=20process=20was=20terminated=20by=20signal=20%d:=20= %s)"),=0A-=09=09=09=20=20=20WTERMSIG(exitstatus),=20= pg_strsignal(WTERMSIG(exitstatus)));=0A+=09=09diag("(test=20process=20= was=20terminated=20by=20signal=20%d:=20%s)",=0A+=09=09=09=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=09=09=20=20=20exitstatus);=0A= +=09=09diag("(test=20process=20exited=20with=20unrecognized=20status=20= %d)",=20exitstatus);=0A=20}=0A=20=0A=20/*=0A@@=20-1540,9=20+1649,8=20@@=20= run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09scf=20=3D=20fopen(schedule,=20"r");=0A=20=09if=20= (!scf)=0A=20=09{=0A-=09=09fprintf(stderr,=20_("%s:=20could=20not=20open=20= file=20\"%s\"=20for=20reading:=20%s\n"),=0A-=09=09=09=09progname,=20= schedule,=20strerror(errno));=0A-=09=09exit(2);=0A+=09=09bail("could=20= not=20open=20file=20\"%s\"=20for=20reading:=20%s",=0A+=09=09=09=20= schedule,=20strerror(errno));=0A=20=09}=0A=20=0A=20=09while=20= (fgets(scbuf,=20sizeof(scbuf),=20scf))=0A@@=20-1566,9=20+1674,8=20@@=20= run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09=09=09test=20=3D=20scbuf=20+=206;=0A=20=09=09else=0A=20= =09=09{=0A-=09=09=09fprintf(stderr,=20_("syntax=20error=20in=20schedule=20= file=20\"%s\"=20line=20%d:=20%s\n"),=0A-=09=09=09=09=09schedule,=20= line_num,=20scbuf);=0A-=09=09=09exit(2);=0A+=09=09=09bail("syntax=20= error=20in=20schedule=20file=20\"%s\"=20line=20%d:=20%s",=0A+=09=09=09=09= =20schedule,=20line_num,=20scbuf);=0A=20=09=09}=0A=20=0A=20=09=09= num_tests=20=3D=200;=0A@@=20-1584,9=20+1691,8=20@@=20run_schedule(const=20= char=20*schedule,=20test_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=20than=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,=20= line_num,=20scbuf);=0A-=09=09=09=09=09=09exit(2);=0A+=09=09=09=09=09=09= bail("too=20many=20parallel=20tests=20(more=20than=20%d)=20in=20schedule=20= file=20\"%s\"=20line=20%d:=20%s",=0A+=09=09=09=09=09=09=09=20= MAX_PARALLEL_TESTS,=20schedule,=20line_num,=20scbuf);=0A=20=09=09=09=09=09= }=0A=20=09=09=09=09=09sav=20=3D=20*c;=0A=20=09=09=09=09=09*c=20=3D=20= '\0';=0A@@=20-1608,14=20+1714,12=20@@=20run_schedule(const=20char=20= *schedule,=20test_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=20schedule=20file=20\"%s\"=20line=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=20file=20\"%s\"=20line=20%d:=20= %s",=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= -1623,16=20+1727,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",=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=09note_detail("parallel=20= group=20(%d=20tests,=20in=20groups=20of=20%d):=20",=0A+=09=09=09=09=09=09= num_tests,=20max_connections);=0A=20=09=09=09for=20(i=20=3D=200;=20i=20<=20= num_tests;=20i++)=0A=20=09=09=09{=0A=20=09=09=09=09if=20(i=20-=20oldest=20= >=3D=20max_connections)=0A@@=20-1648,18=20+1751,18=20@@=20= run_schedule(const=20char=20*schedule,=20test_start_function=20= startfunc,=0A=20=09=09=09wait_for_tests(pids=20+=20oldest,=20statuses=20= +=20oldest,=0A=20=09=09=09=09=09=09=20=20=20stoptimes=20+=20oldest,=0A=20= =09=09=09=09=09=09=20=20=20tests=20+=20oldest,=20i=20-=20oldest);=0A-=09=09= =09status_end();=0A+=09=09=09note_end();=0A=20=09=09}=0A=20=09=09else=0A=20= =09=09{=0A-=09=09=09status(_("parallel=20group=20(%d=20tests):=20"),=20= num_tests);=0A+=09=09=09note_detail("parallel=20group=20(%d=20tests):=20= ",=20num_tests);=0A=20=09=09=09for=20(i=20=3D=200;=20i=20<=20num_tests;=20= i++)=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=09=09= =09=09INSTR_TIME_SET_CURRENT(starttimes[i]);=0A=20=09=09=09}=0A=20=09=09=09= wait_for_tests(pids,=20statuses,=20stoptimes,=20tests,=20num_tests);=0A-=09= =09=09status_end();=0A+=09=09=09note_end();=0A=20=09=09}=0A=20=0A=20=09=09= /*=20Check=20results=20for=20all=20tests=20*/=0A@@=20-1670,8=20+1773,7=20= @@=20run_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= 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-1692,36=20+1794,27=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=09diag("tag:=20%s",=20= tl->str);=0A=20=09=09=09=09}=0A=20=09=09=09=09differ=20|=3D=20newdiff;=0A= =20=09=09=09}=0A=20=0A=20=09=09=09if=20(statuses[i]=20!=3D=200)=0A=20=09=09= =09{=0A-=09=09=09=09status(_("FAILED"));=0A+=09=09=09=09= test_status_failed(tests[i],=20INSTR_TIME_GET_MILLISEC(stoptimes[i]),=20= (num_tests=20>=201));=0A=20=09=09=09=09log_child_failure(statuses[i]);=0A= -=09=09=09=09fail_count++;=0A=20=09=09=09}=0A=20=09=09=09else=0A=20=09=09= =09{=0A-=0A=20=09=09=09=09if=20(differ)=0A=20=09=09=09=09{=0A-=09=09=09=09= =09status(_("FAILED"));=0A-=09=09=09=09=09fail_count++;=0A+=09=09=09=09=09= test_status_failed(tests[i],=20INSTR_TIME_GET_MILLISEC(stoptimes[i]),=20= (num_tests=20>=201));=0A=20=09=09=09=09}=0A=20=09=09=09=09else=0A=20=09=09= =09=09{=0A-=09=09=09=09=09status(_("ok=20=20=20=20"));=09/*=20align=20= with=20FAILED=20*/=0A-=09=09=09=09=09success_count++;=0A+=09=09=09=09=09= test_status_ok(tests[i],=20INSTR_TIME_GET_MILLISEC(stoptimes[i]),=20= (num_tests=20>=201));=0A=20=09=09=09=09}=0A=20=09=09=09}=0A-=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= -=09=09=09status_end();=0A=20=09=09}=0A=20=0A=20=09=09for=20(i=20=3D=20= 0;=20i=20<=20num_tests;=20i++)=0A@@=20-1756,7=20+1849,6=20@@=20= run_single_test(const=20char=20*test,=20test_start_function=20startfunc,=0A= =20=09=09=09=20=20=20*tl;=0A=20=09bool=09=09differ=20=3D=20false;=0A=20=0A= -=09status(_("test=20%-28s=20...=20"),=20test);=0A=20=09pid=20=3D=20= (startfunc)=20(test,=20&resultfiles,=20&expectfiles,=20&tags);=0A=20=09= INSTR_TIME_SET_CURRENT(starttime);=0A=20=09wait_for_tests(&pid,=20= &exit_status,=20&stoptime,=20NULL,=201);=0A@@=20-1780,35=20+1872,29=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=09diag("tag:=20%s",=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= (exit_status=20!=3D=200)=0A=20=09{=0A-=09=09status(_("FAILED"));=0A-=09=09= fail_count++;=0A+=09=09test_status_failed(test,=20false,=20= INSTR_TIME_GET_MILLISEC(stoptime));=0A=20=09=09= log_child_failure(exit_status);=0A=20=09}=0A=20=09else=0A=20=09{=0A=20=09= =09if=20(differ)=0A=20=09=09{=0A-=09=09=09status(_("FAILED"));=0A-=09=09=09= fail_count++;=0A+=09=09=09test_status_failed(test,=20false,=20= INSTR_TIME_GET_MILLISEC(stoptime));=0A=20=09=09}=0A=20=09=09else=0A=20=09= =09{=0A-=09=09=09status(_("ok=20=20=20=20"));=09/*=20align=20with=20= FAILED=20*/=0A-=09=09=09success_count++;=0A+=09=09=09= test_status_ok(test,=20INSTR_TIME_GET_MILLISEC(stoptime),=20false);=0A=20= =09=09}=0A=20=09}=0A-=0A-=09INSTR_TIME_SUBTRACT(stoptime,=20starttime);=0A= -=09status(_("=20%8.0f=20ms"),=20INSTR_TIME_GET_MILLISEC(stoptime));=0A-=0A= -=09status_end();=0A=20}=0A=20=0A=20/*=0A@@=20-1830,9=20+1916,8=20@@=20= open_result_files(void)=0A=20=09logfile=20=3D=20fopen(logfilename,=20= "w");=0A=20=09if=20(!logfile)=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,=20logfilename,=20strerror(errno));=0A-=09=09= exit(2);=0A+=09=09bail("could=20not=20open=20file=20\"%s\"=20for=20= writing:=20%s",=0A+=09=09=09=20logfilename,=20strerror(errno));=0A=20=09= }=0A=20=0A=20=09/*=20create=20the=20diffs=20file=20as=20empty=20*/=0A@@=20= -1841,9=20+1926,8=20@@=20open_result_files(void)=0A=20=09difffile=20=3D=20= fopen(difffilename,=20"w");=0A=20=09if=20(!difffile)=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,=20difffilename,=20= strerror(errno));=0A-=09=09exit(2);=0A+=09=09bail("could=20not=20open=20= file=20\"%s\"=20for=20writing:=20%s",=0A+=09=09=09=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-1859,7=20= +1943,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-1876,7=20+1959,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-1898,10=20+1980,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-1909,7=20+1988,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-1921,7=20= +1999,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-2143,8=20= +2220,8=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=09= =09progname);=0A+=09=09=09=09pg_log_error_hint("Try=20\"%s=20--help\"=20= for=20more=20information.",=0A+=09=09=09=09=09=09=09=09=20=20progname);=0A= =20=09=09=09=09exit(2);=0A=20=09=09}=0A=20=09}=0A@@=20-2164,9=20+2241,7=20= @@=20regression_main(int=20argc,=20char=20*argv[],=0A=20=09=20*/=0A=20=09= if=20(!(dblist=20&&=20dblist->str=20&&=20dblist->str[0]))=0A=20=09{=0A-=09= =09fprintf(stderr,=20_("%s:=20no=20database=20name=20was=20= specified\n"),=0A-=09=09=09=09progname);=0A-=09=09exit(2);=0A+=09=09= bail("no=20database=20name=20was=20specified");=0A=20=09}=0A=20=0A=20=09= if=20(config_auth_datadir)=0A@@=20-2217,17=20+2292,12=20@@=20= regression_main(int=20argc,=20char=20*argv[],=0A=20=0A=20=09=09if=20= (directory_exists(temp_instance))=0A=20=09=09{=0A-=09=09=09= header(_("removing=20existing=20temp=20instance"));=0A=20=09=09=09if=20= (!rmtree(temp_instance,=20true))=0A=20=09=09=09{=0A-=09=09=09=09= fprintf(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("could=20not=20remove=20temp=20instance=20= \"%s\"",=20temp_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-2237,7=20+2307,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-2249,8=20+2318,10=20@@=20= regression_main(int=20argc,=20char=20*argv[],=0A=20=09=09fflush(NULL);=0A= =20=09=09if=20(system(buf))=0A=20=09=09{=0A-=09=09=09fprintf(stderr,=20= _("\n%s:=20initdb=20failed\nExamine=20%s/log/initdb.log=20for=20the=20= reason.\nCommand=20was:=20%s\n"),=20progname,=20outputdir,=20buf);=0A-=09= =09=09exit(2);=0A+=09=09=09bail("initdb=20failed\n"=0A+=09=09=09=09=20"#=20= Examine=20\"%s/log/initdb.log\"=20for=20the=20reason.\n"=0A+=09=09=09=09=20= "#=20Command=20was:=20%s",=0A+=09=09=09=09=20outputdir,=20buf);=0A=20=09=09= }=0A=20=0A=20=09=09/*=0A@@=20-2265,8=20+2336,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("could=20not=20= open=20\"%s\"=20for=20adding=20extra=20config:=20%s",=0A+=09=09=09=09=20= buf,=20strerror(errno));=0A=20=09=09}=0A=20=09=09fputs("\n#=20= Configuration=20added=20by=20pg_regress\n\n",=20pg_conf);=0A=20=09=09= fputs("log_autovacuum_min_duration=20=3D=200\n",=20pg_conf);=0A@@=20= -2285,8=20+2356,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=09= if=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("could=20not=20open=20\"%s\"=20= to=20read=20extra=20config:=20%s",=0A+=09=09=09=09=09=20temp_config,=20= strerror(errno));=0A=20=09=09=09}=0A=20=09=09=09while=20(fgets(line_buf,=20= sizeof(line_buf),=20extra_conf)=20!=3D=20NULL)=0A=20=09=09=09=09= fputs(line_buf,=20pg_conf);=0A@@=20-2325,14=20+2396,13=20@@=20= regression_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=20in=20use\n"),=20= port);=0A+=09=09=09=09=09note("port=20%d=20apparently=20in=20use",=20= port);=0A=20=09=09=09=09=09if=20(!port_specified_by_user)=0A-=09=09=09=09= =09=09fprintf(stderr,=20_("%s:=20could=20not=20determine=20an=20= available=20port\n"),=20progname);=0A-=09=09=09=09=09fprintf(stderr,=20= _("Specify=20an=20unused=20port=20using=20the=20--port=20option=20or=20= shut=20down=20any=20conflicting=20PostgreSQL=20servers.\n"));=0A-=09=09=09= =09=09exit(2);=0A+=09=09=09=09=09=09note("could=20not=20determine=20an=20= available=20port");=0A+=09=09=09=09=09bail("Specify=20an=20unused=20port=20= using=20the=20--port=20option=20or=20shut=20down=20any=20conflicting=20= PostgreSQL=20servers.");=0A=20=09=09=09=09}=0A=20=0A-=09=09=09=09= fprintf(stderr,=20_("port=20%d=20apparently=20in=20use,=20trying=20= %d\n"),=20port,=20port=20+=201);=0A+=09=09=09=09note("port=20%d=20= apparently=20in=20use,=20trying=20%d",=20port,=20port=20+=201);=0A=20=09=09= =09=09port++;=0A=20=09=09=09=09sprintf(s,=20"%d",=20port);=0A=20=09=09=09= =09setenv("PGPORT",=20s,=201);=0A@@=20-2344,7=20+2414,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-2356,11=20+2425,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",=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-2395,16=20+2460,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,=20examine=20\"%s/log/postmaster.log\"=20for=20the=20reason",=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=09diag("postmaster=20= did=20not=20respond=20within=20%d=20seconds,=20examine=20= \"%s/log/postmaster.log\"=20for=20the=20reason",=0A+=09=09=09=09=20= 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-2413,17=20+2478,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=20GetLastError());=0A= =20#endif=0A-=0A-=09=09=09exit(2);=0A+=09=09=09bail("postmaster=20= failed");=0A=20=09=09}=0A=20=0A=20=09=09postmaster_running=20=3D=20true;=0A= @@=20-2434,8=20+2496,8=20@@=20regression_main(int=20argc,=20char=20= *argv[],=0A=20#else=0A=20#define=20ULONGPID(x)=20(unsigned=20long)=20(x)=0A= =20#endif=0A-=09=09printf(_("running=20on=20port=20%d=20with=20PID=20= %lu\n"),=0A-=09=09=09=20=20=20port,=20ULONGPID(postmaster_pid));=0A+=09=09= note("using=20temp=20instance=20on=20port=20%d=20with=20PID=20%lu",=0A+=09= =09=09=20port,=20ULONGPID(postmaster_pid));=0A=20=09}=0A=20=09else=0A=20=09= {=0A@@=20-2466,8=20+2528,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-2483,7=20+2543,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-2494,42=20+2553,30=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)=0A=20=09{=0A-=09=09= header(_("removing=20temporary=20instance"));=0A=20=09=09if=20= (!rmtree(temp_instance,=20true))=0A-=09=09=09fprintf(stderr,=20_("\n%s:=20= could=20not=20remove=20temp=20instance=20\"%s\"\n"),=0A-=09=09=09=09=09= progname,=20temp_instance);=0A+=09=09=09diag("could=20not=20remove=20= temp=20instance=20\"%s\"",=0A+=09=09=09=09=20temp_instance);=0A=20=09}=0A= =20=0A-=09fclose(logfile);=0A+=09/*=0A+=09=20*=20Emit=20a=20TAP=20= compliant=20Plan=0A+=09=20*/=0A+=09plan(fail_count=20+=20success_count);=0A= =20=0A=20=09/*=0A=20=09=20*=20Emit=20nice-looking=20summary=20message=0A=20= =09=20*/=0A=20=09if=20(fail_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+=09=09note("All=20%d=20tests=20= passed.",=20success_count);=0A=20=09else=0A-=09=09snprintf(buf,=20= sizeof(buf),=0A-=09=09=09=09=20_("=20%d=20of=20%d=20tests=20failed.=20= "),=0A-=09=09=09=09=20fail_count,=0A-=09=09=09=09=20success_count=20+=20= fail_count);=0A-=0A-=09putchar('\n');=0A-=09for=20(i=20=3D=20= strlen(buf);=20i=20>=200;=20i--)=0A-=09=09putchar('=3D');=0A-=09= printf("\n%s\n",=20buf);=0A-=09for=20(i=20=3D=20strlen(buf);=20i=20>=20= 0;=20i--)=0A-=09=09putchar('=3D');=0A-=09putchar('\n');=0A-=09= putchar('\n');=0A+=09=09diag("%d=20of=20%d=20tests=20failed.",=20= fail_count,=20success_count=20+=20fail_count);=0A=20=0A=20=09if=20= (file_size(difffilename)=20>=200)=0A=20=09{=0A-=09=09printf(_("The=20= differences=20that=20caused=20some=20tests=20to=20fail=20can=20be=20= viewed=20in=20the\n"=0A-=09=09=09=09=20"file=20\"%s\".=20=20A=20copy=20= of=20the=20test=20summary=20that=20you=20see\n"=0A-=09=09=09=09=20"above=20= is=20saved=20in=20the=20file=20\"%s\".\n\n"),=0A-=09=09=09=20=20=20= difffilename,=20logfilename);=0A+=09=09diag("The=20differences=20that=20= caused=20some=20tests=20to=20fail=20can=20be=20viewed=20in=20the=20file=20= \"%s\".",=0A+=09=09=09=20difffilename);=0A+=09=09diag("A=20copy=20of=20= the=20test=20summary=20that=20you=20see=20above=20is=20saved=20in=20the=20= file=20\"%s\".",=0A+=09=09=09=20logfilename);=0A=20=09}=0A=20=09else=0A=20= =09{=0A@@=20-2537,6=20+2584,9=20@@=20regression_main(int=20argc,=20char=20= *argv[],=0A=20=09=09unlink(logfilename);=0A=20=09}=0A=20=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=_34FA7BDF-0C7E-41EC-A25B-2DACD98660DA--