diff --git a/cmd/podinfo/main.go b/cmd/podinfo/main.go index 4ee920e..b5f5216 100644 --- a/cmd/podinfo/main.go +++ b/cmd/podinfo/main.go @@ -40,7 +40,10 @@ func main() { fs.String("ui-color", "#34577c", "UI color") fs.String("ui-message", fmt.Sprintf("greetings from podinfo v%v", version.VERSION), "UI message") fs.Bool("h2c", false, "allow upgrading to H2C") - fs.Bool("random-delay", false, "between 0 and 5 seconds random delay") + fs.Bool("random-delay", false, "between 0 and 5 seconds random delay by default") + fs.String("random-delay-unit", "s", "either s(seconds) or ms(milliseconds") + fs.Int("random-delay-min", 0, "min for random delay: 0 by default") + fs.Int("random-delay-max", 5, "max for random delay: 5 by default") fs.Bool("random-error", false, "1/3 chances of a random response error") fs.Bool("unhealthy", false, "when set, healthy state is never reached") fs.Bool("unready", false, "when set, ready state is never reached") @@ -101,6 +104,20 @@ func main() { viper.Set("port", strconv.Itoa(port)) } + // validate random delay options + if viper.GetInt("random-delay-max") < viper.GetInt("random-delay-min") { + logger.Panic("`--random-delay-max` should be greater than `--random-delay-min`") + } + + switch delayUnit := viper.GetString("random-delay-unit"); delayUnit { + case + "s", + "ms": + break + default: + logger.Panic("`random-delay-unit` accepted values are: s|ms") + } + // load gRPC server config var grpcCfg grpc.Config if err := viper.Unmarshal(&grpcCfg); err != nil { diff --git a/go.sum b/go.sum index e994966..0d1e041 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aws/aws-sdk-go v1.15.78 h1:LaXy6lWR0YK7LKyuU0QWy2ws/LWTPfYV/UgfiBu4tvY= @@ -244,6 +245,7 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -441,6 +443,7 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= 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= diff --git a/pkg/api/delay.go b/pkg/api/delay.go index da3e353..94df23f 100644 --- a/pkg/api/delay.go +++ b/pkg/api/delay.go @@ -1,6 +1,7 @@ package api import ( + "math/rand" "net/http" "strconv" @@ -9,6 +10,39 @@ import ( "github.com/gorilla/mux" ) +type RandomDelayMiddleware struct { + min int + max int + unit string +} + +func NewRandomDelayMiddleware(minDelay, maxDelay int, delayUnit string) *RandomDelayMiddleware { + return &RandomDelayMiddleware{ + min: minDelay, + max: maxDelay, + unit: delayUnit, + } +} + +func (m *RandomDelayMiddleware) Handler(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var unit time.Duration + rand.Seed(time.Now().Unix()) + switch m.unit { + case "s": + unit = time.Second + case "ms": + unit = time.Millisecond + default: + unit = time.Second + } + + delay := rand.Intn(m.max-m.min) + m.min + time.Sleep(time.Duration(delay) * unit) + next.ServeHTTP(w, r) + }) +} + // Delay godoc // @Summary Delay // @Description waits for the specified period diff --git a/pkg/api/http.go b/pkg/api/http.go index ca6cf13..5db65a4 100644 --- a/pkg/api/http.go +++ b/pkg/api/http.go @@ -11,17 +11,6 @@ import ( "go.uber.org/zap" ) -func randomDelayMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - min := 0 - max := 5 - rand.Seed(time.Now().Unix()) - delay := rand.Intn(max-min) + min - time.Sleep(time.Duration(delay) * time.Second) - next.ServeHTTP(w, r) - }) -} - func randomErrorMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rand.Seed(time.Now().Unix()) diff --git a/pkg/api/server.go b/pkg/api/server.go index 0934914..4be3255 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -59,6 +59,9 @@ type Config struct { Hostname string `mapstructure:"hostname"` H2C bool `mapstructure:"h2c"` RandomDelay bool `mapstructure:"random-delay"` + RandomDelayUnit string `mapstructure:"random-delay-unit"` + RandomDelayMin int `mapstructure:"random-delay-min"` + RandomDelayMax int `mapstructure:"random-delay-max"` RandomError bool `mapstructure:"random-error"` Unhealthy bool `mapstructure:"unhealthy"` Unready bool `mapstructure:"unready"` @@ -134,7 +137,8 @@ func (s *Server) registerMiddlewares() { s.router.Use(httpLogger.Handler) s.router.Use(versionMiddleware) if s.config.RandomDelay { - s.router.Use(randomDelayMiddleware) + randomDelayer := NewRandomDelayMiddleware(s.config.RandomDelayMin, s.config.RandomDelayMax, s.config.RandomDelayUnit) + s.router.Use(randomDelayer.Handler) } if s.config.RandomError { s.router.Use(randomErrorMiddleware)