Skip to content

Commit 154fc96

Browse files
re-TickRitik Jain
andauthored
feat(mux) : Adds support for Gorilla/Mux multiplexer and refactor mongo (#67)
* feat(mongo): Adds Distinct, CountDocuments and Aggregate methods to mock their outputs. * fix(keploy): adds a delay in between capture and denoise calls to keploy server delay is necessary to capture the noise fields of response accurately * fix(kmongo): adds a check for nil pointer to prevent crash in find, findone mocked method refactors kmongo code to improve maintainence #63 * feat(kmux): adds a middleware function for gorilla/mux multiplexer #66 Co-authored-by: Ritik Jain <[email protected]>
1 parent 9c37af0 commit 154fc96

File tree

5 files changed

+132
-2
lines changed

5 files changed

+132
-2
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,33 @@ kwebgo.WebGoV4(k
174174
, router)
175175
router.Start()
176176
```
177+
### 5. Gorilla/Mux
178+
```go
179+
r := mux.NewRouter()
180+
kmux.Mux(k, r)
181+
```
182+
#### Example
183+
```go
184+
import(
185+
"github.com/keploy/go-sdk/integrations/kmux"
186+
"net/http"
187+
)
188+
189+
r := mux.NewRouter()
190+
port := "8080"
191+
k := keploy.New(keploy.Config{
192+
App: keploy.AppConfig{
193+
Name: "my-app",
194+
Port: port,
195+
},
196+
Server: keploy.ServerConfig{
197+
URL: "http://localhost:8081/api",
198+
},
199+
})
200+
kmux.Mux(k, r)
201+
http.ListenAndServe(":"+port, r)
202+
```
203+
177204
## Supported Databases
178205
### 1. MongoDB
179206
```go

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ require (
3131
github.com/golang/protobuf v1.4.3 // indirect
3232
github.com/golang/snappy v0.0.1 // indirect
3333
github.com/google/uuid v1.3.0 // indirect
34+
github.com/gorilla/mux v1.8.0
3435
github.com/jmespath/go-jmespath v0.4.0 // indirect
3536
github.com/json-iterator/go v1.1.9 // indirect
3637
github.com/klauspost/compress v1.13.6 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
9393
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
9494
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
9595
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
96+
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
97+
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
9698
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
9799
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
98100
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=

integrations/kmux/mux.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package kmux
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"io"
7+
"io/ioutil"
8+
"net/http"
9+
10+
"github.com/gorilla/mux"
11+
"github.com/keploy/go-sdk/keploy"
12+
"go.keploy.io/server/pkg/models"
13+
"go.uber.org/zap"
14+
)
15+
16+
// Mux adds keploy instrumentation for Mux router.
17+
// It should be ideally used after other instrumentation libraries like APMs.
18+
//
19+
// k is the Keploy instance
20+
//
21+
// w is the mux router instance
22+
func Mux(k *keploy.Keploy, w *mux.Router) {
23+
if keploy.GetMode() == keploy.MODE_OFF {
24+
return
25+
}
26+
w.Use(mw(k))
27+
}
28+
29+
func captureRespMux(w http.ResponseWriter, r *http.Request, next http.Handler) models.HttpResp {
30+
resBody := new(bytes.Buffer)
31+
mw := io.MultiWriter(w, resBody)
32+
writer := &keploy.BodyDumpResponseWriter{
33+
Writer: mw,
34+
ResponseWriter: w,
35+
Status: http.StatusOK,
36+
}
37+
w = writer
38+
39+
next.ServeHTTP(w, r)
40+
return models.HttpResp{
41+
//Status
42+
43+
StatusCode: writer.Status,
44+
Header: w.Header(),
45+
Body: resBody.String(),
46+
}
47+
}
48+
49+
func mw(k *keploy.Keploy) func( http.Handler) http.Handler {
50+
if k == nil {
51+
return func(next http.Handler) http.Handler{
52+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
53+
next.ServeHTTP(w, r)
54+
})
55+
}
56+
}
57+
return func(next http.Handler) http.Handler {
58+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
59+
id := r.Header.Get("KEPLOY_TEST_ID")
60+
if id != "" {
61+
// id is only present during simulation
62+
// run it similar to how testcases would run
63+
ctx := context.WithValue(r.Context(), keploy.KCTX, &keploy.Context{
64+
Mode: "test",
65+
TestID: id,
66+
Deps: k.GetDependencies(id),
67+
})
68+
69+
r = r.WithContext(ctx)
70+
resp := captureRespMux(w, r, next)
71+
k.PutResp(id, resp)
72+
return
73+
}
74+
ctx := context.WithValue(r.Context(), keploy.KCTX, &keploy.Context{
75+
Mode: "capture",
76+
})
77+
78+
r = r.WithContext(ctx)
79+
80+
// Request
81+
var reqBody []byte
82+
var err error
83+
if r.Body != nil { // Read
84+
reqBody, err = ioutil.ReadAll(r.Body)
85+
if err != nil {
86+
// TODO right way to log errors
87+
k.Log.Error("Unable to read request body", zap.Error(err))
88+
return
89+
}
90+
}
91+
r.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody)) // Reset
92+
93+
resp := captureRespMux(w, r, next)
94+
// params := webgo.Context(r).Params()
95+
params := mux.Vars(r)
96+
keploy.CaptureTestcase(k, r, reqBody, resp, params)
97+
98+
})
99+
}
100+
}

keploy/keploy.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ type Keploy struct {
123123
Log *zap.Logger
124124
client *http.Client
125125
deps sync.Map
126-
//Deps map[string][]models.Dependency
127-
resp sync.Map
126+
//Deps map[string][]models.Dependency
127+
resp sync.Map
128128
//Resp map[string]models.HttpResp
129129
}
130130

0 commit comments

Comments
 (0)