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 }