Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit aeb8ea3

Browse files
committed
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
1 parent 02ed3c2 commit aeb8ea3

File tree

9 files changed

+294
-13
lines changed

9 files changed

+294
-13
lines changed

contrib/sepgsql/.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
/sepgsql-regtest.if
44
/sepgsql-regtest.pp
55
/tmp
6-
# Generated subdirectories
7-
/results/
6+
# Generated by test suite
7+
/tmp_check/

contrib/sepgsql/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ OBJS = \
1515
DATA_built = sepgsql.sql
1616
PGFILEDESC = "sepgsql - SELinux integration"
1717

18+
TAP_TESTS = 1
19+
1820
# Note: because we don't tell the Makefile there are any regression tests,
1921
# we have to clean those result files explicitly
2022
EXTRA_CLEAN = -r $(pg_regress_clean_files) tmp/ *.pp sepgsql-regtest.if sepgsql-regtest.fc

contrib/sepgsql/meson.build

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,13 @@ contrib_targets += custom_target('sepgsql.sql',
4040
install_dir: dir_data / 'contrib',
4141
)
4242

43-
# TODO: implement sepgsql tests
43+
tests += {
44+
'name': 'sepgsql',
45+
'sd': meson.current_source_dir(),
46+
'bd': meson.current_build_dir(),
47+
'tap': {
48+
'tests': [
49+
't/001_sepgsql.pl',
50+
],
51+
},
52+
}

