Skip to content

Commit 71090d3

Browse files
authored
Gl/avg latency (#1)
* Add IDE files in gitignore * Add IDE files in gitignore * Add latency option * Add random latency algorithm
1 parent 6aabf0c commit 71090d3

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
/TODO.md
44
/stripe-mock
55
/dist/
6+
7+
# IDE files
8+
.idea

main.go

+19-1
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import (
77
"crypto/tls"
88
"flag"
99
"fmt"
10+
"math/rand"
1011
"net"
1112
"net/http"
1213
"os"
1314
"strconv"
15+
"time"
1416

1517
"github.com/stripe/stripe-mock/server"
1618
)
@@ -62,7 +64,11 @@ func main() {
6264
flag.BoolVar(&verbose, "verbose", false, "Enable verbose mode")
6365
flag.BoolVar(&options.showVersion, "version", false, "Show version and exit")
6466

67+
flag.IntVar(&options.avgLatency, "avg-latency", -1, "Average response latency for reasonable response time (ms)")
68+
flag.Float64Var(&options.stdv, "stdv", 0.5, "Standard deviation for latency, must be in range (0, 1)")
69+
6570
flag.Parse()
71+
rand.Seed(time.Now().UnixNano())
6672

6773
fmt.Printf("stripe-mock %s\n", version)
6874
if options.showVersion || len(flag.Args()) == 1 && flag.Arg(0) == "version" {
@@ -90,7 +96,14 @@ func main() {
9096
abort(err.Error())
9197
}
9298

93-
stub, err := server.NewStubServer(fixtures, stripeSpec, options.strictVersionCheck, verbose)
99+
stub, err := server.NewStubServer(
100+
fixtures,
101+
stripeSpec,
102+
options.strictVersionCheck,
103+
verbose,
104+
server.SetAvgLatency(options.avgLatency),
105+
server.SetStdv(options.stdv),
106+
)
94107
if err != nil {
95108
abort(fmt.Sprintf("Error initializing router: %v\n", err))
96109
}
@@ -166,6 +179,8 @@ func main() {
166179
}()
167180
}
168181

182+
fmt.Printf("Average latency: %dms, STDV: %f\n", options.avgLatency, options.stdv)
183+
169184
// Block forever. The serve Goroutines above will abort the program if
170185
// either of them fails.
171186
select {}
@@ -196,6 +211,9 @@ type options struct {
196211
specPath string
197212
strictVersionCheck bool
198213
unixSocket string
214+
215+
avgLatency int // For reasonable response times - in milliseconds
216+
stdv float64 // For reasonable response times - standard deviation in rage (0, 1)
199217
}
200218

201219
func (o *options) checkConflictingOptions() error {

server/server.go

+45-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"fmt"
77
"io/ioutil"
8+
"math/rand"
89
"net/http"
910
"net/url"
1011
"path/filepath"
@@ -14,6 +15,7 @@ import (
1415
"time"
1516

1617
"github.com/lestrrat-go/jsval"
18+
1719
"github.com/stripe/stripe-mock/param"
1820
"github.com/stripe/stripe-mock/param/coercer"
1921
"github.com/stripe/stripe-mock/spec"
@@ -206,30 +208,72 @@ type StubServer struct {
206208
fixtures *spec.Fixtures
207209
routes map[spec.HTTPVerb][]stubServerRoute
208210
spec *spec.Spec
211+
stdv float64
212+
avgLatency int
213+
delayResponses bool
209214
strictVersionCheck bool
210215
verbose bool
211216
}
212217

218+
type StubServerOption func(s *StubServer)
219+
220+
func SetAvgLatency(avgLatency int) StubServerOption {
221+
return func(s *StubServer) {
222+
if avgLatency <= 0 {
223+
return
224+
}
225+
s.delayResponses = true
226+
s.avgLatency = avgLatency
227+
}
228+
}
229+
230+
func SetStdv(stdv float64) StubServerOption {
231+
return func(s *StubServer) {
232+
s.stdv = stdv
233+
}
234+
}
235+
213236
// NewStubServer creates a new instance of StubServer
214-
func NewStubServer(fixtures *spec.Fixtures, spec *spec.Spec, strictVersionCheck, verbose bool) (*StubServer, error) {
237+
func NewStubServer(fixtures *spec.Fixtures, spec *spec.Spec, strictVersionCheck, verbose bool, opts ...StubServerOption) (*StubServer, error) {
215238
s := StubServer{
216239
fixtures: fixtures,
217240
spec: spec,
218241
strictVersionCheck: strictVersionCheck,
219242
verbose: verbose,
220243
}
244+
245+
for _, option := range opts {
246+
option(&s)
247+
}
248+
221249
err := s.initializeRouter()
222250
if err != nil {
223251
return nil, err
224252
}
225253
return &s, nil
226254
}
227255

256+
func (s *StubServer) delay() {
257+
lat := float64(s.avgLatency/1000) + s.stdv*rand.NormFloat64()
258+
if lat < 0 {
259+
lat = - lat
260+
}
261+
262+
fmt.Printf("Request latency = %f", lat*1000)
263+
time.Sleep(time.Duration(lat*1000) * time.Millisecond)
264+
}
265+
228266
// HandleRequest handes an HTTP request directed at the API stub.
229267
func (s *StubServer) HandleRequest(w http.ResponseWriter, r *http.Request) {
230268
start := time.Now()
231269
fmt.Printf("Request: %v %v\n", r.Method, r.URL.Path)
232270

271+
//
272+
// Delaying the response according to acg-latency and stdv
273+
//
274+
275+
s.delay()
276+
233277
//
234278
// Validate headers
235279
//

0 commit comments

Comments
 (0)