mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-10 01:17:44 +03:00
test-execute: Fix systemd escaping and shell issues
In most cases, systemd requires escaping $ (for systemd variable substitution) and % (for specifiers) by doubling them. This was somewhat of an issue in tests like exec-environment*.service where systemd was doing the substitutions and we were not really checking that those were available in the actual environment of the command. Fix that. Expressions such as `exit $(test ...)` are incorrect. They only work because $(test ...) will produce no output, so the command will become a bare "exit" which will exit with the status of the latest executed command which turns out to be the test... The direct approach is simply calling "test" as the last command, for which the shell will propagate the exit status. One situation where this was breaking tests was on `exit $(test ...) && $(test ...) && $(test ...)` where the second and third tests were not really executing, since the first command is actually `exit` so && was doing nothing there. Fixed it by just using `test ... && test ... && test ...` as it was initially intended. Pass -x to all shell executions for them to produce useful debugging output to stderr. Consequently, removed most of the explicit `echo`s that are no longer needed. Mark all units as Type=oneshot explicitly. Also made sure all shell variables are properly quoted. v2: Added an explicit LC_ALL=C to ionice invocations since some locales (such as French) will add a space before the colon in the output. Tested by running `sudo ./test-execute` and confirming all tests enabled on my system (essentially all of them except for the s390 one) passed. Tweaked the variables or options or expected values and confirmed the tests do indeed fail when the values are not exactly the expected ones. v2: Also tested with `LANG=fr_FR.UTF-8 sudo ./test-execute` to confirm it still works in a different locale.
This commit is contained in:
parent
8f84882240
commit
cdaf507048
@ -2,5 +2,6 @@
|
||||
Description=Test for CapabilityBoundingSet
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'c=$(capsh --print | grep "Bounding set " | grep "cap_chown"); echo $c; exit $(test -z $c)'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(capsh --print | grep "^Bounding set .*cap_chown"); test -z "$$c"'
|
||||
Type=oneshot
|
||||
CapabilityBoundingSet=~CAP_CHOWN
|
||||
|
@ -2,6 +2,7 @@
|
||||
Description=Test for CapabilityBoundingSet
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'c=$(capsh --print | grep "Bounding set " | cut -f 2 -d "="); echo $c; exit $(test $c = "cap_chown,cap_fowner,cap_kill")'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(capsh --print | grep "Bounding set "); test "$$c" = "Bounding set =cap_chown,cap_fowner,cap_kill"'
|
||||
Type=oneshot
|
||||
CapabilityBoundingSet=CAP_FOWNER
|
||||
CapabilityBoundingSet=CAP_KILL CAP_CHOWN
|
||||
|
@ -2,6 +2,7 @@
|
||||
Description=Test for CapabilityBoundingSet
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'c=$(capsh --print | grep "Bounding set " | cut -f 2 -d "="); echo $c; exit $(test -z $c)'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(capsh --print | grep "Bounding set "); test "$$c" = "Bounding set ="'
|
||||
Type=oneshot
|
||||
CapabilityBoundingSet=CAP_FOWNER CAP_KILL
|
||||
CapabilityBoundingSet=
|
||||
|
@ -2,5 +2,6 @@
|
||||
Description=Test for CapabilityBoundingSet
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'c=$(capsh --print | grep "Bounding set " | cut -f 2 -d "="); echo $c; exit $(test $c = "cap_fowner,cap_kill")'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(capsh --print | grep "Bounding set "); test "$$c" = "Bounding set =cap_fowner,cap_kill"'
|
||||
Type=oneshot
|
||||
CapabilityBoundingSet=CAP_FOWNER CAP_KILL
|
||||
|
@ -2,6 +2,7 @@
|
||||
Description=Test for Environment
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test ! "$VAR1" = "word1 word2") && $(test ! "$VAR2" = word3) && $(test ! "$VAR3" = \'$word 5 6\')'
|
||||
ExecStart=/bin/sh -x -c 'test "$${VAR1-unset}" = "unset" && test "$${VAR2-unset}" = "unset" && test "$${VAR3-unset}" = "unset"'
|
||||
Type=oneshot
|
||||
Environment="VAR1=word1 word2" VAR2=word3 "VAR3=$word 5 6"
|
||||
Environment=
|
||||
|
@ -2,6 +2,7 @@
|
||||
Description=Test for Environment
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test "$VAR1" = "word1 word2") && $(test "$VAR2" = word3) && $(test "$VAR3" = foobar)'
|
||||
ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = foobar'
|
||||
Type=oneshot
|
||||
Environment="VAR1=word1 word2" VAR2=word3 "VAR3=$word 5 6"
|
||||
Environment="VAR3=foobar"
|
||||
|
@ -2,5 +2,6 @@
|
||||
Description=Test for Environment
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test "$VAR1" = "word1 word2") && $(test "$VAR2" = word3) && $(test "$VAR3" = \'$word 5 6\')'
|
||||
ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6"'
|
||||
Type=oneshot
|
||||
Environment="VAR1=word1 word2" VAR2=word3 "VAR3=$word 5 6"
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for EnvironmentFile
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test "$VAR1" = "word1 word2") && $(test "$VAR2" = word3) && $(test "$VAR3" = \'$word 5 6\')'
|
||||
ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6"'
|
||||
Type=oneshot
|
||||
EnvironmentFile=/tmp/test-exec_environmentfile.conf
|
||||
|
@ -2,5 +2,6 @@
|
||||
Description=Test for Group
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test $(id -n -g) = nobody)'
|
||||
ExecStart=/bin/sh -x -c 'test "$$(id -n -g)" = "nobody"'
|
||||
Type=oneshot
|
||||
Group=nobody
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for IgnoreSIGPIPE=no
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'kill -PIPE 0'
|
||||
ExecStart=/bin/sh -x -c 'kill -PIPE 0'
|
||||
Type=oneshot
|
||||
IgnoreSIGPIPE=no
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for IgnoreSIGPIPE=yes
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'kill -PIPE 0'
|
||||
ExecStart=/bin/sh -x -c 'kill -PIPE 0'
|
||||
Type=oneshot
|
||||
IgnoreSIGPIPE=yes
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for IOSchedulingClass=best-effort
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c 'c=$(ionice); echo $c; [[ "$c" == best-effort* ]]'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(LC_ALL=C ionice); test "$${c%%:*}" = "best-effort"'
|
||||
Type=oneshot
|
||||
IOSchedulingClass=best-effort
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for IOSchedulingClass=idle
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c 'c=$(ionice); echo $c; [[ "$c" == idle* ]]'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(LC_ALL=C ionice); test "$${c%%:*}" = "idle"'
|
||||
Type=oneshot
|
||||
IOSchedulingClass=idle
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for IOSchedulingClass=none
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c 'c=$(ionice); echo $c; [[ "$c" == none* ]]'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(LC_ALL=C ionice); test "$${c%%:*}" = "none"'
|
||||
Type=oneshot
|
||||
IOSchedulingClass=none
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for IOSchedulingClass=realtime
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c 'c=$(ionice); echo $c; [[ "$c" == realtime* ]]'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(LC_ALL=C ionice); test "$${c%%:*}" = "realtime"'
|
||||
Type=oneshot
|
||||
IOSchedulingClass=realtime
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for OOMScoreAdjust
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c 'c=$(cat /proc/self/oom_score_adj); echo $c; exit $(test $c -eq -100)'
|
||||
OOMScoreAdjust=-100
|
||||
ExecStart=/bin/sh -x -c 'c=$$(cat /proc/self/oom_score_adj); test "$$c" -eq -100'
|
||||
Type=oneshot
|
||||
OOMScoreAdjust=-100
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for OOMScoreAdjust
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c 'c=$(cat /proc/self/oom_score_adj); echo $c; exit $(test $c -eq 100)'
|
||||
OOMScoreAdjust=100
|
||||
ExecStart=/bin/sh -x -c 'c=$$(cat /proc/self/oom_score_adj); test "$$c" -eq 100'
|
||||
Type=oneshot
|
||||
OOMScoreAdjust=100
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for Personality=s390
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'echo $(uname -m); exit $(test $(uname -m) = "s390")'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(uname -m); test "$$c" = "s390"'
|
||||
Type=oneshot
|
||||
Personality=s390
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for Personality=x86-64
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'echo $(uname -m); exit $(test $(uname -m) = "x86_64")'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(uname -m); test "$$c" = "x86_64"'
|
||||
Type=oneshot
|
||||
Personality=x86-64
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for Personality=x86
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'echo $(uname -m); exit $(test $(uname -m) = "i686")'
|
||||
ExecStart=/bin/sh -x -c 'c=$$(uname -m); test "$$c" = "i686"'
|
||||
Type=oneshot
|
||||
Personality=x86
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for PrivateDev=no
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test -c /dev/mem)'
|
||||
ExecStart=/bin/sh -x -c 'test -c /dev/mem'
|
||||
Type=oneshot
|
||||
PrivateDevices=no
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for PrivateDev=yes
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test ! -c /dev/mem)'
|
||||
ExecStart=/bin/sh -c 'test ! -c /dev/mem'
|
||||
Type=oneshot
|
||||
PrivateDevices=yes
|
||||
|
@ -2,5 +2,6 @@
|
||||
Description=Test for PrivateNetwork
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'i=$(ip link | grep ": " | grep -v lo); echo $i; exit $(test -z $i)'
|
||||
ExecStart=/bin/sh -x -c 'i=$$(ip link | grep ": " | grep -v ": lo:"); test -z "$$i"'
|
||||
Type=oneshot
|
||||
PrivateNetwork=yes
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for PrivateTmp=no
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test -f /tmp/test-exec_privatetmp)'
|
||||
ExecStart=/bin/sh -x -c 'test -f /tmp/test-exec_privatetmp'
|
||||
Type=oneshot
|
||||
PrivateTmp=no
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for PrivateTmp=yes
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test ! -f /tmp/test-exec_privatetmp)'
|
||||
ExecStart=/bin/sh -x -c 'test ! -f /tmp/test-exec_privatetmp'
|
||||
Type=oneshot
|
||||
PrivateTmp=yes
|
||||
|
@ -2,7 +2,7 @@
|
||||
Description=Test for RuntimeDirectoryMode
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 's=$(stat -c %a /tmp/test-exec_runtimedirectory-mode); echo $s; exit $(test $s = "750")'
|
||||
ExecStart=/bin/sh -x -c 'mode=$$(stat -c %%a /tmp/test-exec_runtimedirectory-mode); test "$$mode" = "750"'
|
||||
Type=oneshot
|
||||
RuntimeDirectory=test-exec_runtimedirectory-mode
|
||||
RuntimeDirectoryMode=0750
|
||||
|
@ -2,7 +2,7 @@
|
||||
Description=Test for RuntimeDirectory owner (must not be the default group of the user if Group is set)
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'f=/tmp/test-exec_runtimedirectory-owner;g=$(stat -c %G $f); echo "$g"; exit $(test $g = "nobody")'
|
||||
ExecStart=/bin/sh -x -c 'group=$$(stat -c %%G /tmp/test-exec_runtimedirectory-owner); test "$$group" = "nobody"'
|
||||
Type=oneshot
|
||||
Group=nobody
|
||||
User=root
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for RuntimeDirectory
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test -d /tmp/test-exec_runtimedirectory)'
|
||||
ExecStart=/bin/sh -x -c 'test -d /tmp/test-exec_runtimedirectory'
|
||||
Type=oneshot
|
||||
RuntimeDirectory=test-exec_runtimedirectory
|
||||
|
@ -2,6 +2,7 @@
|
||||
Description=Test for SystemCallErrorNumber
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'uname -a'
|
||||
ExecStart=/bin/sh -x -c 'uname -a'
|
||||
Type=oneshot
|
||||
SystemCallFilter=~uname
|
||||
SystemCallErrorNumber=EACCES
|
||||
|
@ -3,6 +3,7 @@ Description=Test for SystemCallFilter
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/echo "This should not be seen"
|
||||
Type=oneshot
|
||||
SystemCallFilter=ioperm
|
||||
SystemCallFilter=~ioperm
|
||||
SystemCallFilter=ioperm
|
||||
|
@ -3,4 +3,5 @@ Description=Test for SystemCallFilter
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/echo "This should not be seen"
|
||||
Type=oneshot
|
||||
SystemCallFilter=~write open execve exit_group close mmap munmap fstat DONOTEXIST
|
||||
|
@ -3,6 +3,7 @@ Description=Test for SystemCallFilter
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/echo "Foo bar"
|
||||
Type=oneshot
|
||||
SystemCallFilter=~read write open execve ioperm
|
||||
SystemCallFilter=ioctl
|
||||
SystemCallFilter=read write open execve
|
||||
|
@ -3,4 +3,5 @@ Description=Test for SystemCallFilter
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/echo "Foo bar"
|
||||
Type=oneshot
|
||||
SystemCallFilter=
|
||||
|
@ -2,6 +2,7 @@
|
||||
Description=Test for UMask
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'touch /tmp/test-exec-umask; s=$(stat -c %a /tmp/test-exec-umask); echo $s; exit $(test $s = "600")'
|
||||
ExecStart=/bin/sh -x -c 'touch /tmp/test-exec-umask; mode=$$(stat -c %%a /tmp/test-exec-umask); test "$$mode" = "600"'
|
||||
Type=oneshot
|
||||
UMask=0177
|
||||
PrivateTmp=yes
|
||||
|
@ -2,5 +2,6 @@
|
||||
Description=Test for UMask default
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'touch /tmp/test-exec-umask; s=$(stat -c %a /tmp/test-exec-umask); echo $s; exit $(test $s = "644")'
|
||||
ExecStart=/bin/sh -x -c 'touch /tmp/test-exec-umask; mode=$$(stat -c %%a /tmp/test-exec-umask); test "$$mode" = "644"'
|
||||
Type=oneshot
|
||||
PrivateTmp=yes
|
||||
|
@ -2,5 +2,6 @@
|
||||
Description=Test for User
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'exit $(test "$USER" = nobody)'
|
||||
ExecStart=/bin/sh -x -c 'test "$$USER" = "nobody"'
|
||||
Type=oneshot
|
||||
User=nobody
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=Test for WorkingDirectory
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'echo $PWD; exit $(test $PWD = "/tmp/test-exec_workingdirectory")'
|
||||
ExecStart=/bin/sh -x -c 'test "$$PWD" = "/tmp/test-exec_workingdirectory"'
|
||||
Type=oneshot
|
||||
WorkingDirectory=/tmp/test-exec_workingdirectory
|
||||
|
Loading…
Reference in New Issue
Block a user