contrib/sepgsql/t/001_sepgsql.pl

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
2+
# Copyright (c) 2024, PostgreSQL Global Development Group
3+
4+
use strict;
5+
use warnings FATAL => 'all';
6+
7+
use PostgreSQL::Test::Cluster;
8+
use PostgreSQL::Test::Utils;
9+
10+
use Test::More;
11+
12+
if (!$ENV{PG_TEST_EXTRA} || $ENV{PG_TEST_EXTRA} !~ /\bsepgsql\b/)
13+
{
14+
plan skip_all =>
15+
'Potentially unsafe test sepgsql not enabled in PG_TEST_EXTRA';
16+
}
17+
18+
note "checking selinux environment";
19+
20+
# matchpathcon must be present to assess whether the installation environment
21+
# is OK.
22+
note "checking for matchpathcon";
23+
if (system('matchpathcon -n . >/dev/null 2>&1') != 0)
24+
{
25+
diag <<EOS;
26+
27+
The matchpathcon command must be available.
28+
Please install it or update your PATH to include it
29+
(it is typically in '/usr/sbin', which might not be in your PATH).
30+
matchpathcon is typically included in the libselinux-utils package.
31+
EOS
32+
die;
33+
}
34+
35+
# runcon must be present to launch psql using the correct environment
36+
note "checking for runcon";
37+
if (system('runcon --help >/dev/null 2>&1') != 0)
38+
{
39+
diag <<EOS;
40+
41+
The runcon command must be available.
42+
runcon is typically included in the coreutils package.
43+
EOS
44+
die;
45+
}
46+
47+
# check sestatus too, since that lives in yet another package
48+
note "checking for sestatus";
49+
if (system('sestatus >/dev/null 2>&1') != 0)
50+
{
51+
diag <<EOS;
52+
53+
The sestatus command must be available.
54+
sestatus is typically included in the policycoreutils package.
55+
EOS
56+
die;
57+
}
58+
59+
# check that the user is running in the unconfined_t domain
60+
note "checking current user domain";
61+
my $DOMAIN = (split /:/, `id -Z 2>/dev/null`)[2];
62+
note "current user domain is '$DOMAIN'";
63+
if ($DOMAIN ne 'unconfined_t')
64+
{
65+
diag <<'EOS';
66+
67+
The regression tests must be launched from the unconfined_t domain.
68+
69+
The unconfined_t domain is typically the default domain for user
70+
shell processes. If the default has been changed on your system,
71+
you can revert the changes like this:
72+
73+
$ sudo semanage login -d `whoami`
74+
75+
Or, you can add a setting to log in using the unconfined_t domain:
76+
77+
$ sudo semanage login -a -s unconfined_u -r s0-s0:c0.c255 `whoami`
78+
79+
EOS
80+
die;
81+
}
82+
83+
# SELinux must be configured in enforcing mode
84+
note "checking selinux operating mode";
85+
my $CURRENT_MODE =
86+
(split /: */, `LANG=C sestatus | grep '^Current mode:'`)[1];
87+
chomp $CURRENT_MODE;
88+
note "current operating mode is '$CURRENT_MODE'";
89+
if ($CURRENT_MODE eq 'enforcing')
90+
{
91+
# OK
92+
}
93+
elsif ($CURRENT_MODE eq 'permissive' || $CURRENT_MODE eq 'disabled')
94+
{
95+
diag <<'EOS';
96+
97+
Before running the regression tests, SELinux must be enabled and
98+
must be running in enforcing mode.
99+
100+
If SELinux is currently running in permissive mode, you can
101+
switch to enforcing mode using the 'setenforce' command.
102+
103+
$ sudo setenforce 1
104+
105+
The system default setting is configured in /etc/selinux/config,
106+
or using a kernel boot parameter.
107+
EOS
108+
die;
109+
}
110+
else
111+
{
112+
diag <<EOS;
113+
114+
Unable to determine the current selinux operating mode. Please
115+
verify that the sestatus command is installed and in your PATH.
116+
EOS
117+
die;
118+
}
119+
120+
# 'sepgsql-regtest' policy module must be loaded
121+
note "checking for sepgsql-regtest policy";
122+
my $SELINUX_MNT = (split /: */, `sestatus | grep '^SELinuxfs mount:'`)[1];
123+
chomp $SELINUX_MNT;
124+
if ($SELINUX_MNT eq "")
125+
{
126+
diag <<EOS;
127+
128+
Unable to find SELinuxfs mount point.
129+
130+
The sestatus command should report the location where SELinuxfs
131+
is mounted, but did not do so.
132+
EOS
133+
die;
134+
}
135+
if (!-e "${SELINUX_MNT}/booleans/sepgsql_regression_test_mode")
136+
{
137+
diag <<'EOS';
138+
139+
The 'sepgsql-regtest' policy module appears not to be installed.
140+
Without this policy installed, the regression tests will fail.
141+
You can install this module using the following commands:
142+
143+
$ make -f /usr/share/selinux/devel/Makefile
144+
$ sudo semodule -u sepgsql-regtest.pp
145+
146+
To confirm that the policy package is installed, use this command:
147+
148+
$ sudo semodule -l | grep sepgsql
149+
150+
EOS
151+
die;
152+
}
153+
154+
# Verify that sepgsql_regression_test_mode is active.
155+
note "checking whether policy is enabled";
156+
foreach
157+
my $policy ('sepgsql_regression_test_mode', 'sepgsql_enable_users_ddl')
158+
{
159+
my $POLICY_STATUS = (split ' ', `getsebool $policy`)[2];
160+
note "$policy is '$POLICY_STATUS'";
161+
if ($POLICY_STATUS ne "on")
162+
{
163+
diag <<EOS;
164+
165+
The SELinux boolean '$policy' must be
166+
turned on in order to enable the rules necessary to run the
167+
regression tests.
168+
169+
EOS
170+
171+
if ($POLICY_STATUS eq "")
172+
{
173+
diag <<EOS;
174+
We attempted to determine the state of this Boolean using
175+
'getsebool', but that command did not produce the expected
176+
output. Please verify that getsebool is available and in
177+
your PATH.
178+
EOS
179+
}
180+
else
181+
{
182+
diag <<EOS;
183+
You can turn on this variable using the following commands:
184+
185+
\$ sudo setsebool $policy on
186+
187+
For security reasons, it is suggested that you turn off this
188+
variable when regression testing is complete and the associated
189+
rules are no longer needed.
190+
EOS
191+
}
192+
die;
193+
}
194+
}
195+
196+
197+
#
198+
# checking complete - let's run the tests
199+
#
200+
201+
note "running sepgsql regression tests";
202+
203+
my $node;
204+
205+
$node = PostgreSQL::Test::Cluster->new('test');
206+
$node->init;
207+
$node->append_conf('postgresql.conf', 'log_statement=none');
208+
209+
{
210+
local %ENV = $node->_get_env();
211+
212+
my $result = run_log(
213+
[
214+
'postgres', '--single',
215+
'-F', '-c',
216+
'exit_on_error=true', '-D',
217+
$node->data_dir, 'template0'
218+
],
219+
'<',
220+
$ENV{share_contrib_dir} . '/sepgsql.sql');
221+
ok($result, 'sepgsql installation script');
222+
}
223+
224+
$node->append_conf('postgresql.conf', 'shared_preload_libraries=sepgsql');
225+
$node->start;
226+
227+
my @tests = qw(label dml ddl alter misc);
228+
229+
# Check if the truncate permission exists in the loaded policy, and if so,
230+
# run the truncate test
231+
#
232+
# Testing the TRUNCATE regression test can be done by manually adding
233+
# the permission with CIL if necessary:
234+
# sudo semodule -cE base
235+
# sudo sed -i -E 's/(class db_table.*?) \)/\1 truncate\)/' base.cil
236+
# sudo semodule -i base.cil
237+
push @tests, 'truncate' if -f '/sys/fs/selinux/class/db_table/perms/truncate';
238+
239+
$node->command_ok(
240+
[
241+
$ENV{PG_REGRESS}, '--bindir=', '--inputdir=.', '--launcher',
242+
'./launcher', @tests
243+
],
244+
'sepgsql tests');
245+
246+
done_testing();

