github.com/kubeshop/testkube@v1.17.23/contrib/executor/soapui/pkg/runner/runner.go (about)

     1  package runner
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/kubeshop/testkube/pkg/executor/agent"
    11  	"github.com/kubeshop/testkube/pkg/executor/scraper"
    12  	"github.com/kubeshop/testkube/pkg/executor/scraper/factory"
    13  
    14  	"github.com/pkg/errors"
    15  
    16  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    17  	"github.com/kubeshop/testkube/pkg/envs"
    18  	"github.com/kubeshop/testkube/pkg/executor"
    19  	"github.com/kubeshop/testkube/pkg/executor/content"
    20  	"github.com/kubeshop/testkube/pkg/executor/env"
    21  	"github.com/kubeshop/testkube/pkg/executor/output"
    22  	"github.com/kubeshop/testkube/pkg/executor/runner"
    23  	"github.com/kubeshop/testkube/pkg/ui"
    24  )
    25  
    26  const FailureMessage string = "finished with status [FAILED]"
    27  
    28  // NewRunner creates a new SoapUIRunner
    29  func NewRunner(ctx context.Context, params envs.Params) (*SoapUIRunner, error) {
    30  	output.PrintLogf("%s Preparing test runner", ui.IconTruck)
    31  
    32  	var err error
    33  	r := &SoapUIRunner{
    34  		SoapUILogsPath: "/home/soapui/.soapuios/logs",
    35  		Params:         params,
    36  	}
    37  
    38  	r.Scraper, err = factory.TryGetScrapper(ctx, params)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  
    43  	return r, nil
    44  }
    45  
    46  // SoapUIRunner runs SoapUI tests
    47  type SoapUIRunner struct {
    48  	SoapUILogsPath string
    49  	Scraper        scraper.Scraper
    50  	Params         envs.Params
    51  }
    52  
    53  var _ runner.Runner = &SoapUIRunner{}
    54  
    55  // Run executes the test and returns the test results
    56  func (r *SoapUIRunner) Run(ctx context.Context, execution testkube.Execution) (result testkube.ExecutionResult, err error) {
    57  	if r.Scraper != nil {
    58  		defer r.Scraper.Close()
    59  	}
    60  	output.PrintLogf("%s Preparing for test run", ui.IconTruck)
    61  
    62  	testFile, workingDir, err := content.GetPathAndWorkingDir(execution.Content, r.Params.DataDir)
    63  	if err != nil {
    64  		output.PrintLogf("%s Failed to resolve absolute directory for %s, using the path directly", ui.IconWarning, r.Params.DataDir)
    65  	}
    66  
    67  	fileInfo, err := os.Stat(testFile)
    68  	if err != nil {
    69  		return result, err
    70  	}
    71  
    72  	if fileInfo.IsDir() {
    73  		scriptName := execution.Args[len(execution.Args)-1]
    74  		if workingDir != "" {
    75  			testFile = ""
    76  			if execution.Content != nil && execution.Content.Repository != nil {
    77  				scriptName = filepath.Join(execution.Content.Repository.Path, scriptName)
    78  			}
    79  		}
    80  
    81  		execution.Args = execution.Args[:len(execution.Args)-1]
    82  		output.PrintLogf("%s It is a directory test - trying to find file from the last executor argument %s in directory %s", ui.IconWorld, scriptName, testFile)
    83  
    84  		// sanity checking for test script
    85  		scriptFile := filepath.Join(testFile, workingDir, scriptName)
    86  		fileInfo, errFile := os.Stat(scriptFile)
    87  		if errors.Is(errFile, os.ErrNotExist) || fileInfo.IsDir() {
    88  			output.PrintLogf("%s Could not find file %s in the directory, error: %s", ui.IconCross, scriptName, errFile)
    89  			return *result.Err(errors.Errorf("could not find file %s in the directory: %v", scriptName, errFile)), nil
    90  		}
    91  		testFile = scriptFile
    92  	}
    93  
    94  	setUpEnvironment(execution.Args, testFile)
    95  
    96  	output.PrintLogf("%s Running SoapUI tests", ui.IconMicroscope)
    97  	result = r.runSoapUI(&execution, workingDir)
    98  
    99  	var rerr error
   100  	if execution.PostRunScript != "" && execution.ExecutePostRunScriptBeforeScraping {
   101  		output.PrintLog(fmt.Sprintf("%s Running post run script...", ui.IconCheckMark))
   102  
   103  		if rerr = agent.RunScript(execution.PostRunScript, r.Params.WorkingDir); rerr != nil {
   104  			output.PrintLogf("%s Failed to execute post run script %s", ui.IconWarning, rerr)
   105  		}
   106  	}
   107  
   108  	if r.Params.ScrapperEnabled {
   109  		directories := []string{r.SoapUILogsPath}
   110  		var masks []string
   111  		if execution.ArtifactRequest != nil {
   112  			directories = append(directories, execution.ArtifactRequest.Dirs...)
   113  			masks = execution.ArtifactRequest.Masks
   114  		}
   115  
   116  		output.PrintLogf("Scraping directories: %v with masks: %v", directories, masks)
   117  
   118  		if err := r.Scraper.Scrape(ctx, directories, masks, execution); err != nil {
   119  			return *result.Err(err), errors.Wrap(err, "error scraping artifacts from SoapUI executor")
   120  		}
   121  	}
   122  
   123  	if rerr != nil {
   124  		return *result.Err(rerr), nil
   125  	}
   126  
   127  	return result, nil
   128  }
   129  
   130  // setUpEnvironment sets up the COMMAND_LINE environment variable to
   131  // contain the incoming arguments and to point to the test file path
   132  func setUpEnvironment(args []string, testFilePath string) {
   133  	for i := range args {
   134  		if args[i] == "<runPath>" {
   135  			args[i] = testFilePath
   136  		}
   137  
   138  		args[i] = os.ExpandEnv(args[i])
   139  	}
   140  	os.Setenv("COMMAND_LINE", strings.Join(args, " "))
   141  }
   142  
   143  // runSoapUI runs the SoapUI executable and returns the output
   144  func (r *SoapUIRunner) runSoapUI(execution *testkube.Execution, workingDir string) testkube.ExecutionResult {
   145  
   146  	envManager := env.NewManagerWithVars(execution.Variables)
   147  	envManager.GetReferenceVars(envManager.Variables)
   148  
   149  	runPath := workingDir
   150  	command, args := executor.MergeCommandAndArgs(execution.Command, nil)
   151  	output.PrintLogf("%s Test run command %s %s", ui.IconRocket, strings.Join(execution.Command, " "),
   152  		strings.Join(envManager.ObfuscateStringSlice(execution.Args), " "))
   153  	output, err := executor.Run(runPath, command, envManager, args...)
   154  	output = envManager.ObfuscateSecrets(output)
   155  	if err != nil {
   156  		return testkube.ExecutionResult{
   157  			Status:       testkube.ExecutionStatusFailed,
   158  			ErrorMessage: err.Error(),
   159  		}
   160  	}
   161  	if strings.Contains(string(output), FailureMessage) {
   162  		return testkube.ExecutionResult{
   163  			Status:       testkube.ExecutionStatusFailed,
   164  			ErrorMessage: FailureMessage,
   165  			Output:       string(output),
   166  		}
   167  	}
   168  
   169  	return testkube.ExecutionResult{
   170  		Status: testkube.ExecutionStatusPassed,
   171  		Output: string(output),
   172  	}
   173  }
   174  
   175  // GetType returns runner type
   176  func (r *SoapUIRunner) GetType() runner.Type {
   177  	return runner.TypeMain
   178  }