1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package internal_test
import (
"context"
"fmt"
"net"
"strings"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"tildegit.org/tjp/sliderule/internal"
)
type captureLogger struct {
mu sync.Mutex
logs []string
}
func (cl *captureLogger) Log(keyvals ...any) error {
cl.mu.Lock()
defer cl.mu.Unlock()
for _, val := range keyvals {
cl.logs = append(cl.logs, fmt.Sprint(val))
}
return nil
}
func (cl *captureLogger) String() string {
cl.mu.Lock()
defer cl.mu.Unlock()
return strings.Join(cl.logs, " ")
}
func TestServerRecoversConnectionPanic(t *testing.T) {
var logs captureLogger
server, err := internal.NewServer(
context.Background(),
"localhost",
"tcp",
"127.0.0.1:0",
&logs,
func(net.Conn) { panic("boom") },
)
require.Nil(t, err)
done := make(chan error, 1)
go func() { done <- server.Serve() }()
conn, err := net.Dial(server.Network(), server.Address())
require.Nil(t, err)
_ = conn.Close()
require.Eventually(t, func() bool {
return strings.Contains(logs.String(), "panic in server goroutine")
}, time.Second, 10*time.Millisecond)
server.Close()
assert.Nil(t, <-done)
assert.Contains(t, logs.String(), "boom")
}
|