Skip to content

Commit

Permalink
remove panics
Browse files Browse the repository at this point in the history
  • Loading branch information
hendrik-haase committed Aug 27, 2024
1 parent 3df116e commit 58cc4f8
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 61 deletions.
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ require (

require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/rs/zerolog v1.33.0 // indirect
golang.org/x/net v0.15.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
google.golang.org/protobuf v1.31.0 // indirect
Expand Down
16 changes: 16 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/LENSHOOD/go-lock-free-ring-buffer v0.2.0 h1:oxVFVKYrxWno7RwwnTvVYqdHmCCeYhMBpqjHevAXasM=
github.com/LENSHOOD/go-lock-free-ring-buffer v0.2.0/go.mod h1:jNNtDmtE7fiSWNrNyKtCOTAZxbgUkisQRQ/mmHIljoI=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
Expand All @@ -10,16 +12,30 @@ github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU=
github.com/mroth/weightedrand/v2 v2.1.0/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU=
github.com/paulbellamy/ratecounter v0.2.0 h1:2L/RhJq+HA8gBQImDXtLPrDXK5qAj6ozWVK/zFXVJGs=
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
5 changes: 3 additions & 2 deletions group.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package goload
import (
"context"
"github.com/mroth/weightedrand/v2"
"github.com/rs/zerolog/log"
"time"
)

Expand All @@ -16,7 +17,7 @@ type executorGroup struct {
// TODO: add options
func NewGroup(name string, weight int, executors []Executor) Executor {
if len(executors) == 0 {
panic("group can't be empty")
log.Fatal().Msg("group can't be empty")
}
choises := make([]weightedrand.Choice[Executor, int], 0, len(executors))
for _, exec := range executors {
Expand All @@ -26,7 +27,7 @@ func NewGroup(name string, weight int, executors []Executor) Executor {
choises...,
)
if err != nil {
panic(err)
log.Fatal().Err(err).Msg("can't create chooser")
}

return &executorGroup{
Expand Down
69 changes: 47 additions & 22 deletions http/http_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"github.com/HenriBeck/goload"
"github.com/rs/zerolog/log"
"io"
"net/http"
"net/url"
Expand Down Expand Up @@ -32,49 +33,73 @@ type endpoint struct {

client *http.Client

urlFunc func() *url.URL
methodFunc func() string
bodyFunc func() io.Reader
headerFunc func() http.Header
urlFunc func() (*url.URL, error)
methodFunc func() (string, error)
bodyFunc func() (io.Reader, error)
headerFunc func() (http.Header, error)

validateResponse func(response *http.Response) error
}

func (e *endpoint) Execute(ctx context.Context) goload.ExecutionResponse {
response := goload.ExecutionResponse{
Identifier: e.name,
}

var body io.Reader
if e.bodyFunc != nil {
body = e.bodyFunc()
var err error
body, err = e.bodyFunc()
if err != nil {
response.Err = err
log.Error().Err(err).Msg("failed to get body")
return response
}
}

fullURL := e.urlFunc().String()
req, err := http.NewRequestWithContext(ctx, e.methodFunc(), fullURL, body)
targetURL, err := e.urlFunc()
if err != nil {
return goload.ExecutionResponse{
Identifier: e.name,
Err: err,
}
response.Err = err
log.Error().Err(err).Msg("failed to get target URL")
return response
}
targetURLStr := targetURL.String()

method, err := e.methodFunc()
if err != nil {
response.Err = err
log.Error().Err(err).Msg("failed to get method")
return response
}

req, err := http.NewRequestWithContext(ctx, method, targetURLStr, body)
if err != nil {
response.Err = err
log.Error().Err(err).Msg("failed to create request")
return response
}

if e.headerFunc != nil {
req.Header = e.headerFunc()
headers, err := e.headerFunc()
if err != nil {
response.Err = err
log.Error().Err(err).Msg("failed to get headers")
return response
}
req.Header = headers
}

res, err := e.client.Do(req)
if err != nil {
return goload.ExecutionResponse{
Identifier: e.name,
Err: err,
}
response.Err = err
log.Error().Err(err).Msg("failed to execute request")
return response
}

defer res.Body.Close()

response := goload.ExecutionResponse{
Identifier: e.name,
Err: nil,
AdditionalData: map[string]string{
"url": fullURL,
},
response.AdditionalData = map[string]string{
"url": targetURLStr,
}

if e.validateResponse != nil {
Expand Down
36 changes: 20 additions & 16 deletions http/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ func renderAndValidateOptions(opts []EndpointOption) (*endpoint, error) {
timeout: 0,
client: defaultClient,
urlFunc: nil,
methodFunc: func() string {
return http.MethodGet
methodFunc: func() (string, error) {
return http.MethodGet, nil
},
bodyFunc: nil,
headerFunc: nil,
Expand All @@ -34,7 +34,11 @@ func renderAndValidateOptions(opts []EndpointOption) (*endpoint, error) {
}

if endpoint.name == "" {
endpoint.name = endpoint.urlFunc().Path
targetURL, err := endpoint.urlFunc()
if err != nil {
return nil, err
}
endpoint.name = targetURL.Path
}

return &endpoint, nil
Expand Down Expand Up @@ -66,58 +70,58 @@ func WithClient(client http.Client) EndpointOption {

func WithURL(rawURL string) EndpointOption {
return func(ep *endpoint) {
ep.urlFunc = func() *url.URL {
ep.urlFunc = func() (*url.URL, error) {
if basePath != nil {
var err error
rawURL, err = url.JoinPath(*basePath, rawURL)
if err != nil {
panic(err)
return nil, err
}
}
u, err := url.Parse(rawURL)
if err != nil {
panic(err)
return nil, err
}
return u
return u, nil
}
}
}

func WithURLFunc(urlFunc func() *url.URL) EndpointOption {
func WithURLFunc(urlFunc func() (*url.URL, error)) EndpointOption {
return func(ep *endpoint) {
ep.urlFunc = urlFunc
}
}

func WithMethod(method string) EndpointOption {
return func(ep *endpoint) {
ep.methodFunc = func() string {
return method
ep.methodFunc = func() (string, error) {
return method, nil
}
}
}

func WithMethodFunc(methodFunc func() string) EndpointOption {
func WithMethodFunc(methodFunc func() (string, error)) EndpointOption {
return func(ep *endpoint) {
ep.methodFunc = methodFunc
}
}

func WithBodyFunc(bodyFunc func() io.Reader) EndpointOption {
func WithBodyFunc(bodyFunc func() (io.Reader, error)) EndpointOption {
return func(ep *endpoint) {
ep.bodyFunc = bodyFunc
}
}

func WithHeader(header http.Header) EndpointOption {
return func(ep *endpoint) {
ep.headerFunc = func() http.Header {
return header
ep.headerFunc = func() (http.Header, error) {
return header, nil
}
}
}

func WithHeaderFunc(headerFunc func() http.Header) EndpointOption {
func WithHeaderFunc(headerFunc func() (http.Header, error)) EndpointOption {
return func(ep *endpoint) {
ep.headerFunc = headerFunc
}
Expand All @@ -132,7 +136,7 @@ func WithValidateResponse(validationFunc func(response *http.Response) error) En
func WithURLBuilder(opts ...url_builder.URLBuilderOption) EndpointOption {
builder := url_builder.NewURLBuilder(opts)
return func(ep *endpoint) {
ep.urlFunc = func() *url.URL {
ep.urlFunc = func() (*url.URL, error) {
return builder.Build(basePath)
}
}
Expand Down
9 changes: 5 additions & 4 deletions http/url_builder/query_param.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package url_builder
import (
"github.com/HenriBeck/goload/utils/random"
"github.com/mroth/weightedrand/v2"
"github.com/rs/zerolog/log"
"net/url"
)

Expand Down Expand Up @@ -31,7 +32,7 @@ func NewQueryParameter(opts ...QueryParameterOption) *QueryParameter {
opt(param)
}
if param.Name == nil || param.Value == nil {
panic("query_param.NewQueryParameter must contain opts for name and value")
log.Fatal().Msg("NewQueryParameter must contain opts for name and value")
}
return param
}
Expand Down Expand Up @@ -59,7 +60,7 @@ type oneOfParam struct {

func WithOneOfParam(params ...QueryParamBuilder) QueryParamBuilder {
if len(params) == 0 {
panic("NewOneOfParam must contain at least one parameter")
log.Fatal().Msg("WithOneOfParam must contain at least one parameter")
}
return &oneOfParam{params: params}
}
Expand All @@ -77,14 +78,14 @@ type chanceParam struct {

func NewParamWithUsageChange(chance int, param QueryParamBuilder) QueryParamBuilder {
if chance > 100 || chance < 0 {
panic("chance value must be between 0 and 100")
log.Fatal().Msg("NewParamWithUsageChange chance value must be between 0 and 100")
}
r, err := weightedrand.NewChooser(
weightedrand.NewChoice(true, chance),
weightedrand.NewChoice(true, 100-chance),
)
if err != nil {
panic(err)
log.Fatal().Err(err).Msg("can't create chooser")
}

return &chanceParam{chance: chance, param: param, r: r}
Expand Down
11 changes: 6 additions & 5 deletions http/url_builder/query_param_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package url_builder
import (
"github.com/HenriBeck/goload/utils/random"
"github.com/mroth/weightedrand/v2"
"github.com/rs/zerolog/log"
"strconv"
)

Expand All @@ -16,14 +17,14 @@ func WithParamName(name string) QueryParameterOption {

func WithParamUsagePercentage(pct int) QueryParameterOption {
if pct > 100 || pct < 0 {
panic("WithParamUsagePercentage value must be between 0 and 100")
log.Fatal().Msg("WithParamUsagePercentage pct must be between 0 and 100")
}
r, err := weightedrand.NewChooser(
weightedrand.NewChoice(true, pct),
weightedrand.NewChoice(true, 100-pct),
)
if err != nil {
panic(err)
log.Fatal().Err(err).Msg("can't create chooser")
}

return func(param *QueryParameter) {
Expand Down Expand Up @@ -58,7 +59,7 @@ type WeightedValueOpt struct {

func WithWeightedParamValue(opts ...WeightedValueOpt) QueryParameterOption {
if len(opts) == 0 {
panic("WithWeightedParamValue opts can't be empty")
log.Fatal().Msg("WithWeightedParamValue must have at least one option")
}
values := make([]weightedrand.Choice[string, int], 0, len(opts))
for _, opt := range opts {
Expand All @@ -67,7 +68,7 @@ func WithWeightedParamValue(opts ...WeightedValueOpt) QueryParameterOption {

r, err := weightedrand.NewChooser(values...)
if err != nil {
panic(err)
log.Fatal().Err(err).Msg("can't create chooser")
}

return func(param *QueryParameter) {
Expand All @@ -79,7 +80,7 @@ func WithWeightedParamValue(opts ...WeightedValueOpt) QueryParameterOption {

func WithOneOfParamValue(values []string) QueryParameterOption {
if len(values) == 0 {
panic("one off values needs at least one option")
log.Fatal().Msg("WithOneOfParamValue must have at least one value")
}
return func(param *QueryParameter) {
param.Value = func() []string {
Expand Down
Loading

0 comments on commit 58cc4f8

Please sign in to comment.