1
2
3
4
5 package http2
6
7 import (
8 "flag"
9 "fmt"
10 "os"
11 "path/filepath"
12 "regexp"
13 "strings"
14 "testing"
15 "time"
16 )
17
18 var knownFailing = flag.Bool("known_failing", false, "Run known-failing tests.")
19
20 func condSkipFailingTest(t *testing.T) {
21 if !*knownFailing {
22 t.Skip("Skipping known-failing test without --known_failing")
23 }
24 }
25
26 func init() {
27 DebugGoroutines = true
28 flag.BoolVar(&VerboseLogs, "verboseh2", VerboseLogs, "Verbose HTTP/2 debug logging")
29 }
30
31 func TestSettingString(t *testing.T) {
32 tests := []struct {
33 s Setting
34 want string
35 }{
36 {Setting{SettingMaxFrameSize, 123}, "[MAX_FRAME_SIZE = 123]"},
37 {Setting{1<<16 - 1, 123}, "[UNKNOWN_SETTING_65535 = 123]"},
38 }
39 for i, tt := range tests {
40 got := fmt.Sprint(tt.s)
41 if got != tt.want {
42 t.Errorf("%d. for %#v, string = %q; want %q", i, tt.s, got, tt.want)
43 }
44 }
45 }
46
47 func TestSorterPoolAllocs(t *testing.T) {
48 ss := []string{"a", "b", "c"}
49 h := Header{
50 "a": nil,
51 "b": nil,
52 "c": nil,
53 }
54 sorter := new(sorter)
55
56 if allocs := testing.AllocsPerRun(100, func() {
57 sorter.SortStrings(ss)
58 }); allocs >= 1 {
59 t.Logf("SortStrings allocs = %v; want <1", allocs)
60 }
61
62 if allocs := testing.AllocsPerRun(5, func() {
63 if len(sorter.Keys(h)) != 3 {
64 t.Fatal("wrong result")
65 }
66 }); allocs > 0 {
67 t.Logf("Keys allocs = %v; want <1", allocs)
68 }
69 }
70
71
72
73
74 func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
75 deadline := time.Now().Add(waitFor)
76 for time.Now().Before(deadline) {
77 if fn() {
78 return true
79 }
80 time.Sleep(checkEvery)
81 }
82 return false
83 }
84
85
86 func waitErrCondition(waitFor, checkEvery time.Duration, fn func() error) error {
87 deadline := time.Now().Add(waitFor)
88 var err error
89 for time.Now().Before(deadline) {
90 if err = fn(); err == nil {
91 return nil
92 }
93 time.Sleep(checkEvery)
94 }
95 return err
96 }
97
98 func equalError(a, b error) bool {
99 if a == nil {
100 return b == nil
101 }
102 if b == nil {
103 return a == nil
104 }
105 return a.Error() == b.Error()
106 }
107
108 var forbiddenStringsFunctions = map[string]bool{
109
110 "EqualFold": true,
111 "Title": true,
112 "ToLower": true,
113 "ToLowerSpecial": true,
114 "ToTitle": true,
115 "ToTitleSpecial": true,
116 "ToUpper": true,
117 "ToUpperSpecial": true,
118
119
120 "Fields": true,
121 "TrimSpace": true,
122 }
123
124
125
126
127 func TestNoUnicodeStrings(t *testing.T) {
128 re := regexp.MustCompile(`(strings|bytes).([A-Za-z]+)`)
129 if err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
130 if err != nil {
131 t.Fatal(err)
132 }
133
134 if path == "h2i" || path == "h2c" {
135 return filepath.SkipDir
136 }
137 if !strings.HasSuffix(path, ".go") ||
138 strings.HasSuffix(path, "_test.go") ||
139 path == "ascii.go" || info.IsDir() {
140 return nil
141 }
142
143 contents, err := os.ReadFile(path)
144 if err != nil {
145 t.Fatal(err)
146 }
147 for lineNum, line := range strings.Split(string(contents), "\n") {
148 for _, match := range re.FindAllStringSubmatch(line, -1) {
149 if !forbiddenStringsFunctions[match[2]] {
150 continue
151 }
152 t.Errorf("disallowed call to %s at %s:%d", match[0], path, lineNum+1)
153 }
154 }
155
156 return nil
157 }); err != nil {
158 t.Fatal(err)
159 }
160 }
161
162
163 func SetForTest[T any](t testing.TB, p *T, v T) {
164 orig := *p
165 t.Cleanup(func() {
166 *p = orig
167 })
168 *p = v
169 }
170
171
172 func Must[T any](v T, err error) T {
173 if err != nil {
174 panic(err)
175 }
176 return v
177 }
178
View as plain text