Skip to content

Commit

Permalink
limit-n-passes v0.5.20
Browse files Browse the repository at this point in the history
limit and passes fixes
  • Loading branch information
oke11o committed Jan 29, 2024
1 parent 745ec08 commit 5b4899f
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 106 deletions.
3 changes: 3 additions & 0 deletions .mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,13 @@
"script/checkfmt.sh":"load/projects/pandora/script/checkfmt.sh",
"script/coverage.sh":"load/projects/pandora/script/coverage.sh",
"tests/acceptance/http_test.go":"load/projects/pandora/tests/acceptance/http_test.go",
"tests/acceptance/testdata/http/http-check-limit.yaml":"load/projects/pandora/tests/acceptance/testdata/http/http-check-limit.yaml",
"tests/acceptance/testdata/http/http-check-passes.yaml":"load/projects/pandora/tests/acceptance/testdata/http/http-check-passes.yaml",
"tests/acceptance/testdata/http/http.yaml":"load/projects/pandora/tests/acceptance/testdata/http/http.yaml",
"tests/acceptance/testdata/http/http2.yaml":"load/projects/pandora/tests/acceptance/testdata/http/http2.yaml",
"tests/acceptance/testdata/http/https.yaml":"load/projects/pandora/tests/acceptance/testdata/http/https.yaml",
"tests/acceptance/testdata/http/payload.uri":"load/projects/pandora/tests/acceptance/testdata/http/payload.uri",
"tests/acceptance/testdata/http/payload5.uri":"load/projects/pandora/tests/acceptance/testdata/http/payload5.uri",
"tests/grpc_scenario/main_test.go":"load/projects/pandora/tests/grpc_scenario/main_test.go",
"tests/grpc_scenario/testdata/filter.json":"load/projects/pandora/tests/grpc_scenario/testdata/filter.json",
"tests/grpc_scenario/testdata/grpc_payload.hcl":"load/projects/pandora/tests/grpc_scenario/testdata/grpc_payload.hcl",
Expand Down
2 changes: 1 addition & 1 deletion cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"go.uber.org/zap/zapcore"
)

const Version = "0.5.19"
const Version = "0.5.20"
const defaultConfigFile = "load"
const stdinConfigSelector = "-"

