po 18. 11. 2019 v 7:39 odesílatel Pavel Stehule <pavel.steh...@gmail.com>
napsal:

>
>
> po 18. 11. 2019 v 7:37 odesílatel Amit Kapila <amit.kapil...@gmail.com>
> napsal:
>
>> On Mon, Nov 18, 2019 at 10:59 AM Pavel Stehule <pavel.steh...@gmail.com>
>> wrote:
>> > po 18. 11. 2019 v 6:24 odesílatel Amit Kapila <amit.kapil...@gmail.com>
>> napsal:
>> >>
>> >> On Mon, Nov 18, 2019 at 10:33 AM Pavel Stehule <
>> pavel.steh...@gmail.com> wrote:
>> >> >
>> >> > po 18. 11. 2019 v 4:43 odesílatel vignesh C <vignes...@gmail.com>
>> napsal:
>> >> >>
>> >> >>
>> >> >> I had seen that isolation test(src/test/isolation) has a framework
>> to
>> >> >> support this. You can have a look to see if it can be handled using
>> >> >> that.
>> >> >
>> >> >
>> >> > I'll look there
>> >> >
>> >>
>> >> If we want to have a test for this, then you might want to look at
>> >> test src/test/recovery/t/013_crash_restart.  In that test, we keep a
>> >> connection open and then validate whether it is terminated.  Having
>> >> said that, I think it might be better to add this as a separate test
>> >> patch apart from main patch because it is a bit of a timing-dependent
>> >> test and might fail on some slow machines.  We can always revert this
>> >> if it turns out to be an unstable test.
>> >
>> >
>> > +1
>> >
>>
>> So, are you planning to give it a try?  I think even if we want to
>> commit this separately, it is better to have a test for this before we
>> commit.
>>
>
> I'll send this test today
>

here is it

Regards

Pavel

>
> Pavel
>
>
>>
>> --
>> With Regards,
>> Amit Kapila.
>> EnterpriseDB: http://www.enterprisedb.com
>>
>
diff --git a/src/bin/scripts/t/060_dropdb_force.pl b/src/bin/scripts/t/060_dropdb_force.pl
new file mode 100644
index 0000000000..b895a7fbba
--- /dev/null
+++ b/src/bin/scripts/t/060_dropdb_force.pl
@@ -0,0 +1,149 @@
+#
+# Tests killing session connected to dropped database
+#
+use strict;
+use warnings;
+use PostgresNode;
+use TestLib;
+use Test::More tests => 10;
+
+# To avoid hanging while expecting some specific input from a psql
+# instance being driven by us, add a timeout high enough that it
+# should never trigger even on very slow machines, unless something
+# is really wrong.
+my $psql_timeout = IPC::Run::timer(60);
+
+my $node = get_new_node('master');
+$node->init;
+$node->start;
+
+# Create database that will be dropped
+$node->safe_psql('postgres', 'CREATE DATABASE foobar1');
+
+# Run psql, keeping session alive, so we have an alive backend to kill.
+my ($killme_stdin, $killme_stdout, $killme_stderr) = ('', '', '');
+my $killme = IPC::Run::start(
+	[
+		'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d',
+		$node->connstr('foobar1')
+	],
+	'<',
+	\$killme_stdin,
+	'>',
+	\$killme_stdout,
+	'2>',
+	\$killme_stderr,
+	$psql_timeout);
+
+#Ensure killme process is active
+$killme_stdin .= q[
+SELECT pg_backend_pid();
+];
+ok(pump_until($killme, \$killme_stdout, qr/[[:digit:]]+[\r\n]$/m),
+	'acquired pid');
+my $pid = $killme_stdout;
+chomp($pid);
+$killme_stdout = '';
+$killme_stderr = '';
+
+# and it is connected to foobar1 database
+is($node->safe_psql('postgres', qq[SELECT pid FROM pg_stat_activity WHERE datname='foobar1' AND pid = $pid;]),
+	$pid, 'database foobar1 is used');
+
+$node->safe_psql('postgres', 'DROP DATABASE foobar1 WITH (FORCE)');
+
+# Check that psql sees the killed backend as having been terminated
+$killme_stdin .= q[
+SELECT 1;
+];
+ok( pump_until(
+		$killme,
+		\$killme_stderr,
+		qr/FATAL:  terminating connection due to administrator command/m
+	),
+	"psql query died successfully after SIGTERM");
+$killme_stderr = '';
+$killme_stdout = '';
+$killme->finish;
+
+# and there is not a database with this name
+is($node->safe_psql('postgres', qq[SELECT EXISTS(SELECT * FROM pg_database WHERE datname='foobar1');]),
+	'f', 'database foobar1 was removed');
+
+# Create database that will be dropped
+$node->safe_psql('postgres', 'CREATE DATABASE foobar1');
+
+# restart psql processes, now that the crash cycle finished
+($killme_stdin, $killme_stdout, $killme_stderr) = ('', '', '');
+$killme->run();
+
+# Acquire pid of new backend
+$killme_stdin .= q[
+SELECT pg_backend_pid();
+];
+ok(pump_until($killme, \$killme_stdout, qr/[[:digit:]]+[\r\n]$/m),
+	"acquired pid for SIGKILL");
+$pid = $killme_stdout;
+chomp($pid);
+$killme_stdout = '';
+$killme_stderr = '';
+
+# and it is connected to foobar1 database
+is($node->safe_psql('postgres', qq[SELECT pid FROM pg_stat_activity WHERE datname='foobar1' AND pid = $pid;]),
+	$pid, 'database foobar1 is used');
+
+# Now drop database with dropdb --force command
+$node->issues_sql_like(
+	[ 'dropdb', '--force', 'foobar1' ],
+	qr/statement: DROP DATABASE foobar1 WITH \(FORCE\);/,
+	'SQL DROP DATABASE (FORCE) run');
+
+# Check that psql sees the killed backend as having been terminated
+$killme_stdin .= q[
+SELECT 1;
+];
+ok( pump_until(
+		$killme,
+		\$killme_stderr,
+		qr/FATAL:  terminating connection due to administrator command/m
+	),
+	"psql query died successfully after SIGTERM");
+$killme_stderr = '';
+$killme_stdout = '';
+$killme->finish;
+
+# and there is not a database with this name
+is($node->safe_psql('postgres', qq[SELECT EXISTS(SELECT * FROM pg_database WHERE datname='foobar1');]),
+	'f', 'database foobar1 was removed');
+
+$node->stop();
+
+# Pump until string is matched, or timeout occurs
+sub pump_until
+{
+	my ($proc, $stream, $untl) = @_;
+	$proc->pump_nb();
+	while (1)
+	{
+		last if $$stream =~ /$untl/;
+		if ($psql_timeout->is_expired)
+		{
+			diag("aborting wait: program timed out");
+			diag("stream contents: >>", $$stream, "<<");
+			diag("pattern searched for: ", $untl);
+
+			return 0;
+		}
+		if (not $proc->pumpable())
+		{
+			diag("aborting wait: program died");
+			diag("stream contents: >>", $$stream, "<<");
+			diag("pattern searched for: ", $untl);
+
+			return 0;
+		}
+		$proc->pump();
+	}
+	return 1;
+
+}

Reply via email to