[Pkg-shadow-devel] [Git][debian/adduser][wip/improve-testsuite] 6 commits: make AdduserTestsCommon a proper module
Marc Haber (@zugschlus)
gitlab at salsa.debian.org
Sat Jan 24 19:43:23 GMT 2026
Marc Haber pushed to branch wip/improve-testsuite at Debian / adduser
Commits:
ca633511 by Marc Haber at 2026-01-24T20:35:12+01:00
make AdduserTestsCommon a proper module
Git-Dch: ignore
- - - - -
f6e7556f by Marc Haber at 2026-01-24T20:35:12+01:00
improve existing test helper functions
This also adds cleanup_user and cleanup_tree
Git-Dch: ignore
- - - - -
9df76bbe by Marc Haber at 2026-01-24T20:35:12+01:00
add cleanup class to help cleaning up after tests
Git-Dch: ignore
- - - - -
4d401a7e by Marc Haber at 2026-01-24T20:35:12+01:00
add code to do better home directory tests
this pulls part of the skel.t to the library so that other tests
can work with strange files in /etc/skel, this might help debugging
code that handles the home directory contents
Git-Dch: ignore
- - - - -
c8f761b7 by Marc Haber at 2026-01-24T20:35:12+01:00
make skel.t use the new Common functions
Git-Dch: ignore
- - - - -
034bc07c by Marc Haber at 2026-01-24T20:35:12+01:00
adapt three tests to use the new cleanup class
Git-Dch: ignore
- - - - -
5 changed files:
- debian/tests/f/addusertogroup_underscore.t
- debian/tests/f/deluser_quiet.t
- debian/tests/f/skel.t
- debian/tests/f/uidgidpool.t
- debian/tests/lib/AdduserTestsCommon.pm
Changes:
=====================================
debian/tests/f/addusertogroup_underscore.t
=====================================
@@ -9,12 +9,17 @@ use warnings;
use AdduserTestsCommon;
+my $cl_user = AdduserTestsCommon::AdduserTestCleanup->new(
+ \&cleanup_user
+);
+
# create user and group
my $test_user="u1099397";
my $test_sysuser="_u1099397";
my $test_group="g1099397";
my $test_sysgroup="_g1099397";
my $nonexistent="/nonexistent";
+$cl_user->add(qw($test_user $test_sysuser $test_group $test_sysgroup));
assert_user_does_not_exist($test_user);
assert_user_does_not_exist($test_sysuser);
assert_group_does_not_exist($test_group);
@@ -113,6 +118,7 @@ assert_command_success('/usr/sbin/deluser',
$test_sysuser);
assert_user_does_not_exist($test_sysuser);
+$cl_user->finalize();
# end of test
# vim: tabstop=4 shiftwidth=4 expandtab
=====================================
debian/tests/f/deluser_quiet.t
=====================================
@@ -9,13 +9,12 @@ my $name='duq';
use AdduserTestsCommon;
-
-END {
- remove_tree("/home/$name");
- remove_tree("/var/mail/$name");
-}
+my $cl_user = AdduserTestsCommon::AdduserTestCleanup->new(
+ \&cleanup_user
+);
assert_user_does_not_exist($name);
+$cl_user->add($name);
assert_command_success(
'/usr/sbin/adduser',
'--stdoutmsglevel=error', '--stderrmsglevel=error',
@@ -28,5 +27,6 @@ my $output = `/usr/sbin/deluser --stdoutmsglevel=error --stderrmsglevel=error $n
is($output, '', 'option "--stdoutmsglevel=error" silences deluser output under normal use');
assert_user_does_not_exist($name);
+$cl_user->finalize();
# vim: tabstop=4 shiftwidth=4 expandtab
=====================================
debian/tests/f/skel.t
=====================================
@@ -10,24 +10,10 @@ use AdduserTestsCommon;
my $name="ausskel";
END {
- remove_tree("/var/mail/$name");
- unlink("/etc/skel/test\ file");
- unlink("/etc/skel/Tüst");
- unlink("/etc/skel/ŞĞÇaŞ-tst");
- unlink("/etc/skel/Masaüstü/ŞĞÇaŞ-tst");
- rmdir("/etc/skel/Masaüstü");
+ cleanup_home_directory_tests();
+ cleanup_user($name);
}
-
-system("cp /etc/skel/.bashrc /etc/skel/test\\ file");
-assert_path_is_a_file("/etc/skel/test file");
-system("cp /etc/skel/.bashrc /etc/skel/Tüst");
-assert_path_is_a_file("/etc/skel/Tüst");
-system("cp /etc/skel/.bashrc /etc/skel/ŞĞÇaŞ-tst");
-assert_path_is_a_file("/etc/skel/ŞĞÇaŞ-tst");
-system("mkdir -p /etc/skel/Masaüstü");
-assert_path_is_a_directory("/etc/skel/Masaüstü");
-system("cp /etc/skel/.bashrc /etc/skel/Masaüstü/ŞĞÇaŞ-tst");
-assert_path_is_a_file("/etc/skel/Masaüstü/ŞĞÇaŞ-tst");
+my $homedir_contents = initialize_home_directory_tests();
assert_user_does_not_exist($name);
assert_command_success(
@@ -40,15 +26,6 @@ assert_command_success(
assert_user_exists($name);
assert_user_has_home_directory($name,"/home/$name");
assert_path_is_a_directory("/home/$name");
-
-my $skel_list = `find /etc/skel/ -mindepth 1 -printf "%f %l %m %s\n" | sort`;
-my $home_list = `find /home/$name/ -mindepth 1 -printf "%f %l %m %s\n" | sort`;
-ok($? == 0, "find /home/$name successful");
-if( !ok($home_list eq $skel_list, 'files copied to home directory correct') ) {
- print("skel_list: $skel_list\n");
- print("home_list $home_list\n");
- system("ls -al /etc/skel");
- system("ls -al /home/$name");
-}
+assert_user_home_directory_content($name, "/home/$name", $homedir_contents);
# vim: tabstop=4 shiftwidth=4 expandtab
=====================================
debian/tests/f/uidgidpool.t
=====================================
@@ -10,6 +10,14 @@ use AdduserTestsCommon;
my @quiet=("--stdoutmsglevel=error", '--stderrmsglevel=error');
+my $cl_user = AdduserTestsCommon::AdduserTestCleanup->new(
+ \&cleanup_user
+);
+my $cl_tree = AdduserTestsCommon::AdduserTestCleanup->new(
+ \&cleanup_tree
+);
+
+
# single pool file
my $uidpoolfile="/etc/adduser-uidpool.conf";
my $gidpoolfile="/etc/adduser-gidpool.conf";
@@ -17,6 +25,8 @@ my $poolbasedir="/etc/adduser-pool.d";
my $uidpooldir="$poolbasedir/uid";
my $gidpooldir="$poolbasedir/gid";
my %confhash;
+$cl_tree->add(qw(/etc/adduser-uidpool.conf /etc/adduser-gidpool.conf));
+$cl_tree->add(qw(/etc/adduser-pool.d));
my $auid=40123;
my $agid=40234;
@@ -40,6 +50,8 @@ my @uidlist = (
'shell' => '/bin/sh',
}
);
+$cl_tree->add(qw(/home/pool101 /home/pool202));
+$cl_user->add(qw(pooluid101 pooluid202));
my $firstuid = (sort map {$_->{id}} @uidlist)[0];
my @uidreserved = (
@@ -52,6 +64,8 @@ my @uidreserved = (
'shell' => '/bin/sh',
}
);
+$cl_tree->add(qw(/home/uidreserved1 /home/auidreserved1));
+$cl_user->add(qw(uidreserved1));
my @gidlist = (
{
@@ -69,6 +83,7 @@ my @gidreserved = (
id => $firstgid,
}
);
+$cl_user->add(qw(poolgid101 poolgid202 gidreserved1));
# test creating user/group without uidpool set
@@ -414,7 +429,7 @@ foreach my $user( @uidlist ) {
cleanup();
}
-# remove test pool directories
-assert_command_success('rm', '-rf', $uidpooldir, $gidpooldir, $poolbasedir);
+$cl_user->finalize();
+$cl_tree->finalize();
# vim: tabstop=4 shiftwidth=4 expandtab
=====================================
debian/tests/lib/AdduserTestsCommon.pm
=====================================
@@ -1,12 +1,97 @@
+package AdduserTestsCommon;
+
+use utf8;
+use Exporter 'import';
use diagnostics;
use strict;
use warnings;
use Encode;
-use utf8;
use I18N::Langinfo qw(langinfo CODESET);
use File::Path qw(remove_tree);
use Test::More qw(no_plan);
+our @EXPORT = qw(
+ egetgrnam
+ egetpwnam
+ in_range
+ find_unused_uid
+ find_unused_name
+ find_unused_gid
+ assert_command_success
+ assert_command_failure
+ assert_command_result_silent
+ assert_command_failure_silent
+ assert_command_success_silent
+ assert_command_match_output
+ initialize_home_directory_tests
+ cleanup_home_directory_tests
+ assert_user_has_home_directory
+ assert_user_home_directory_empty
+ assert_user_home_directory_content
+ assert_group_does_not_exist
+ assert_group_is_system
+ assert_group_is_non_system
+ assert_user_is_system
+ assert_user_is_non_system
+ assert_gid_does_not_exist
+ assert_group_exists
+ assert_gid_exists
+ assert_group_gid_exists
+ group_gid_exists
+ assert_group_membership_does_not_exist
+ assert_group_membership_exists
+ group_membership_exists
+ assert_primary_group_membership_exists
+ primary_group_membership_exists
+ assert_supplementary_group_membership_exists
+ assert_supplementary_group_membership_does_not_exist
+ supplementary_group_membership_exists
+ assert_path_does_not_exist
+ assert_path_exists
+ assert_path_has_mode
+ assert_path_has_ownership
+ assert_path_is_a_file
+ assert_path_is_a_directory
+ assert_path_is_an_empty_directory
+ assert_user_does_not_exist
+ assert_user_exists
+ assert_uid_does_not_exist
+ assert_uid_exists
+ assert_user_uid_exists
+ user_uid_exists
+ assert_user_has_disabled_password
+ assert_user_has_comment
+ assert_dir_group_owner
+ assert_user_has_login_shell
+ assert_user_has_uid
+ assert_group_has_gid
+ which
+ apply_config
+ apply_config_hash
+ assert_user_status
+ existing_user_status
+ existing_group_status
+ cleanup_tree
+ cleanup_user
+ EXISTING_NOT_FOUND
+ EXISTING_FOUND
+ EXISTING_SYSTEM
+ EXISTING_ID_MISMATCH
+ EXISTING_LOCKED
+ EXISTING_HAS_PASSWORD
+ EXISTING_EXPIRED
+ EXISTING_NOLOGIN
+ SYS_MIN
+ SYS_MAX
+ USER_MIN
+ USER_MAX
+ remove_tree
+ is
+ ok
+ like
+);
+
+
BEGIN {
if (! -f '/var/cache/adduser/tests/state.tar') {
my @conffiles = (
@@ -49,6 +134,13 @@ my $charset = langinfo(CODESET);
binmode(STDOUT, ":encoding($charset)");
binmode(STDERR, ":encoding($charset)");
+our @skelfiles = (
+ "test file",
+ "Tüst",
+ "ŞĞÇaŞ-tst",
+ "Masaüstü/ŞĞÇaŞ-tst",
+);
+
sub egetgrnam {
my ($name) = @_;
$name = encode($charset, $name);
@@ -182,6 +274,49 @@ sub assert_command_match_output {
isnt($? >> 8, 0, "command failure (expected): @_");
}
+sub initialize_home_directory_tests {
+ # initialize /etc/skel with some weird files
+ ok(1, "initialize /etc/skel with test files");
+ system("mkdir", "-p", "/etc/skel/Masaüstü");
+ assert_path_is_a_directory("/etc/skel/Masaüstü");
+ foreach my $file (@skelfiles) {
+ system("cp", "/etc/skel/.bashrc", "/etc/skel/$file");
+ assert_path_is_a_file("/etc/skel/$file");
+ }
+
+ my $skel_contents = `find /etc/skel/ -mindepth 1 -printf "%f %l %m %s\n" | sort`;
+ return $skel_contents;
+}
+
+sub assert_user_has_home_directory {
+ my ($user, $home) = @_;
+ is((egetpwnam($user))[7], $home, "user has home directory: ~$user is $home");
+}
+
+sub assert_user_home_directory_empty {
+ my ($user, $home) = @_;
+}
+
+sub assert_user_home_directory_content {
+ my ($user, $home, $expected_content) = @_;
+ my $current_content = `find $home -mindepth 1 -printf "%f %l %m %s\n" | sort`;
+ if( !ok($expected_content eq $current_content, 'files copied to home directory correct') ) {
+ print("expected_content (internal format):\n$expected_content\n");
+ print("current_content (internal format):\n$current_content\n");
+ system("ls", "-al", "$home");
+ }
+}
+
+sub cleanup_home_directory_tests {
+ ok(1, "remove test files from /etc/skel");
+ foreach my $file (@skelfiles) {
+ cleanup_tree("/etc/skel/$file");
+ assert_path_does_not_exist("/etc/skel/$file");
+ }
+ cleanup_tree("/etc/skel/Masaüstü");
+ assert_path_does_not_exist("/etc/skel/Masaüstü");
+}
+
sub assert_group_does_not_exist {
my $group = shift;
is(egetgrnam($group), undef, "group does not exist: $group");
@@ -333,7 +468,7 @@ sub supplementary_group_membership_exists {
}
sub assert_path_does_not_exist {
- my $path = shift;
+ my $path = encode('UTF-8', shift);
ok(! -e $path, "path does not exist: $path");
}
@@ -383,17 +518,17 @@ sub assert_path_has_ownership {
}
sub assert_path_is_a_file {
- my $path = shift;
+ my $path = encode('UTF-8', shift);
ok(-f $path, "path is a file: $path");
}
sub assert_path_is_a_directory {
- my $path = shift;
+ my $path = encode('UTF-8', shift);
ok(-d $path, "path is a directory: $path");
}
sub assert_path_is_an_empty_directory {
- my $path = shift;
+ my $path = encode('UTF-8', shift);
my $name = "path is an empty directory: $path";
my $dh;
@@ -471,11 +606,6 @@ sub assert_user_has_disabled_password {
fail($name);
}
-sub assert_user_has_home_directory {
- my ($user, $home) = @_;
- is((egetpwnam($user))[7], $home, "user has home directory: ~$user is $home");
-}
-
sub assert_user_has_comment {
my ($user, $comment) = @_;
is((egetpwnam($user))[6], $comment, "user has comment: ~$user is $comment");
@@ -626,6 +756,109 @@ sub existing_group_status {
return $ret;
}
+# those functions can be used as cleanup functions for AdduserTestCleanup
+
+sub cleanup_tree {
+ my ($path) = @_;
+ return unless defined $path && length $path;
+
+ remove_tree($path);
+}
+
+sub cleanup_user {
+ my ($username) = @_;
+ return unless defined $username && length $username;
+
+ my $home_dir;
+
+ # Look up passwd entry
+ if (my @pw = getpwnam($username)) {
+ $home_dir = $pw[7]; # in getpwnam: (name, passwd, uid, gid, quota, comment, gcos, dir, shell)
+ }
+
+ open(my $null, '>', '/dev/null') or die;
+ open(STDOUT, '>&', $null);
+ open(STDERR, '>&', $null);
+ system('userdel', '-r', $username);
+ system('groupdel', $username);
+ close($null);
+
+ remove_tree($home_dir) if $home_dir;
+ remove_tree("/var/mail/$username");
+ remove_tree("/var/spool/cron/crontabs/$username");
+}
+
+
+package AdduserTestsCommon::AdduserTestCleanup;
+
+sub new {
+ my ($class, $callback) = @_;
+ bless {
+ list => [],
+ callback => $callback,
+ done => 0,
+ }, $class;
+}
+
+sub add {
+ my ($self, @items) = @_;
+ push @{ $self->{list} }, @items;
+}
+
+sub finalize {
+ my ($self) = @_;
+ return if $self->{done}++;
+
+ my $cb = $self->{callback} or return;
+ for my $item (@{ $self->{list} }) {
+ eval { $cb->($item) };
+ warn "cleanup failed for [$item]: $@" if $@;
+ }
+}
+
+sub DESTROY {
+ my ($self) = @_;
+
+ # Safe fallback only
+ return if ${^GLOBAL_PHASE} eq 'DESTRUCT';
+
+ $self->finalize;
+}
+
+
+# example usage
+#
+# use AdduserTestsCommon::AdduserTestCleanup;
+#
+# sub cleanup_file {
+# my ($path) = @_;
+# unlink $path or warn "unlink $path failed: $!";
+# }
+#
+# my $cleanup = AdduserTestsCommon::AdduserTestCleanup->new(
+# sub {
+# my ($item) = @_;
+# cleanup_file($item);
+# }
+# );
+#
+# $cleanup->add(qw(
+# /tmp/adduser-test-1
+# /tmp/adduser-test-2
+# ));
+#
+# $cleanup->add(qw(
+# /tmp/adduser-test-3
+# ));
+#
+# # later, at a convenient point
+# $cleanup->finalize;
+#
+#
+# # Leaving the block destroys $cleanup, triggering cleanup callbacks
+#
+# done_testing;
+
1;
# vim: tabstop=4 shiftwidth=4 expandtab
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/3e98f569c74c02a77b3249aba29d3d721c069667...034bc07c4fdeb045c9e6178294e363ef662ef59b
--
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/3e98f569c74c02a77b3249aba29d3d721c069667...034bc07c4fdeb045c9e6178294e363ef662ef59b
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-shadow-devel/attachments/20260124/38159dad/attachment-0001.htm>
More information about the Pkg-shadow-devel
mailing list