Skip to content

Commit 67ffcf0

Browse files
committed
Extend expectations match with prefix, suffix and infix types
1 parent 3970764 commit 67ffcf0

File tree

11 files changed

+527
-19
lines changed

11 files changed

+527
-19
lines changed

conf/types/action.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type CustomExpectationAction struct {
2828

2929
type OutputExpectation struct {
3030
Order string `wst:"order,enum=fixed|random,default=fixed"`
31-
Match string `wst:"match,enum=exact|regexp,default=exact"`
31+
Match string `wst:"match,enum=exact|regexp|prefix|suffix|infix,default=exact"`
3232
Type string `wst:"type,enum=stdout|stderr|any,default=any"`
3333
RenderTemplate bool `wst:"render_template,default=true"`
3434
Messages []string `wst:"messages"`
@@ -45,7 +45,7 @@ type Headers map[string]string
4545

4646
type ResponseBody struct {
4747
Content string `wst:"content"`
48-
Match string `wst:"match,enum=exact|regexp,default=exact"`
48+
Match string `wst:"match,enum=exact|regexp|prefix|suffix|infix,default=exact"`
4949
RenderTemplate bool `wst:"render_template,default=true"`
5050
}
5151

run/actions/action/expect/output.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,25 @@ func (a *outputAction) matchMessages(line string, messages []string) ([]string,
170170
}
171171

172172
func (a *outputAction) matchMessage(line, message string) (bool, error) {
173-
if a.MatchType == expectations.MatchTypeExact {
174-
a.fnd.Logger().Debugf("Matching message '%s' against line: %s", message, line)
173+
a.fnd.Logger().Debugf("Matching '%s' against line: %s (type: %s)", message, line, a.MatchType)
174+
175+
switch a.MatchType {
176+
case expectations.MatchTypeExact:
175177
return line == message, nil
176-
} else if a.MatchType == expectations.MatchTypeRegexp {
177-
a.fnd.Logger().Debugf("Matching pattern '%s' against line: %s", message, line)
178+
179+
case expectations.MatchTypeRegexp:
178180
return regexp.MatchString(message, line)
179-
} else {
181+
182+
case expectations.MatchTypePrefix:
183+
return strings.HasPrefix(line, message), nil
184+
185+
case expectations.MatchTypeSuffix:
186+
return strings.HasSuffix(line, message), nil
187+
188+
case expectations.MatchTypeInfix:
189+
return strings.Contains(line, message), nil
190+
191+
default:
180192
return false, fmt.Errorf("unknown match type %s", string(a.MatchType))
181193
}
182194
}

run/actions/action/expect/output_test.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,84 @@ func Test_outputAction_Execute(t *testing.T) {
275275
outputType: output.Stdout,
276276
want: true,
277277
},
278+
{
279+
name: "successful output fixed prefix match without template rendering",
280+
setupMocks: func(
281+
t *testing.T,
282+
fnd *appMocks.MockFoundation,
283+
ctx context.Context,
284+
svc *servicesMocks.MockService,
285+
params parameters.Parameters,
286+
outputType output.Type,
287+
) {
288+
mockLogger := external.NewMockLogger()
289+
fnd.On("Logger").Return(mockLogger.SugaredLogger)
290+
r := strings.NewReader("test message")
291+
scanner := bufio.NewScanner(r)
292+
svc.On("OutputScanner", ctx, outputType).Return(scanner, nil)
293+
},
294+
expectation: &expectations.OutputExpectation{
295+
OrderType: expectations.OrderTypeFixed,
296+
MatchType: expectations.MatchTypePrefix,
297+
OutputType: expectations.OutputTypeStdout,
298+
RenderTemplate: false,
299+
Messages: []string{"test"},
300+
},
301+
outputType: output.Stdout,
302+
want: true,
303+
},
304+
{
305+
name: "successful output fixed suffix match without template rendering",
306+
setupMocks: func(
307+
t *testing.T,
308+
fnd *appMocks.MockFoundation,
309+
ctx context.Context,
310+
svc *servicesMocks.MockService,
311+
params parameters.Parameters,
312+
outputType output.Type,
313+
) {
314+
mockLogger := external.NewMockLogger()
315+
fnd.On("Logger").Return(mockLogger.SugaredLogger)
316+
r := strings.NewReader("some test")
317+
scanner := bufio.NewScanner(r)
318+
svc.On("OutputScanner", ctx, outputType).Return(scanner, nil)
319+
},
320+
expectation: &expectations.OutputExpectation{
321+
OrderType: expectations.OrderTypeFixed,
322+
MatchType: expectations.MatchTypeSuffix,
323+
OutputType: expectations.OutputTypeStdout,
324+
RenderTemplate: false,
325+
Messages: []string{"test"},
326+
},
327+
outputType: output.Stdout,
328+
want: true,
329+
},
330+
{
331+
name: "successful output fixed infix match without template rendering",
332+
setupMocks: func(
333+
t *testing.T,
334+
fnd *appMocks.MockFoundation,
335+
ctx context.Context,
336+
svc *servicesMocks.MockService,
337+
params parameters.Parameters,
338+
outputType output.Type,
339+
) {
340+
mockLogger := external.NewMockLogger()
341+
fnd.On("Logger").Return(mockLogger.SugaredLogger)
342+
r := strings.NewReader("some test message")
343+
scanner := bufio.NewScanner(r)
344+
svc.On("OutputScanner", ctx, outputType).Return(scanner, nil)
345+
},
346+
expectation: &expectations.OutputExpectation{
347+
OrderType: expectations.OrderTypeFixed,
348+
MatchType: expectations.MatchTypeInfix,
349+
OutputType: expectations.OutputTypeStdout,
350+
RenderTemplate: false,
351+
Messages: []string{"test"},
352+
},
353+
outputType: output.Stdout,
354+
want: true,
355+
},
278356
{
279357
name: "successful output random regexp match without template rendering",
280358
setupMocks: func(
@@ -492,6 +570,87 @@ func Test_outputAction_Execute(t *testing.T) {
492570
expectErr: true,
493571
expectedErrorMsg: "unknown match type x",
494572
},
573+
{
574+
name: "failed output fixed prefix match",
575+
setupMocks: func(
576+
t *testing.T,
577+
fnd *appMocks.MockFoundation,
578+
ctx context.Context,
579+
svc *servicesMocks.MockService,
580+
params parameters.Parameters,
581+
outputType output.Type,
582+
) {
583+
mockLogger := external.NewMockLogger()
584+
fnd.On("Logger").Return(mockLogger.SugaredLogger)
585+
fnd.On("DryRun").Return(false)
586+
r := strings.NewReader("different start message")
587+
scanner := bufio.NewScanner(r)
588+
svc.On("OutputScanner", ctx, outputType).Return(scanner, nil)
589+
},
590+
expectation: &expectations.OutputExpectation{
591+
OrderType: expectations.OrderTypeFixed,
592+
MatchType: expectations.MatchTypePrefix,
593+
OutputType: expectations.OutputTypeStdout,
594+
RenderTemplate: false,
595+
Messages: []string{"test"},
596+
},
597+
outputType: output.Stdout,
598+
want: false,
599+
},
600+
{
601+
name: "failed output fixed suffix match",
602+
setupMocks: func(
603+
t *testing.T,
604+
fnd *appMocks.MockFoundation,
605+
ctx context.Context,
606+
svc *servicesMocks.MockService,
607+
params parameters.Parameters,
608+
outputType output.Type,
609+
) {
610+
mockLogger := external.NewMockLogger()
611+
fnd.On("Logger").Return(mockLogger.SugaredLogger)
612+
fnd.On("DryRun").Return(false)
613+
r := strings.NewReader("message with wrong ending")
614+
scanner := bufio.NewScanner(r)
615+
svc.On("OutputScanner", ctx, outputType).Return(scanner, nil)
616+
},
617+
expectation: &expectations.OutputExpectation{
618+
OrderType: expectations.OrderTypeFixed,
619+
MatchType: expectations.MatchTypeSuffix,
620+
OutputType: expectations.OutputTypeStdout,
621+
RenderTemplate: false,
622+
Messages: []string{"test"},
623+
},
624+
outputType: output.Stdout,
625+
want: false,
626+
},
627+
{
628+
name: "failed output fixed infix match",
629+
setupMocks: func(
630+
t *testing.T,
631+
fnd *appMocks.MockFoundation,
632+
ctx context.Context,
633+
svc *servicesMocks.MockService,
634+
params parameters.Parameters,
635+
outputType output.Type,
636+
) {
637+
mockLogger := external.NewMockLogger()
638+
fnd.On("Logger").Return(mockLogger.SugaredLogger)
639+
fnd.On("DryRun").Return(false)
640+
r := strings.NewReader("message without expected content inside")
641+
scanner := bufio.NewScanner(r)
642+
svc.On("OutputScanner", ctx, outputType).Return(scanner, nil)
643+
},
644+
expectation: &expectations.OutputExpectation{
645+
OrderType: expectations.OrderTypeFixed,
646+
MatchType: expectations.MatchTypeInfix,
647+
OutputType: expectations.OutputTypeStdout,
648+
RenderTemplate: false,
649+
Messages: []string{"test"},
650+
},
651+
outputType: output.Stdout,
652+
want: false,
653+
},
495654
{
496655
name: "failed due to invalid random match",
497656
setupMocks: func(

run/actions/action/expect/response.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/wstool/wst/run/parameters"
2727
"github.com/wstool/wst/run/services"
2828
"regexp"
29+
"strings"
2930
"time"
3031
)
3132

@@ -127,6 +128,24 @@ func (a *responseAction) Execute(_ context.Context, runData runtime.Data) (bool,
127128
a.fnd.Logger().Infof("Body did not match the pattern")
128129
return noMatchResult, nil
129130
}
131+
case expectations.MatchTypePrefix:
132+
a.fnd.Logger().Debugf("Matching body %s with expected prefix %s", responseData.Body, content)
133+
if !strings.HasPrefix(responseData.Body, content) {
134+
a.fnd.Logger().Infof("Body did not match the prefix")
135+
return noMatchResult, nil
136+
}
137+
case expectations.MatchTypeSuffix:
138+
a.fnd.Logger().Debugf("Matching body %s with expected suffix %s", responseData.Body, content)
139+
if !strings.HasSuffix(responseData.Body, content) {
140+
a.fnd.Logger().Infof("Body did not match the suffix")
141+
return noMatchResult, nil
142+
}
143+
case expectations.MatchTypeInfix:
144+
a.fnd.Logger().Debugf("Matching body %s with expected infix %s", responseData.Body, content)
145+
if !strings.Contains(responseData.Body, content) {
146+
a.fnd.Logger().Infof("Body did not contain the expected content")
147+
return noMatchResult, nil
148+
}
130149
}
131150

132151
return true, nil

0 commit comments

Comments
 (0)