additional contrib test suites

Started by Peter Eisentrautover 8 years ago13 messages
#1Peter Eisentraut
peter.eisentraut@2ndquadrant.com
7 attachment(s)

Here are some small test suites for some contrib modules as well as
pg_archivecleanup that didn't have one previously, as well as one patch
to improve code coverage in a module.

Will add to commit fest. Testing on different platforms and with
different build configurations would be useful.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

0001-adminpack-Add-test-suite.patchtext/plain; charset=UTF-8; name=0001-adminpack-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From 65b09d5b15b43c7eab24aae2d2e7e7a7979d57f3 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH 1/7] adminpack: Add test suite

---
 contrib/adminpack/.gitignore             |   4 +
 contrib/adminpack/Makefile               |   2 +
 contrib/adminpack/expected/adminpack.out | 144 +++++++++++++++++++++++++++++++
 contrib/adminpack/sql/adminpack.sql      |  56 ++++++++++++
 4 files changed, 206 insertions(+)
 create mode 100644 contrib/adminpack/.gitignore
 create mode 100644 contrib/adminpack/expected/adminpack.out
 create mode 100644 contrib/adminpack/sql/adminpack.sql

diff --git a/contrib/adminpack/.gitignore b/contrib/adminpack/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/adminpack/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/adminpack/Makefile b/contrib/adminpack/Makefile
index f065f84bfb..89c249bc0d 100644
--- a/contrib/adminpack/Makefile
+++ b/contrib/adminpack/Makefile
@@ -8,6 +8,8 @@ EXTENSION = adminpack
 DATA = adminpack--1.0.sql
 PGFILEDESC = "adminpack - support functions for pgAdmin"
 
+REGRESS = adminpack
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/adminpack/expected/adminpack.out b/contrib/adminpack/expected/adminpack.out
new file mode 100644
index 0000000000..83cbb741da
--- /dev/null
+++ b/contrib/adminpack/expected/adminpack.out
@@ -0,0 +1,144 @@
+CREATE EXTENSION adminpack;
+-- create new file
+SELECT pg_file_write('test_file1', 'test1', false);
+ pg_file_write 
+---------------
+             5
+(1 row)
+
+SELECT pg_read_file('test_file1');
+ pg_read_file 
+--------------
+ test1
+(1 row)
+
+-- append
+SELECT pg_file_write('test_file1', 'test1', true);
+ pg_file_write 
+---------------
+             5
+(1 row)
+
+SELECT pg_read_file('test_file1');
+ pg_read_file 
+--------------
+ test1test1
+(1 row)
+
+-- error, already exists
+SELECT pg_file_write('test_file1', 'test1', false);
+ERROR:  file "test_file1" exists
+SELECT pg_read_file('test_file1');
+ pg_read_file 
+--------------
+ test1test1
+(1 row)
+
+-- disallowed file paths
+SELECT pg_file_write('../test_file0', 'test0', false);
+ERROR:  path must be in or below the current directory
+SELECT pg_file_write('/tmp/test_file0', 'test0', false);
+ERROR:  absolute path not allowed
+SELECT pg_file_write(current_setting('data_directory') || '/test_file4', 'test4', false);
+ pg_file_write 
+---------------
+             5
+(1 row)
+
+SELECT pg_file_write(current_setting('data_directory') || '/../test_file4', 'test4', false);
+ERROR:  reference to parent directory ("..") not allowed
+-- rename file
+SELECT pg_file_rename('test_file1', 'test_file2');
+ pg_file_rename 
+----------------
+ t
+(1 row)
+
+SELECT pg_read_file('test_file1');  -- not there
+ERROR:  could not stat file "test_file1": No such file or directory
+SELECT pg_read_file('test_file2');
+ pg_read_file 
+--------------
+ test1test1
+(1 row)
+
+-- error
+SELECT pg_file_rename('test_file1', 'test_file2');
+WARNING:  file "test_file1" is not accessible: No such file or directory
+ pg_file_rename 
+----------------
+ f
+(1 row)
+
+-- rename file and archive
+SELECT pg_file_write('test_file3', 'test3', false);
+ pg_file_write 
+---------------
+             5
+(1 row)
+
+SELECT pg_file_rename('test_file2', 'test_file3', 'test_file3_archive');
+ pg_file_rename 
+----------------
+ t
+(1 row)
+
+SELECT pg_read_file('test_file2');  -- not there
+ERROR:  could not stat file "test_file2": No such file or directory
+SELECT pg_read_file('test_file3');
+ pg_read_file 
+--------------
+ test1test1
+(1 row)
+
+SELECT pg_read_file('test_file3_archive');
+ pg_read_file 
+--------------
+ test3
+(1 row)
+
+-- unlink
+SELECT pg_file_unlink('test_file1');  -- does not exist
+ pg_file_unlink 
+----------------
+ f
+(1 row)
+
+SELECT pg_file_unlink('test_file2');  -- does not exist
+ pg_file_unlink 
+----------------
+ f
+(1 row)
+
+SELECT pg_file_unlink('test_file3');
+ pg_file_unlink 
+----------------
+ t
+(1 row)
+
+SELECT pg_file_unlink('test_file3_archive');
+ pg_file_unlink 
+----------------
+ t
+(1 row)
+
+SELECT pg_file_unlink('test_file4');
+ pg_file_unlink 
+----------------
+ t
+(1 row)
+
+-- superuser checks
+CREATE USER regress_user1;
+SET ROLE regress_user1;
+SELECT pg_file_write('test_file0', 'test0', false);
+ERROR:  only superuser may access generic file functions
+SELECT pg_file_rename('test_file0', 'test_file0');
+ERROR:  only superuser may access generic file functions
+CONTEXT:  SQL function "pg_file_rename" statement 1
+SELECT pg_file_unlink('test_file0');
+ERROR:  only superuser may access generic file functions
+SELECT pg_logdir_ls();
+ERROR:  only superuser can list the log directory
+RESET ROLE;
+DROP USER regress_user1;
diff --git a/contrib/adminpack/sql/adminpack.sql b/contrib/adminpack/sql/adminpack.sql
new file mode 100644
index 0000000000..d29b2468b6
--- /dev/null
+++ b/contrib/adminpack/sql/adminpack.sql
@@ -0,0 +1,56 @@
+CREATE EXTENSION adminpack;
+
+-- create new file
+SELECT pg_file_write('test_file1', 'test1', false);
+SELECT pg_read_file('test_file1');
+
+-- append
+SELECT pg_file_write('test_file1', 'test1', true);
+SELECT pg_read_file('test_file1');
+
+-- error, already exists
+SELECT pg_file_write('test_file1', 'test1', false);
+SELECT pg_read_file('test_file1');
+
+-- disallowed file paths
+SELECT pg_file_write('../test_file0', 'test0', false);
+SELECT pg_file_write('/tmp/test_file0', 'test0', false);
+SELECT pg_file_write(current_setting('data_directory') || '/test_file4', 'test4', false);
+SELECT pg_file_write(current_setting('data_directory') || '/../test_file4', 'test4', false);
+
+
+-- rename file
+SELECT pg_file_rename('test_file1', 'test_file2');
+SELECT pg_read_file('test_file1');  -- not there
+SELECT pg_read_file('test_file2');
+
+-- error
+SELECT pg_file_rename('test_file1', 'test_file2');
+
+-- rename file and archive
+SELECT pg_file_write('test_file3', 'test3', false);
+SELECT pg_file_rename('test_file2', 'test_file3', 'test_file3_archive');
+SELECT pg_read_file('test_file2');  -- not there
+SELECT pg_read_file('test_file3');
+SELECT pg_read_file('test_file3_archive');
+
+
+-- unlink
+SELECT pg_file_unlink('test_file1');  -- does not exist
+SELECT pg_file_unlink('test_file2');  -- does not exist
+SELECT pg_file_unlink('test_file3');
+SELECT pg_file_unlink('test_file3_archive');
+SELECT pg_file_unlink('test_file4');
+
+
+-- superuser checks
+CREATE USER regress_user1;
+SET ROLE regress_user1;
+
+SELECT pg_file_write('test_file0', 'test0', false);
+SELECT pg_file_rename('test_file0', 'test_file0');
+SELECT pg_file_unlink('test_file0');
+SELECT pg_logdir_ls();
+
+RESET ROLE;
+DROP USER regress_user1;

base-commit: 8d6442377df5451a8db598788847e6a70b3b49ef
-- 
2.14.0

0002-fuzzystrmatch-Add-test-suite.patchtext/plain; charset=UTF-8; name=0002-fuzzystrmatch-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From bdf68d9626a307a58158e954eef265735811499c Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH 2/7] fuzzystrmatch: Add test suite

---
 contrib/fuzzystrmatch/.gitignore                 |  4 ++
 contrib/fuzzystrmatch/Makefile                   |  2 +
 contrib/fuzzystrmatch/expected/fuzzystrmatch.out | 67 ++++++++++++++++++++++++
 contrib/fuzzystrmatch/sql/fuzzystrmatch.sql      | 21 ++++++++
 doc/src/sgml/fuzzystrmatch.sgml                  |  8 +--
 5 files changed, 98 insertions(+), 4 deletions(-)
 create mode 100644 contrib/fuzzystrmatch/.gitignore
 create mode 100644 contrib/fuzzystrmatch/expected/fuzzystrmatch.out
 create mode 100644 contrib/fuzzystrmatch/sql/fuzzystrmatch.sql

diff --git a/contrib/fuzzystrmatch/.gitignore b/contrib/fuzzystrmatch/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/fuzzystrmatch/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/fuzzystrmatch/Makefile b/contrib/fuzzystrmatch/Makefile
index 51e215a919..bd6f5e50d1 100644
--- a/contrib/fuzzystrmatch/Makefile
+++ b/contrib/fuzzystrmatch/Makefile
@@ -8,6 +8,8 @@ DATA = fuzzystrmatch--1.1.sql fuzzystrmatch--1.0--1.1.sql \
 	fuzzystrmatch--unpackaged--1.0.sql
 PGFILEDESC = "fuzzystrmatch - similarities and distance between strings"
 
