Convert sepgsql tests to TAP
Add a TAP test for sepgsql. This automates the previously required manual setup before the test. The actual tests are still run by pg_regress, as before, but now called from within the TAP Perl script. The previous manual test script (test_sepgsql) is left in place, since its purpose is (also) to test whether a running instance was properly initialized for sepgsql. But it has been changed to call pg_regress directly and no longer require make. Reviewed-by: Andreas Karlsson <andreas@proxel.se> Discussion: https://www.postgresql.org/message-id/flat/651a5baf-5c45-4a5a-a202-0c8453a4ebf8@eisentraut.org
This commit is contained in:
parent
02ed3c2bdc
commit
aeb8ea361a
4
contrib/sepgsql/.gitignore
vendored
4
contrib/sepgsql/.gitignore
vendored
@ -3,5 +3,5 @@
|
||||
/sepgsql-regtest.if
|
||||
/sepgsql-regtest.pp
|
||||
/tmp
|
||||
# Generated subdirectories
|
||||
/results/
|
||||
# Generated by test suite
|
||||
/tmp_check/
|
||||
|
@ -15,6 +15,8 @@ OBJS = \
|
||||
DATA_built = sepgsql.sql
|
||||
PGFILEDESC = "sepgsql - SELinux integration"
|
||||
|
||||
TAP_TESTS = 1
|
||||
|
||||
# Note: because we don't tell the Makefile there are any regression tests,
|
||||
# we have to clean those result files explicitly
|
||||
EXTRA_CLEAN = -r $(pg_regress_clean_files) tmp/ *.pp sepgsql-regtest.if sepgsql-regtest.fc
|
||||
|
@ -40,4 +40,13 @@ contrib_targets += custom_target('sepgsql.sql',
|
||||
install_dir: dir_data / 'contrib',
|
||||
)
|
||||
|
||||
# TODO: implement sepgsql tests
|
||||
tests += {
|
||||
'name': 'sepgsql',
|
||||
'sd': meson.current_source_dir(),
|
||||
'bd': meson.current_build_dir(),
|
||||
'tap': {
|
||||
'tests': [
|
||||
't/001_sepgsql.pl',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
246
contrib/sepgsql/t/001_sepgsql.pl
Normal file
246
contrib/sepgsql/t/001_sepgsql.pl
Normal file
@ -0,0 +1,246 @@
|
||||
|
||||
# Copyright (c) 2024, PostgreSQL Global Development Group
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
use PostgreSQL::Test::Cluster;
|
||||
use PostgreSQL::Test::Utils;
|
||||
|
||||
use Test::More;
|
||||
|
||||
if (!$ENV{PG_TEST_EXTRA} || $ENV{PG_TEST_EXTRA} !~ /\bsepgsql\b/)
|
||||
{
|
||||
plan skip_all =>
|
||||
'Potentially unsafe test sepgsql not enabled in PG_TEST_EXTRA';
|
||||
}
|
||||
|
||||
note "checking selinux environment";
|
||||
|
||||
# matchpathcon must be present to assess whether the installation environment
|
||||
# is OK.
|
||||
note "checking for matchpathcon";
|
||||
if (system('matchpathcon -n . >/dev/null 2>&1') != 0)
|
||||
{
|
||||
diag <<EOS;
|
||||
|
||||
The matchpathcon command must be available.
|
||||
Please install it or update your PATH to include it
|
||||
(it is typically in '/usr/sbin', which might not be in your PATH).
|
||||
matchpathcon is typically included in the libselinux-utils package.
|
||||
EOS
|
||||
die;
|
||||
}
|
||||
|
||||
# runcon must be present to launch psql using the correct environment
|
||||
note "checking for runcon";
|
||||
if (system('runcon --help >/dev/null 2>&1') != 0)
|
||||
{
|
||||
diag <<EOS;
|
||||
|
||||
The runcon command must be available.
|
||||
runcon is typically included in the coreutils package.
|
||||
EOS
|
||||
die;
|
||||
}
|
||||
|
||||
# check sestatus too, since that lives in yet another package
|
||||
note "checking for sestatus";
|
||||
if (system('sestatus >/dev/null 2>&1') != 0)
|
||||
{
|
||||
diag <<EOS;
|
||||
|
||||
The sestatus command must be available.
|
||||
sestatus is typically included in the policycoreutils package.
|
||||
EOS
|
||||
die;
|
||||
}
|
||||
|
||||
# check that the user is running in the unconfined_t domain
|
||||
note "checking current user domain";
|
||||
my $DOMAIN = (split /:/, `id -Z 2>/dev/null`)[2];
|
||||
note "current user domain is '$DOMAIN'";
|
||||
if ($DOMAIN ne 'unconfined_t')
|
||||
{
|
||||
diag <<'EOS';
|
||||
|
||||
The regression tests must be launched from the unconfined_t domain.
|
||||
|
||||
The unconfined_t domain is typically the default domain for user
|
||||
shell processes. If the default has been changed on your system,
|
||||
you can revert the changes like this:
|
||||
|
||||
$ sudo semanage login -d `whoami`
|
||||
|
||||
Or, you can add a setting to log in using the unconfined_t domain:
|
||||
|
||||
$ sudo semanage login -a -s unconfined_u -r s0-s0:c0.c255 `whoami`
|
||||
|
||||
EOS
|
||||
die;
|
||||
}
|
||||
|
||||
# SELinux must be configured in enforcing mode
|
||||
note "checking selinux operating mode";
|
||||
my $CURRENT_MODE =
|
||||
(split /: */, `LANG=C sestatus | grep '^Current mode:'`)[1];
|
||||
chomp $CURRENT_MODE;
|
||||
note "current operating mode is '$CURRENT_MODE'";
|
||||
if ($CURRENT_MODE eq 'enforcing')
|
||||
{
|
||||
# OK
|
||||
}
|
||||
elsif ($CURRENT_MODE eq 'permissive' || $CURRENT_MODE eq 'disabled')
|
||||
{
|
||||
diag <<'EOS';
|
||||
|
||||
Before running the regression tests, SELinux must be enabled and
|
||||
must be running in enforcing mode.
|
||||
|
||||
If SELinux is currently running in permissive mode, you can
|
||||
switch to enforcing mode using the 'setenforce' command.
|
||||
|
||||
$ sudo setenforce 1
|
||||
|
||||
The system default setting is configured in /etc/selinux/config,
|
||||
or using a kernel boot parameter.
|
||||
EOS
|
||||
die;
|
||||
}
|
||||
else
|
||||
{
|
||||
diag <<EOS;
|
||||
|
||||
Unable to determine the current selinux operating mode. Please
|
||||
verify that the sestatus command is installed and in your PATH.
|
||||
EOS
|
||||
die;
|
||||
}
|
||||
|
||||
# 'sepgsql-regtest' policy module must be loaded
|
||||
note "checking for sepgsql-regtest policy";
|
||||
my $SELINUX_MNT = (split /: */, `sestatus | grep '^SELinuxfs mount:'`)[1];
|
||||
chomp $SELINUX_MNT;
|
||||
if ($SELINUX_MNT eq "")
|
||||
{
|
||||
diag <<EOS;
|
||||
|
||||
Unable to find SELinuxfs mount point.
|
||||
|
||||
The sestatus command should report the location where SELinuxfs
|
||||
is mounted, but did not do so.
|
||||
EOS
|
||||
die;
|
||||
}
|
||||
if (!-e "${SELINUX_MNT}/booleans/sepgsql_regression_test_mode")
|
||||
{
|
||||
diag <<'EOS';
|
||||
|
||||
The 'sepgsql-regtest' policy module appears not to be installed.
|
||||
Without this policy installed, the regression tests will fail.
|
||||
You can install this module using the following commands:
|
||||
|
||||
$ make -f /usr/share/selinux/devel/Makefile
|
||||
$ sudo semodule -u sepgsql-regtest.pp
|
||||
|
||||
To confirm that the policy package is installed, use this command:
|
||||
|
||||
$ sudo semodule -l | grep sepgsql
|
||||
|
||||
EOS
|
||||
die;
|
||||
}
|
||||
|
||||
# Verify that sepgsql_regression_test_mode is active.
|
||||
note "checking whether policy is enabled";
|
||||
foreach
|
||||
my $policy ('sepgsql_regression_test_mode', 'sepgsql_enable_users_ddl')
|
||||
{
|
||||
my $POLICY_STATUS = (split ' ', `getsebool $policy`)[2];
|
||||
note "$policy is '$POLICY_STATUS'";
|
||||
if ($POLICY_STATUS ne "on")
|
||||
{
|
||||
diag <<EOS;
|
||||
|
||||
The SELinux boolean '$policy' must be
|
||||
turned on in order to enable the rules necessary to run the
|
||||
regression tests.
|
||||
|
||||
EOS
|
||||
|
||||
if ($POLICY_STATUS eq "")
|
||||
{
|
||||
diag <<EOS;
|
||||
We attempted to determine the state of this Boolean using
|
||||
'getsebool', but that command did not produce the expected
|
||||
output. Please verify that getsebool is available and in
|
||||
your PATH.
|
||||
EOS
|
||||
}
|
||||
else
|
||||
{
|
||||
diag <<EOS;
|
||||
You can turn on this variable using the following commands:
|
||||
|
||||
\$ sudo setsebool $policy on
|
||||
|
||||
For security reasons, it is suggested that you turn off this
|
||||
variable when regression testing is complete and the associated
|
||||
rules are no longer needed.
|
||||
EOS
|
||||
}
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# checking complete - let's run the tests
|
||||
#
|
||||
|
||||
note "running sepgsql regression tests";
|
||||
|
||||
my $node;
|
||||
|
||||
$node = PostgreSQL::Test::Cluster->new('test');
|
||||
$node->init;
|
||||
$node->append_conf('postgresql.conf', 'log_statement=none');
|
||||
|
||||
{
|
||||
local %ENV = $node->_get_env();
|
||||
|
||||
my $result = run_log(
|
||||
[
|
||||
'postgres', '--single',
|
||||
'-F', '-c',
|
||||
'exit_on_error=true', '-D',
|
||||
$node->data_dir, 'template0'
|
||||
],
|
||||
'<',
|
||||
$ENV{share_contrib_dir} . '/sepgsql.sql');
|
||||
ok($result, 'sepgsql installation script');
|
||||
}
|
||||
|
||||
$node->append_conf('postgresql.conf', 'shared_preload_libraries=sepgsql');
|
||||
$node->start;
|
||||
|
||||
my @tests = qw(label dml ddl alter misc);
|
||||
|
||||
# Check if the truncate permission exists in the loaded policy, and if so,
|
||||
# run the truncate test
|
||||
#
|
||||
# Testing the TRUNCATE regression test can be done by manually adding
|
||||
# the permission with CIL if necessary:
|
||||
# sudo semodule -cE base
|
||||
# sudo sed -i -E 's/(class db_table.*?) \)/\1 truncate\)/' base.cil
|
||||
# sudo semodule -i base.cil
|
||||
push @tests, 'truncate' if -f '/sys/fs/selinux/class/db_table/perms/truncate';
|
||||
|
||||
$node->command_ok(
|
||||
[
|
||||
$ENV{PG_REGRESS}, '--bindir=', '--inputdir=.', '--launcher',
|
||||
'./launcher', @tests
|
||||
],
|
||||
'sepgsql tests');
|
||||
|
||||
done_testing();
|
@ -4,10 +4,10 @@
|
||||
# to try to ensure that the SELinux environment is set up appropriately and
|
||||
# the database is configured correctly.
|
||||
#
|
||||
# Note that this must be run against an installed Postgres database.
|
||||
# There's no equivalent of "make check", and that wouldn't be terribly useful
|
||||
# since much of the value is in checking that you installed sepgsql into
|
||||
# your database correctly.
|
||||
# This must be run against an installed Postgres database. The
|
||||
# purpose of this script is in checking that you installed sepgsql
|
||||
# into your database correctly. For testing sepgsql during
|
||||
# development, "make check", "meson test", etc. are also available.
|
||||
#
|
||||
# This must be run in the contrib/sepgsql directory of a Postgres build tree.
|
||||
#
|
||||
@ -302,5 +302,5 @@ if [ -f /sys/fs/selinux/class/db_table/perms/truncate ]; then
|
||||
tests+=" truncate"
|
||||
fi
|
||||
|
||||
make REGRESS="$tests" REGRESS_OPTS="--launcher ./launcher" installcheck
|
||||
# exit with the exit code provided by "make"
|
||||
PGXS=`pg_config --pgxs`
|
||||
"$(dirname $PGXS)/../../src/test/regress/pg_regress" --inputdir=. --bindir="$PG_BINDIR" --launcher=./launcher $tests
|
||||
|
@ -284,6 +284,17 @@ make check-world PG_TEST_EXTRA='kerberos ldap ssl load_balance libpq_encryption'
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>sepgsql</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Runs the test suite under <filename>contrib/sepgsql</filename>. This
|
||||
requires an SELinux environment that is set up in a specific way; see
|
||||
<xref linkend="sepgsql-regression"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>ssl</literal></term>
|
||||
<listitem>
|
||||
|
@ -151,14 +151,23 @@ $ for DBNAME in template0 template1 postgres; do
|
||||
<sect2 id="sepgsql-regression">
|
||||
<title>Regression Tests</title>
|
||||
|
||||
<para>
|
||||
The <filename>sepgsql</filename> test suite is run if
|
||||
<literal>PG_TEST_EXTRA</literal> contains <literal>sepgsql</literal> (see
|
||||
<xref linkend="regress-additional"/>). This method is suitable during
|
||||
development of <productname>PostgreSQL</productname>. Alternatively, there
|
||||
is a way to run the tests to checks whether a database instance has been
|
||||
set up properly for <literal>sepgsql</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Due to the nature of <productname>SELinux</productname>, running the
|
||||
regression tests for <filename>sepgsql</filename> requires several extra
|
||||
configuration steps, some of which must be done as root.
|
||||
The regression tests will not be run by an ordinary
|
||||
<literal>make check</literal> or <literal>make installcheck</literal> command; you must
|
||||
set up the configuration and then invoke the test script manually.
|
||||
The tests must be run in the <filename>contrib/sepgsql</filename> directory
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The manual tests must be run in the <filename>contrib/sepgsql</filename> directory
|
||||
of a configured PostgreSQL build tree. Although they require a build tree,
|
||||
the tests are designed to be executed against an installed server,
|
||||
that is they are comparable to <literal>make installcheck</literal> not
|
||||
|
@ -3473,6 +3473,8 @@ foreach test_dir : tests
|
||||
# also test/ for non-installed test binaries built separately.
|
||||
env = test_env
|
||||
env.prepend('PATH', temp_install_bindir, test_dir['bd'], test_dir['bd'] / 'test')
|
||||
temp_install_datadir = '@0@@1@'.format(test_install_destdir, dir_prefix / dir_data)
|
||||
env.set('share_contrib_dir', temp_install_datadir / 'contrib')
|
||||
|
||||
foreach name, value : t.get('env', {})
|
||||
env.set(name, value)
|
||||
|
@ -454,6 +454,7 @@ cd $(srcdir) && \
|
||||
PATH="$(bindir):$(CURDIR):$$PATH" \
|
||||
PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' \
|
||||
PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' \
|
||||
share_contrib_dir='$(DESTDIR)$(datadir)/$(datamoduledir)' \
|
||||
$(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl)
|
||||
endef
|
||||
else # PGXS case
|
||||
@ -481,6 +482,7 @@ cd $(srcdir) && \
|
||||
$(with_temp_install) \
|
||||
PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' \
|
||||
PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' \
|
||||
share_contrib_dir='$(abs_top_builddir)/tmp_install$(datadir)/$(datamoduledir)' \
|
||||
$(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl)
|
||||
endef
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user