Expand Down
1 change: 1 addition & 0 deletions components/providers/http/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func (p *Provider) Release(a core.Ammo) {
func (p *Provider) Run(ctx context.Context, deps core.ProviderDeps) (err error) {
p.Deps = deps
defer func() {
close(p.Sink)
// TODO: wrap in go 1.20
// err = errors.Join(err, p.Close())
if p.Close == nil {
Expand Down
228 changes: 123 additions & 105 deletions tests/acceptance/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"text/template"

"github.com/spf13/afero"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/yandex/pandora/cli"
grpc "github.com/yandex/pandora/components/grpc/import"
Expand All @@ -22,6 +23,7 @@ import (
"github.com/yandex/pandora/lib/monitoring"
"go.uber.org/atomic"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.uber.org/zap/zaptest/observer"
"golang.org/x/net/http2"
"gopkg.in/yaml.v2"
Expand All @@ -46,132 +48,148 @@ func (s *PandoraSuite) SetupSuite() {
phttpimport.Import(s.fs)
grpc.Import(s.fs)

s.log = setupLogsCapture()
s.log = newNullLogger()
// s.log = newLogger()
s.metrics = newEngineMetrics()
}

func (s *PandoraSuite) Test_Http() {
var requetsCount atomic.Int64 // Request served by test server.
requetsCount.Store(0)
srv := httptest.NewUnstartedServer(http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
requetsCount.Inc()
rw.WriteHeader(http.StatusOK)
}))
defer srv.Close()

conf := s.parseConfigFile("testdata/http/http.yaml", srv.Listener.Addr().String())
s.Require().Equal(1, len(conf.Engine.Pools))
aggr := &aggregator{}
conf.Engine.Pools[0].Aggregator = aggr
pandora := engine.New(s.log, s.metrics, conf.Engine)

srv.Start()
err := pandora.Run(context.Background())
s.Assert().Equal(int64(4), requetsCount.Load())
s.Require().NoError(err)
s.Require().Equal(4, len(aggr.samples))
}

func (s *PandoraSuite) Test_Https() {
var requetsCount atomic.Int64 // Request served by test server.
requetsCount.Store(0)
srv := httptest.NewUnstartedServer(http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
requetsCount.Inc()
rw.WriteHeader(http.StatusOK)
}))
defer srv.Close()

conf := s.parseConfigFile("testdata/http/https.yaml", srv.Listener.Addr().String())
s.Require().Equal(1, len(conf.Engine.Pools))
aggr := &aggregator{}
conf.Engine.Pools[0].Aggregator = aggr
pandora := engine.New(s.log, s.metrics, conf.Engine)

srv.StartTLS()
err := pandora.Run(context.Background())
s.Assert().Equal(int64(4), requetsCount.Load())
s.Require().NoError(err)
s.Require().Equal(4, len(aggr.samples))
func (s *PandoraSuite) Test_Http_Check_Passes() {
tests := []struct {
name string
filecfg string
isTLS bool
preStartSrv func(srv *httptest.Server)
wantErrContain string
wantCnt int
}{
{
name: "http",
filecfg: "testdata/http/http.yaml",
isTLS: false,
wantCnt: 4,
},
{
name: "https",
filecfg: "testdata/http/https.yaml",
isTLS: true,
wantCnt: 4,
},
{
name: "http2",
filecfg: "testdata/http/http2.yaml",
isTLS: true,
preStartSrv: func(srv *httptest.Server) {
_ = http2.ConfigureServer(srv.Config, nil)
srv.TLS = srv.Config.TLSConfig
},
wantCnt: 4,
},
{
name: "http2 unsapported",
filecfg: "testdata/http/http2.yaml",
isTLS: true,
preStartSrv: func(srv *httptest.Server) {
//_ = http2.ConfigureServer(srv.Config, nil)
//srv.TLS = srv.Config.TLSConfig
},
wantErrContain: "shoot panic: Non HTTP/2 connection established. Seems that target doesn't support HTTP/2.",
},
{
name: "http-check-limits",
filecfg: "testdata/http/http-check-limit.yaml",
isTLS: false,
wantCnt: 8,
},
{
name: "http-check-passes",
filecfg: "testdata/http/http-check-passes.yaml",
isTLS: false,
wantCnt: 15,
},
}
for _, tt := range tests {
s.Run(tt.name, func() {
var requetsCount atomic.Int64 // Request served by test server.
requetsCount.Store(0)
var reqs []string
srv := httptest.NewUnstartedServer(http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
requetsCount.Inc()
reqs = append(reqs, req.URL.String())
rw.WriteHeader(http.StatusOK)
}))
defer srv.Close()

conf := parseConfigFile(s.T(), tt.filecfg, srv.Listener.Addr().String())
s.Require().Equal(1, len(conf.Engine.Pools))
aggr := &aggregator{}
conf.Engine.Pools[0].Aggregator = aggr
pandora := engine.New(s.log, s.metrics, conf.Engine)

if tt.preStartSrv != nil {
tt.preStartSrv(srv)
}
if tt.isTLS {
srv.StartTLS()
} else {
srv.Start()
}
err := pandora.Run(context.Background())
if tt.wantErrContain != "" {
s.Assert().Equal(int64(0), requetsCount.Load())
s.Require().Error(err)
s.Require().Contains(err.Error(), tt.wantErrContain)
return
}
s.Require().NoError(err)
s.Assert().Equal(int64(tt.wantCnt), requetsCount.Load())
s.Require().Equal(tt.wantCnt, len(aggr.samples))
})
}
}

func (s *PandoraSuite) Test_Http2() {
var requetsCount atomic.Int64 // Request served by test server.
requetsCount.Store(0)
srv := httptest.NewUnstartedServer(http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
requetsCount.Inc()
rw.WriteHeader(http.StatusOK)
}))
defer srv.Close()

conf := s.parseConfigFile("testdata/http/http2.yaml", srv.Listener.Addr().String())
s.Require().Equal(1, len(conf.Engine.Pools))
aggr := &aggregator{}
conf.Engine.Pools[0].Aggregator = aggr
pandora := engine.New(s.log, s.metrics, conf.Engine)

_ = http2.ConfigureServer(srv.Config, nil)
srv.TLS = srv.Config.TLSConfig
srv.StartTLS()

