aCdDefLprRwxXz are tested with --dry-run.
I added a primitive test of bc.
There were no tests for AhHt, and I didn't add those either.
mkdir /tmp/d/2
chmod 777 /tmp/d/2
+systemd-tmpfiles --dry-run --create - <<EOF
+d /tmp/d/1 0755 daemon daemon - -
+d /tmp/d/2 0755 daemon daemon - -
+EOF
+
+test ! -d /tmp/d/1
+test -d /tmp/d/2
+
systemd-tmpfiles --create - <<EOF
d /tmp/d/1 0755 daemon daemon - -
d /tmp/d/2 0755 daemon daemon - -
mkdir /tmp/C/{2,3}
touch /tmp/C/3/f1
+systemd-tmpfiles --dry-run --create - <<EOF
+C /tmp/C/1 0755 daemon daemon - /tmp/C/1-origin
+C /tmp/C/2 0755 daemon daemon - /tmp/C/2-origin
+EOF
+
+test ! -d /tmp/C/1
+test -d /tmp/C/2
+
systemd-tmpfiles --create - <<EOF
C /tmp/C/1 0755 daemon daemon - /tmp/C/1-origin
C /tmp/C/2 0755 daemon daemon - /tmp/C/2-origin
#
# 'f'
#
+systemd-tmpfiles --dry-run --create - <<EOF
+f /tmp/f/1 0644 - - - -
+f /tmp/f/2 0644 - - - This string should be written
+EOF
+
+test ! -e /tmp/f/1
+test ! -e /tmp/f/2
+
systemd-tmpfiles --create - <<EOF
f /tmp/f/1 0644 - - - -
f /tmp/f/2 0644 - - - This string should be written
touch /tmp/w/appended
### nop if the target does not exist.
+systemd-tmpfiles --dry-run --create - <<EOF
+w /tmp/w/unexistent 0644 - - - new content
+EOF
+test ! -e /tmp/w/unexistent
+
systemd-tmpfiles --create - <<EOF
w /tmp/w/unexistent 0644 - - - new content
EOF
EOF
### write into an empty file.
+systemd-tmpfiles --dry-run --create - <<EOF
+w /tmp/w/overwritten 0644 - - - old content
+EOF
+test -f /tmp/w/overwritten
+test -z "$(< /tmp/w/overwritten)"
+
systemd-tmpfiles --create - <<EOF
w /tmp/w/overwritten 0644 - - - old content
EOF
test "$(< /tmp/w/overwritten)" = "old content"
### old content is overwritten
+systemd-tmpfiles --dry-run --create - <<EOF
+w /tmp/w/overwritten 0644 - - - new content
+EOF
+test -f /tmp/w/overwritten
+test "$(< /tmp/w/overwritten)" = "old content"
+
systemd-tmpfiles --create - <<EOF
w /tmp/w/overwritten 0644 - - - new content
EOF
test "$(< /tmp/w/appended)" = "$(echo -ne '12\n3')"
### writing into an 'exotic' file should be allowed.
+systemd-tmpfiles --dry-run --create - <<EOF
+w /dev/null - - - - new content
+EOF
+
systemd-tmpfiles --create - <<EOF
w /dev/null - - - - new content
EOF
mkdir /tmp/p
touch /tmp/p/f1
+systemd-tmpfiles --dry-run --create - <<EOF
+p /tmp/p/fifo1 0666 - - - -
+EOF
+
+test ! -p /tmp/p/fifo1
+
systemd-tmpfiles --create - <<EOF
p /tmp/p/fifo1 0666 - - - -
EOF
mkdir /tmp/z/d{1,2}
touch /tmp/z/f1 /tmp/z/d1/f11 /tmp/z/d2/f21
+systemd-tmpfiles --dry-run --create - <<EOF
+z /tmp/z/f1 0755 daemon daemon - -
+z /tmp/z/d1 0755 daemon daemon - -
+EOF
+
+test "$(stat -c %U /tmp/z/f1)" = "$USER"
+test "$(stat -c %U /tmp/z/d1)" = "$USER"
+test "$(stat -c %U /tmp/z/d1/f11)" = "$USER"
+
systemd-tmpfiles --create - <<EOF
z /tmp/z/f1 0755 daemon daemon - -
z /tmp/z/d1 0755 daemon daemon - -
set -o pipefail
test_snippet() {
- systemd-tmpfiles "$@" - <<EOF
+ # First call with --dry-run to test the code paths
+ systemd-tmpfiles --dry-run "$@" - <<EOF
+d /var/tmp/foobar-test-06
+d /var/tmp/foobar-test-06/important
+R /var/tmp/foobar-test-06
+EOF
+
+ systemd-tmpfiles "$@" - <<EOF
d /var/tmp/foobar-test-06
d /var/tmp/foobar-test-06/important
R /var/tmp/foobar-test-06
mkdir -p /tmp/x/{1,2}
touch /tmp/x/1/{x1,x2} /tmp/x/2/{y1,y2} /tmp/x/{z1,z2}
+systemd-tmpfiles --clean --dry-run - <<EOF
+d /tmp/x - - - 0
+x /tmp/x/1
+EOF
+
+find /tmp/x | sort
+test -f /tmp/x/1/x1
+test -f /tmp/x/1/x2
+test -f /tmp/x/2/y1
+test -f /tmp/x/2/y2
+test -f /tmp/x/z1
+test -f /tmp/x/z2
+
systemd-tmpfiles --clean - <<EOF
d /tmp/x - - - 0
x /tmp/x/1
mkdir -p /tmp/x/{1,2}
touch /tmp/x/1/{x1,x2} /tmp/x/2/{y1,y2} /tmp/x/{z1,z2}
+systemd-tmpfiles --dry-run --clean - <<EOF
+d /tmp/x - - - 0
+X /tmp/x/1
+EOF
+
+find /tmp/x | sort
+test -f /tmp/x/1/x1
+test -f /tmp/x/1/x2
+test -f /tmp/x/2/y1
+test -f /tmp/x/2/y2
+test -f /tmp/x/z1
+test -f /tmp/x/z2
+
systemd-tmpfiles --clean - <<EOF
d /tmp/x - - - 0
X /tmp/x/1
mkdir -p /tmp/x/{1,2}
touch /tmp/x/1/{x1,x2} /tmp/x/2/{y1,y2} /tmp/x/{z1,z2}
+systemd-tmpfiles --dry-run --clean - <<EOF
+d /tmp/x - - - 0
+x /tmp/x/[1345]
+x /tmp/x/z*
+EOF
+
+find /tmp/x | sort
+test -f /tmp/x/1/x1
+test -f /tmp/x/1/x2
+test -f /tmp/x/2/y1
+test -f /tmp/x/2/y2
+test -f /tmp/x/z1
+test -f /tmp/x/z2
+
systemd-tmpfiles --clean - <<EOF
d /tmp/x - - - 0
x /tmp/x/[1345]
mkdir -p /tmp/x/{1,2}
touch /tmp/x/1/{x1,x2} /tmp/x/2/{y1,y2} /tmp/x/{z1,z2}
+systemd-tmpfiles --dry-run --clean - <<EOF
+d /tmp/x - - - 0
+X /tmp/x/[1345]
+X /tmp/x/?[12]
+EOF
+
+find /tmp/x | sort
+test -f /tmp/x/1/x1
+test -f /tmp/x/1/x2
+test -f /tmp/x/2/y1
+test -f /tmp/x/2/y2
+test -f /tmp/x/z1
+test -f /tmp/x/z2
+
systemd-tmpfiles --clean - <<EOF
d /tmp/x - - - 0
X /tmp/x/[1345]
mkdir -p /tmp/x/{1,2}/a
touch /tmp/x/1/a/{x1,x2} /tmp/x/2/a/{y1,y2}
+systemd-tmpfiles --dry-run --clean - <<EOF
+# x/X is not supposed to influence r
+x /tmp/x/1/a
+X /tmp/x/2/a
+r /tmp/x/1
+r /tmp/x/2
+EOF
+
+test -f /tmp/x/1/a/x1
+test -f /tmp/x/1/a/x2
+test -f /tmp/x/2/a/y1
+test -f /tmp/x/2/a/y2
+
systemd-tmpfiles --clean - <<EOF
# x/X is not supposed to influence r
x /tmp/x/1/a
mkdir -p /tmp/x/{1,2}/a
touch /tmp/x/1/a/{x1,x2} /tmp/x/2/a/{y1,y2}
+systemd-tmpfiles --dry-run --remove - <<EOF
+# Check that X is honoured below R
+X /tmp/x/1/a
+X /tmp/x/2/a
+R /tmp/x/1
+EOF
+
+test -f /tmp/x/1/a/x1
+test -f /tmp/x/1/a/x2
+test -f /tmp/x/2/a/y1
+test -f /tmp/x/2/a/y2
+
systemd-tmpfiles --remove - <<EOF
# Check that X is honoured below R
X /tmp/x/1/a
touch /tmp/x/{11,22,33}
+systemd-tmpfiles --dry-run --remove - <<EOF
+# Check that X is honoured below R
+r /tmp/x/11
+R /tmp/x/22
+D /tmp/x/33
+EOF
+
+test -f /tmp/x/11
+test -f /tmp/x/22
+test -f /tmp/x/33
+
systemd-tmpfiles --remove - <<EOF
# Check that X is honoured below R
r /tmp/x/11
touch /tmp/ageby/d{3,4}/f{2..4}
# Check for cleanup of "f1" in each of "/tmp/d{1..4}".
+systemd-tmpfiles --dry-run --clean - <<-EOF
+d /tmp/ageby/d1 - - - a:1m -
+e /tmp/ageby/d2 - - - m:3m -
+D /tmp/ageby/d3 - - - c:2s -
+EOF
+
+for d in d{1..3}; do
+ test -f "/tmp/ageby/${d}/f1"
+done
+
systemd-tmpfiles --clean - <<-EOF
d /tmp/ageby/d1 - - - a:1m -
e /tmp/ageby/d2 - - - m:3m -
home='/somewhere'
dst='/tmp/L/1'
src="$home"
+HOME="$home" \
+systemd-tmpfiles --dry-run --create - <<EOF
+L $dst - - - - %h
+EOF
+test ! -h "$dst"
+
HOME="$home" \
systemd-tmpfiles --create - <<EOF
L $dst - - - - %h
src="/usr/share/factory$home"
mkdir -p "$root$src"
dst="$root$home"
+HOME="$home" \
+systemd-tmpfiles --create --dry-run --root="$root" - <<EOF
+L %h - - - -
+EOF
+test ! -h "$dst"
+
HOME="$home" \
systemd-tmpfiles --create --root="$root" - <<EOF
L %h - - - -
touch /tmp/acl_exec
# No ACL set yet
+systemd-tmpfiles --dry-run --create - <<EOF
+a /tmp/acl_exec - - - - u:root:rwX
+EOF
+assert_not_in 'user:root:rw-' "$(getfacl -Ec /tmp/acl_exec)"
+
systemd-tmpfiles --create - <<EOF
a /tmp/acl_exec - - - - u:root:rwX
EOF
export SYSTEMD_LOG_LEVEL=debug
-systemd-tmpfiles --create - <<EOF
+c='
d /tmp/somedir
f /tmp/somedir/somefile - - - - baz
-EOF
+'
+systemd-tmpfiles --create - <<<"$c"
test -f /tmp/somedir/somefile
grep -q baz /tmp/somedir/somefile
-systemd-tmpfiles --purge - <<EOF
-d /tmp/somedir
-f /tmp/somedir/somefile - - - - baz
-EOF
+systemd-tmpfiles --purge --dry-run - <<<"$c"
+test -f /tmp/somedir/somefile
+grep -q baz /tmp/somedir/somefile
+systemd-tmpfiles --purge - <<<"$c"
test ! -f /tmp/somedir/somefile
test ! -d /tmp/somedir/
-systemd-tmpfiles --create --purge - <<EOF
-d /tmp/somedir
-f /tmp/somedir/somefile - - - - baz
-EOF
+systemd-tmpfiles --create --purge --dry-run - <<<"$c"
+test ! -f /tmp/somedir/somefile
+test ! -d /tmp/somedir/
+systemd-tmpfiles --create --purge - <<<"$c"
test -f /tmp/somedir/somefile
grep -q baz /tmp/somedir/somefile
--- /dev/null
+#!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Tests for character and block device creation
+#
+set -eux
+set -o pipefail
+
+rm -rf /tmp/dev
+mkdir /tmp/dev
+
+# We are running tests in /tmp, which would normally be mounted nodev,
+# so we only try with --dry-run.
+
+systemd-tmpfiles --dry-run --create - <<EOF
+c /tmp/dev/char - - - - 11:12
+b /tmp/dev/block - - - - 11:14
+EOF
+
+test ! -e /tmp/dev/char
+test ! -e /tmp/dev/block
+
+systemd-tmpfiles --dry-run --create - <<EOF
+c+ /tmp/dev/char - - - - 11:12
+b+ /tmp/dev/block - - - - 11:14
+EOF
+
+test ! -e /tmp/dev/char
+test ! -e /tmp/dev/block