1
2
3
4
5 package gin
6
7 import (
8 "html/template"
9 "net/http"
10 "os"
11 "testing"
12 )
13
14 func BenchmarkOneRoute(B *testing.B) {
15 router := New()
16 router.GET("/ping", func(c *Context) {})
17 runRequest(B, router, "GET", "/ping")
18 }
19
20 func BenchmarkRecoveryMiddleware(B *testing.B) {
21 router := New()
22 router.Use(Recovery())
23 router.GET("/", func(c *Context) {})
24 runRequest(B, router, "GET", "/")
25 }
26
27 func BenchmarkLoggerMiddleware(B *testing.B) {
28 router := New()
29 router.Use(LoggerWithWriter(newMockWriter()))
30 router.GET("/", func(c *Context) {})
31 runRequest(B, router, "GET", "/")
32 }
33
34 func BenchmarkManyHandlers(B *testing.B) {
35 router := New()
36 router.Use(Recovery(), LoggerWithWriter(newMockWriter()))
37 router.Use(func(c *Context) {})
38 router.Use(func(c *Context) {})
39 router.GET("/ping", func(c *Context) {})
40 runRequest(B, router, "GET", "/ping")
41 }
42
43 func Benchmark5Params(B *testing.B) {
44 DefaultWriter = os.Stdout
45 router := New()
46 router.Use(func(c *Context) {})
47 router.GET("/param/:param1/:params2/:param3/:param4/:param5", func(c *Context) {})
48 runRequest(B, router, "GET", "/param/path/to/parameter/john/12345")
49 }
50
51 func BenchmarkOneRouteJSON(B *testing.B) {
52 router := New()
53 data := struct {
54 Status string `json:"status"`
55 }{"ok"}
56 router.GET("/json", func(c *Context) {
57 c.JSON(http.StatusOK, data)
58 })
59 runRequest(B, router, "GET", "/json")
60 }
61
62 func BenchmarkOneRouteHTML(B *testing.B) {
63 router := New()
64 t := template.Must(template.New("index").Parse(`
65 <html><body><h1>{{.}}</h1></body></html>`))
66 router.SetHTMLTemplate(t)
67
68 router.GET("/html", func(c *Context) {
69 c.HTML(http.StatusOK, "index", "hola")
70 })
71 runRequest(B, router, "GET", "/html")
72 }
73
74 func BenchmarkOneRouteSet(B *testing.B) {
75 router := New()
76 router.GET("/ping", func(c *Context) {
77 c.Set("key", "value")
78 })
79 runRequest(B, router, "GET", "/ping")
80 }
81
82 func BenchmarkOneRouteString(B *testing.B) {
83 router := New()
84 router.GET("/text", func(c *Context) {
85 c.String(http.StatusOK, "this is a plain text")
86 })
87 runRequest(B, router, "GET", "/text")
88 }
89
90 func BenchmarkManyRoutesFist(B *testing.B) {
91 router := New()
92 router.Any("/ping", func(c *Context) {})
93 runRequest(B, router, "GET", "/ping")
94 }
95
96 func BenchmarkManyRoutesLast(B *testing.B) {
97 router := New()
98 router.Any("/ping", func(c *Context) {})
99 runRequest(B, router, "OPTIONS", "/ping")
100 }
101
102 func Benchmark404(B *testing.B) {
103 router := New()
104 router.Any("/something", func(c *Context) {})
105 router.NoRoute(func(c *Context) {})
106 runRequest(B, router, "GET", "/ping")
107 }
108
109 func Benchmark404Many(B *testing.B) {
110 router := New()
111 router.GET("/", func(c *Context) {})
112 router.GET("/path/to/something", func(c *Context) {})
113 router.GET("/post/:id", func(c *Context) {})
114 router.GET("/view/:id", func(c *Context) {})
115 router.GET("/favicon.ico", func(c *Context) {})
116 router.GET("/robots.txt", func(c *Context) {})
117 router.GET("/delete/:id", func(c *Context) {})
118 router.GET("/user/:id/:mode", func(c *Context) {})
119
120 router.NoRoute(func(c *Context) {})
121 runRequest(B, router, "GET", "/viewfake")
122 }
123
124 type mockWriter struct {
125 headers http.Header
126 }
127
128 func newMockWriter() *mockWriter {
129 return &mockWriter{
130 http.Header{},
131 }
132 }
133
134 func (m *mockWriter) Header() (h http.Header) {
135 return m.headers
136 }
137
138 func (m *mockWriter) Write(p []byte) (n int, err error) {
139 return len(p), nil
140 }
141
142 func (m *mockWriter) WriteString(s string) (n int, err error) {
143 return len(s), nil
144 }
145
146 func (m *mockWriter) WriteHeader(int) {}
147
148 func runRequest(B *testing.B, r *Engine, method, path string) {
149
150 req, err := http.NewRequest(method, path, nil)
151 if err != nil {
152 panic(err)
153 }
154 w := newMockWriter()
155 B.ReportAllocs()
156 B.ResetTimer()
157 for i := 0; i < B.N; i++ {
158 r.ServeHTTP(w, req)
159 }
160 }
161
View as plain text