TestReapInterrupt verifies that ForkReap forwards caught signals to the child process. The test sends SIGINT to its own process and checks that the child receives it. Running in a subprocess ensures SIGINT cannot kill the parent test binary.
(t *testing.T)
| 169 | // and checks that the child receives it. Running in a subprocess |
| 170 | // ensures SIGINT cannot kill the parent test binary. |
| 171 | func TestReapInterrupt(t *testing.T) { |
| 172 | t.Parallel() |
| 173 | if testutil.InCI() { |
| 174 | t.Skip("Detected CI, skipping reaper tests") |
| 175 | } |
| 176 | if !runSubprocess(t) { |
| 177 | return |
| 178 | } |
| 179 | |
| 180 | errC := make(chan error, 1) |
| 181 | pids := make(reap.PidCh, 1) |
| 182 | |
| 183 | // Use signals to notify when the child process is ready for the |
| 184 | // next step of our test. |
| 185 | usrSig := make(chan os.Signal, 1) |
| 186 | signal.Notify(usrSig, syscall.SIGUSR1, syscall.SIGUSR2) |
| 187 | defer signal.Stop(usrSig) |
| 188 | |
| 189 | go func() { |
| 190 | opts := append([]reaper.Option{ |
| 191 | reaper.WithPIDCallback(pids), |
| 192 | reaper.WithCatchSignals(os.Interrupt), |
| 193 | // Signal propagation does not extend to children of children, so |
| 194 | // we create a little bash script to ensure sleep is interrupted. |
| 195 | reaper.WithExecArgs("/bin/sh", "-c", fmt.Sprintf( |
| 196 | "pid=0; trap 'kill -USR2 %d; kill -TERM $pid' INT; sleep 10 &\npid=$!; kill -USR1 %d; wait", |
| 197 | os.Getpid(), os.Getpid(), |
| 198 | )), |
| 199 | }, withDone(t)...) |
| 200 | exitCode, err := reaper.ForkReap(opts...) |
| 201 | // The child exits with 128 + SIGTERM (15) = 143, but the trap catches |
| 202 | // SIGINT and sends SIGTERM to the sleep process, so exit code varies. |
| 203 | _ = exitCode |
| 204 | errC <- err |
| 205 | }() |
| 206 | |
| 207 | require.Equal(t, syscall.SIGUSR1, <-usrSig) |
| 208 | |
| 209 | err := syscall.Kill(os.Getpid(), syscall.SIGINT) |
| 210 | require.NoError(t, err) |
| 211 | |
| 212 | require.Equal(t, syscall.SIGUSR2, <-usrSig) |
| 213 | require.NoError(t, <-errC) |
| 214 | } |
nothing calls this directly
no test coverage detected