contrib/sepgsql/test_sepgsql

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
# to try to ensure that the SELinux environment is set up appropriately and
55
# the database is configured correctly.
66
#
7-
# Note that this must be run against an installed Postgres database.
8-
# There's no equivalent of "make check", and that wouldn't be terribly useful
9-
# since much of the value is in checking that you installed sepgsql into
10-
# your database correctly.
7+
# This must be run against an installed Postgres database. The
8+
# purpose of this script is in checking that you installed sepgsql
9+
# into your database correctly. For testing sepgsql during
10+
# development, "make check", "meson test", etc. are also available.
1111
#
1212
# This must be run in the contrib/sepgsql directory of a Postgres build tree.
1313
#
@@ -302,5 +302,5 @@ if [ -f /sys/fs/selinux/class/db_table/perms/truncate ]; then
302302
tests+=" truncate"
303303
fi
304304

305-
make REGRESS="$tests" REGRESS_OPTS="--launcher ./launcher" installcheck
306-
# exit with the exit code provided by "make"
305+
PGXS=`pg_config --pgxs`
306+
"$(dirname $PGXS)/../../src/test/regress/pg_regress" --inputdir=. --bindir="$PG_BINDIR" --launcher=./launcher $tests

doc/src/sgml/regress.sgml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,17 @@ make check-world PG_TEST_EXTRA='kerberos ldap ssl load_balance libpq_encryption'
284284
</listitem>
285285
</varlistentry>
286286

287+
<varlistentry>
288+
<term><literal>sepgsql</literal></term>
289+
<listitem>
290+
<para>
291+
Runs the test suite under <filename>contrib/sepgsql</filename>. This
292+
requires an SELinux environment that is set up in a specific way; see
293+
<xref linkend="sepgsql-regression"/>.
294+
</para>
295+
</listitem>
296+
</varlistentry>
297+
287298
<varlistentry>
288299
<term><literal>ssl</literal></term>
289300
<listitem>

doc/src/sgml/sepgsql.sgml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,23 @@ $ for DBNAME in template0 template1 postgres; do
151151
<sect2 id="sepgsql-regression">
152152
<title>Regression Tests</title>
153153

154+
<para>
155+
The <filename>sepgsql</filename> test suite is run if
156+
<literal>PG_TEST_EXTRA</literal> contains <literal>sepgsql</literal> (see
157+
<xref linkend="regress-additional"/>). This method is suitable during
158+
development of <productname>PostgreSQL</productname>. Alternatively, there
159+
is a way to run the tests to checks whether a database instance has been
160+
set up properly for <literal>sepgsql</literal>.
161+
</para>
162+
154163
<para>
155164
Due to the nature of <productname>SELinux</productname>, running the
156165
regression tests for <filename>sepgsql</filename> requires several extra
157166
configuration steps, some of which must be done as root.
158-
The regression tests will not be run by an ordinary
159-
<literal>make check</literal> or <literal>make installcheck</literal> command; you must
160-
set up the configuration and then invoke the test script manually.
161-
The tests must be run in the <filename>contrib/sepgsql</filename> directory
167+
</para>
168+
169+
<para>
170+
The manual tests must be run in the <filename>contrib/sepgsql</filename> directory
162171
of a configured PostgreSQL build tree. Although they require a build tree,
163172
the tests are designed to be executed against an installed server,
164173
that is they are comparable to <literal>make installcheck</literal> not

meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3473,6 +3473,8 @@ foreach test_dir : tests
34733473
# also test/ for non-installed test binaries built separately.
34743474
env = test_env
34753475
env.prepend('PATH', temp_install_bindir, test_dir['bd'], test_dir['bd'] / 'test')
3476+
temp_install_datadir = '@0@@1@'.format(test_install_destdir, dir_prefix / dir_data)
3477+
env.set('share_contrib_dir', temp_install_datadir / 'contrib')
34763478

34773479
foreach name, value : t.get('env', {})
34783480
env.set(name, value)

src/Makefile.global.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ cd $(srcdir) && \
454454
PATH="$(bindir):$(CURDIR):$$PATH" \
455455
PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' \
456456
PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' \
457+
share_contrib_dir='$(DESTDIR)$(datadir)/$(datamoduledir)' \
457458
$(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl)
458459
endef
459460
else # PGXS case
@@ -481,6 +482,7 @@ cd $(srcdir) && \
481482
$(with_temp_install) \
482483
PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' \
483484
PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' \
485+
share_contrib_dir='$(abs_top_builddir)/tmp_install$(datadir)/$(datamoduledir)' \
484486
$(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl)
485487
endef
486488

0 commit comments

Comments
 (0)