summaryrefslogtreecommitdiffstats
path: root/test/test-sysusers
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xtest/test-sysusers.sh.in160
-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-1.expected-group2
-rw-r--r--test/test-sysusers/test-1.expected-passwd1
-rw-r--r--test/test-sysusers/test-1.input5
-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.input5
-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.input3
-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.input1
-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.input13
-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.input4
-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.input8
-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.input10
-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.input6
-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.input47
-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.input7
-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.input26
-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.input2
-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.input2
-rw-r--r--test/test-sysusers/unhappy-1.expected-err1
-rw-r--r--test/test-sysusers/unhappy-1.input4
-rw-r--r--test/test-sysusers/unhappy-2.expected-err1
-rw-r--r--test/test-sysusers/unhappy-2.input4
-rw-r--r--test/test-sysusers/unhappy-3.expected-err1
-rw-r--r--test/test-sysusers/unhappy-3.input4
56 files changed, 469 insertions, 0 deletions
diff --git a/test/test-sysusers.sh.in b/test/test-sysusers.sh.in
new file mode 100755
index 0000000..6e133cc
--- /dev/null
+++ b/test/test-sysusers.sh.in
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+set -e
+
+SYSUSERS="${1:-systemd-sysusers}"
+
+[ -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")
+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
+}
+
+[ @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}
+
+ 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 $(ls -1 $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 $(ls -1 $SOURCE/test-*.input | sort -V); do
+ echo "*** Running $f on stdin"
+ prepare_testdir ${f%.input}
+ touch $TESTDIR/etc/sysusers.d/test.conf
+ cat $f | $SYSUSERS --root=$TESTDIR -
+
+ compare ${f%.*} "on stdin"
+done
+
+for f in $(ls -1 $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
+ cat $f | $SYSUSERS --root=$TESTDIR --replace=/etc/sysusers.d/test.conf -
+ # this should be ignored
+ cat $SOURCE/test-1.input | $SYSUSERS --root=$TESTDIR --replace=/usr/lib/sysusers.d/test.conf -
+
+ 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=…)"
+
+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 $(ls -1 $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
+
+ [ @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 $(ls -1 $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
+
+ [ @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 $(ls -1 $SOURCE/unhappy-*.input | sort -V); do
+ echo "*** Running test $f"
+ prepare_testdir ${f%.input}
+ cp $f $TESTDIR/usr/lib/sysusers.d/test.conf
+ $SYSUSERS --root=$TESTDIR 2>&1 | tail -n1 > $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/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-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..297bbe3
--- /dev/null
+++ b/test/test-sysusers/test-1.input
@@ -0,0 +1,5 @@
+# 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..8e18a00
--- /dev/null
+++ b/test/test-sysusers/test-10.input
@@ -0,0 +1,5 @@
+# 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..bffc2cd
--- /dev/null
+++ b/test/test-sysusers/test-11.input
@@ -0,0 +1,3 @@
+#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..5d94846
--- /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..2913120
--- /dev/null
+++ b/test/test-sysusers/test-12.input
@@ -0,0 +1 @@
+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..bad2f09
--- /dev/null
+++ b/test/test-sysusers/test-13.input
@@ -0,0 +1,13 @@
+# 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..0a11a2e
--- /dev/null
+++ b/test/test-sysusers/test-14.input
@@ -0,0 +1,4 @@
+# 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-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..773d9e5
--- /dev/null
+++ b/test/test-sysusers/test-2.input
@@ -0,0 +1,8 @@
+# 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..3257082
--- /dev/null
+++ b/test/test-sysusers/test-3.input
@@ -0,0 +1,10 @@
+# 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..557f61c
--- /dev/null
+++ b/test/test-sysusers/test-4.input
@@ -0,0 +1,6 @@
+# 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..57519d7
--- /dev/null
+++ b/test/test-sysusers/test-5.input
@@ -0,0 +1,47 @@
+# 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..764f57e
--- /dev/null
+++ b/test/test-sysusers/test-6.input
@@ -0,0 +1,7 @@
+# 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..4e10b74
--- /dev/null
+++ b/test/test-sysusers/test-7.input
@@ -0,0 +1,26 @@
+# 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..b76dd3e
--- /dev/null
+++ b/test/test-sysusers/test-8.input
@@ -0,0 +1,2 @@
+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..4d53647
--- /dev/null
+++ b/test/test-sysusers/test-9.input
@@ -0,0 +1,2 @@
+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..d334240
--- /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..b8ed855
--- /dev/null
+++ b/test/test-sysusers/unhappy-1.input
@@ -0,0 +1,4 @@
+# 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..3266b22
--- /dev/null
+++ b/test/test-sysusers/unhappy-2.input
@@ -0,0 +1,4 @@
+# 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..64e60dd
--- /dev/null
+++ b/test/test-sysusers/unhappy-3.input
@@ -0,0 +1,4 @@
+# Ensure it is not allowed to create groups implicitly in the uid:groupname syntax
+#
+#Type Name ID GECOS HOMEDIR
+u u1 100:g1 -