On 22/06/18 12:07오후, Michael Paquier wrote: > On Sat, Jun 18, 2022 at 11:06:02AM +0900, Dong Wook Lee wrote: > > I have written a test for the auth_delay extension before, > > but if it is okay, can you review it? > > +# check enter wrong password > +my $t0 = [gettimeofday]; > +test_login($node, 'user_role', "wrongpass", 2); > +my $elapsed = tv_interval($t0, [gettimeofday]); > +ok($elapsed >= $delay_milliseconds / 1000, "auth_delay $elapsed seconds"); > + > +# check enter correct password > +my $t0 = [gettimeofday]; > +test_login($node, 'user_role', "pass", 0); > +my $elapsed = tv_interval($t0, [gettimeofday]); > +ok($elapsed < $delay_milliseconds / 1000, "auth_delay $elapsed seconds"); > > On a slow machine, I suspect that the second test is going to be > unstable as it would fail if the login attempt (that succeeds) takes > more than $delay_milliseconds. You could increase more > delay_milliseconds to leverage that, but it would make the first test > slower for nothing on faster machines in the case where the > authentication attempt has failed. I guess that you could leverage > that by using a large value for delay_milliseconds in the second test, > because we are never going to wait. For the first test, you could on > the contrary use a much lower value, still on slow machines it may not > test what the code path of auth_delay you are willing to test. >
Thank you for your valuable advice I didn't think about the slow system. Therefore, in the case of the second test, the time was extended a little. > As a whole, I am not sure that this is really worth spending cycles on > when running check-world or similar, and the code of the extension is > trivial. Even though it is trivial, I think it would be better if there was a test. > -- > Michael
diff --git a/contrib/auth_delay/Makefile b/contrib/auth_delay/Makefile index 4b86ec37f0..b65097789a 100644 --- a/contrib/auth_delay/Makefile +++ b/contrib/auth_delay/Makefile @@ -3,6 +3,8 @@ MODULES = auth_delay PGFILEDESC = "auth_delay - delay authentication failure reports" +TAP_TESTS = 1 + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/contrib/auth_delay/t/001_auth_delay.pl b/contrib/auth_delay/t/001_auth_delay.pl new file mode 100644 index 0000000000..644026e4f2 --- /dev/null +++ b/contrib/auth_delay/t/001_auth_delay.pl @@ -0,0 +1,87 @@ + +# Copyright (c) 2021-2022, PostgreSQL Global Development Group + +use strict; +use warnings; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; +use Time::HiRes qw(gettimeofday tv_interval); + +# Delete pg_hba.conf from the given node, add a new entry to it +# and then execute a reload to refresh it. +sub reset_pg_hba +{ + my $node = shift; + my $hba_method = shift; + + unlink($node->data_dir . '/pg_hba.conf'); + # just for testing purposes, use a continuation line + $node->append_conf('pg_hba.conf', "local all all $hba_method"); + $node->reload; + return; +} + +# Test access for a single role, with password +sub test_login +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my $node = shift; + my $role = shift; + my $password = shift; + my $expected_res = shift; + my $status_string = 'failed'; + + $status_string = 'success' if ($expected_res eq 0); + + my $connstr = "user=$role"; + my $testname = + "authentication $status_string for role $role with password $password"; + + $ENV{"PGPASSWORD"} = $password; + + if ($expected_res eq 0) + { + $node->connect_ok($connstr, $testname); + } + else + { + # No checks of the error message, only the status code. + $node->connect_fails($connstr, $testname); + } +} + +note "setting up PostgreSQL instance"; + +my $delay_milliseconds = 500; + +my $node = PostgreSQL::Test::Cluster->new('main'); +$node->init; +$node->append_conf('postgresql.conf', + qq{shared_preload_libraries = 'auth_delay' + auth_delay.milliseconds = '$delay_milliseconds'}); +$node->start; + +$node->safe_psql( + 'postgres', + "CREATE ROLE user_role LOGIN PASSWORD 'pass';"); +reset_pg_hba($node, 'password'); + +note "running tests"; + +# check enter wrong password +my $t0 = [gettimeofday]; +test_login($node, 'user_role', "wrongpass", 2); +my $elapsed = tv_interval($t0, [gettimeofday]); +ok($elapsed >= $delay_milliseconds / 1000, "auth_delay $elapsed seconds"); + +# check enter correct password +my $t0 = [gettimeofday]; +test_login($node, 'user_role', "pass", 0); +my $elapsed = tv_interval($t0, [gettimeofday]); +ok($elapsed < $delay_milliseconds / 1000, "auth_delay $elapsed seconds"); + +done_testing(); +