+REGRESS = fuzzystrmatch
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/fuzzystrmatch/expected/fuzzystrmatch.out b/contrib/fuzzystrmatch/expected/fuzzystrmatch.out
new file mode 100644
index 0000000000..493c95cdfa
--- /dev/null
+++ b/contrib/fuzzystrmatch/expected/fuzzystrmatch.out
@@ -0,0 +1,67 @@
+CREATE EXTENSION fuzzystrmatch;
+SELECT soundex('hello world!');
+ soundex 
+---------
+ H464
+(1 row)
+
+SELECT soundex('Anne'), soundex('Ann'), difference('Anne', 'Ann');
+ soundex | soundex | difference 
+---------+---------+------------
+ A500    | A500    |          4
+(1 row)
+
+SELECT soundex('Anne'), soundex('Andrew'), difference('Anne', 'Andrew');
+ soundex | soundex | difference 
+---------+---------+------------
+ A500    | A536    |          2
+(1 row)
+
+SELECT soundex('Anne'), soundex('Margaret'), difference('Anne', 'Margaret');
+ soundex | soundex | difference 
+---------+---------+------------
+ A500    | M626    |          0
+(1 row)
+
+SELECT levenshtein('GUMBO', 'GAMBOL');
+ levenshtein 
+-------------
+           2
+(1 row)
+
+SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1);
+ levenshtein 
+-------------
+           3
+(1 row)
+
+SELECT levenshtein_less_equal('extensive', 'exhaustive', 2);
+ levenshtein_less_equal 
+------------------------
+                      3
+(1 row)
+
+SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
+ levenshtein_less_equal 
+------------------------
+                      4
+(1 row)
+
+SELECT metaphone('GUMBO', 4);
+ metaphone 
+-----------
+ KM
+(1 row)
+
+SELECT dmetaphone('gumbo');
+ dmetaphone 
+------------
+ KMP
+(1 row)
+
+SELECT dmetaphone_alt('gumbo');
+ dmetaphone_alt 
+----------------
+ KMP
+(1 row)
+
diff --git a/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql b/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql
new file mode 100644
index 0000000000..f05dc28ffb
--- /dev/null
+++ b/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql
@@ -0,0 +1,21 @@
+CREATE EXTENSION fuzzystrmatch;
+
+
+SELECT soundex('hello world!');
+
+SELECT soundex('Anne'), soundex('Ann'), difference('Anne', 'Ann');
+SELECT soundex('Anne'), soundex('Andrew'), difference('Anne', 'Andrew');
+SELECT soundex('Anne'), soundex('Margaret'), difference('Anne', 'Margaret');
+
+
+SELECT levenshtein('GUMBO', 'GAMBOL');
+SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1);
+SELECT levenshtein_less_equal('extensive', 'exhaustive', 2);
+SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
+
+
+SELECT metaphone('GUMBO', 4);
+
+
+SELECT dmetaphone('gumbo');
+SELECT dmetaphone_alt('gumbo');
diff --git a/doc/src/sgml/fuzzystrmatch.sgml b/doc/src/sgml/fuzzystrmatch.sgml
index feb06861da..ff5bc08fea 100644
--- a/doc/src/sgml/fuzzystrmatch.sgml
+++ b/doc/src/sgml/fuzzystrmatch.sgml
@@ -133,19 +133,19 @@ <title>Levenshtein</title>
            2
 (1 row)
 
-test=# SELECT levenshtein('GUMBO', 'GAMBOL', 2,1,1);
+test=# SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1);
  levenshtein
 -------------
            3
 (1 row)
 
-test=# SELECT levenshtein_less_equal('extensive', 'exhaustive',2);
+test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 2);
  levenshtein_less_equal
 ------------------------
                       3
 (1 row)
 
-test=# SELECT levenshtein_less_equal('extensive', 'exhaustive',4);
+test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
  levenshtein_less_equal
 ------------------------
                       4
@@ -227,7 +227,7 @@ <title>Double Metaphone</title>
   </para>
 
 <screen>
-test=# select dmetaphone('gumbo');
+test=# SELECT dmetaphone('gumbo');
  dmetaphone
 ------------
  KMP
-- 
2.14.0

0003-lo-Add-test-suite.patchtext/plain; charset=UTF-8; name=0003-lo-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From fb23fda4933b5b78fbfc9a834fdd5e7352d96ae7 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH 3/7] lo: Add test suite

---
 contrib/lo/.gitignore      |  4 ++++
 contrib/lo/Makefile        |  2 ++
 contrib/lo/expected/lo.out | 42 ++++++++++++++++++++++++++++++++++++++++++
 contrib/lo/sql/lo.sql      | 25 +++++++++++++++++++++++++
 doc/src/sgml/lo.sgml       |  2 +-
 5 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 contrib/lo/.gitignore
 create mode 100644 contrib/lo/expected/lo.out
 create mode 100644 contrib/lo/sql/lo.sql

diff --git a/contrib/lo/.gitignore b/contrib/lo/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/lo/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/lo/Makefile b/contrib/lo/Makefile
index 71f0cb0d24..bd4fd6b72d 100644
--- a/contrib/lo/Makefile
+++ b/contrib/lo/Makefile
@@ -6,6 +6,8 @@ EXTENSION = lo
 DATA = lo--1.1.sql lo--1.0--1.1.sql lo--unpackaged--1.0.sql
 PGFILEDESC = "lo - management for large objects"
 
+REGRESS = lo
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/lo/expected/lo.out b/contrib/lo/expected/lo.out
new file mode 100644
index 0000000000..f7104aee3f
--- /dev/null
+++ b/contrib/lo/expected/lo.out
@@ -0,0 +1,42 @@
+CREATE EXTENSION lo;
+CREATE TABLE image (title text, raster lo);
+CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
+    FOR EACH ROW EXECUTE PROCEDURE lo_manage(raster);
+SELECT lo_create(43213);
+ lo_create 
+-----------
+     43213
+(1 row)
+
+SELECT lo_create(43214);
+ lo_create 
+-----------
+     43214
+(1 row)
+
+INSERT INTO image (title, raster) VALUES ('beautiful image', 43213);
+SELECT lo_get(43213);
+ lo_get 
+--------
+ \x
+(1 row)
+
+SELECT lo_get(43214);
+ lo_get 
+--------
+ \x
+(1 row)
+
+UPDATE image SET raster = 43214 WHERE title = 'beautiful image';
+SELECT lo_get(43213);
+ERROR:  large object 43213 does not exist
+SELECT lo_get(43214);
+ lo_get 
+--------
+ \x
+(1 row)
+
+DELETE FROM image;
+SELECT lo_get(43214);
+ERROR:  large object 43214 does not exist
+DROP TABLE image;
diff --git a/contrib/lo/sql/lo.sql b/contrib/lo/sql/lo.sql
new file mode 100644
index 0000000000..34ba6f00ec
--- /dev/null
+++ b/contrib/lo/sql/lo.sql
@@ -0,0 +1,25 @@
+CREATE EXTENSION lo;
+
+CREATE TABLE image (title text, raster lo);
+
+CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
+    FOR EACH ROW EXECUTE PROCEDURE lo_manage(raster);
+
+SELECT lo_create(43213);
+SELECT lo_create(43214);
+
+INSERT INTO image (title, raster) VALUES ('beautiful image', 43213);
+
+SELECT lo_get(43213);
+SELECT lo_get(43214);
+
+UPDATE image SET raster = 43214 WHERE title = 'beautiful image';
+
+SELECT lo_get(43213);
+SELECT lo_get(43214);
+
+DELETE FROM image;
+
+SELECT lo_get(43214);
+
+DROP TABLE image;
diff --git a/doc/src/sgml/lo.sgml b/doc/src/sgml/lo.sgml
index cd4ed6030b..9c318f1c98 100644
--- a/doc/src/sgml/lo.sgml
+++ b/doc/src/sgml/lo.sgml
@@ -67,7 +67,7 @@ <title>How to Use It</title>
   </para>
 
 <programlisting>
-CREATE TABLE image (title TEXT, raster lo);
+CREATE TABLE image (title text, raster lo);
 
 CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
     FOR EACH ROW EXECUTE PROCEDURE lo_manage(raster);
-- 
2.14.0

0004-chkpass-Add-test-suite.patchtext/plain; charset=UTF-8; name=0004-chkpass-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From 1d05800b4ecfc408ff3cb64fc95b78e24f044366 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH 4/7] chkpass: Add test suite

---
 contrib/chkpass/.gitignore           |  4 ++++
 contrib/chkpass/Makefile             |  2 ++
 contrib/chkpass/expected/chkpass.out | 18 ++++++++++++++++++
 contrib/chkpass/sql/chkpass.sql      |  7 +++++++
 4 files changed, 31 insertions(+)
 create mode 100644 contrib/chkpass/.gitignore
 create mode 100644 contrib/chkpass/expected/chkpass.out
 create mode 100644 contrib/chkpass/sql/chkpass.sql

diff --git a/contrib/chkpass/.gitignore b/contrib/chkpass/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/chkpass/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/chkpass/Makefile b/contrib/chkpass/Makefile
index a2599ea239..dbecc3360b 100644
--- a/contrib/chkpass/Makefile
+++ b/contrib/chkpass/Makefile
@@ -9,6 +9,8 @@ PGFILEDESC = "chkpass - encrypted password data type"
 
 SHLIB_LINK = $(filter -lcrypt, $(LIBS))
 
+REGRESS = chkpass
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/chkpass/expected/chkpass.out b/contrib/chkpass/expected/chkpass.out
new file mode 100644
index 0000000000..b53557bf2a
--- /dev/null
+++ b/contrib/chkpass/expected/chkpass.out
@@ -0,0 +1,18 @@
+CREATE EXTENSION chkpass;
+WARNING:  type input function chkpass_in should not be volatile
+CREATE TABLE test (i int, p chkpass);
+INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+SELECT i, p = 'hello' AS "hello?" FROM test;
+ i | hello? 
+---+--------
+ 1 | t
+ 2 | f
+(2 rows)
+
+SELECT i, p <> 'hello' AS "!hello?" FROM test;
+ i | !hello? 
+---+---------
+ 1 | f
+ 2 | t
+(2 rows)
+
diff --git a/contrib/chkpass/sql/chkpass.sql b/contrib/chkpass/sql/chkpass.sql
new file mode 100644
index 0000000000..595683e249
--- /dev/null
+++ b/contrib/chkpass/sql/chkpass.sql
@@ -0,0 +1,7 @@
+CREATE EXTENSION chkpass;
+
+CREATE TABLE test (i int, p chkpass);
+INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+
+SELECT i, p = 'hello' AS "hello?" FROM test;
+SELECT i, p <> 'hello' AS "!hello?" FROM test;
-- 
2.14.0

