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 h := Header{
49 "a": nil,
50 "b": nil,
51 "c": nil,
52 }
53 sorter := new(sorter)
54
55 if allocs := testing.AllocsPerRun(5, func() {
56 if len(sorter.Keys(h)) != 3 {
57 t.Fatal("wrong result")
58 }
59 }); allocs > 0 {
60 t.Logf("Keys allocs = %v; want <1", allocs)
61 }
62 }
63
64
65
66
67 func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
68 deadline := time.Now().Add(waitFor)
69 for time.Now().Before(deadline) {
70 if fn() {
71 return true
72 }
73 time.Sleep(checkEvery)
74 }
75 return false
76 }
77
78
79 func waitErrCondition(waitFor, checkEvery time.Duration, fn func() error) error {
80 deadline := time.Now().Add(waitFor)
81 var err error
82 for time.Now().Before(deadline) {
83 if err = fn(); err == nil {
84 return nil
85 }
86 time.Sleep(checkEvery)
87 }
88 return err
89 }
90
91 func equalError(a, b error) bool {
92 if a == nil {
93 return b == nil
94 }
95 if b == nil {
96 return a == nil
97 }
98 return a.Error() == b.Error()
99 }
100
101 var forbiddenStringsFunctions = map[string]bool{
102
103 "EqualFold": true,
104 "Title": true,
105 "ToLower": true,
106 "ToLowerSpecial": true,
107 "ToTitle": true,
108 "ToTitleSpecial": true,
109 "ToUpper": true,
110 "ToUpperSpecial": true,
111
112
113 "Fields": true,
114 "TrimSpace": true,
115 }
116
117
118
119
120 func TestNoUnicodeStrings(t *testing.T) {
121 re := regexp.MustCompile(`(strings|bytes).([A-Za-z]+)`)
122 if err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
123 if err != nil {
124 t.Fatal(err)
125 }
126
127 if path == "h2i" || path == "h2c" {
128 return filepath.SkipDir
129 }
130 if !strings.HasSuffix(path, ".go") ||
131 strings.HasSuffix(path, "_test.go") ||
132 path == "ascii.go" || info.IsDir() {
133 return nil
134 }
135
136 contents, err := os.ReadFile(path)
137 if err != nil {
138 t.Fatal(err)
139 }
140 for lineNum, line := range strings.Split(string(contents), "\n") {
141 for _, match := range re.FindAllStringSubmatch(line, -1) {
142 if !forbiddenStringsFunctions[match[2]] {
143 continue
144 }
145 t.Errorf("disallowed call to %s at %s:%d", match[0], path, lineNum+1)
146 }
147 }
148
149 return nil
150 }); err != nil {
151 t.Fatal(err)
152 }
153 }
154
155
156 func SetForTest[T any](t testing.TB, p *T, v T) {
157 orig := *p
158 t.Cleanup(func() {
159 *p = orig
160 })
161 *p = v
162 }
163
164
165 func Must[T any](v T, err error) T {
166 if err != nil {
167 panic(err)
168 }
169 return v
170 }
171
View as plain text