diff --git a/src/test/Makefile b/src/test/Makefile
new file mode 100644
index efb206a..441d954
*** a/src/test/Makefile
--- b/src/test/Makefile
*************** subdir = src/test
*** 12,18 ****
  top_builddir = ../..
  include $(top_builddir)/src/Makefile.global
  
! SUBDIRS = perl regress isolation modules authentication recovery subscription
  
  # Test suites that are not safe by default but can be run if selected
  # by the user via the whitespace-separated list in variable
--- 12,19 ----
  top_builddir = ../..
  include $(top_builddir)/src/Makefile.global
  
! SUBDIRS = perl regress isolation modules authentication recovery subscription \
! 	configuration
  
  # Test suites that are not safe by default but can be run if selected
  # by the user via the whitespace-separated list in variable
diff --git a/src/test/configuration/.gitignore b/src/test/configuration/.gitignore
new file mode 100644
index ...871e943
*** a/src/test/configuration/.gitignore
--- b/src/test/configuration/.gitignore
***************
*** 0 ****
--- 1,2 ----
+ # Generated by test suite
+ /tmp_check/
diff --git a/src/test/configuration/Makefile b/src/test/configuration/Makefile
new file mode 100644
index ...69e9697
*** a/src/test/configuration/Makefile
--- b/src/test/configuration/Makefile
***************
*** 0 ****
--- 1,25 ----
+ #-------------------------------------------------------------------------
+ #
+ # Makefile for src/test/configuration
+ #
+ # Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+ # Portions Copyright (c) 1994, Regents of the University of California
+ #
+ # src/test/configuration/Makefile
+ #
+ #-------------------------------------------------------------------------
+ 
+ EXTRA_INSTALL=contrib/test_decoding
+ 
+ subdir = src/test/recovery
+ top_builddir = ../../..
+ include $(top_builddir)/src/Makefile.global
+ 
+ check:
+ 	$(prove_check)
+ 
+ installcheck:
+ 	$(prove_installcheck)
+ 
+ clean distclean maintainer-clean:
+ 	rm -rf tmp_check
diff --git a/src/test/configuration/README b/src/test/configuration/README
new file mode 100644
index ...1796f5c
*** a/src/test/configuration/README
--- b/src/test/configuration/README
***************
*** 0 ****
--- 1,25 ----
+ src/test/configuration/README
+ 
+ Regression tests for configuration files
+ ========================================
+ 
+ This directory contains a test suite for configuration files.
+ 
+ Running the tests
+ =================
+ 
+ NOTE: You must have given the --enable-tap-tests argument to configure.
+ Also, to use "make installcheck", you must have built and installed
+ contrib/test_decoding in addition to the core code.
+ 
+ Run
+     make check
+ or
+     make installcheck
+ You can use "make installcheck" if you previously did "make install".
+ In that case, the code in the installation tree is tested.  With
+ "make check", a temporary installation tree is built from the current
+ sources and then tested.
+ 
+ Either way, this test initializes, starts, and stops several test Postgres
+ clusters.
diff --git a/src/test/configuration/t/001_alter_system.pl b/src/test/configuration/t/001_alter_system.pl
new file mode 100644
index ...f0975e7
*** a/src/test/configuration/t/001_alter_system.pl
--- b/src/test/configuration/t/001_alter_system.pl
***************
*** 0 ****
--- 1,140 ----
+ # Test that ALTER SYSTEM updates postgresql.auto.conf as expected
+ 
+ use strict;
+ use warnings;
+ use PostgresNode;
+ use TestLib;
+ use Test::More tests => 8;
+ 
+ our $postgresql_auto_conf = 'postgresql.auto.conf';
+ 
+ my ($expected, $result, $auto_conf, $vacuum_cost_delay_value);
+ 
+ # Initialize a single node
+ 
+ my $node = get_new_node('primary');
+ $node->init();
+ $node->start;
+ 
+ # 1. Check default postgresql.auto.conf contents
+ # ----------------------------------------------
+ 
+ my $expected_default = <<'EO_CONF';
+ # Do not edit this file manually!
+ # It will be overwritten by the ALTER SYSTEM command.
+ EO_CONF
+ 
+ $auto_conf = $node->read_conf($postgresql_auto_conf);
+ 
+ is($auto_conf, $expected_default, 'check default contents of postgresql.auto.conf');
+ 
+ # 2. Check ALTER SYSTEM SET foo = 'bar'
+ # --------------------------------------
+ #
+ # Verify postgresql.auto.conf updated as expected
+ 
+ $vacuum_cost_delay_value = '1ms';
+ 
+ $node->safe_psql('postgres',
+ 	"ALTER SYSTEM SET vacuum_cost_delay = '$vacuum_cost_delay_value'");
+ 
+ $expected = sprintf(
+ 	<<'EO_CONF',
+ # Do not edit this file manually!
+ # It will be overwritten by the ALTER SYSTEM command.
+ vacuum_cost_delay = '%s'
+ EO_CONF
+ 	$vacuum_cost_delay_value
+ );
+ 
+ $auto_conf = $node->read_conf($postgresql_auto_conf);
+ 
+ is($auto_conf, $expected, "check ALTER SYSTEM SET foo = 'bar'");
+ 
+ # 3. Check changed value is registered
+ # ------------------------------------
+ 
+ $node->safe_psql('postgres',
+ 	"SELECT pg_catalog.pg_reload_conf()");
+ 
+ $result = $node->safe_psql('postgres',
+ 	"SELECT setting FROM pg_catalog.pg_settings WHERE name = 'vacuum_cost_delay'");
+ 
+ is($result, '1', 'Check changed value is registered');
+ 
+ # 4. Check ALTER SYSTEM RESET foo
+ # -------------------------------
+ #
+ # postgresql.auto.conf should be reset to the default
+ 
+ $node->safe_psql('postgres',
+ 	"ALTER SYSTEM RESET vacuum_cost_delay");
+ 
+ $auto_conf = $node->read_conf($postgresql_auto_conf);
+ 
+ is($auto_conf, $expected_default, "check ALTER SYSTEM RESET foo");
+ 
+ # 5. Check behaviour with duplicate values
+ # ----------------------------------------
+ 
+ my $duplicate_values = <<'EO_CONF';
+ vacuum_cost_delay = '2ms'
+ vacuum_cost_page_hit = '2'
+ vacuum_cost_delay = '1ms'
+ vacuum_cost_delay = '0ms'
+ EO_CONF
+ 
+ $node->safe_psql('postgres',
+ 	"SELECT pg_catalog.pg_reload_conf()");
+ 
+ $node->append_conf($postgresql_auto_conf, $duplicate_values);
+ 
+ $node->safe_psql('postgres',
+ 	"SELECT pg_catalog.pg_reload_conf()");
+ 
+ $result = $node->safe_psql('postgres',
+ 	"SELECT setting FROM pg_catalog.pg_settings WHERE name = 'vacuum_cost_delay'");
+ 
+ is($result, '0', 'If duplicates present, check last value present is registered');
+ 
+ # 6. Check ALTER SYSTEM works as expected when duplicate values present
+ # ---------------------------------------------------------------------
+ 
+ $vacuum_cost_delay_value = '3ms';
+ 
+ $node->safe_psql('postgres',
+ 	"ALTER SYSTEM SET vacuum_cost_delay = '$vacuum_cost_delay_value'");
+ 
+ $node->safe_psql('postgres',
+ 	"SELECT pg_catalog.pg_reload_conf()");
+ 
+ $result = $node->safe_psql('postgres',
+ 	"SELECT setting FROM pg_catalog.pg_settings WHERE name = 'vacuum_cost_delay'");
+ 
+ is($result, '3', 'If duplicates present, check ALTER SYSTEM SET works as expected');
+ 
+ # 7. Check ALTER SYSTEM RESET works as expected when duplicate values present
+ # ---------------------------------------------------------------------------
+ 
+ $expected = <<'EO_CONF';
+ # Do not edit this file manually!
+ # It will be overwritten by the ALTER SYSTEM command.
+ vacuum_cost_page_hit = '2'
+ EO_CONF
+ 
+ $node->safe_psql('postgres',
+ 	"ALTER SYSTEM RESET vacuum_cost_delay");
+ 
+ $auto_conf = $node->read_conf($postgresql_auto_conf);
+ 
+ is($auto_conf, $expected, "check ALTER SYSTEM RESET works when duplicate values present");
+ 
+ # 8. Check ALTER SYSTEM RESET ALL works as expected
+ # -------------------------------------------------
+ 
+ $node->safe_psql('postgres',
+ 	"ALTER SYSTEM RESET ALL");
+ 
+ $auto_conf = $node->read_conf($postgresql_auto_conf);
+ 
+ is($auto_conf, $expected_default, "check ALTER SYSTEM RESET ALL works as expected");
diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm
new file mode 100644
index 8d5ad6b..0d3d3f4
*** a/src/test/perl/PostgresNode.pm
--- b/src/test/perl/PostgresNode.pm
*************** sub append_conf
*** 538,543 ****
--- 538,562 ----
  
  =pod
  
+ =item $node->read_conf(filename)
+ 
+ A shortcut method to read the contents of a configuration file.
+ 
+ Does no validation, parsing or sanity checking.
+ 
+ =cut
+ 
+ sub read_conf
+ {
+ 	my ($self, $filename, $str) = @_;
+ 
+ 	my $conffile = $self->data_dir . '/' . $filename;
+ 
+ 	return TestLib::slurp_file($conffile);
+ }
+ 
+ =pod
+ 
  =item $node->backup(backup_name)
  
  Create a hot backup with B<pg_basebackup> in subdirectory B<backup_name> of