0005-passwordcheck-Add-test-suite.patchtext/plain; charset=UTF-8; name=0005-passwordcheck-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From 2a52489036fd336a8a9219cf27357c9ecf318d12 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH 5/7] passwordcheck: Add test suite

Also improve one error message.
---
 contrib/passwordcheck/.gitignore                 |  4 ++++
 contrib/passwordcheck/Makefile                   |  5 +++++
 contrib/passwordcheck/expected/passwordcheck.out | 18 ++++++++++++++++++
 contrib/passwordcheck/passwordcheck.c            |  2 +-
 contrib/passwordcheck/passwordcheck.conf         |  1 +
 contrib/passwordcheck/sql/passwordcheck.sql      | 21 +++++++++++++++++++++
 6 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 contrib/passwordcheck/.gitignore
 create mode 100644 contrib/passwordcheck/expected/passwordcheck.out
 create mode 100644 contrib/passwordcheck/passwordcheck.conf
 create mode 100644 contrib/passwordcheck/sql/passwordcheck.sql

diff --git a/contrib/passwordcheck/.gitignore b/contrib/passwordcheck/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/passwordcheck/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/passwordcheck/Makefile b/contrib/passwordcheck/Makefile
index 4652aeb3d7..7edc968b90 100644
--- a/contrib/passwordcheck/Makefile
+++ b/contrib/passwordcheck/Makefile
@@ -8,6 +8,11 @@ PGFILEDESC = "passwordcheck - strengthen user password checks"
 # PG_CPPFLAGS = -DUSE_CRACKLIB '-DCRACKLIB_DICTPATH="/usr/lib/cracklib_dict"'
 # SHLIB_LINK = -lcrack
 
+REGRESS_OPTS = --temp-config $(srcdir)/passwordcheck.conf
+REGRESS = passwordcheck
+# disabled because these tests require setting shared_preload_libraries
+NO_INSTALLCHECK = 1
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/passwordcheck/expected/passwordcheck.out b/contrib/passwordcheck/expected/passwordcheck.out
new file mode 100644
index 0000000000..b3515df3e8
--- /dev/null
+++ b/contrib/passwordcheck/expected/passwordcheck.out
@@ -0,0 +1,18 @@
+CREATE USER regress_user1;
+-- ok
+ALTER USER regress_user1 PASSWORD 'a_nice_long_password';
+-- error: too short
+ALTER USER regress_user1 PASSWORD 'tooshrt';
+ERROR:  password is too short
+-- error: contains user name
+ALTER USER regress_user1 PASSWORD 'xyzregress_user1';
+ERROR:  password must not contain user name
+-- error: contains only letters
+ALTER USER regress_user1 PASSWORD 'alessnicelongpassword';
+ERROR:  password must contain both letters and nonletters
+-- encrypted ok (password is "secret")
+ALTER USER regress_user1 PASSWORD 'md51a44d829a20a23eac686d9f0d258af13';
+-- error: password is user name
+ALTER USER regress_user1 PASSWORD 'md5e589150ae7d28f93333afae92b36ef48';
+ERROR:  password must not equal user name
+DROP USER regress_user1;
diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c
index b80fd458ad..64d43462f0 100644
--- a/contrib/passwordcheck/passwordcheck.c
+++ b/contrib/passwordcheck/passwordcheck.c
@@ -70,7 +70,7 @@ check_password(const char *username,
 		if (plain_crypt_verify(username, shadow_pass, username, &logdetail) == STATUS_OK)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-					 errmsg("password must not contain user name")));
+					 errmsg("password must not equal user name")));
 	}
 	else
 	{
diff --git a/contrib/passwordcheck/passwordcheck.conf b/contrib/passwordcheck/passwordcheck.conf
new file mode 100644
index 0000000000..f6604f3d6b
--- /dev/null
+++ b/contrib/passwordcheck/passwordcheck.conf
@@ -0,0 +1 @@
+shared_preload_libraries = 'passwordcheck'
diff --git a/contrib/passwordcheck/sql/passwordcheck.sql b/contrib/passwordcheck/sql/passwordcheck.sql
new file mode 100644
index 0000000000..59c84f522e
--- /dev/null
+++ b/contrib/passwordcheck/sql/passwordcheck.sql
@@ -0,0 +1,21 @@
+CREATE USER regress_user1;
+
+-- ok
+ALTER USER regress_user1 PASSWORD 'a_nice_long_password';
+
+-- error: too short
+ALTER USER regress_user1 PASSWORD 'tooshrt';
+
+-- error: contains user name
+ALTER USER regress_user1 PASSWORD 'xyzregress_user1';
+
+-- error: contains only letters
+ALTER USER regress_user1 PASSWORD 'alessnicelongpassword';
+
+-- encrypted ok (password is "secret")
+ALTER USER regress_user1 PASSWORD 'md51a44d829a20a23eac686d9f0d258af13';
+
+-- error: password is user name
+ALTER USER regress_user1 PASSWORD 'md5e589150ae7d28f93333afae92b36ef48';
+
+DROP USER regress_user1;
-- 
2.14.0

0006-pg_archivecleanup-Add-test-suite.patchtext/plain; charset=UTF-8; name=0006-pg_archivecleanup-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From b40be6c497bf0410bb3103467998973dd060a494 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH 6/7] pg_archivecleanup: Add test suite

---
 src/bin/pg_archivecleanup/.gitignore               |  2 +
 src/bin/pg_archivecleanup/Makefile                 |  7 ++
 .../pg_archivecleanup/t/010_pg_archivecleanup.pl   | 81 ++++++++++++++++++++++
 3 files changed, 90 insertions(+)
 create mode 100644 src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl

diff --git a/src/bin/pg_archivecleanup/.gitignore b/src/bin/pg_archivecleanup/.gitignore
index 804089070d..bd05d00156 100644
--- a/src/bin/pg_archivecleanup/.gitignore
+++ b/src/bin/pg_archivecleanup/.gitignore
@@ -1 +1,3 @@
 /pg_archivecleanup
+
+/tmp_check/
diff --git a/src/bin/pg_archivecleanup/Makefile b/src/bin/pg_archivecleanup/Makefile
index 5bda78490c..c5bf99db0f 100644
--- a/src/bin/pg_archivecleanup/Makefile
+++ b/src/bin/pg_archivecleanup/Makefile
@@ -25,3 +25,10 @@ uninstall:
 
 clean distclean maintainer-clean:
 	rm -f pg_archivecleanup$(X) $(OBJS)
+	rm -rf tmp_check
+
+check:
+	$(prove_check)
+
+installcheck:
+	$(prove_installcheck)
diff --git a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
new file mode 100644
index 0000000000..c0a2e38cc9
--- /dev/null
+++ b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
@@ -0,0 +1,81 @@
+use strict;
+use warnings;
+use TestLib;
+use Test::More tests => 42;
+
+program_help_ok('pg_archivecleanup');
+program_version_ok('pg_archivecleanup');
+program_options_handling_ok('pg_archivecleanup');
+
+my $tempdir = TestLib::tempdir;
+
+my @walfiles = (
+	'00000001000000370000000C.gz',
+	'00000001000000370000000D',
+	'00000001000000370000000E',
+	'00000001000000370000000F.partial',
+);
+
+sub create_files
+{
+	foreach my $fn (@walfiles, 'unrelated_file')
+	{
+		open my $file, '>', "$tempdir/$fn";
+		print $file 'CONTENT';
+		close $file;
+	}
+}
+
+create_files();
+
+command_fails_like(['pg_archivecleanup'],
+				   qr/must specify archive location/,
+				   'fails if archive location is not specified');
+
+command_fails_like(['pg_archivecleanup', $tempdir],
+				   qr/must specify restartfilename/,
+				   'fails if restart file name is not specified');
+
+command_fails_like(['pg_archivecleanup', 'notexist', 'foo'],
+				   qr/archive location .* does not exist/,
+				   'fails if archive location does not exist');
+
+command_fails_like(['pg_archivecleanup', $tempdir, 'foo', 'bar'],
+				   qr/too many parameters/,
+				   'fails with too many parameters');
+
+command_fails_like(['pg_archivecleanup', $tempdir, 'foo'],
+				   qr/invalid filename/,
+				   'fails with invalid restart file name');
+
+{
+	# like command_like but checking stderr
+	my $stderr;
+	my $result = IPC::Run::run ['pg_archivecleanup', '-d', '-n', $tempdir, $walfiles[2]], '2>', \$stderr;
+	ok($result, "pg_archivecleanup dry run: exit code 0");
+	like($stderr, qr/$walfiles[1].*would be removed/, "pg_archivecleanup dry run: matches");
+	foreach my $fn (@walfiles)
+	{
+		ok(-f "$tempdir/$fn", "$fn not removed");
+	}
+}
+
+sub run_check
+{
+	my ($suffix, $test_name) = @_;
+
+	create_files();
+
+	command_ok(['pg_archivecleanup', '-x', '.gz', $tempdir, $walfiles[2] . $suffix],
+			   "$test_name: runs");
+
+	ok(! -f "$tempdir/$walfiles[0]", "$test_name: first older WAL file was cleaned up");
+	ok(! -f "$tempdir/$walfiles[1]", "$test_name: second older WAL file was cleaned up");
+	ok(-f "$tempdir/$walfiles[2]", "$test_name: restartfile was not cleaned up");
+	ok(-f "$tempdir/$walfiles[3]", "$test_name: newer WAL file was not cleaned up");
+	ok(-f "$tempdir/unrelated_file", "$test_name: unrelated file was not cleaned up");
+}
+
+run_check('', 'pg_archivecleanup');
+run_check('.partial', 'pg_archivecleanup with .partial file');
+run_check('.00000020.backup', 'pg_archivecleanup with .backup file');
-- 
2.14.0

