Skip to content

Commit cc9efa5

Browse files
committed
Add command output expectation support
1 parent 67ffcf0 commit cc9efa5

File tree

17 files changed

+376
-113
lines changed

17 files changed

+376
-113
lines changed

TODO.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ in the future.
4949

5050
#### Structure - Instances, Actions, Servers, Services
5151

52-
- add command expectation for checking its output
53-
- look into doing some partial expectation
54-
- some sort of contains mode rather than full match
52+
- test properly command action / expectation usage and possibly add some tweaks and fixes
5553
- introduce action parameter `on_failure` to set what to do when action fails
5654
- it should either fail (default) or skip the rest of sequence
5755
- this is to allow skipping the tests that are for example not applicable on certain configuration

conf/types/action.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type CustomExpectationAction struct {
2727
}
2828

2929
type OutputExpectation struct {
30+
Command string `wst:"command"`
3031
Order string `wst:"order,enum=fixed|random,default=fixed"`
3132
Match string `wst:"match,enum=exact|regexp|prefix|suffix|infix,default=exact"`
3233
Type string `wst:"type,enum=stdout|stderr|any,default=any"`

mocks/generated/run/environments/environment/output/mock_Collector.go

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/generated/run/services/mock_Service.go

Lines changed: 17 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

run/actions/action/expect/custom_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package expect
22

33
import (
4-
"bufio"
54
"context"
65
"errors"
76
"fmt"
@@ -223,8 +222,7 @@ func Test_customAction_Execute(t *testing.T) {
223222
fnd.On("Logger").Return(mockLogger.SugaredLogger)
224223
svc.On("RenderTemplate", "test", params).Return("test tmp", nil)
225224
r := strings.NewReader("test tmp")
226-
scanner := bufio.NewScanner(r)
227-
svc.On("OutputScanner", ctx, outputType).Return(scanner, nil)
225+
svc.On("OutputReader", ctx, outputType).Return(r, nil)
228226
},
229227
expectedOutputType: output.Any,
230228
want: true,

run/actions/action/expect/output.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@
1515
package expect
1616

1717
import (
18+
"bufio"
1819
"context"
1920
"fmt"
21+
"github.com/pkg/errors"
2022
"github.com/wstool/wst/conf/types"
2123
"github.com/wstool/wst/run/actions/action"
2224
"github.com/wstool/wst/run/environments/environment/output"
2325
"github.com/wstool/wst/run/expectations"
2426
"github.com/wstool/wst/run/instances/runtime"
2527
"github.com/wstool/wst/run/parameters"
2628
"github.com/wstool/wst/run/services"
29+
"io"
2730
"regexp"
2831
"strings"
2932
"time"
@@ -65,22 +68,44 @@ func (a *outputAction) Timeout() time.Duration {
6568
return a.timeout
6669
}
6770

68-
func (a *outputAction) Execute(ctx context.Context, runData runtime.Data) (bool, error) {
69-
logger := a.fnd.Logger()
70-
logger.Infof("Executing expectation output action")
71+
func (a *outputAction) getReader(ctx context.Context, runData runtime.Data) (io.Reader, error) {
7172
outputType, err := a.getServiceOutputType(a.OutputType)
7273
if err != nil {
73-
return false, err
74+
return nil, err
75+
}
76+
if a.Command == "" {
77+
// Command is empty so use service output
78+
a.fnd.Logger().Debugf("Checking service output")
79+
return a.service.OutputReader(ctx, outputType)
80+
}
81+
// Otherwise get the command data
82+
data, ok := runData.Load(fmt.Sprintf("command/%s", a.Command))
83+
if !ok {
84+
return nil, errors.New("command data not found")
7485
}
86+
// Cast it to Collector
87+
oc, ok := data.(output.Collector)
88+
if !ok {
89+
return nil, errors.New("invalid response data type")
90+
}
91+
a.fnd.Logger().Debugf("Checking command %s data", a.Command)
92+
// Get collector reader
93+
return oc.Reader(ctx, outputType)
94+
}
95+
96+
func (a *outputAction) Execute(ctx context.Context, runData runtime.Data) (bool, error) {
97+
logger := a.fnd.Logger()
98+
logger.Infof("Executing expectation output action")
7599
messages, err := a.renderMessages(a.Messages)
76100
if err != nil {
77101
return false, err
78102
}
79-
scanner, err := a.service.OutputScanner(ctx, outputType)
103+
reader, err := a.getReader(ctx, runData)
80104
if err != nil {
81105
return false, err
82106
}
83-
lines := []string{}
107+
var lines []string
108+
scanner := bufio.NewScanner(reader)
84109
for scanner.Scan() {
85110
line := scanner.Text()
86111
lines = append(lines, line)
@@ -92,18 +117,18 @@ func (a *outputAction) Execute(ctx context.Context, runData runtime.Data) (bool,
92117
return true, nil
93118
}
94119
}
95-
if scanner.Err() != nil {
120+
scannerErr := scanner.Err()
121+
if scannerErr != nil {
96122
for _, msg := range messages {
97123
logger.Debugf("Expected message not found: %s", msg)
98124
}
99125
for _, line := range lines {
100126
logger.Debugf("Unexpected line found: %s", line)
101127
}
102-
err = scanner.Err()
103-
if strings.Contains(err.Error(), "context deadline exceeded") {
128+
if strings.Contains(scannerErr.Error(), "context deadline exceeded") {
104129
return false, nil
105130
}
106-
return false, scanner.Err()
131+
return false, scannerErr
107132
}
108133

109134
if a.fnd.DryRun() {

0 commit comments

Comments
 (0)