github.com/containers/podman/v5@v5.1.0-rc1/test/system/130-kill.bats (about) 1 #!/usr/bin/env bats -*- bats -*- 2 # 3 # tests for podman kill 4 # 5 6 load helpers 7 8 # bats test_tags=distro-integration 9 @test "podman kill - test signal handling in containers" { 10 11 # Prepare for 'logs -f' 12 run_podman info --format '{{.Host.LogDriver}}' 13 log_driver=$output 14 run_podman info --format '{{.Host.EventLogger}}' 15 event_logger=$output 16 opt_log_driver= 17 if [ $log_driver = "journald" ] && [ $event_logger != "journald" ]; then 18 # Since PR#10431, 'logs -f' with journald driver is only supported with journald events backend. 19 # Set '--log driver' temporally because remote doesn't support '--events-backend'. 20 opt_log_driver="--log-driver k8s-file" 21 fi 22 23 # Start a container that will handle all signals by emitting 'got: N' 24 local -a signals=(1 2 3 4 5 6 8 10 12 13 14 15 16 20 21 22 23 24 25 26 64) 25 run_podman run -d ${opt_log_driver} $IMAGE sh -c \ 26 "for i in ${signals[*]}; do trap \"echo got: \$i\" \$i; done; 27 echo READY; 28 while ! test -e /stop; do sleep 0.1; done; 29 echo DONE" 30 cid="$output" 31 32 # Run 'logs -f' on that container, but run it in the background with 33 # redirection to a named pipe from which we (foreground job) read 34 # and confirm that signals are received. We can't use run_podman here. 35 local fifo=${PODMAN_TMPDIR}/podman-kill-fifo.$(random_string 10) 36 mkfifo $fifo 37 $PODMAN logs -f $cid >$fifo </dev/null & 38 podman_log_pid=$! 39 40 # Open the FIFO for reading, and keep it open. This prevents a race 41 # condition in which the container can exit (e.g. if for some reason 42 # it doesn't handle the signal) and we (this test) try to read from 43 # the FIFO. Since there wouldn't be an active writer, the open() 44 # would hang forever. With this exec we keep the FD open, allowing 45 # 'read -t' to time out and report a useful error. 46 exec 5<$fifo 47 48 # First container emits READY when ready; wait for it. 49 read -t 60 -u 5 ready 50 is "$ready" "READY" "first log message from container" 51 52 # Helper function: send the given signal, verify that it's received. 53 kill_and_check() { 54 local signal=$1 55 local signum=${2:-$1} # e.g. if signal=HUP, we expect to see '1' 56 57 run_podman kill -s $signal $cid 58 read -t 60 -u 5 actual || die "Timed out: no ACK for kill -s $signal" 59 is "$actual" "got: $signum" "Signal $signal handled by container" 60 } 61 62 # Send signals in random order; make sure each one is received 63 for s in $(fmt --width=2 <<< "${signals[*]}" | sort --random-sort);do 64 kill_and_check $s 65 done 66 67 # Variations: with leading dash; by name, with/without dash or SIG 68 kill_and_check -1 1 69 kill_and_check -INT 2 70 kill_and_check FPE 8 71 kill_and_check -SIGUSR1 10 72 kill_and_check SIGUSR2 12 73 74 # Done. Tell the container to stop, and wait for final DONE. 75 # The '-d' is because container exit is racy: the exec process itself 76 # could get caught and killed by cleanup, causing this step to exit 137 77 run_podman exec -d $cid touch /stop 78 read -t 5 -u 5 done || die "Timed out waiting for DONE from container" 79 is "$done" "DONE" "final log message from container" 80 81 # Clean up 82 run_podman wait $cid 83 run_podman rm $cid 84 wait $podman_log_pid 85 } 86 87 @test "podman kill - rejects invalid args" { 88 # These errors are thrown by the imported docker/signal.ParseSignal() 89 local -a bad_signal_names=(0 SIGBADSIG SIG BADSIG %% ! "''" '""' " ") 90 for s in ${bad_signal_names[@]}; do 91 # 'nosuchcontainer' is fine: podman should bail before it gets there 92 run_podman 125 kill -s $s nosuchcontainer 93 is "$output" "Error: invalid signal: $s" "Error from kill -s $s" 94 95 run_podman 125 pod kill -s $s nosuchpod 96 is "$output" "Error: invalid signal: $s" "Error from pod kill -s $s" 97 done 98 99 # Special case: these too are thrown by docker/signal.ParseSignal(), 100 # but the dash sign is stripped by our wrapper in utils, so the 101 # error message doesn't include the dash. 102 local -a bad_dash_signals=(-0 -SIGBADSIG -SIG -BADSIG -) 103 for s in ${bad_dash_signals[@]}; do 104 run_podman 125 kill -s $s nosuchcontainer 105 is "$output" "Error: invalid signal: ${s##-}" "Error from kill -s $s" 106 done 107 108 # This error (signal out of range) is thrown by our wrapper 109 local -a bad_signal_nums=(65 -65 96 999 99999999) 110 for s in ${bad_signal_nums[@]}; do 111 run_podman 125 kill -s $s nosuchcontainer 112 is "$output" "Error: valid signals are 1 through 64" \ 113 "Error from kill -s $s" 114 done 115 116 # 'podman create' uses the same parsing code 117 run_podman 125 create --stop-signal=99 $IMAGE 118 is "$output" "Error: valid signals are 1 through 64" "podman create" 119 } 120 121 @test "podman kill - print IDs or raw input" { 122 # kill -a must print the IDs 123 run_podman run --rm -d $IMAGE top 124 ctrID="$output" 125 run_podman kill -a 126 is "$output" "$ctrID" 127 128 # kill $input must print $input 129 cname=$(random_string) 130 run_podman run --rm -d --name $cname $IMAGE top 131 run_podman kill $cname 132 is "$output" $cname 133 } 134 135 @test "podman kill - concurrent stop" { 136 # 14761 - concurrent kill/stop must record the exit code 137 random_name=$(random_string 10) 138 run_podman run -d --replace --name=$random_name $IMAGE sh -c "trap 'echo Received SIGTERM, ignoring' SIGTERM; echo READY; while :; do sleep 0.2; done" 139 $PODMAN stop -t 1 $random_name & 140 run_podman kill $random_name 141 run_podman wait $random_name 142 run_podman rm -f $random_name 143 } 144 145 @test "podman wait - exit codes" { 146 random_name=$(random_string 10) 147 run_podman create --name=$random_name $IMAGE /no/such/command 148 run_podman container inspect --format "{{.State.StoppedByUser}}" $random_name 149 is "$output" "false" "container not marked to be stopped by a user" 150 # Container never ran -> exit code == 0 151 run_podman wait $random_name 152 # Container did not start successfully -> exit code != 0 153 run_podman 125 start $random_name 154 # FIXME(#14873): while older Podmans return 0 on wait, Docker does not. 155 run_podman wait $random_name 156 } 157 158 @test "podman kill - no restart" { 159 ctr=$(random_string 10) 160 run_podman run -d --restart=always --name=$ctr $IMAGE \ 161 sh -c "trap 'exit 42' SIGTERM; echo READY; while :; do sleep 0.2; done" 162 run_podman container inspect --format "{{.State.Status}}" $ctr 163 is "$output" "running" "make sure container is running" 164 # Send SIGTERM and make sure the container exits. 165 run_podman kill -s=TERM $ctr 166 run_podman wait $ctr 167 is "$output" "42" "container exits with 42 on receiving SIGTERM" 168 run_podman container inspect --format "{{.State.StoppedByUser}}" $ctr 169 is "$output" "true" "container is marked to be stopped by a user" 170 } 171 172 # vim: filetype=sh