140 lines
3.0 KiB
Go
140 lines
3.0 KiB
Go
package hrp
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/httprunner/funplugin/myexec"
|
|
"github.com/pkg/errors"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type Shell struct {
|
|
String string `json:"string" yaml:"string"`
|
|
ExpectExitCode int `json:"expect_exit_code" yaml:"expect_exit_code"`
|
|
}
|
|
|
|
// StepShell implements IStep interface.
|
|
type StepShell struct {
|
|
StepConfig
|
|
Shell *Shell `json:"shell,omitempty" yaml:"shell,omitempty"`
|
|
}
|
|
|
|
func (s *StepShell) Name() string {
|
|
return s.StepName
|
|
}
|
|
|
|
func (s *StepShell) Type() StepType {
|
|
return StepTypeShell
|
|
}
|
|
|
|
func (s *StepShell) Config() *StepConfig {
|
|
return &StepConfig{
|
|
StepName: s.StepName,
|
|
Variables: s.Variables,
|
|
}
|
|
}
|
|
|
|
func (s *StepShell) Run(r *SessionRunner) (*StepResult, error) {
|
|
return runStepShell(r, s)
|
|
}
|
|
|
|
// Validate switches to step validation.
|
|
func (s *StepShell) Validate() *StepShellValidation {
|
|
return &StepShellValidation{
|
|
StepConfig: s.StepConfig,
|
|
Shell: s.Shell,
|
|
}
|
|
}
|
|
|
|
// StepShellValidation implements IStep interface.
|
|
type StepShellValidation struct {
|
|
StepConfig
|
|
Shell *Shell `json:"shell,omitempty" yaml:"shell,omitempty"`
|
|
}
|
|
|
|
func (s *StepShellValidation) Name() string {
|
|
return s.StepName
|
|
}
|
|
|
|
func (s *StepShellValidation) Type() StepType {
|
|
return StepTypeShell + stepTypeSuffixValidation
|
|
}
|
|
|
|
func (s *StepShellValidation) Config() *StepConfig {
|
|
return &StepConfig{
|
|
StepName: s.StepName,
|
|
Variables: s.Variables,
|
|
}
|
|
}
|
|
|
|
func (s *StepShellValidation) Run(r *SessionRunner) (*StepResult, error) {
|
|
return runStepShell(r, s)
|
|
}
|
|
|
|
func (s *StepShellValidation) AssertExitCode(expected int) *StepShellValidation {
|
|
s.Shell.ExpectExitCode = expected
|
|
return s
|
|
}
|
|
|
|
func runStepShell(r *SessionRunner, step IStep) (stepResult *StepResult, err error) {
|
|
var shell *Shell
|
|
switch stepShell := step.(type) {
|
|
case *StepShell:
|
|
shell = stepShell.Shell
|
|
case *StepShellValidation:
|
|
shell = stepShell.Shell
|
|
default:
|
|
return nil, errors.New("invalid shell step type")
|
|
}
|
|
|
|
log.Info().
|
|
Str("name", step.Name()).
|
|
Str("type", string(StepTypeShell)).
|
|
Str("content", shell.String).
|
|
Msg("run shell string")
|
|
|
|
start := time.Now()
|
|
stepResult = &StepResult{
|
|
Name: step.Name(),
|
|
StepType: StepTypeShell,
|
|
Success: false,
|
|
ContentSize: 0,
|
|
StartTime: start.Unix(),
|
|
}
|
|
defer func() {
|
|
stepResult.Elapsed = time.Since(start).Milliseconds()
|
|
}()
|
|
|
|
vars := r.caseRunner.Config.Get().Variables
|
|
for key, value := range vars {
|
|
os.Setenv(key, fmt.Sprintf("%v", value))
|
|
}
|
|
|
|
exitCode, err := myexec.RunShell(shell.String)
|
|
if err != nil {
|
|
if exitCode == shell.ExpectExitCode {
|
|
// get expected error
|
|
log.Warn().Err(err).
|
|
Int("exitCode", exitCode).
|
|
Msg("get expected error, ignore")
|
|
stepResult.Success = true
|
|
return stepResult, nil
|
|
}
|
|
|
|
err = errors.Wrap(err, "exec shell string failed")
|
|
return
|
|
}
|
|
|
|
// validate response
|
|
if exitCode != shell.ExpectExitCode {
|
|
err = fmt.Errorf("unexpected exit code %d, expect %d",
|
|
exitCode, shell.ExpectExitCode)
|
|
return
|
|
}
|
|
|
|
stepResult.Success = true
|
|
return stepResult, nil
|
|
}
|