(t *testing.T)
| 90 | |
| 91 | require.NotEqual(t, time.Time{}, txts) |
| 92 | require.Equal(t, 1, attempts) |
| 93 | require.Nil(t, err) |
| 94 | } |
| 95 | |
| 96 | func errQueueSocket(t *testing.T) int { |
| 97 | t.Helper() |
| 98 | conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 0}) |
| 99 | require.NoError(t, err) |
| 100 | t.Cleanup(func() { conn.Close() }) |
| 101 | |
| 102 | connFd, err := ConnFd(conn) |
| 103 | require.NoError(t, err) |
| 104 | require.NoError(t, EnableSWTimestamps(connFd)) |
| 105 | return connFd |
| 106 | } |
| 107 | |
| 108 | func TestWaitForHWTSReportsTimeout(t *testing.T) { |
| 109 | connFd := errQueueSocket(t) |
| 110 | |
| 111 | oldTimeout := TimeoutTXTS |
| 112 | t.Cleanup(func() { TimeoutTXTS = oldTimeout }) |
| 113 | TimeoutTXTS = 100 * time.Millisecond |
| 114 | |
| 115 | start := time.Now() |
| 116 | err := waitForHWTS(connFd) |
| 117 | elapsed := time.Since(start) |
| 118 | |
| 119 | require.ErrorIs(t, err, syscall.ETIMEDOUT) |
| 120 | require.GreaterOrEqual(t, elapsed, TimeoutTXTS) |
| 121 | } |
| 122 | |
| 123 | func TestWaitForHWTSSharesOneDeadlineAcrossEINTR(t *testing.T) { |
| 124 | connFd := errQueueSocket(t) |
| 125 | |
| 126 | oldTimeout := TimeoutTXTS |
| 127 | t.Cleanup(func() { TimeoutTXTS = oldTimeout }) |
| 128 | TimeoutTXTS = 100 * time.Millisecond |
| 129 | |
| 130 | // interrupting far more often than the deadline allows: a loop that shares one |
| 131 | // deadline gives up part way through, a loop that restarts the timeout never does |
| 132 | const interrupts = 100 |
| 133 | const perCall = 10 * time.Millisecond |
| 134 | var budgets []time.Duration |
| 135 | poll := func(_ []unix.PollFd, timeout *unix.Timespec, _ *unix.Sigset_t) (int, error) { |
| 136 | budgets = append(budgets, time.Duration(timeout.Nano())) |
| 137 | time.Sleep(perCall) |
| 138 | if len(budgets) >= interrupts { |
| 139 | return 0, nil |
| 140 | } |
| 141 | return -1, syscall.EINTR |
| 142 | } |
| 143 | |
| 144 | require.ErrorIs(t, pollForHWTS(connFd, poll), syscall.ETIMEDOUT) |
| 145 | |
| 146 | require.NotEmpty(t, budgets) |
| 147 | require.Less(t, len(budgets), interrupts) |
| 148 | require.LessOrEqual(t, budgets[0], TimeoutTXTS) |
| 149 | for i := 1; i < len(budgets); i++ { |
nothing calls this directly
no test coverage detected
searching dependent graphs…