in plugins/teststeps/cmd/cmd.go [96:158]
func (ts *Cmd) Run(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
log := ctx.Logger()
if err := ts.validateAndPopulate(params); err != nil {
return nil, err
}
f := func(ctx xcontext.Context, target *target.Target) error {
// expand args
var args []string
for _, arg := range ts.args {
expArg, err := arg.Expand(target)
if err != nil {
return fmt.Errorf("failed to expand argument '%s': %v", arg, err)
}
args = append(args, expArg)
}
cmd := exec.CommandContext(ctx, ts.executable, args...)
pwd, err := ts.dir.Expand(target)
if err != nil {
return fmt.Errorf("failed to expand argument dir '%s': %v", ts.dir, err)
}
cmd.Dir = pwd
var stdout, stderr bytes.Buffer
cmd.Stdout, cmd.Stderr = &stdout, &stderr
cmd.SysProcAttr = &syscall.SysProcAttr{
// Put the command into a separate session (and group) so signals do not propagate directly to it.
Setsid: true,
}
if cmd.Dir != "" {
log.Debugf("Running command '%+v' in directory '%+v'", cmd, cmd.Dir)
} else {
log.Debugf("Running command '%+v'", cmd)
}
// Emit EventCmdStart
if err := emitEvent(ctx, EventCmdStart, eventCmdStartPayload{Path: cmd.Path, Args: cmd.Args, Dir: cmd.Dir}, target, ev); err != nil {
log.Warnf("Failed to emit event: %v", err)
}
runErr := cmd.Run()
if err := emitEvent(ctx, EventCmdEnd, nil, target, ev); err != nil {
log.Warnf("Failed to emit event: %v", err)
}
if ts.emitStdout {
log.Infof("Emitting stdout event")
if err := emitEvent(ctx, EventCmdStdout, eventCmdStdoutPayload{Msg: stdout.String()}, target, ev); err != nil {
log.Warnf("Failed to emit event: %v", err)
}
}
if ts.emitStderr {
log.Infof("Emitting stderr event")
if err := emitEvent(ctx, EventCmdStderr, eventCmdStderrPayload{Msg: stderr.String()}, target, ev); err != nil {
log.Warnf("Failed to emit event: %v", err)
}
}
log.Infof("Command's '%s' with args '%s' stdout '%s', stderr is '%s', run err: '%v'",
cmd.Path, cmd.Args, stdout.Bytes(), stderr.Bytes(), runErr)
return runErr
}
return teststeps.ForEachTarget(Name, ctx, ch, f)
}