1
2
3
4
5 package http3
6
7 import (
8 "encoding/hex"
9 "errors"
10 "strings"
11 "sync"
12 "testing"
13 "testing/synctest"
14 )
15
16 func unhex(s string) []byte {
17 b, err := hex.DecodeString(strings.Map(func(c rune) rune {
18 switch c {
19 case ' ', '\t', '\n':
20 return -1
21 }
22 return c
23 }, s))
24 if err != nil {
25 panic(err)
26 }
27 return b
28 }
29
30
31 type testReader struct {
32 readFunc func([]byte) (int, error)
33 }
34
35 func (r testReader) Read(p []byte) (n int, err error) { return r.readFunc(p) }
36
37 var errTestBodyClosed = errors.New("test body closed")
38
39
40
41 type testRequestBody struct {
42 closec chan struct{}
43
44 mu sync.Mutex
45 closes int
46 }
47
48 func newTestRequestBody() *testRequestBody {
49 return &testRequestBody{closec: make(chan struct{})}
50 }
51
52
53 func (b *testRequestBody) Read([]byte) (int, error) {
54 <-b.closec
55 return 0, errTestBodyClosed
56 }
57
58 func (b *testRequestBody) Close() error {
59 b.mu.Lock()
60 defer b.mu.Unlock()
61 if b.closes++; b.closes == 1 {
62 close(b.closec)
63 }
64 return nil
65 }
66
67
68 func (b *testRequestBody) closeCount() int {
69 b.mu.Lock()
70 defer b.mu.Unlock()
71 return b.closes
72 }
73
74
75 func synctestSubtest(t *testing.T, name string, f func(t *testing.T)) {
76 t.Run(name, func(t *testing.T) {
77 synctest.Test(t, f)
78 })
79 }
80
View as plain text