Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Gin compatible middleware #25

Merged
merged 1 commit into from
Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/go.yml → .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Go
name: CI
on: [push]
jobs:
test:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Added

- Gin compatible middleware.

## [0.4.0] - 2019-03-27

### Breaking changes
Expand Down
4 changes: 3 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The middleware is mainly focused to be compatible with Go std library using http
- [Negroni][negroni-example]
- [httprouter][httprouter-example]
- [go-restful][gorestful-example]
- [Gin][gin-example]

## Getting Started

Expand Down Expand Up @@ -202,7 +203,7 @@ BenchmarkMiddlewareHandler/benchmark_with_grouped_status_code.-4 1000000
BenchmarkMiddlewareHandler/benchmark_with_predefined_handler_ID-4 1000000 1258 ns/op 256 B/op 6 allocs/op
```

[github-actions-image]: https://github.com/slok/go-http-metrics/workflows/Go/badge.svg
[github-actions-image]: https://github.com/slok/go-http-metrics/workflows/CI/badge.svg
[github-actions-url]: https://github.com/slok/go-http-metrics/actions
[goreport-image]: https://goreportcard.com/badge/github.com/slok/go-http-metrics
[goreport-url]: https://goreportcard.com/report/github.com/slok/go-http-metrics
Expand All @@ -217,5 +218,6 @@ BenchmarkMiddlewareHandler/benchmark_with_predefined_handler_ID-4 1000000
[negroni-example]: examples/negroni
[httprouter-example]: examples/httprouter
[gorestful-example]: examples/gorestful
[gin-example]: examples/gin
[prometheus-recorder]: metrics/prometheus
[opencensus-recorder]: metrics/opencensus
60 changes: 60 additions & 0 deletions examples/gin/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"log"
"net/http"
"os"
"os/signal"
"syscall"

"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus/promhttp"
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
"github.com/slok/go-http-metrics/middleware"
ginmiddleware "github.com/slok/go-http-metrics/middleware/gin"
)

const (
srvAddr = ":8080"
metricsAddr = ":8081"
)

func main() {
// Create our middleware.
mdlw := middleware.New(middleware.Config{
Recorder: metrics.NewRecorder(metrics.Config{}),
})

// Create Gin engine and global middleware.
engine := gin.New()
engine.Use(ginmiddleware.Handler("", mdlw))

// Add our handler.
engine.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello world")
})
engine.GET("/wrong", func(c *gin.Context) {
c.String(http.StatusTooManyRequests, "oops")
})

// Serve our handler.
go func() {
log.Printf("server listening at %s", srvAddr)
if err := http.ListenAndServe(srvAddr, engine); err != nil {
log.Panicf("error while serving: %s", err)
}
}()

// Serve our metrics.
go func() {
log.Printf("metrics listening at %s", metricsAddr)
if err := http.ListenAndServe(metricsAddr, promhttp.Handler()); err != nil {
log.Panicf("error while serving metrics: %s", err)
}
}()

// Wait until some signal is captured.
sigC := make(chan os.Signal, 1)
signal.Notify(sigC, syscall.SIGTERM, syscall.SIGINT)
<-sigC
}
2 changes: 1 addition & 1 deletion examples/gorestful/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func main() {
// Serve our handler.
go func() {
log.Printf("server listening at %s", srvAddr)
if err := http.ListenAndServe(":8080", c); err != nil {
if err := http.ListenAndServe(srvAddr, c); err != nil {
log.Panicf("error while serving: %s", err)
}
}()
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ module github.com/slok/go-http-metrics
require (
contrib.go.opencensus.io/exporter/prometheus v0.1.0
github.com/emicklei/go-restful v2.9.6+incompatible
github.com/gin-gonic/gin v1.5.0
github.com/julienschmidt/httprouter v1.2.0
github.com/prometheus/client_golang v1.0.0
github.com/stretchr/testify v1.3.0
github.com/stretchr/testify v1.4.0
github.com/urfave/negroni v1.0.0
go.opencensus.io v0.22.0
)

go 1.13
30 changes: 30 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w=
github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc=
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
Expand All @@ -24,24 +32,34 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
Expand Down Expand Up @@ -71,6 +89,12 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
Expand Down Expand Up @@ -105,6 +129,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd h1:r7DufRZuZbWB7j439YfAzP8RPDa9unLkpwQKUYbIMPI=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand All @@ -121,6 +146,11 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
41 changes: 41 additions & 0 deletions middleware/gin/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package gin_test

import (
"log"
"net/http"

"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus/promhttp"

metrics "github.com/slok/go-http-metrics/metrics/prometheus"
"github.com/slok/go-http-metrics/middleware"
ginmiddleware "github.com/slok/go-http-metrics/middleware/gin"
)

// GinMiddleware shows how you would create a default middleware factory and use it
// to create a Gin compatible middleware.
func Example_ginMiddleware() {
// Create our middleware factory with the default settings.
mdlw := middleware.New(middleware.Config{
Recorder: metrics.NewRecorder(metrics.Config{}),
})

// Create our gin instance.
engine := gin.New()

// Add our handler and middleware
h := func(c *gin.Context) {
c.String(http.StatusOK, "Hello world")
}
engine.GET("/", ginmiddleware.Handler("", mdlw), h)

// Serve metrics from the default prometheus registry.
log.Printf("serving metrics at: %s", ":8081")
go http.ListenAndServe(":8081", promhttp.Handler())

// Serve our handler.
log.Printf("listening at: %s", ":8080")
if err := http.ListenAndServe(":8080", engine); err != nil {
log.Panicf("error while serving: %s", err)
}
}
52 changes: 52 additions & 0 deletions middleware/gin/gin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Package gin is a helper package to get a gin compatible
// handler/middleware from the standard net/http Middleware factory.
package gin

import (
"net/http"

"github.com/gin-gonic/gin"

"github.com/slok/go-http-metrics/middleware"
)

// Handler returns a Gin compatible middleware from a Middleware factory instance.
// The first handlerID argument is the same argument passed on Middleware.Handler method.
func Handler(handlerID string, m middleware.Middleware) gin.HandlerFunc {
// Create a dummy handler to wrap the middleware chain of Gin, this way Middleware
// interface can wrap the Gin chain.
return func(c *gin.Context) {
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
c.Writer = &ginResponseWriter{
ResponseWriter: c.Writer,
middlewareRW: w,
}
c.Next()
})
m.Handler(handlerID, h).ServeHTTP(c.Writer, c.Request)
}
}

// ginResponseWriter is a helper type that intercepts the middleware ResponseWriter
// interceptor.
// This is required because gin's context Writer (c.Writer) is a gin.ResponseWriter
// interface and we can't access to the internal object http.ResponseWriter, so
// we already know that our middleware intercepts the regular http.ResponseWriter,
// and doesn't change anything, just intercepts to read information. So in order to
// get this information on our interceptor we create a gin.ResponseWriter implementation
// that will call the real gin.Context.Writer and our interceptor. This way Gin gets the
// information and our interceptor also.
type ginResponseWriter struct {
middlewareRW http.ResponseWriter
gin.ResponseWriter
}

func (w *ginResponseWriter) WriteHeader(statusCode int) {
w.middlewareRW.WriteHeader(statusCode)
w.ResponseWriter.WriteHeader(statusCode)
}

func (w *ginResponseWriter) Write(p []byte) (int, error) {
w.middlewareRW.Write(p)
return w.ResponseWriter.Write(p)
}
71 changes: 71 additions & 0 deletions middleware/gin/gin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package gin_test

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

mmetrics "github.com/slok/go-http-metrics/internal/mocks/metrics"
"github.com/slok/go-http-metrics/middleware"
ginmiddleware "github.com/slok/go-http-metrics/middleware/gin"
)

func getTestHandler(statusCode int) gin.HandlerFunc {
return func(c *gin.Context) {
c.String(statusCode, "Hello world")
}
}

func TestMiddlewareIntegration(t *testing.T) {
tests := []struct {
name string
handlerID string
statusCode int
req *http.Request
config middleware.Config
expHandlerID string
expMethod string
expStatusCode string
}{
{
name: "A default HTTP middleware should call the recorder to measure.",
statusCode: http.StatusAccepted,
req: httptest.NewRequest(http.MethodPost, "/test", nil),
expHandlerID: "/test",
expMethod: http.MethodPost,
expStatusCode: "202",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
assert := assert.New(t)

// Mocks.
mr := &mmetrics.Recorder{}
mr.On("ObserveHTTPRequestDuration", mock.Anything, test.expHandlerID, mock.Anything, test.expMethod, test.expStatusCode).Once()
mr.On("ObserveHTTPResponseSize", mock.Anything, test.expHandlerID, mock.Anything, test.expMethod, test.expStatusCode).Once()
mr.On("AddInflightRequests", mock.Anything, test.expHandlerID, 1).Once()
mr.On("AddInflightRequests", mock.Anything, test.expHandlerID, -1).Once()

// Create our instance with the middleware.
mdlw := middleware.New(middleware.Config{Recorder: mr})
engine := gin.New()
engine.POST("/test",
ginmiddleware.Handler("", mdlw),
getTestHandler(test.statusCode))

// Make the request.
resp := httptest.NewRecorder()
engine.ServeHTTP(resp, test.req)

// Check.
mr.AssertExpectations(t)
assert.Equal(test.statusCode, resp.Result().StatusCode)
})
}
}