0007-isn-Fix-debug-code.patchtext/plain; charset=UTF-8; name=0007-isn-Fix-debug-code.patch; x-mac-creator=0; x-mac-type=0Download
From 278a08c56e9bbee9034867cfb0e8f26bce5ae8ee Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH 7/7] isn: Fix debug code

The ISN_DEBUG code did not compile.  Fix that code, don't hide it behind
an #ifdef, make it run when building with asserts, and make it error out
instead of just logging if it fails.
---
 contrib/isn/isn.c | 41 +++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/contrib/isn/isn.c b/contrib/isn/isn.c
index 4d845b716f..0148f9549f 100644
--- a/contrib/isn/isn.c
+++ b/contrib/isn/isn.c
@@ -26,6 +26,12 @@
 
 PG_MODULE_MAGIC;
 
+#ifdef USE_ASSERT_CHECKING
+#define ISN_DEBUG 1
+#else
+#define ISN_DEBUG 0
+#endif
+
 #define MAXEAN13LEN 18
 
 enum isn_type
@@ -36,7 +42,6 @@ enum isn_type
 static const char *const isn_names[] = {"EAN13/UPC/ISxN", "EAN13/UPC/ISxN", "EAN13", "ISBN", "ISMN", "ISSN", "UPC"};
 
 static bool g_weak = false;
-static bool g_initialized = false;
 
 
 /***********************************************************************
@@ -56,7 +61,7 @@ static bool g_initialized = false;
 /*
  * Check if the table and its index is correct (just for debugging)
  */