err := pandora.Run(context.Background())
s.Assert().Equal(int64(4), requetsCount.Load())
s.Require().NoError(err)
s.Require().Equal(4, len(aggr.samples))
func parseConfigFile(t *testing.T, filename string, serverAddr string) *cli.CliConfig {
mapCfg := unmarshalConfigFile(t, filename, serverAddr)
conf := decodeConfig(t, mapCfg)
return conf
}

func (s *PandoraSuite) Test_Http2_UnsupportTarget() {
var requetsCount atomic.Int64 // Request served by test server.
requetsCount.Store(0)
srv := httptest.NewUnstartedServer(http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
requetsCount.Inc()
rw.WriteHeader(http.StatusOK)
}))
defer srv.Close()

conf := s.parseConfigFile("testdata/http/http2.yaml", srv.Listener.Addr().String())
s.Require().Equal(1, len(conf.Engine.Pools))
aggr := &aggregator{}
conf.Engine.Pools[0].Aggregator = aggr
pandora := engine.New(s.log, s.metrics, conf.Engine)

//_ = http2.ConfigureServer(srv.Config, nil)
//srv.TLS = srv.Config.TLSConfig
srv.StartTLS()

err := pandora.Run(context.Background())
s.Assert().Equal(int64(0), requetsCount.Load())
s.Require().Error(err)
s.Require().Contains(err.Error(), "shoot panic: Non HTTP/2 connection established. Seems that target doesn't support HTTP/2.")
func decodeConfig(t *testing.T, mapCfg map[string]any) *cli.CliConfig {
conf := cli.DefaultConfig()
err := config.DecodeAndValidate(mapCfg, conf)
require.NoError(t, err)
return conf
}

func (s *PandoraSuite) parseConfigFile(filename string, serverAddr string) *cli.CliConfig {
func unmarshalConfigFile(t *testing.T, filename string, serverAddr string) map[string]any {
f, err := os.ReadFile(filename)
s.Require().NoError(err)
require.NoError(t, err)
tmpl, err := template.New("x").Parse(string(f))
s.Require().NoError(err)
require.NoError(t, err)
b := &bytes.Buffer{}
err = tmpl.Execute(b, map[string]string{"target": serverAddr})
s.Require().NoError(err)
require.NoError(t, err)
mapCfg := map[string]any{}
err = yaml.Unmarshal(b.Bytes(), &mapCfg)
s.Require().NoError(err)

conf := cli.DefaultConfig()
err = config.DecodeAndValidate(mapCfg, conf)
s.Require().NoError(err)

return conf
require.NoError(t, err)
return mapCfg
}

func setupLogsCapture() *zap.Logger {
func newNullLogger() *zap.Logger {
c, _ := observer.New(zap.InfoLevel)
return zap.New(c)
}

func newLogger() *zap.Logger {
zapConf := zap.NewDevelopmentConfig()
zapConf.Level.SetLevel(zapcore.DebugLevel)
log, err := zapConf.Build(zap.AddCaller())
if err != nil {
zap.L().Fatal("Logger build failed", zap.Error(err))
}
return log
}

func newEngineMetrics() engine.Metrics {
return engine.Metrics{
Request: monitoring.NewCounter("engine_Requests"),
Expand Down
23 changes: 23 additions & 0 deletions tests/acceptance/testdata/http/http-check-limit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pools:
- id: ""
ammo:
file: testdata/http/payload5.uri
type: uri
limit: 8
result:
type: discard
gun:
target: {{.target}}
type: http
answlog:
enabled: false
rps-per-instance: false
rps:
- duration: 5s
ops: 10
type: const
startup:
- times: 2
type: once
log:
level: debug
23 changes: 23 additions & 0 deletions tests/acceptance/testdata/http/http-check-passes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pools:
- id: ""
ammo:
file: testdata/http/payload5.uri
type: uri
passes: 3
result:
type: discard
gun:
target: {{.target}}
type: http
answlog:
enabled: false
rps-per-instance: false
rps:
- duration: 5s
ops: 10
type: const
startup:
- times: 2
type: once
log:
level: debug
5 changes: 5 additions & 0 deletions tests/acceptance/testdata/http/payload5.uri
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/a
/b
/c
/d
/e

0 comments on commit 5b4899f

Please sign in to comment.