summaryrefslogtreecommitdiffstats
path: root/test/test-sysusers
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xtest/test-sysusers.sh.in175
-rw-r--r--test/test-sysusers/.gitattributes2
-rw-r--r--test/test-sysusers/inline.expected-group2
-rw-r--r--test/test-sysusers/inline.expected-passwd1
-rw-r--r--test/test-sysusers/test-00-basic.expected-group19
-rw-r--r--test/test-sysusers/test-00-basic.expected-passwd2
-rw-r--r--test/test-sysusers/test-00-basic.input41
-rw-r--r--test/test-sysusers/test-1.expected-group2
-rw-r--r--test/test-sysusers/test-1.expected-passwd1
-rw-r--r--test/test-sysusers/test-1.input6
-rw-r--r--test/test-sysusers/test-10.expected-group2
-rw-r--r--test/test-sysusers/test-10.expected-passwd2
-rw-r--r--test/test-sysusers/test-10.input6
-rw-r--r--test/test-sysusers/test-11.expected-group6
-rw-r--r--test/test-sysusers/test-11.expected-passwd6
-rw-r--r--test/test-sysusers/test-11.initial-group4
-rw-r--r--test/test-sysusers/test-11.initial-passwd5
-rw-r--r--test/test-sysusers/test-11.input4
-rw-r--r--test/test-sysusers/test-12.expected-group2
-rw-r--r--test/test-sysusers/test-12.expected-passwd2
-rw-r--r--test/test-sysusers/test-12.initial-group1
-rw-r--r--test/test-sysusers/test-12.initial-passwd1
-rw-r--r--test/test-sysusers/test-12.input2
-rw-r--r--test/test-sysusers/test-13.expected-group5
-rw-r--r--test/test-sysusers/test-13.expected-passwd5
-rw-r--r--test/test-sysusers/test-13.input14
-rw-r--r--test/test-sysusers/test-14.expected-group1
-rw-r--r--test/test-sysusers/test-14.expected-passwd1
-rw-r--r--test/test-sysusers/test-14.initial-group1
-rw-r--r--test/test-sysusers/test-14.input5
-rw-r--r--test/test-sysusers/test-15.expected-group1
-rw-r--r--test/test-sysusers/test-15.expected-passwd1
-rw-r--r--test/test-sysusers/test-15.initial-passwd1
-rw-r--r--test/test-sysusers/test-15.input5
-rw-r--r--test/test-sysusers/test-2.expected-group4
-rw-r--r--test/test-sysusers/test-2.expected-passwd4
-rw-r--r--test/test-sysusers/test-2.input9
-rw-r--r--test/test-sysusers/test-3.expected-group4
-rw-r--r--test/test-sysusers/test-3.expected-passwd4
-rw-r--r--test/test-sysusers/test-3.input11
-rw-r--r--test/test-sysusers/test-4.expected-group1
-rw-r--r--test/test-sysusers/test-4.expected-passwd2
-rw-r--r--test/test-sysusers/test-4.input7
-rw-r--r--test/test-sysusers/test-5.expected-group39
-rw-r--r--test/test-sysusers/test-5.expected-passwd18
-rw-r--r--test/test-sysusers/test-5.input48
-rw-r--r--test/test-sysusers/test-6.expected-group2
-rw-r--r--test/test-sysusers/test-6.expected-passwd1
-rw-r--r--test/test-sysusers/test-6.input8
-rw-r--r--test/test-sysusers/test-7.expected-group16
-rw-r--r--test/test-sysusers/test-7.expected-passwd5
-rw-r--r--test/test-sysusers/test-7.input27
-rw-r--r--test/test-sysusers/test-8.expected-group1
-rw-r--r--test/test-sysusers/test-8.expected-passwd1
-rw-r--r--test/test-sysusers/test-8.input3
-rw-r--r--test/test-sysusers/test-9.expected-group1
-rw-r--r--test/test-sysusers/test-9.expected-passwd2
-rw-r--r--test/test-sysusers/test-9.input3
-rw-r--r--test/test-sysusers/unhappy-1.expected-err1
-rw-r--r--test/test-sysusers/unhappy-1.input5
-rw-r--r--test/test-sysusers/unhappy-2.expected-err1
-rw-r--r--test/test-sysusers/unhappy-2.input5
-rw-r--r--test/test-sysusers/unhappy-3.expected-err1
-rw-r--r--test/test-sysusers/unhappy-3.input5
64 files changed, 573 insertions, 0 deletions
diff --git a/test/test-sysusers.sh.in b/test/test-sysusers.sh.in
new file mode 100755
index 0000000..11e3940
--- /dev/null
+++ b/test/test-sysusers.sh.in
@@ -0,0 +1,175 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -e
+
+SYSUSERS="${1:-systemd-sysusers}"
+
+# shellcheck disable=SC1090
+[ -e "$(dirname "$0")/../systemd-runtest.env" ] && . "$(dirname "$0")/../systemd-runtest.env"
+SYSTEMD_TEST_DATA=${SYSTEMD_TEST_DATA:-@SYSTEMD_TEST_DATA@}
+SOURCE=$SYSTEMD_TEST_DATA/test-sysusers
+
+TESTDIR=$(mktemp --tmpdir --directory "test-sysusers.XXXXXXXXXX")
+# shellcheck disable=SC2064
+trap "rm -rf '$TESTDIR'" EXIT INT QUIT PIPE
+
+prepare_testdir() {
+ mkdir -p "$TESTDIR/etc/sysusers.d/"
+ mkdir -p "$TESTDIR/usr/lib/sysusers.d/"
+ rm -f "$TESTDIR"/etc/*{passwd,group,shadow}
+ for i in $1.initial-{passwd,group,shadow}; do
+ test -f "$i" && cp "$i" "$TESTDIR/etc/${i#*.initial-}"
+ done
+ return 0
+}
+
+# shellcheck disable=SC2050
+[ @SYSTEM_UID_MAX@ -lt @SYSTEM_GID_MAX@ ] && system_guid_max=@SYSTEM_UID_MAX@ || system_guid_max=@SYSTEM_GID_MAX@
+
+preprocess() {
+ m=${2:-$system_guid_max}
+
+ # shellcheck disable=SC2140
+ sed -e "s/SYSTEM_UGID_MAX/$m/g;
+ s#NOLOGIN#@NOLOGIN@#g" "$1"
+}
+
+compare() {
+ if ! diff -u "$TESTDIR/etc/passwd" <(preprocess "$1.expected-passwd" "$3"); then
+ echo "**** Unexpected output for $f $2"
+ exit 1
+ fi
+
+ if ! diff -u "$TESTDIR/etc/group" <(preprocess "$1.expected-group" "$3"); then
+ echo "**** Unexpected output for $f $2"
+ exit 1
+ fi
+}
+
+rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
+
+# happy tests
+for f in $(find "$SOURCE"/test-*.input | sort -V); do
+ echo "*** Running $f"
+ prepare_testdir "${f%.input}"
+ cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
+ $SYSUSERS --root="$TESTDIR"
+
+ compare "${f%.*}" ""
+done
+
+for f in $(find "$SOURCE"/test-*.input | sort -V); do
+ echo "*** Running $f on stdin"
+ prepare_testdir "${f%.input}"
+ touch "$TESTDIR/etc/sysusers.d/test.conf"
+ $SYSUSERS --root="$TESTDIR" - <"$f"
+
+ compare "${f%.*}" "on stdin"
+done
+
+for f in $(find "$SOURCE"/test-*.input | sort -V); do
+ echo "*** Running $f on stdin with --replace"
+ prepare_testdir "${f%.input}"
+ touch "$TESTDIR/etc/sysusers.d/test.conf"
+ # this overrides test.conf which is masked on disk
+ $SYSUSERS --root="$TESTDIR" --replace=/etc/sysusers.d/test.conf - <"$f"
+ # this should be ignored
+ $SYSUSERS --root="$TESTDIR" --replace=/usr/lib/sysusers.d/test.conf - <"$SOURCE/test-1.input"
+
+ compare "${f%.*}" "on stdin with --replace"
+done
+
+# test --inline
+echo "*** Testing --inline"
+prepare_testdir "$SOURCE/inline"
+# copy a random file to make sure it is ignored
+cp "$f" "$TESTDIR/etc/sysusers.d/confuse.conf"
+$SYSUSERS --root="$TESTDIR" --inline \
+ "u u1 222 - - /bin/zsh" \
+ "g g1 111"
+
+compare "$SOURCE/inline" "(--inline)"
+
+# test --replace
+echo "*** Testing --inline with --replace"
+prepare_testdir "$SOURCE/inline"
+# copy a random file to make sure it is ignored
+cp "$f" "$TESTDIR/etc/sysusers.d/confuse.conf"
+$SYSUSERS --root="$TESTDIR" \
+ --inline \
+ --replace=/etc/sysusers.d/confuse.conf \
+ "u u1 222 - - /bin/zsh" \
+ "g g1 111"
+
+compare "$SOURCE/inline" "(--inline --replace=…)"
+
+echo "*** Testing --inline with no /etc"
+rm -rf "${TESTDIR:?}/etc"
+$SYSUSERS --root="$TESTDIR" --inline \
+ "u u1 222 - - /bin/zsh" \
+ "g g1 111"
+
+compare "$SOURCE/inline" "(--inline)"
+
+rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
+
+cat >"$TESTDIR/etc/login.defs" <<EOF
+SYS_UID_MIN abcd
+SYS_UID_MAX abcd
+SYS_GID_MIN abcd
+SYS_GID_MAX abcd
+SYS_UID_MIN 401
+SYS_UID_MAX 555
+SYS_GID_MIN 405
+SYS_GID_MAX 666
+SYS_UID_MIN abcd
+SYS_UID_MAX abcd
+SYS_GID_MIN abcd
+SYS_GID_MAX abcd
+SYS_UID_MIN999
+SYS_UID_MAX999
+SYS_GID_MIN999
+SYS_GID_MAX999
+EOF
+
+for f in $(find "$SOURCE"/test-*.input | sort -V); do
+ echo "*** Running $f (with login.defs)"
+ prepare_testdir "${f%.input}"
+ cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
+ $SYSUSERS --root="$TESTDIR"
+
+ # shellcheck disable=SC2050
+ [ @ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES@ = 1 ] && bound=555 || bound=$system_guid_max
+ compare "${f%.*}" "(with login.defs)" "$bound"
+done
+
+rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
+
+mv "$TESTDIR/etc/login.defs" "$TESTDIR/etc/login.defs.moved"
+ln -s ../../../../../etc/login.defs.moved "$TESTDIR/etc/login.defs"
+
+for f in $(find "$SOURCE"/test-*.input | sort -V); do
+ echo "*** Running $f (with login.defs symlinked)"
+ prepare_testdir "${f%.input}"
+ cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
+ $SYSUSERS --root="$TESTDIR"
+
+ # shellcheck disable=SC2050
+ [ @ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES@ = 1 ] && bound=555 || bound=$system_guid_max
+ compare "${f%.*}" "(with login.defs symlinked)" "$bound"
+done
+
+rm -f "$TESTDIR"/etc/sysusers.d/* "$TESTDIR"/usr/lib/sysusers.d/*
+
+# tests for error conditions
+for f in $(find "$SOURCE"/unhappy-*.input | sort -V); do
+ echo "*** Running test $f"
+ prepare_testdir "${f%.input}"
+ cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
+ SYSTEMD_LOG_LEVEL=info $SYSUSERS --root="$TESTDIR" 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >"$TESTDIR/err"
+ if ! diff -u "$TESTDIR/err" "${f%.*}.expected-err"; then
+ echo "**** Unexpected error output for $f"
+ cat "$TESTDIR/err"
+ exit 1
+ fi
+done
diff --git a/test/test-sysusers/.gitattributes b/test/test-sysusers/.gitattributes
new file mode 100644
index 0000000..f03f6c0
--- /dev/null
+++ b/test/test-sysusers/.gitattributes
@@ -0,0 +1,2 @@
+/*.initial* generated
+/*.expected* generated
diff --git a/test/test-sysusers/inline.expected-group b/test/test-sysusers/inline.expected-group
new file mode 100644
index 0000000..cc9093f
--- /dev/null
+++ b/test/test-sysusers/inline.expected-group
@@ -0,0 +1,2 @@
+g1:x:111:
+u1:x:222:
diff --git a/test/test-sysusers/inline.expected-passwd b/test/test-sysusers/inline.expected-passwd
new file mode 100644
index 0000000..f50f25c
--- /dev/null
+++ b/test/test-sysusers/inline.expected-passwd
@@ -0,0 +1 @@
+u1:x:222:222::/:/bin/zsh
diff --git a/test/test-sysusers/test-00-basic.expected-group b/test/test-sysusers/test-00-basic.expected-group
new file mode 100644
index 0000000..0d08ec9
--- /dev/null
+++ b/test/test-sysusers/test-00-basic.expected-group
@@ -0,0 +1,19 @@
+root:x:0:
+nobody:x:65534:
+adm:x:999:
+wheel:x:998:
+utmp:x:997:
+audio:x:996:
+cdrom:x:995:
+dialout:x:994:
+disk:x:993:
+input:x:992:
+kmem:x:991:
+kvm:x:990:
+lp:x:989:
+render:x:988:
+sgx:x:987:
+tape:x:986:
+tty:x:5:
+video:x:985:
+users:x:984:
diff --git a/test/test-sysusers/test-00-basic.expected-passwd b/test/test-sysusers/test-00-basic.expected-passwd
new file mode 100644
index 0000000..e2b2fdf
--- /dev/null
+++ b/test/test-sysusers/test-00-basic.expected-passwd
@@ -0,0 +1,2 @@
+root:x:0:0:Super User:/root:/bin/sh
+nobody:x:65534:65534:Kernel Overflow User:/:NOLOGIN
diff --git a/test/test-sysusers/test-00-basic.input b/test/test-sysusers/test-00-basic.input
new file mode 100644
index 0000000..3031c6b
--- /dev/null
+++ b/test/test-sysusers/test-00-basic.input
@@ -0,0 +1,41 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+# The superuser
+g root 0 - -
+u root 0:0 "Super User" /root
+
+# The nobody user/group for NFS file systems
+g nobody 65534 - -
+u nobody 65534:65534 "Kernel Overflow User" -
+
+# Administrator group: can *see* more than normal users
+g adm 999 - -
+
+# Administrator group: can *do* more than normal users
+g wheel 998 - -
+
+# Access to shared database of users on the system
+g utmp 997 - -
+
+# Physical and virtual hardware access groups
+g audio 996 - -
+g cdrom 995 - -
+g dialout 994 - -
+g disk 993 - -
+g input 992 - -
+g kmem 991 - -
+g kvm 990 - -
+g lp 989 - -
+g render 988 - -
+g sgx 987 - -
+g tape 986 - -
+g tty 5 - -
+g video 985 - -
+
+# Default group for normal users
+g users 984 - -
diff --git a/test/test-sysusers/test-1.expected-group b/test/test-sysusers/test-1.expected-group
new file mode 100644
index 0000000..cc9093f
--- /dev/null
+++ b/test/test-sysusers/test-1.expected-group
@@ -0,0 +1,2 @@
+g1:x:111:
+u1:x:222:
diff --git a/test/test-sysusers/test-1.expected-passwd b/test/test-sysusers/test-1.expected-passwd
new file mode 100644
index 0000000..f59303b
--- /dev/null
+++ b/test/test-sysusers/test-1.expected-passwd
@@ -0,0 +1 @@
+u1:x:222:222::/:NOLOGIN
diff --git a/test/test-sysusers/test-1.input b/test/test-sysusers/test-1.input
new file mode 100644
index 0000000..05c51e8
--- /dev/null
+++ b/test/test-sysusers/test-1.input
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Trivial smoke test that covers the most basic functionality
+#
+#Type Name ID GECOS HOMEDIR
+u u1 222 - -
+g g1 111 - -
diff --git a/test/test-sysusers/test-10.expected-group b/test/test-sysusers/test-10.expected-group
new file mode 100644
index 0000000..c94a832
--- /dev/null
+++ b/test/test-sysusers/test-10.expected-group
@@ -0,0 +1,2 @@
+u1:x:300:u2
+u2:x:SYSTEM_UGID_MAX:
diff --git a/test/test-sysusers/test-10.expected-passwd b/test/test-sysusers/test-10.expected-passwd
new file mode 100644
index 0000000..e5f2a69
--- /dev/null
+++ b/test/test-sysusers/test-10.expected-passwd
@@ -0,0 +1,2 @@
+u1:x:300:300::/:NOLOGIN
+u2:x:SYSTEM_UGID_MAX:SYSTEM_UGID_MAX::/:NOLOGIN
diff --git a/test/test-sysusers/test-10.input b/test/test-sysusers/test-10.input
new file mode 100644
index 0000000..f5ae087
--- /dev/null
+++ b/test/test-sysusers/test-10.input
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# check that 'm' lines do not conflicts 'u' line
+#
+#Type Name ID GECOS HOMEDIR
+u u1 300 - -
+m u2 u1
diff --git a/test/test-sysusers/test-11.expected-group b/test/test-sysusers/test-11.expected-group
new file mode 100644
index 0000000..815a6c5
--- /dev/null
+++ b/test/test-sysusers/test-11.expected-group
@@ -0,0 +1,6 @@
+o1:x:100:
+g1:x:111:
+u1:x:222:
++giant:::bill,tina,alan,hetty
+-transport:::
++:::
diff --git a/test/test-sysusers/test-11.expected-passwd b/test/test-sysusers/test-11.expected-passwd
new file mode 100644
index 0000000..737e43b
--- /dev/null
+++ b/test/test-sysusers/test-11.expected-passwd
@@ -0,0 +1,6 @@
+root:x:0:0:root:/root:/bin/bash
+systemd-network:x:492:492:Systemd Network Management:/:/usr/sbin/nologin
+systemd-resolve:x:491:491:Systemd Resolver:/:/usr/sbin/nologin
+systemd-timesync:x:493:493:Systemd Time Synchronization:/:/usr/sbin/nologin
+u1:x:222:222::/:NOLOGIN
++::::::
diff --git a/test/test-sysusers/test-11.initial-group b/test/test-sysusers/test-11.initial-group
new file mode 100644
index 0000000..88d31f2
--- /dev/null
+++ b/test/test-sysusers/test-11.initial-group
@@ -0,0 +1,4 @@
+o1:x:100
++giant:::bill,tina,alan,hetty
+-transport:::
++:::
diff --git a/test/test-sysusers/test-11.initial-passwd b/test/test-sysusers/test-11.initial-passwd
new file mode 100644
index 0000000..45d3ffd
--- /dev/null
+++ b/test/test-sysusers/test-11.initial-passwd
@@ -0,0 +1,5 @@
+root:x:0:0:root:/root:/bin/bash
+systemd-network:x:492:492:Systemd Network Management:/:/usr/sbin/nologin
+systemd-resolve:x:491:491:Systemd Resolver:/:/usr/sbin/nologin
+systemd-timesync:x:493:493:Systemd Time Synchronization:/:/usr/sbin/nologin
++::::::
diff --git a/test/test-sysusers/test-11.input b/test/test-sysusers/test-11.input
new file mode 100644
index 0000000..d881b7b
--- /dev/null
+++ b/test/test-sysusers/test-11.input
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#Type Name ID GECOS HOMEDIR
+u u1 222 - -
+g g1 111 - -
diff --git a/test/test-sysusers/test-12.expected-group b/test/test-sysusers/test-12.expected-group
new file mode 100644
index 0000000..5d94846e
--- /dev/null
+++ b/test/test-sysusers/test-12.expected-group
@@ -0,0 +1,2 @@
+root:x:0:
+systemd-coredump:x:1:
diff --git a/test/test-sysusers/test-12.expected-passwd b/test/test-sysusers/test-12.expected-passwd
new file mode 100644
index 0000000..f076f3d
--- /dev/null
+++ b/test/test-sysusers/test-12.expected-passwd
@@ -0,0 +1,2 @@
+root:x:0:0:root:/root:/bin/bash
+systemd-coredump:x:1:1:systemd Core Dumper:/:NOLOGIN
diff --git a/test/test-sysusers/test-12.initial-group b/test/test-sysusers/test-12.initial-group
new file mode 100644
index 0000000..1dbf901
--- /dev/null
+++ b/test/test-sysusers/test-12.initial-group
@@ -0,0 +1 @@
+root:x:0:
diff --git a/test/test-sysusers/test-12.initial-passwd b/test/test-sysusers/test-12.initial-passwd
new file mode 100644
index 0000000..aebc492
--- /dev/null
+++ b/test/test-sysusers/test-12.initial-passwd
@@ -0,0 +1 @@
+root:x:0:0:root:/root:/bin/bash
diff --git a/test/test-sysusers/test-12.input b/test/test-sysusers/test-12.input
new file mode 100644
index 0000000..2dd2e4b
--- /dev/null
+++ b/test/test-sysusers/test-12.input
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+u systemd-coredump 1 "systemd Core Dumper"
diff --git a/test/test-sysusers/test-13.expected-group b/test/test-sysusers/test-13.expected-group
new file mode 100644
index 0000000..1677d41
--- /dev/null
+++ b/test/test-sysusers/test-13.expected-group
@@ -0,0 +1,5 @@
+hoge:x:300:
+baz:x:302:
+yyy:x:SYSTEM_UGID_MAX:
+foo:x:301:
+ccc:x:305:
diff --git a/test/test-sysusers/test-13.expected-passwd b/test/test-sysusers/test-13.expected-passwd
new file mode 100644
index 0000000..4a2c34b
--- /dev/null
+++ b/test/test-sysusers/test-13.expected-passwd
@@ -0,0 +1,5 @@
+foo:x:301:301::/:NOLOGIN
+aaa:x:303:302::/:NOLOGIN
+bbb:x:304:302::/:NOLOGIN
+ccc:x:305:305::/:NOLOGIN
+zzz:x:306:SYSTEM_UGID_MAX::/:NOLOGIN
diff --git a/test/test-sysusers/test-13.input b/test/test-sysusers/test-13.input
new file mode 100644
index 0000000..f2ccd44
--- /dev/null
+++ b/test/test-sysusers/test-13.input
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Ensure that the semantic for the uid:groupname syntax is correct
+#
+#Type Name ID GECOS HOMEDIR
+g hoge 300 - -
+u foo 301 - -
+
+g baz 302 - -
+u aaa 303:baz - -
+u bbb 304:baz - -
+u ccc 305 - -
+
+g yyy -
+u zzz 306:yyy
diff --git a/test/test-sysusers/test-14.expected-group b/test/test-sysusers/test-14.expected-group
new file mode 100644
index 0000000..2e619bc
--- /dev/null
+++ b/test/test-sysusers/test-14.expected-group
@@ -0,0 +1 @@
+pre:x:987:
diff --git a/test/test-sysusers/test-14.expected-passwd b/test/test-sysusers/test-14.expected-passwd
new file mode 100644
index 0000000..3c3bef2
--- /dev/null
+++ b/test/test-sysusers/test-14.expected-passwd
@@ -0,0 +1 @@
+aaa:x:SYSTEM_UGID_MAX:987::/:NOLOGIN
diff --git a/test/test-sysusers/test-14.initial-group b/test/test-sysusers/test-14.initial-group
new file mode 100644
index 0000000..2e619bc
--- /dev/null
+++ b/test/test-sysusers/test-14.initial-group
@@ -0,0 +1 @@
+pre:x:987:
diff --git a/test/test-sysusers/test-14.input b/test/test-sysusers/test-14.input
new file mode 100644
index 0000000..a1cf58b
--- /dev/null
+++ b/test/test-sysusers/test-14.input
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Ensure that a preexisting system group can be used as primary
+#
+#Type Name ID GECOS HOMEDIR
+u aaa -:pre
diff --git a/test/test-sysusers/test-15.expected-group b/test/test-sysusers/test-15.expected-group
new file mode 100644
index 0000000..1dbf901
--- /dev/null
+++ b/test/test-sysusers/test-15.expected-group
@@ -0,0 +1 @@
+root:x:0:
diff --git a/test/test-sysusers/test-15.expected-passwd b/test/test-sysusers/test-15.expected-passwd
new file mode 100644
index 0000000..a880bd4
--- /dev/null
+++ b/test/test-sysusers/test-15.expected-passwd
@@ -0,0 +1 @@
+root::0:0::/root:/bin/sh
diff --git a/test/test-sysusers/test-15.initial-passwd b/test/test-sysusers/test-15.initial-passwd
new file mode 100644
index 0000000..a880bd4
--- /dev/null
+++ b/test/test-sysusers/test-15.initial-passwd
@@ -0,0 +1 @@
+root::0:0::/root:/bin/sh
diff --git a/test/test-sysusers/test-15.input b/test/test-sysusers/test-15.input
new file mode 100644
index 0000000..cc46672
--- /dev/null
+++ b/test/test-sysusers/test-15.input
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Create proper group when matching user entry is in place.
+#
+#Type Name ID GECOS HOMEDIR
+u root 0 "Super User" /root
diff --git a/test/test-sysusers/test-2.expected-group b/test/test-sysusers/test-2.expected-group
new file mode 100644
index 0000000..fa216d7
--- /dev/null
+++ b/test/test-sysusers/test-2.expected-group
@@ -0,0 +1,4 @@
+u1:x:SYSTEM_UGID_MAX:
+u2:x:777:
+u3:x:778:
+u4:x:779:
diff --git a/test/test-sysusers/test-2.expected-passwd b/test/test-sysusers/test-2.expected-passwd
new file mode 100644
index 0000000..ce49e84
--- /dev/null
+++ b/test/test-sysusers/test-2.expected-passwd
@@ -0,0 +1,4 @@
+u1:x:SYSTEM_UGID_MAX:SYSTEM_UGID_MAX:some gecos:/random/dir:NOLOGIN
+u2:x:777:777:some gecos:/random/dir:/bin/zsh
+u3:x:778:778::/random/dir2:/bin/bash
+u4:x:779:779::/:/bin/csh
diff --git a/test/test-sysusers/test-2.input b/test/test-sysusers/test-2.input
new file mode 100644
index 0000000..8d2b1aa
--- /dev/null
+++ b/test/test-sysusers/test-2.input
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Test generation of ID dynamically based on SYSTEM_UGID_MAX and
+# replacement of all fields up to the login shell.
+#
+#Type Name ID GECOS homedir shell
+u u1 - "some gecos" /random/dir -
+u u2 777 "some gecos" /random/dir /bin/zsh
+u u3 778 - /random/dir2 /bin/bash
+u u4 779 - - /bin/csh
diff --git a/test/test-sysusers/test-3.expected-group b/test/test-sysusers/test-3.expected-group
new file mode 100644
index 0000000..c3a6328
--- /dev/null
+++ b/test/test-sysusers/test-3.expected-group
@@ -0,0 +1,4 @@
+hoge:x:300:
+baz:x:302:
+foo:x:301:
+ccc:x:305:
diff --git a/test/test-sysusers/test-3.expected-passwd b/test/test-sysusers/test-3.expected-passwd
new file mode 100644
index 0000000..946303f
--- /dev/null
+++ b/test/test-sysusers/test-3.expected-passwd
@@ -0,0 +1,4 @@
+foo:x:301:301::/:NOLOGIN
+aaa:x:303:302::/:NOLOGIN
+bbb:x:304:302::/:NOLOGIN
+ccc:x:305:305::/:NOLOGIN
diff --git a/test/test-sysusers/test-3.input b/test/test-sysusers/test-3.input
new file mode 100644
index 0000000..b436959
--- /dev/null
+++ b/test/test-sysusers/test-3.input
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Ensure that the semantic for the uid:gid syntax is correct
+#
+#Type Name ID GECOS HOMEDIR
+g hoge 300 - -
+u foo 301 - -
+
+g baz 302 - -
+u aaa 303:302 - -
+u bbb 304:302 - -
+u ccc 305 - -
diff --git a/test/test-sysusers/test-4.expected-group b/test/test-sysusers/test-4.expected-group
new file mode 100644
index 0000000..64913a5
--- /dev/null
+++ b/test/test-sysusers/test-4.expected-group
@@ -0,0 +1 @@
+xxx:x:310:
diff --git a/test/test-sysusers/test-4.expected-passwd b/test/test-sysusers/test-4.expected-passwd
new file mode 100644
index 0000000..99d1048
--- /dev/null
+++ b/test/test-sysusers/test-4.expected-passwd
@@ -0,0 +1,2 @@
+yyy:x:311:310::/:NOLOGIN
+xxx:x:312:310::/:NOLOGIN
diff --git a/test/test-sysusers/test-4.input b/test/test-sysusers/test-4.input
new file mode 100644
index 0000000..85275cb
--- /dev/null
+++ b/test/test-sysusers/test-4.input
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Ensure that already created groups are used when using the uid:gid syntax
+#
+#Type Name ID GECOS HOMEDIR
+g xxx 310
+u yyy 311:310
+u xxx 312:310
diff --git a/test/test-sysusers/test-5.expected-group b/test/test-sysusers/test-5.expected-group
new file mode 100644
index 0000000..e9ef0a7
--- /dev/null
+++ b/test/test-sysusers/test-5.expected-group
@@ -0,0 +1,39 @@
+adm:x:4:
+tty:x:5:
+disk:x:6:
+man:x:12:
+kmem:x:15:
+dialout:x:20:
+fax:x:21:
+voice:x:22:
+cdrom:x:24:
+floppy:x:25:
+tape:x:26:
+sudo:x:27:
+audio:x:29:
+dip:x:30:
+operator:x:37:
+src:x:40:
+shadow:x:42:
+utmp:x:43:
+video:x:44:
+sasl:x:45:
+plugdev:x:46:
+staff:x:50:
+games:x:60:
+users:x:100:
+nogroup:x:65534:
+root:x:0:
+daemon:x:1:
+bin:x:2:
+sys:x:3:
+lp:x:7:
+mail:x:8:
+news:x:9:
+uucp:x:10:
+proxy:x:13:
+www-data:x:33:
+backup:x:34:
+list:x:38:
+irc:x:39:
+gnats:x:41:
diff --git a/test/test-sysusers/test-5.expected-passwd b/test/test-sysusers/test-5.expected-passwd
new file mode 100644
index 0000000..a83d566
--- /dev/null
+++ b/test/test-sysusers/test-5.expected-passwd
@@ -0,0 +1,18 @@
+root:x:0:0::/root:/bin/sh
+daemon:x:1:1::/usr/sbin:NOLOGIN
+bin:x:2:2::/bin:NOLOGIN
+sys:x:3:3::/dev:NOLOGIN
+sync:x:4:65534::/bin:NOLOGIN
+games:x:5:60::/usr/games:NOLOGIN
+man:x:6:12::/var/cache/man:NOLOGIN
+lp:x:7:7::/var/spool/lpd:NOLOGIN
+mail:x:8:8::/var/mail:NOLOGIN
+news:x:9:9::/var/spool/news:NOLOGIN
+uucp:x:10:10::/var/spool/uucp:NOLOGIN
+proxy:x:13:13::/bin:NOLOGIN
+www-data:x:33:33::/var/www:NOLOGIN
+backup:x:34:34::/var/backups:NOLOGIN
+list:x:38:38::/var/list:NOLOGIN
+irc:x:39:39::/var/run/ircd:NOLOGIN
+gnats:x:41:41::/var/lib/gnats:NOLOGIN
+nobody:x:65534:65534::/nonexistent:NOLOGIN
diff --git a/test/test-sysusers/test-5.input b/test/test-sysusers/test-5.input
new file mode 100644
index 0000000..ac005d2
--- /dev/null
+++ b/test/test-sysusers/test-5.input
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Reproduce the base-passwd master.{passwd,group} from Debian
+#
+#Type Name ID GECOS Home directory
+g adm 4 -
+g tty 5 -
+g disk 6 -
+g man 12 -
+g kmem 15 -
+g dialout 20 -
+g fax 21 -
+g voice 22 -
+g cdrom 24 -
+g floppy 25 -
+g tape 26 -
+g sudo 27 -
+g audio 29 -
+g dip 30 -
+g operator 37 -
+g src 40 -
+g shadow 42 -
+g utmp 43 -
+g video 44 -
+g sasl 45 -
+g plugdev 46 -
+g staff 50 -
+g games 60 -
+g users 100 -
+g nogroup 65534 -
+
+u root 0 - /root
+u daemon 1 - /usr/sbin
+u bin 2 - /bin
+u sys 3 - /dev
+u sync 4:65534 - /bin
+u games 5:60 - /usr/games
+u man 6:12 - /var/cache/man
+u lp 7 - /var/spool/lpd
+u mail 8 - /var/mail
+u news 9 - /var/spool/news
+u uucp 10 - /var/spool/uucp
+u proxy 13 - /bin
+u www-data 33 - /var/www
+u backup 34 - /var/backups
+u list 38 - /var/list
+u irc 39 - /var/run/ircd
+u gnats 41 - /var/lib/gnats
+u nobody 65534:65534 - /nonexistent
diff --git a/test/test-sysusers/test-6.expected-group b/test/test-sysusers/test-6.expected-group
new file mode 100644
index 0000000..2ef661a
--- /dev/null
+++ b/test/test-sysusers/test-6.expected-group
@@ -0,0 +1,2 @@
+g1:x:111:
+u1:x:SYSTEM_UGID_MAX:
diff --git a/test/test-sysusers/test-6.expected-passwd b/test/test-sysusers/test-6.expected-passwd
new file mode 100644
index 0000000..d589e2e
--- /dev/null
+++ b/test/test-sysusers/test-6.expected-passwd
@@ -0,0 +1 @@
+u1:x:SYSTEM_UGID_MAX:SYSTEM_UGID_MAX::/:NOLOGIN
diff --git a/test/test-sysusers/test-6.input b/test/test-sysusers/test-6.input
new file mode 100644
index 0000000..f0b2c9c
--- /dev/null
+++ b/test/test-sysusers/test-6.input
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Ensure that existing IDs are not reused by default. I.e. the existing
+# ID 111 from g1 will cause u1 to get a new and different ID (999 on most
+# systems).
+#
+#Type Name ID GECOS HOMEDIR
+g g1 111 - -
+u u1 111 - -
diff --git a/test/test-sysusers/test-7.expected-group b/test/test-sysusers/test-7.expected-group
new file mode 100644
index 0000000..ae9539c
--- /dev/null
+++ b/test/test-sysusers/test-7.expected-group
@@ -0,0 +1,16 @@
+sys:x:3:
+mem:x:8:
+ftp:x:11:
+mail:x:12:
+log:x:19:
+smmsp:x:25:
+proc:x:26:
+games:x:50:
+lock:x:54:
+network:x:90:
+floppy:x:94:
+scanner:x:96:
+power:x:98:
+bin:x:1:
+daemon:x:2:
+http:x:33:
diff --git a/test/test-sysusers/test-7.expected-passwd b/test/test-sysusers/test-7.expected-passwd
new file mode 100644
index 0000000..0c5d370
--- /dev/null
+++ b/test/test-sysusers/test-7.expected-passwd
@@ -0,0 +1,5 @@
+bin:x:1:1::/:NOLOGIN
+daemon:x:2:2::/:NOLOGIN
+mail:x:8:12::/var/spool/mail:NOLOGIN
+ftp:x:14:11::/srv/ftp:NOLOGIN
+http:x:33:33::/srv/http:NOLOGIN
diff --git a/test/test-sysusers/test-7.input b/test/test-sysusers/test-7.input
new file mode 100644
index 0000000..a7f1e57
--- /dev/null
+++ b/test/test-sysusers/test-7.input
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Issue #8315
+#
+#Type Name ID GECOS HOMEDIR
+
+# default arch groups
+# groups first, because we have user/group id mismatch on ftp and mail
+g sys 3 - -
+g mem 8 - -
+g ftp 11 - -
+g mail 12 - -
+g log 19 - -
+g smmsp 25 - -
+g proc 26 - -
+g games 50 - -
+g lock 54 - -
+g network 90 - -
+g floppy 94 - -
+g scanner 96 - -
+g power 98 - -
+
+# default arch users
+u bin 1 - -
+u daemon 2 - -
+u mail 8 - /var/spool/mail
+u ftp 14 - /srv/ftp
+u http 33 - /srv/http
diff --git a/test/test-sysusers/test-8.expected-group b/test/test-sysusers/test-8.expected-group
new file mode 100644
index 0000000..f09b2b6
--- /dev/null
+++ b/test/test-sysusers/test-8.expected-group
@@ -0,0 +1 @@
+groupname:x:300:
diff --git a/test/test-sysusers/test-8.expected-passwd b/test/test-sysusers/test-8.expected-passwd
new file mode 100644
index 0000000..b5b8fac
--- /dev/null
+++ b/test/test-sysusers/test-8.expected-passwd
@@ -0,0 +1 @@
+username:x:SYSTEM_UGID_MAX:300::/:NOLOGIN
diff --git a/test/test-sysusers/test-8.input b/test/test-sysusers/test-8.input
new file mode 100644
index 0000000..055e899
--- /dev/null
+++ b/test/test-sysusers/test-8.input
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+g groupname 300
+u username -:300
diff --git a/test/test-sysusers/test-9.expected-group b/test/test-sysusers/test-9.expected-group
new file mode 100644
index 0000000..33335d4
--- /dev/null
+++ b/test/test-sysusers/test-9.expected-group
@@ -0,0 +1 @@
+user1:x:300:
diff --git a/test/test-sysusers/test-9.expected-passwd b/test/test-sysusers/test-9.expected-passwd
new file mode 100644
index 0000000..fc2a060
--- /dev/null
+++ b/test/test-sysusers/test-9.expected-passwd
@@ -0,0 +1,2 @@
+user1:x:300:300::/:NOLOGIN
+user2:x:SYSTEM_UGID_MAX:300::/:NOLOGIN
diff --git a/test/test-sysusers/test-9.input b/test/test-sysusers/test-9.input
new file mode 100644
index 0000000..dd31ff1
--- /dev/null
+++ b/test/test-sysusers/test-9.input
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+u user1 300
+u user2 -:300
diff --git a/test/test-sysusers/unhappy-1.expected-err b/test/test-sysusers/unhappy-1.expected-err
new file mode 100644
index 0000000..f6b1b3c
--- /dev/null
+++ b/test/test-sysusers/unhappy-1.expected-err
@@ -0,0 +1 @@
+ Failed to parse UID: '9999999999': Numerical result out of range
diff --git a/test/test-sysusers/unhappy-1.input b/test/test-sysusers/unhappy-1.input
new file mode 100644
index 0000000..178382b
--- /dev/null
+++ b/test/test-sysusers/unhappy-1.input
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Ensure invalid uids are detected
+#
+#Type Name ID GECOS HOMEDIR
+u u1 9999999999 - -
diff --git a/test/test-sysusers/unhappy-2.expected-err b/test/test-sysusers/unhappy-2.expected-err
new file mode 100644
index 0000000..5db5c20
--- /dev/null
+++ b/test/test-sysusers/unhappy-2.expected-err
@@ -0,0 +1 @@
+Failed to create u1: please create GID 100
diff --git a/test/test-sysusers/unhappy-2.input b/test/test-sysusers/unhappy-2.input
new file mode 100644
index 0000000..8d52746
--- /dev/null
+++ b/test/test-sysusers/unhappy-2.input
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Ensure it is not allowed to create groups implicitly in the uid:gid syntax
+#
+#Type Name ID GECOS HOMEDIR
+u u1 100:100 -
diff --git a/test/test-sysusers/unhappy-3.expected-err b/test/test-sysusers/unhappy-3.expected-err
new file mode 100644
index 0000000..d55b366
--- /dev/null
+++ b/test/test-sysusers/unhappy-3.expected-err
@@ -0,0 +1 @@
+Group g1 not found.
diff --git a/test/test-sysusers/unhappy-3.input b/test/test-sysusers/unhappy-3.input
new file mode 100644
index 0000000..cd4de7e
--- /dev/null
+++ b/test/test-sysusers/unhappy-3.input
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Ensure it is not allowed to create groups implicitly in the uid:groupname syntax
+#
+#Type Name ID GECOS HOMEDIR
+u u1 100:g1 -