(t *testing.T)
| 18 | ) |
| 19 | |
| 20 | func TestProgramTestRunInterrupt(t *testing.T) { |
| 21 | testutils.SkipOnOldKernel(t, "5.0", "EINTR from BPF_PROG_TEST_RUN") |
| 22 | |
| 23 | prog := createBasicProgram(t) |
| 24 | |
| 25 | var ( |
| 26 | tgid = unix.Getpid() |
| 27 | tidChan = make(chan int, 1) |
| 28 | exit = make(chan struct{}) |
| 29 | errs = make(chan error, 1) |
| 30 | timeout = time.After(5 * time.Second) |
| 31 | ) |
| 32 | |
| 33 | defer close(exit) |
| 34 | |
| 35 | go func() { |
| 36 | runtime.LockOSThread() |
| 37 | defer func() { |
| 38 | // Wait for the test to allow us to unlock the OS thread, to |
| 39 | // ensure that we don't send SIGUSR1 to the wrong thread. |
| 40 | <-exit |
| 41 | runtime.UnlockOSThread() |
| 42 | }() |
| 43 | |
| 44 | tidChan <- unix.Gettid() |
| 45 | |
| 46 | // Block this thread in the BPF syscall, so that we can |
| 47 | // trigger EINTR by sending a signal. |
| 48 | opts := RunOptions{ |
| 49 | Data: internal.EmptyBPFContext, |
| 50 | Repeat: math.MaxInt32, |
| 51 | Reset: func() { |
| 52 | // We don't know how long finishing the |
| 53 | // test run would take, so flag that we've seen |
| 54 | // an interruption and abort the goroutine. |
| 55 | close(errs) |
| 56 | runtime.Goexit() |
| 57 | }, |
| 58 | } |
| 59 | _, _, err := prog.run(&opts) |
| 60 | |
| 61 | errs <- err |
| 62 | }() |
| 63 | |
| 64 | tid := <-tidChan |
| 65 | for { |
| 66 | err := unix.Tgkill(tgid, tid, unix.SIGUSR1) |
| 67 | if err != nil { |
| 68 | t.Fatal("Can't send signal to goroutine thread:", err) |
| 69 | } |
| 70 | |
| 71 | select { |
| 72 | case err, ok := <-errs: |
| 73 | if !ok { |
| 74 | return |
| 75 | } |
| 76 | |
| 77 | testutils.SkipIfNotSupported(t, err) |
nothing calls this directly
no test coverage detected
searching dependent graphs…