-#ifdef ISN_DEBUG
+pg_attribute_unused()
 static bool
 check_table(const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
 {
@@ -68,7 +73,6 @@ check_table(const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
 				y = -1,
 				i = 0,
 				j,
-				cnt = 0,
 				init = 0;
 
 	if (TABLE == NULL || TABLE_index == NULL)
@@ -131,7 +135,6 @@ check_table(const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
 	elog(DEBUG1, "index %d is invalid", j);
 	return false;
 }
-#endif							/* ISN_DEBUG */
 
 /*----------------------------------------------------------
  * Formatting and conversion routines.
@@ -922,22 +925,24 @@ string2ean(const char *str, bool errorOK, ean13 *result,
  * Exported routines.
  *---------------------------------------------------------*/
 
+void _PG_init(void);
+
 void
-initialize(void)
+_PG_init(void)
 {
-#ifdef ISN_DEBUG
-	if (!check_table(EAN13, EAN13_index))
-		elog(LOG, "EAN13 failed check");
-	if (!check_table(ISBN, ISBN_index))
-		elog(LOG, "ISBN failed check");
-	if (!check_table(ISMN, ISMN_index))
-		elog(LOG, "ISMN failed check");
-	if (!check_table(ISSN, ISSN_index))
-		elog(LOG, "ISSN failed check");
-	if (!check_table(UPC, UPC_index))
-		elog(LOG, "UPC failed check");
-#endif
-	g_initialized = true;
+	if (ISN_DEBUG)
+	{
+		if (!check_table(EAN13_range, EAN13_index))
+			elog(ERROR, "EAN13 failed check");
+		if (!check_table(ISBN_range, ISBN_index))
+			elog(ERROR, "ISBN failed check");
+		if (!check_table(ISMN_range, ISMN_index))
+			elog(ERROR, "ISMN failed check");
+		if (!check_table(ISSN_range, ISSN_index))
+			elog(ERROR, "ISSN failed check");
+		if (!check_table(UPC_range, UPC_index))
+			elog(ERROR, "UPC failed check");
+	}
 }
 
 /* isn_out
-- 
2.14.0

#2Thomas Munro
thomas.munro@enterprisedb.com
In reply to: Peter Eisentraut (#1)
Re: additional contrib test suites

On Sat, Aug 12, 2017 at 1:20 PM, Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:

Here are some small test suites for some contrib modules as well as
pg_archivecleanup that didn't have one previously, as well as one patch
to improve code coverage in a module.

Will add to commit fest. Testing on different platforms and with
different build configurations would be useful.

After applying these patches cleanly on top of
0b554e4e63a4ba4852c01951311713e23acdae02 and running "./configure
--enable-tap-tests --with-tcl --with-python --with-perl --with-ldap
--with-icu && make && make check-world" I saw this failure:

cd . && TESTDIR='/home/travis/build/postgresql-cfbot/postgresql/src/bin/pg_archivecleanup'
PATH="/home/travis/build/postgresql-cfbot/postgresql/tmp_install/usr/local/pgsql/bin:$PATH"
LD_LIBRARY_PATH="/home/travis/build/postgresql-cfbot/postgresql/tmp_install/usr/local/pgsql/lib"
PGPORT='65432' PG_REGRESS='/home/travis/build/postgresql-cfbot/postgresql/src/bin/pg_archivecleanup/../../../src/test/regress/pg_regress'
/usr/bin/prove -I ../../../src/test/perl/ -I . t/*.pl
t/010_pg_archivecleanup.pl .. 1/42
# Failed test 'fails if restart file name is not specified: matches'
# at /home/travis/build/postgresql-cfbot/postgresql/src/bin/pg_archivecleanup/../../../src/test/perl/TestLib.pm
line 330.
# 'pg_archivecleanup: must specify oldest kept WAL file
# Try "pg_archivecleanup --help" for more information.
# '
# doesn't match '(?^:must specify restartfilename)'
# Failed test 'fails with too many parameters: matches'
# at /home/travis/build/postgresql-cfbot/postgresql/src/bin/pg_archivecleanup/../../../src/test/perl/TestLib.pm
line 330.
# 'pg_archivecleanup: too many command-line arguments
# Try "pg_archivecleanup --help" for more information.
# '
# doesn't match '(?^:too many parameters)'
# Failed test 'fails with invalid restart file name: matches'
# at /home/travis/build/postgresql-cfbot/postgresql/src/bin/pg_archivecleanup/../../../src/test/perl/TestLib.pm
line 330.
# 'pg_archivecleanup: invalid file name argument
# Try "pg_archivecleanup --help" for more information.
# '
# doesn't match '(?^:invalid filename)'
# Looks like you failed 3 tests of 42.
t/010_pg_archivecleanup.pl .. Dubious, test returned 3 (wstat 768, 0x300)
Failed 3/42 subtests
Test Summary Report
-------------------
t/010_pg_archivecleanup.pl (Wstat: 768 Tests: 42 Failed: 3)
Failed tests: 12, 16, 18
Non-zero exit status: 3
Files=1, Tests=42, 0 wallclock secs ( 0.03 usr 0.00 sys + 0.05 cusr
0.00 csys = 0.08 CPU)
Result: FAIL

--
Thomas Munro
http://www.enterprisedb.com

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Thomas Munro (#2)
7 attachment(s)
Re: additional contrib test suites

On 9/6/17 07:11, Thomas Munro wrote:

After applying these patches cleanly on top of
0b554e4e63a4ba4852c01951311713e23acdae02 and running "./configure
--enable-tap-tests --with-tcl --with-python --with-perl --with-ldap
--with-icu && make && make check-world" I saw this failure:

Yes, some of the error messages had changed. Fixed patches attached.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

v2-0001-adminpack-Add-test-suite.patchtext/plain; charset=UTF-8; name=v2-0001-adminpack-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From bd790a0125729edd44e3d70fba325d3bfcf6da94 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH v2 1/7] adminpack: Add test suite

---
 contrib/adminpack/.gitignore             |   4 +
 contrib/adminpack/Makefile               |   2 +
 contrib/adminpack/expected/adminpack.out | 144 +++++++++++++++++++++++++++++++
 contrib/adminpack/sql/adminpack.sql      |  56 ++++++++++++
 4 files changed, 206 insertions(+)
 create mode 100644 contrib/adminpack/.gitignore
 create mode 100644 contrib/adminpack/expected/adminpack.out
 create mode 100644 contrib/adminpack/sql/adminpack.sql

diff --git a/contrib/adminpack/.gitignore b/contrib/adminpack/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/adminpack/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/adminpack/Makefile b/contrib/adminpack/Makefile
index f065f84bfb..89c249bc0d 100644
--- a/contrib/adminpack/Makefile
+++ b/contrib/adminpack/Makefile
@@ -8,6 +8,8 @@ EXTENSION = adminpack
 DATA = adminpack--1.0.sql
 PGFILEDESC = "adminpack - support functions for pgAdmin"
 
+REGRESS = adminpack
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/adminpack/expected/adminpack.out b/contrib/adminpack/expected/adminpack.out
new file mode 100644
index 0000000000..83cbb741da
--- /dev/null
+++ b/contrib/adminpack/expected/adminpack.out
@@ -0,0 +1,144 @@
+CREATE EXTENSION adminpack;
+-- create new file
+SELECT pg_file_write('test_file1', 'test1', false);
+ pg_file_write 
+---------------
+             5
+(1 row)
+
+SELECT pg_read_file('test_file1');
+ pg_read_file 
+--------------
+ test1
+(1 row)
+
+-- append
+SELECT pg_file_write('test_file1', 'test1', true);
+ pg_file_write 
+---------------
+             5
+(1 row)
+
+SELECT pg_read_file('test_file1');
+ pg_read_file 
+--------------
+ test1test1
+(1 row)
+
+-- error, already exists
+SELECT pg_file_write('test_file1', 'test1', false);
+ERROR:  file "test_file1" exists
+SELECT pg_read_file('test_file1');
+ pg_read_file 
+--------------
+ test1test1
+(1 row)
+
+-- disallowed file paths
+SELECT pg_file_write('../test_file0', 'test0', false);
+ERROR:  path must be in or below the current directory
+SELECT pg_file_write('/tmp/test_file0', 'test0', false);
+ERROR:  absolute path not allowed
+SELECT pg_file_write(current_setting('data_directory') || '/test_file4', 'test4', false);
+ pg_file_write 
+---------------
+             5
+(1 row)
+
+SELECT pg_file_write(current_setting('data_directory') || '/../test_file4', 'test4', false);
+ERROR:  reference to parent directory ("..") not allowed
+-- rename file
+SELECT pg_file_rename('test_file1', 'test_file2');
+ pg_file_rename 
+----------------
+ t
+(1 row)
+
+SELECT pg_read_file('test_file1');  -- not there
+ERROR:  could not stat file "test_file1": No such file or directory
+SELECT pg_read_file('test_file2');
+ pg_read_file 
+--------------
+ test1test1
+(1 row)
+
+-- error
+SELECT pg_file_rename('test_file1', 'test_file2');
+WARNING:  file "test_file1" is not accessible: No such file or directory
+ pg_file_rename 
+----------------
+ f
+(1 row)
+
+-- rename file and archive
+SELECT pg_file_write('test_file3', 'test3', false);
+ pg_file_write 
+---------------
+             5
+(1 row)
+
+SELECT pg_file_rename('test_file2', 'test_file3', 'test_file3_archive');
+ pg_file_rename 
+----------------
+ t
+(1 row)
+
+SELECT pg_read_file('test_file2');  -- not there
+ERROR:  could not stat file "test_file2": No such file or directory
+SELECT pg_read_file('test_file3');
+ pg_read_file 
+--------------
+ test1test1
+(1 row)
+
+SELECT pg_read_file('test_file3_archive');
+ pg_read_file 
+--------------
+ test3
+(1 row)
+
+-- unlink
+SELECT pg_file_unlink('test_file1');  -- does not exist
+ pg_file_unlink 
+----------------
+ f
+(1 row)
+
+SELECT pg_file_unlink('test_file2');  -- does not exist
+ pg_file_unlink 
+----------------
+ f
+(1 row)
+
+SELECT pg_file_unlink('test_file3');
+ pg_file_unlink 
+----------------
+ t
+(1 row)
+
+SELECT pg_file_unlink('test_file3_archive');
+ pg_file_unlink 
+----------------
+ t
+(1 row)
+
+SELECT pg_file_unlink('test_file4');
+ pg_file_unlink 
+----------------
+ t
+(1 row)
+
+-- superuser checks
+CREATE USER regress_user1;
+SET ROLE regress_user1;
+SELECT pg_file_write('test_file0', 'test0', false);
+ERROR:  only superuser may access generic file functions
+SELECT pg_file_rename('test_file0', 'test_file0');
+ERROR:  only superuser may access generic file functions
+CONTEXT:  SQL function "pg_file_rename" statement 1
+SELECT pg_file_unlink('test_file0');
+ERROR:  only superuser may access generic file functions
+SELECT pg_logdir_ls();
+ERROR:  only superuser can list the log directory
+RESET ROLE;
+DROP USER regress_user1;
diff --git a/contrib/adminpack/sql/adminpack.sql b/contrib/adminpack/sql/adminpack.sql
new file mode 100644
index 0000000000..d29b2468b6
--- /dev/null
+++ b/contrib/adminpack/sql/adminpack.sql
@@ -0,0 +1,56 @@
+CREATE EXTENSION adminpack;
+
+-- create new file
+SELECT pg_file_write('test_file1', 'test1', false);
+SELECT pg_read_file('test_file1');
+
+-- append
+SELECT pg_file_write('test_file1', 'test1', true);
+SELECT pg_read_file('test_file1');
+
+-- error, already exists
+SELECT pg_file_write('test_file1', 'test1', false);
+SELECT pg_read_file('test_file1');
+
+-- disallowed file paths
+SELECT pg_file_write('../test_file0', 'test0', false);
+SELECT pg_file_write('/tmp/test_file0', 'test0', false);
+SELECT pg_file_write(current_setting('data_directory') || '/test_file4', 'test4', false);
+SELECT pg_file_write(current_setting('data_directory') || '/../test_file4', 'test4', false);
+
+
+-- rename file
+SELECT pg_file_rename('test_file1', 'test_file2');
+SELECT pg_read_file('test_file1');  -- not there
+SELECT pg_read_file('test_file2');
+
+-- error
+SELECT pg_file_rename('test_file1', 'test_file2');
+
+-- rename file and archive
+SELECT pg_file_write('test_file3', 'test3', false);
+SELECT pg_file_rename('test_file2', 'test_file3', 'test_file3_archive');
+SELECT pg_read_file('test_file2');  -- not there
+SELECT pg_read_file('test_file3');
+SELECT pg_read_file('test_file3_archive');
+
+
+-- unlink
+SELECT pg_file_unlink('test_file1');  -- does not exist
+SELECT pg_file_unlink('test_file2');  -- does not exist
+SELECT pg_file_unlink('test_file3');
+SELECT pg_file_unlink('test_file3_archive');
+SELECT pg_file_unlink('test_file4');
+
+
+-- superuser checks
+CREATE USER regress_user1;
+SET ROLE regress_user1;
+
+SELECT pg_file_write('test_file0', 'test0', false);
+SELECT pg_file_rename('test_file0', 'test_file0');
+SELECT pg_file_unlink('test_file0');
+SELECT pg_logdir_ls();
+
+RESET ROLE;
+DROP USER regress_user1;

base-commit: ee24d2b5cf059cab83711992c0cf110ad44df5f9
-- 
2.11.0 (Apple Git-81)

v2-0002-fuzzystrmatch-Add-test-suite.patchtext/plain; charset=UTF-8; name=v2-0002-fuzzystrmatch-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From b61083dc628dd59c08fda3d13f359a782f8b7e25 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH v2 2/7] fuzzystrmatch: Add test suite

---
 contrib/fuzzystrmatch/.gitignore                 |  4 ++
 contrib/fuzzystrmatch/Makefile                   |  2 +
 contrib/fuzzystrmatch/expected/fuzzystrmatch.out | 67 ++++++++++++++++++++++++
 contrib/fuzzystrmatch/sql/fuzzystrmatch.sql      | 21 ++++++++
 doc/src/sgml/fuzzystrmatch.sgml                  |  8 +--
 5 files changed, 98 insertions(+), 4 deletions(-)
 create mode 100644 contrib/fuzzystrmatch/.gitignore
 create mode 100644 contrib/fuzzystrmatch/expected/fuzzystrmatch.out
 create mode 100644 contrib/fuzzystrmatch/sql/fuzzystrmatch.sql

diff --git a/contrib/fuzzystrmatch/.gitignore b/contrib/fuzzystrmatch/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/fuzzystrmatch/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/fuzzystrmatch/Makefile b/contrib/fuzzystrmatch/Makefile
index 51e215a919..bd6f5e50d1 100644
--- a/contrib/fuzzystrmatch/Makefile
+++ b/contrib/fuzzystrmatch/Makefile
@@ -8,6 +8,8 @@ DATA = fuzzystrmatch--1.1.sql fuzzystrmatch--1.0--1.1.sql \
 	fuzzystrmatch--unpackaged--1.0.sql
 PGFILEDESC = "fuzzystrmatch - similarities and distance between strings"
 
+REGRESS = fuzzystrmatch
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/fuzzystrmatch/expected/fuzzystrmatch.out b/contrib/fuzzystrmatch/expected/fuzzystrmatch.out
new file mode 100644
index 0000000000..493c95cdfa
--- /dev/null
+++ b/contrib/fuzzystrmatch/expected/fuzzystrmatch.out
@@ -0,0 +1,67 @@
+CREATE EXTENSION fuzzystrmatch;
+SELECT soundex('hello world!');
+ soundex 
+---------
+ H464
+(1 row)
+
+SELECT soundex('Anne'), soundex('Ann'), difference('Anne', 'Ann');
+ soundex | soundex | difference 
+---------+---------+------------
+ A500    | A500    |          4
+(1 row)
+
+SELECT soundex('Anne'), soundex('Andrew'), difference('Anne', 'Andrew');
+ soundex | soundex | difference 
+---------+---------+------------
+ A500    | A536    |          2
+(1 row)
+
+SELECT soundex('Anne'), soundex('Margaret'), difference('Anne', 'Margaret');
+ soundex | soundex | difference 
+---------+---------+------------
+ A500    | M626    |          0
+(1 row)
+
+SELECT levenshtein('GUMBO', 'GAMBOL');
+ levenshtein 
+-------------
+           2
+(1 row)
+
+SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1);
+ levenshtein 
+-------------
+           3
+(1 row)
+
+SELECT levenshtein_less_equal('extensive', 'exhaustive', 2);
+ levenshtein_less_equal 
+------------------------
+                      3
+(1 row)
+
+SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
+ levenshtein_less_equal 
+------------------------
+                      4
+(1 row)
+
+SELECT metaphone('GUMBO', 4);
+ metaphone 
+-----------
+ KM
+(1 row)
+
+SELECT dmetaphone('gumbo');
+ dmetaphone 
+------------
+ KMP
+(1 row)
+
+SELECT dmetaphone_alt('gumbo');
+ dmetaphone_alt 
+----------------
+ KMP
+(1 row)
+
diff --git a/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql b/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql
new file mode 100644
index 0000000000..f05dc28ffb
--- /dev/null
+++ b/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql
@@ -0,0 +1,21 @@
+CREATE EXTENSION fuzzystrmatch;
+
+
+SELECT soundex('hello world!');
+
+SELECT soundex('Anne'), soundex('Ann'), difference('Anne', 'Ann');
+SELECT soundex('Anne'), soundex('Andrew'), difference('Anne', 'Andrew');
+SELECT soundex('Anne'), soundex('Margaret'), difference('Anne', 'Margaret');
+
+
+SELECT levenshtein('GUMBO', 'GAMBOL');
+SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1);
+SELECT levenshtein_less_equal('extensive', 'exhaustive', 2);
+SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
+
+
+SELECT metaphone('GUMBO', 4);
+
+
+SELECT dmetaphone('gumbo');
+SELECT dmetaphone_alt('gumbo');
diff --git a/doc/src/sgml/fuzzystrmatch.sgml b/doc/src/sgml/fuzzystrmatch.sgml
index feb06861da..ff5bc08fea 100644
--- a/doc/src/sgml/fuzzystrmatch.sgml
+++ b/doc/src/sgml/fuzzystrmatch.sgml
@@ -133,19 +133,19 @@ <title>Levenshtein</title>
            2
 (1 row)
 
-test=# SELECT levenshtein('GUMBO', 'GAMBOL', 2,1,1);
+test=# SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1);
  levenshtein
 -------------
            3
 (1 row)
 
-test=# SELECT levenshtein_less_equal('extensive', 'exhaustive',2);
+test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 2);
  levenshtein_less_equal
 ------------------------
                       3
 (1 row)
 
-test=# SELECT levenshtein_less_equal('extensive', 'exhaustive',4);
+test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
  levenshtein_less_equal
 ------------------------
                       4
@@ -227,7 +227,7 @@ <title>Double Metaphone</title>
   </para>
 
 <screen>
-test=# select dmetaphone('gumbo');
+test=# SELECT dmetaphone('gumbo');
  dmetaphone
 ------------
  KMP
-- 
2.11.0 (Apple Git-81)

v2-0003-lo-Add-test-suite.patchtext/plain; charset=UTF-8; name=v2-0003-lo-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From 55c4c687867d4b074538dcbb0dbb5f067113ec53 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH v2 3/7] lo: Add test suite

---
 contrib/lo/.gitignore      |  4 ++++
 contrib/lo/Makefile        |  2 ++
 contrib/lo/expected/lo.out | 42 ++++++++++++++++++++++++++++++++++++++++++
 contrib/lo/sql/lo.sql      | 25 +++++++++++++++++++++++++
 doc/src/sgml/lo.sgml       |  2 +-
 5 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 contrib/lo/.gitignore
 create mode 100644 contrib/lo/expected/lo.out
 create mode 100644 contrib/lo/sql/lo.sql

diff --git a/contrib/lo/.gitignore b/contrib/lo/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/lo/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/lo/Makefile b/contrib/lo/Makefile
index 71f0cb0d24..bd4fd6b72d 100644
--- a/contrib/lo/Makefile
+++ b/contrib/lo/Makefile
@@ -6,6 +6,8 @@ EXTENSION = lo
 DATA = lo--1.1.sql lo--1.0--1.1.sql lo--unpackaged--1.0.sql
 PGFILEDESC = "lo - management for large objects"
 
+REGRESS = lo
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/lo/expected/lo.out b/contrib/lo/expected/lo.out
new file mode 100644
index 0000000000..f7104aee3f
--- /dev/null
+++ b/contrib/lo/expected/lo.out
@@ -0,0 +1,42 @@
+CREATE EXTENSION lo;
+CREATE TABLE image (title text, raster lo);
+CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
+    FOR EACH ROW EXECUTE PROCEDURE lo_manage(raster);
+SELECT lo_create(43213);
+ lo_create 
+-----------
+     43213
+(1 row)
+
+SELECT lo_create(43214);
+ lo_create 
+-----------
+     43214
+(1 row)
+
+INSERT INTO image (title, raster) VALUES ('beautiful image', 43213);
+SELECT lo_get(43213);
+ lo_get 
+--------
+ \x
+(1 row)
+
+SELECT lo_get(43214);
+ lo_get 
+--------
+ \x
+(1 row)
+
+UPDATE image SET raster = 43214 WHERE title = 'beautiful image';
+SELECT lo_get(43213);
+ERROR:  large object 43213 does not exist
+SELECT lo_get(43214);
+ lo_get 
+--------
+ \x
+(1 row)
+
+DELETE FROM image;
+SELECT lo_get(43214);
+ERROR:  large object 43214 does not exist
+DROP TABLE image;
diff --git a/contrib/lo/sql/lo.sql b/contrib/lo/sql/lo.sql
new file mode 100644
index 0000000000..34ba6f00ec
--- /dev/null
+++ b/contrib/lo/sql/lo.sql
@@ -0,0 +1,25 @@
+CREATE EXTENSION lo;
+
+CREATE TABLE image (title text, raster lo);
+
+CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
+    FOR EACH ROW EXECUTE PROCEDURE lo_manage(raster);
+
+SELECT lo_create(43213);
+SELECT lo_create(43214);
+
+INSERT INTO image (title, raster) VALUES ('beautiful image', 43213);
+
+SELECT lo_get(43213);
+SELECT lo_get(43214);
+
+UPDATE image SET raster = 43214 WHERE title = 'beautiful image';
+
+SELECT lo_get(43213);
+SELECT lo_get(43214);
+
+DELETE FROM image;
+
+SELECT lo_get(43214);
+
+DROP TABLE image;
diff --git a/doc/src/sgml/lo.sgml b/doc/src/sgml/lo.sgml
index cd4ed6030b..9c318f1c98 100644
--- a/doc/src/sgml/lo.sgml
+++ b/doc/src/sgml/lo.sgml
@@ -67,7 +67,7 @@ <title>How to Use It</title>
   </para>
 
 <programlisting>
-CREATE TABLE image (title TEXT, raster lo);
+CREATE TABLE image (title text, raster lo);
 
 CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
     FOR EACH ROW EXECUTE PROCEDURE lo_manage(raster);
-- 
2.11.0 (Apple Git-81)

v2-0004-chkpass-Add-test-suite.patchtext/plain; charset=UTF-8; name=v2-0004-chkpass-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From 3da0ac8b112ffc24a70c8cd5aff8b17743213732 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH v2 4/7] chkpass: Add test suite

---
 contrib/chkpass/.gitignore           |  4 ++++
 contrib/chkpass/Makefile             |  2 ++
 contrib/chkpass/expected/chkpass.out | 18 ++++++++++++++++++
 contrib/chkpass/sql/chkpass.sql      |  7 +++++++
 4 files changed, 31 insertions(+)
 create mode 100644 contrib/chkpass/.gitignore
 create mode 100644 contrib/chkpass/expected/chkpass.out
 create mode 100644 contrib/chkpass/sql/chkpass.sql

diff --git a/contrib/chkpass/.gitignore b/contrib/chkpass/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/chkpass/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/chkpass/Makefile b/contrib/chkpass/Makefile
index a2599ea239..dbecc3360b 100644
--- a/contrib/chkpass/Makefile
+++ b/contrib/chkpass/Makefile
@@ -9,6 +9,8 @@ PGFILEDESC = "chkpass - encrypted password data type"
 
 SHLIB_LINK = $(filter -lcrypt, $(LIBS))
 
+REGRESS = chkpass
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/chkpass/expected/chkpass.out b/contrib/chkpass/expected/chkpass.out
new file mode 100644
index 0000000000..b53557bf2a
--- /dev/null
+++ b/contrib/chkpass/expected/chkpass.out
@@ -0,0 +1,18 @@
+CREATE EXTENSION chkpass;
+WARNING:  type input function chkpass_in should not be volatile
+CREATE TABLE test (i int, p chkpass);
+INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+SELECT i, p = 'hello' AS "hello?" FROM test;
+ i | hello? 
+---+--------
+ 1 | t
+ 2 | f
+(2 rows)
+
+SELECT i, p <> 'hello' AS "!hello?" FROM test;
+ i | !hello? 
+---+---------
+ 1 | f
+ 2 | t
+(2 rows)
+
diff --git a/contrib/chkpass/sql/chkpass.sql b/contrib/chkpass/sql/chkpass.sql
new file mode 100644
index 0000000000..595683e249
--- /dev/null
+++ b/contrib/chkpass/sql/chkpass.sql
@@ -0,0 +1,7 @@
+CREATE EXTENSION chkpass;
+
+CREATE TABLE test (i int, p chkpass);
+INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+
+SELECT i, p = 'hello' AS "hello?" FROM test;
+SELECT i, p <> 'hello' AS "!hello?" FROM test;
-- 
2.11.0 (Apple Git-81)

v2-0005-passwordcheck-Add-test-suite.patchtext/plain; charset=UTF-8; name=v2-0005-passwordcheck-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From d452d70ca8c73b83494a103fd68bcea2b5285e96 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH v2 5/7] passwordcheck: Add test suite

Also improve one error message.
---
 contrib/passwordcheck/.gitignore                 |  4 ++++
 contrib/passwordcheck/Makefile                   |  5 +++++
 contrib/passwordcheck/expected/passwordcheck.out | 18 ++++++++++++++++++
 contrib/passwordcheck/passwordcheck.c            |  2 +-
 contrib/passwordcheck/passwordcheck.conf         |  1 +
 contrib/passwordcheck/sql/passwordcheck.sql      | 21 +++++++++++++++++++++
 6 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 contrib/passwordcheck/.gitignore
 create mode 100644 contrib/passwordcheck/expected/passwordcheck.out
 create mode 100644 contrib/passwordcheck/passwordcheck.conf
 create mode 100644 contrib/passwordcheck/sql/passwordcheck.sql

diff --git a/contrib/passwordcheck/.gitignore b/contrib/passwordcheck/.gitignore
new file mode 100644
index 0000000000..5dcb3ff972
--- /dev/null
+++ b/contrib/passwordcheck/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/passwordcheck/Makefile b/contrib/passwordcheck/Makefile
index 4652aeb3d7..7edc968b90 100644
--- a/contrib/passwordcheck/Makefile
+++ b/contrib/passwordcheck/Makefile
@@ -8,6 +8,11 @@ PGFILEDESC = "passwordcheck - strengthen user password checks"
 # PG_CPPFLAGS = -DUSE_CRACKLIB '-DCRACKLIB_DICTPATH="/usr/lib/cracklib_dict"'
 # SHLIB_LINK = -lcrack
 
+REGRESS_OPTS = --temp-config $(srcdir)/passwordcheck.conf
+REGRESS = passwordcheck
+# disabled because these tests require setting shared_preload_libraries
+NO_INSTALLCHECK = 1
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/passwordcheck/expected/passwordcheck.out b/contrib/passwordcheck/expected/passwordcheck.out
new file mode 100644
index 0000000000..b3515df3e8
--- /dev/null
+++ b/contrib/passwordcheck/expected/passwordcheck.out
@@ -0,0 +1,18 @@
+CREATE USER regress_user1;
+-- ok
+ALTER USER regress_user1 PASSWORD 'a_nice_long_password';
+-- error: too short
+ALTER USER regress_user1 PASSWORD 'tooshrt';
+ERROR:  password is too short
+-- error: contains user name
+ALTER USER regress_user1 PASSWORD 'xyzregress_user1';
+ERROR:  password must not contain user name
+-- error: contains only letters
+ALTER USER regress_user1 PASSWORD 'alessnicelongpassword';
+ERROR:  password must contain both letters and nonletters
+-- encrypted ok (password is "secret")
+ALTER USER regress_user1 PASSWORD 'md51a44d829a20a23eac686d9f0d258af13';
+-- error: password is user name
+ALTER USER regress_user1 PASSWORD 'md5e589150ae7d28f93333afae92b36ef48';
+ERROR:  password must not equal user name
+DROP USER regress_user1;
diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c
index b80fd458ad..64d43462f0 100644
--- a/contrib/passwordcheck/passwordcheck.c
+++ b/contrib/passwordcheck/passwordcheck.c
@@ -70,7 +70,7 @@ check_password(const char *username,
 		if (plain_crypt_verify(username, shadow_pass, username, &logdetail) == STATUS_OK)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-					 errmsg("password must not contain user name")));
+					 errmsg("password must not equal user name")));
 	}
 	else
 	{
diff --git a/contrib/passwordcheck/passwordcheck.conf b/contrib/passwordcheck/passwordcheck.conf
new file mode 100644
index 0000000000..f6604f3d6b
--- /dev/null
+++ b/contrib/passwordcheck/passwordcheck.conf
@@ -0,0 +1 @@
+shared_preload_libraries = 'passwordcheck'
diff --git a/contrib/passwordcheck/sql/passwordcheck.sql b/contrib/passwordcheck/sql/passwordcheck.sql
new file mode 100644
index 0000000000..59c84f522e
--- /dev/null
+++ b/contrib/passwordcheck/sql/passwordcheck.sql
@@ -0,0 +1,21 @@
+CREATE USER regress_user1;
+
+-- ok
+ALTER USER regress_user1 PASSWORD 'a_nice_long_password';
+
+-- error: too short
+ALTER USER regress_user1 PASSWORD 'tooshrt';
+
+-- error: contains user name
+ALTER USER regress_user1 PASSWORD 'xyzregress_user1';
+
+-- error: contains only letters
+ALTER USER regress_user1 PASSWORD 'alessnicelongpassword';
+
+-- encrypted ok (password is "secret")
+ALTER USER regress_user1 PASSWORD 'md51a44d829a20a23eac686d9f0d258af13';
+
+-- error: password is user name
+ALTER USER regress_user1 PASSWORD 'md5e589150ae7d28f93333afae92b36ef48';
+
+DROP USER regress_user1;
-- 
2.11.0 (Apple Git-81)

v2-0006-pg_archivecleanup-Add-test-suite.patchtext/plain; charset=UTF-8; name=v2-0006-pg_archivecleanup-Add-test-suite.patch; x-mac-creator=0; x-mac-type=0Download
From ef5f9720f4e9f5729bfa7eedffeb60779a32fd98 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH v2 6/7] pg_archivecleanup: Add test suite

---
 src/bin/pg_archivecleanup/.gitignore               |  2 +
 src/bin/pg_archivecleanup/Makefile                 |  7 ++
 .../pg_archivecleanup/t/010_pg_archivecleanup.pl   | 81 ++++++++++++++++++++++
 3 files changed, 90 insertions(+)
 create mode 100644 src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl

diff --git a/src/bin/pg_archivecleanup/.gitignore b/src/bin/pg_archivecleanup/.gitignore
index 804089070d..bd05d00156 100644
--- a/src/bin/pg_archivecleanup/.gitignore
+++ b/src/bin/pg_archivecleanup/.gitignore
@@ -1 +1,3 @@
 /pg_archivecleanup
+
+/tmp_check/
diff --git a/src/bin/pg_archivecleanup/Makefile b/src/bin/pg_archivecleanup/Makefile
index 5bda78490c..c5bf99db0f 100644
--- a/src/bin/pg_archivecleanup/Makefile
+++ b/src/bin/pg_archivecleanup/Makefile
@@ -25,3 +25,10 @@ uninstall:
 
 clean distclean maintainer-clean:
 	rm -f pg_archivecleanup$(X) $(OBJS)
+	rm -rf tmp_check
+
+check:
+	$(prove_check)
+
+installcheck:
+	$(prove_installcheck)
diff --git a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
new file mode 100644
index 0000000000..1d3a1e4fb9
--- /dev/null
+++ b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
@@ -0,0 +1,81 @@
+use strict;
+use warnings;
+use TestLib;
+use Test::More tests => 42;
+
+program_help_ok('pg_archivecleanup');
+program_version_ok('pg_archivecleanup');
+program_options_handling_ok('pg_archivecleanup');
+
+my $tempdir = TestLib::tempdir;
+
+my @walfiles = (
+	'00000001000000370000000C.gz',
+	'00000001000000370000000D',
+	'00000001000000370000000E',
+	'00000001000000370000000F.partial',
+);
+
+sub create_files
+{
+	foreach my $fn (@walfiles, 'unrelated_file')
+	{
+		open my $file, '>', "$tempdir/$fn";
+		print $file 'CONTENT';
+		close $file;
+	}
+}
+
+create_files();
+
+command_fails_like(['pg_archivecleanup'],
+				   qr/must specify archive location/,
+				   'fails if archive location is not specified');
+
+command_fails_like(['pg_archivecleanup', $tempdir],
+				   qr/must specify oldest kept WAL file/,
+				   'fails if oldest kept WAL file name is not specified');
+
+command_fails_like(['pg_archivecleanup', 'notexist', 'foo'],
+				   qr/archive location .* does not exist/,
+				   'fails if archive location does not exist');
+
+command_fails_like(['pg_archivecleanup', $tempdir, 'foo', 'bar'],
+				   qr/too many command-line arguments/,
+				   'fails with too many command-line arguments');
+
+command_fails_like(['pg_archivecleanup', $tempdir, 'foo'],
+				   qr/invalid file name argument/,
+				   'fails with invalid restart file name');
+
+{
+	# like command_like but checking stderr
+	my $stderr;
+	my $result = IPC::Run::run ['pg_archivecleanup', '-d', '-n', $tempdir, $walfiles[2]], '2>', \$stderr;
+	ok($result, "pg_archivecleanup dry run: exit code 0");
+	like($stderr, qr/$walfiles[1].*would be removed/, "pg_archivecleanup dry run: matches");
+	foreach my $fn (@walfiles)
+	{
+		ok(-f "$tempdir/$fn", "$fn not removed");
+	}
+}
+
+sub run_check
+{
+	my ($suffix, $test_name) = @_;
+
+	create_files();
+
+	command_ok(['pg_archivecleanup', '-x', '.gz', $tempdir, $walfiles[2] . $suffix],
+			   "$test_name: runs");
+
+	ok(! -f "$tempdir/$walfiles[0]", "$test_name: first older WAL file was cleaned up");
+	ok(! -f "$tempdir/$walfiles[1]", "$test_name: second older WAL file was cleaned up");
+	ok(-f "$tempdir/$walfiles[2]", "$test_name: restartfile was not cleaned up");
+	ok(-f "$tempdir/$walfiles[3]", "$test_name: newer WAL file was not cleaned up");
+	ok(-f "$tempdir/unrelated_file", "$test_name: unrelated file was not cleaned up");
+}
+
+run_check('', 'pg_archivecleanup');
+run_check('.partial', 'pg_archivecleanup with .partial file');
+run_check('.00000020.backup', 'pg_archivecleanup with .backup file');
-- 
2.11.0 (Apple Git-81)

v2-0007-isn-Fix-debug-code.patchtext/plain; charset=UTF-8; name=v2-0007-isn-Fix-debug-code.patch; x-mac-creator=0; x-mac-type=0Download
From 2a311b72fa252873809ae4f92047d61adbb62e98 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 11 Aug 2017 21:04:04 -0400
Subject: [PATCH v2 7/7] isn: Fix debug code

The ISN_DEBUG code did not compile.  Fix that code, don't hide it behind
an #ifdef, make it run when building with asserts, and make it error out
instead of just logging if it fails.
---
 contrib/isn/isn.c | 41 +++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/contrib/isn/isn.c b/contrib/isn/isn.c
index 4d845b716f..0148f9549f 100644
--- a/contrib/isn/isn.c
+++ b/contrib/isn/isn.c
@@ -26,6 +26,12 @@
 
 PG_MODULE_MAGIC;
 
+#ifdef USE_ASSERT_CHECKING
+#define ISN_DEBUG 1
+#else
+#define ISN_DEBUG 0
+#endif
+
 #define MAXEAN13LEN 18
 
 enum isn_type
@@ -36,7 +42,6 @@ enum isn_type
 static const char *const isn_names[] = {"EAN13/UPC/ISxN", "EAN13/UPC/ISxN", "EAN13", "ISBN", "ISMN", "ISSN", "UPC"};
 
 static bool g_weak = false;
-static bool g_initialized = false;
 
 
 /***********************************************************************
@@ -56,7 +61,7 @@ static bool g_initialized = false;
 /*
  * Check if the table and its index is correct (just for debugging)
  */
-#ifdef ISN_DEBUG
+pg_attribute_unused()
 static bool
 check_table(const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
 {
@@ -68,7 +73,6 @@ check_table(const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
 				y = -1,
 				i = 0,
 				j,
-				cnt = 0,
 				init = 0;
 
 	if (TABLE == NULL || TABLE_index == NULL)
@@ -131,7 +135,6 @@ check_table(const char *(*TABLE)[2], const unsigned TABLE_index[10][2])
 	elog(DEBUG1, "index %d is invalid", j);
 	return false;
 }
-#endif							/* ISN_DEBUG */
 
 /*----------------------------------------------------------
  * Formatting and conversion routines.
@@ -922,22 +925,24 @@ string2ean(const char *str, bool errorOK, ean13 *result,
  * Exported routines.
  *---------------------------------------------------------*/
 
+void _PG_init(void);
+
 void
-initialize(void)
+_PG_init(void)
 {
-#ifdef ISN_DEBUG
-	if (!check_table(EAN13, EAN13_index))
-		elog(LOG, "EAN13 failed check");
-	if (!check_table(ISBN, ISBN_index))
-		elog(LOG, "ISBN failed check");
-	if (!check_table(ISMN, ISMN_index))
-		elog(LOG, "ISMN failed check");
-	if (!check_table(ISSN, ISSN_index))
-		elog(LOG, "ISSN failed check");
-	if (!check_table(UPC, UPC_index))
-		elog(LOG, "UPC failed check");
-#endif
-	g_initialized = true;
+	if (ISN_DEBUG)
+	{
+		if (!check_table(EAN13_range, EAN13_index))
+			elog(ERROR, "EAN13 failed check");
+		if (!check_table(ISBN_range, ISBN_index))
+			elog(ERROR, "ISBN failed check");
+		if (!check_table(ISMN_range, ISMN_index))
+			elog(ERROR, "ISMN failed check");
+		if (!check_table(ISSN_range, ISSN_index))
+			elog(ERROR, "ISSN failed check");
+		if (!check_table(UPC_range, UPC_index))
+			elog(ERROR, "UPC failed check");
+	}
 }
 
 /* isn_out
-- 
2.11.0 (Apple Git-81)

#4David Steele
david@pgmasters.net
In reply to: Peter Eisentraut (#3)
Re: additional contrib test suites

On 9/8/17 1:32 PM, Peter Eisentraut wrote:

Yes, some of the error messages had changed. Fixed patches attached.

Patches apply and all tests pass. A few comments:

* [PATCH v2 1/7] adminpack: Add test suite

There are no regular tests for pg_logdir_ls(). It looks like TAP tests
would be required but I'm not sure it's worth it. The fact that the
"default" log name format is hard-coded in is, um, interesting.

Maybe add:

+ SELECT pg_logdir_ls();
+ ERROR:  could not read directory "log": No such file or directory

to get a little more coverage? It would be good to at least have a note
on why it is not tested.

* [PATCH v2 4/7] chkpass: Add test suite

Well, this is kind of scary:

+CREATE EXTENSION chkpass;
+WARNING:  type input function chkpass_in should not be volatile

I guess the only side effect is that this column cannot be indexed? The
docs say that, so OK, but is there anything else a user should be
worried about?

The rest looks good. I'll mark this "Ready for Committer" since I'm the
only reviewer. I don't think anything you might add based on my
comments above requires a re-review.

As for testing on more platforms, send it to the build farm?

--
-David
david@pgmasters.net

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: David Steele (#4)
Re: additional contrib test suites

On 9/14/17 11:01, David Steele wrote:

On 9/8/17 1:32 PM, Peter Eisentraut wrote:

Yes, some of the error messages had changed. Fixed patches attached.

Patches apply and all tests pass. A few comments:

* [PATCH v2 1/7] adminpack: Add test suite

There are no regular tests for pg_logdir_ls().

Added a comment about that.

* [PATCH v2 4/7] chkpass: Add test suite

Well, this is kind of scary:

+CREATE EXTENSION chkpass;
+WARNING:  type input function chkpass_in should not be volatile

I guess the only side effect is that this column cannot be indexed? The
docs say that, so OK, but is there anything else a user should be
worried about?

Well, we're just testing, not judging. ;-)

The rest looks good. I'll mark this "Ready for Committer" since I'm the
only reviewer. I don't think anything you might add based on my
comments above requires a re-review.

As for testing on more platforms, send it to the build farm?

OK, committed, let's see.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Peter Eisentraut (#5)
Re: additional contrib test suites

On 9/14/17 22:47, Peter Eisentraut wrote:

As for testing on more platforms, send it to the build farm?

OK, committed, let's see.

So, we have one failure for chkpass on OpenBSD, because OpenBSD crypt()
doesn't support the traditional two-character salt format.

Option:

- Use the resultmap features to make this an expected failure on OpenBSD.

- Fix the module to work on OpenBSD. This would involve making a
platform-specific modification to use whatever advanced salt format they
want.

- Replace the entire module with something that does not depend on crypt().

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#6)
Re: additional contrib test suites

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

So, we have one failure for chkpass on OpenBSD, because OpenBSD crypt()
doesn't support the traditional two-character salt format.

Option:

- Use the resultmap features to make this an expected failure on OpenBSD.

- Fix the module to work on OpenBSD. This would involve making a
platform-specific modification to use whatever advanced salt format they
want.

- Replace the entire module with something that does not depend on crypt().

Or (4) drop the module's regression test again.

I'd go for (1) at least as a short-term answer. It's not clear to me
that it's worth the effort to do (2) or (3). Also, (3) probably breaks
backwards compatibility, if there is anyone out there actually using
this datatype.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#7)
Re: additional contrib test suites

I wrote:

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

So, we have one failure for chkpass on OpenBSD, because OpenBSD crypt()
doesn't support the traditional two-character salt format.

Option:

- Use the resultmap features to make this an expected failure on OpenBSD.

- Fix the module to work on OpenBSD. This would involve making a
platform-specific modification to use whatever advanced salt format they
want.

- Replace the entire module with something that does not depend on crypt().

Or (4) drop the module's regression test again.

Noting that mandrill is showing yet a different failure, one that I think
is inherent to chkpass:

  CREATE TABLE test (i int, p chkpass);
  INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+ WARNING:  type chkpass has unstable input conversion for "hello"
+ LINE 1: INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+                                     ^
+ WARNING:  type chkpass has unstable input conversion for "goodbye"
+ LINE 1: INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+                                                   ^

I'm starting to think that (4) might be the best avenue. Or we could
consider

(5) drop contrib/chkpass altogether, on the grounds that it's too badly
designed, and too obsolete crypto-wise, to be useful or supportable.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Michael Paquier
michael.paquier@gmail.com
In reply to: Tom Lane (#8)
Re: additional contrib test suites

On Sat, Sep 16, 2017 at 5:15 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I wrote:

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

So, we have one failure for chkpass on OpenBSD, because OpenBSD crypt()
doesn't support the traditional two-character salt format.

Option:

- Use the resultmap features to make this an expected failure on OpenBSD.

- Fix the module to work on OpenBSD. This would involve making a
platform-specific modification to use whatever advanced salt format they
want.

- Replace the entire module with something that does not depend on crypt().

Or (4) drop the module's regression test again.

Noting that mandrill is showing yet a different failure, one that I think
is inherent to chkpass:

CREATE TABLE test (i int, p chkpass);
INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+ WARNING:  type chkpass has unstable input conversion for "hello"
+ LINE 1: INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+                                     ^
+ WARNING:  type chkpass has unstable input conversion for "goodbye"
+ LINE 1: INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+                                                   ^

I'm starting to think that (4) might be the best avenue. Or we could
consider

(5) drop contrib/chkpass altogether, on the grounds that it's too badly
designed, and too obsolete crypto-wise, to be useful or supportable.

crypt() uses the 7 lowest characters, which makes for 7.2e16 values,
so I would be fine with (5), then (4) as the test suite is not
portable.
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10David Steele
david@pgmasters.net
In reply to: Michael Paquier (#9)
Re: additional contrib test suites

On 9/15/17 6:52 PM, Michael Paquier wrote:

On Sat, Sep 16, 2017 at 5:15 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Noting that mandrill is showing yet a different failure, one that I think
is inherent to chkpass:

CREATE TABLE test (i int, p chkpass);
INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+ WARNING:  type chkpass has unstable input conversion for "hello"
+ LINE 1: INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+                                     ^
+ WARNING:  type chkpass has unstable input conversion for "goodbye"
+ LINE 1: INSERT INTO test VALUES (1, 'hello'), (2, 'goodbye');
+                                                   ^

I'm starting to think that (4) might be the best avenue. Or we could
consider

(5) drop contrib/chkpass altogether, on the grounds that it's too badly
designed, and too obsolete crypto-wise, to be useful or supportable.

crypt() uses the 7 lowest characters, which makes for 7.2e16 values,
so I would be fine with (5), then (4) as the test suite is not
portable.

I'd prefer 5, but can go with 4.

I get that users need to store their own passwords, but we have support
for SHA1 via the crypto module which seems by far the better choice.

--
-David
david@pgmasters.net

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: David Steele (#10)
Re: additional contrib test suites

On 9/16/17 08:10, David Steele wrote:

(5) drop contrib/chkpass altogether, on the grounds that it's too badly
designed, and too obsolete crypto-wise, to be useful or supportable.

crypt() uses the 7 lowest characters, which makes for 7.2e16 values,
so I would be fine with (5), then (4) as the test suite is not
portable.

I'd prefer 5, but can go with 4.

I get that users need to store their own passwords, but we have support
for SHA1 via the crypto module which seems by far the better choice.

I'm also tempted to just remove it. It uses bad/outdated security
practices and it's also not ideal as an example module. Any objections?

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Peter Eisentraut (#11)
Re: additional contrib test suites

On 9/18/17 09:54, Peter Eisentraut wrote:

On 9/16/17 08:10, David Steele wrote:

(5) drop contrib/chkpass altogether, on the grounds that it's too badly
designed, and too obsolete crypto-wise, to be useful or supportable.

crypt() uses the 7 lowest characters, which makes for 7.2e16 values,
so I would be fine with (5), then (4) as the test suite is not
portable.

I'd prefer 5, but can go with 4.

I get that users need to store their own passwords, but we have support
for SHA1 via the crypto module which seems by far the better choice.

I'm also tempted to just remove it. It uses bad/outdated security
practices and it's also not ideal as an example module. Any objections?

Hearing none, thus removed.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Andres Freund
andres@anarazel.de
In reply to: Peter Eisentraut (#11)
Re: additional contrib test suites

On 2017-09-18 09:54:52 -0400, Peter Eisentraut wrote:

On 9/16/17 08:10, David Steele wrote:

(5) drop contrib/chkpass altogether, on the grounds that it's too badly
designed, and too obsolete crypto-wise, to be useful or supportable.

crypt() uses the 7 lowest characters, which makes for 7.2e16 values,
so I would be fine with (5), then (4) as the test suite is not
portable.

I'd prefer 5, but can go with 4.

I get that users need to store their own passwords, but we have support
for SHA1 via the crypto module which seems by far the better choice.

I'm also tempted to just remove it. It uses bad/outdated security
practices and it's also not ideal as an example module. Any objections?

Uhm. I'm not objecting, but I doubt people really noticed your question
in a thread about additional contrib test suites.

Greetings,

Andres Freund

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers