diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index 260f9975..509214c2 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -207,7 +207,7 @@ func Test_JsPodDisruptor(t *testing.T) { averageDelay: "100ms", delayVariation: "10ms", errorBody: '', - exclude: "", + exclude: [], port: 80 } @@ -229,7 +229,7 @@ func Test_JsPodDisruptor(t *testing.T) { averageDelay: "100ms", delayVariation: "10ms", errorBody: '', - exclude: "", + exclude: [], port: 80 } @@ -246,7 +246,7 @@ func Test_JsPodDisruptor(t *testing.T) { averageDelay: "100ms", delayVariation: "10ms", errorBody: '', - exclude: "", + exclude: [], port: 80 } @@ -263,7 +263,7 @@ func Test_JsPodDisruptor(t *testing.T) { averageDelay: "100ms", delayVariation: "10ms", errorBody: '', - exclude: "", + exclude: [], port: 80 } @@ -283,6 +283,17 @@ func Test_JsPodDisruptor(t *testing.T) { `, expectError: true, }, + { + description: "inject HTTP Fault with exclude as a string", + script: ` + const fault = { + exclude: "foo,bar", + } + + d.injectHTTPFaults(fault, "1s") + `, + expectError: false, + }, { description: "inject Grpc Fault with full arguments", script: ` @@ -292,7 +303,7 @@ func Test_JsPodDisruptor(t *testing.T) { statusMessage: '', averageDelay: "100ms", delayVariation: "10ms", - exclude: "", + exclude: [], port: 80 } @@ -314,7 +325,7 @@ func Test_JsPodDisruptor(t *testing.T) { statusMessage: '', averageDelay: "100ms", delayVariation: "10ms", - exclude: "", + exclude: [], port: 80 } @@ -331,7 +342,7 @@ func Test_JsPodDisruptor(t *testing.T) { statusMessage: '', averageDelay: "100ms", delayVariation: "10ms", - exclude: "", + exclude: [], port: 80 } @@ -353,7 +364,7 @@ func Test_JsPodDisruptor(t *testing.T) { statusMessage: '', averageDelay: "100ms", delayVariation: "10ms", - exclude: "", + exclude: [], port: 80 } diff --git a/pkg/api/convert.go b/pkg/api/convert.go index ce8de925..95ddaeb3 100644 --- a/pkg/api/convert.go +++ b/pkg/api/convert.go @@ -3,6 +3,7 @@ package api import ( "fmt" "reflect" + "strings" "time" ) @@ -88,6 +89,18 @@ func convertMap(value interface{}, target interface{}) error { func convertSlice(value interface{}, target interface{}) error { targetValue := reflect.ValueOf(target).Elem() + // Hack: Allow to convert a comma-separated string into a slice of strings. + // This block is to be removed in 1.0. + valueStr, isString := value.(string) + if isString && reflect.TypeOf(target).Elem().Elem().Kind() == reflect.String { + // TODO: Log warning. + var iSlice []interface{} + for _, item := range strings.Split(valueStr, ",") { + iSlice = append(iSlice, item) + } + value = iSlice + } + valueSlice, ok := value.([]interface{}) if !ok { return fmt.Errorf("expected value []interface{} got %s", reflect.TypeOf(value)) diff --git a/pkg/disruptors/cmd_builders.go b/pkg/disruptors/cmd_builders.go index 15108726..16744d61 100644 --- a/pkg/disruptors/cmd_builders.go +++ b/pkg/disruptors/cmd_builders.go @@ -2,6 +2,7 @@ package disruptors import ( "fmt" + "strings" "time" "github.com/grafana/xk6-disruptor/pkg/utils" @@ -43,7 +44,7 @@ func buildGrpcFaultCmd(fault GrpcFault, duration time.Duration, options GrpcDisr } if len(fault.Exclude) > 0 { - cmd = append(cmd, "-x", fault.Exclude) + cmd = append(cmd, "-x", strings.Join(fault.Exclude, ",")) } if options.ProxyPort != 0 { @@ -93,7 +94,7 @@ func buildHTTPFaultCmd(fault HTTPFault, duration time.Duration, options HTTPDisr } if len(fault.Exclude) > 0 { - cmd = append(cmd, "-x", fault.Exclude) + cmd = append(cmd, "-x", strings.Join(fault.Exclude, ",")) } if options.ProxyPort != 0 { diff --git a/pkg/disruptors/pod_test.go b/pkg/disruptors/pod_test.go index 8355f19e..00c6c9c8 100644 --- a/pkg/disruptors/pod_test.go +++ b/pkg/disruptors/pod_test.go @@ -138,7 +138,7 @@ func Test_PodHTTPFaultInjection(t *testing.T) { expectError: false, cmdError: nil, fault: HTTPFault{ - Exclude: "/path1,/path2", + Exclude: []string{"/path1", "/path2"}, }, opts: HTTPDisruptionOptions{}, duration: 60 * time.Second, @@ -292,7 +292,7 @@ func Test_PodGrpcPFaultInjection(t *testing.T) { }, targets: []string{"my-app-pod"}, fault: GrpcFault{ - Exclude: "service1,service2", + Exclude: []string{"service1", "service2"}, }, opts: GrpcDisruptionOptions{}, duration: 60 * time.Second, diff --git a/pkg/disruptors/protocol.go b/pkg/disruptors/protocol.go index e9061c63..1a36f8ab 100644 --- a/pkg/disruptors/protocol.go +++ b/pkg/disruptors/protocol.go @@ -45,8 +45,8 @@ type HTTPFault struct { ErrorCode uint `js:"errorCode"` // Body to be returned when an error is injected ErrorBody string `js:"errorBody"` - // Comma-separated list of url paths to be excluded from disruptions - Exclude string + // List of url paths to be excluded from disruptions + Exclude []string `js:"exclude"` } // GrpcFault specifies a fault to be injected in grpc requests @@ -64,5 +64,5 @@ type GrpcFault struct { // Status message to be returned in requests selected to return an error StatusMessage string `js:"statusMessage"` // List of grpc services to be excluded from disruptions - Exclude string `js:"exclude"` + Exclude []string `js:"exclude"` }