github.com/kubeshop/testkube@v1.17.23/contrib/executor/tracetest/pkg/runner/runner.go (about) 1 package runner 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/kubeshop/testkube/contrib/executor/tracetest/pkg/model" 9 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 10 "github.com/kubeshop/testkube/pkg/envs" 11 "github.com/kubeshop/testkube/pkg/executor/agent" 12 "github.com/kubeshop/testkube/pkg/executor/content" 13 "github.com/kubeshop/testkube/pkg/executor/env" 14 outputPkg "github.com/kubeshop/testkube/pkg/executor/output" 15 "github.com/kubeshop/testkube/pkg/executor/runner" 16 "github.com/kubeshop/testkube/pkg/executor/scraper" 17 "github.com/kubeshop/testkube/pkg/executor/scraper/factory" 18 "github.com/kubeshop/testkube/pkg/ui" 19 ) 20 21 func NewRunner(ctx context.Context, params envs.Params) (*TracetestRunner, error) { 22 outputPkg.PrintLog(fmt.Sprintf("%s [TracetestRunner]: Preparing Runner", ui.IconTruck)) 23 24 scraper, err := factory.TryGetScrapper(ctx, params) 25 if err != nil { 26 return nil, err 27 } 28 29 return &TracetestRunner{ 30 Params: params, 31 Scraper: scraper, 32 coreExecutor: &tracetestCoreExecutor{}, 33 cloudExecutor: &tracetestCloudExecutor{}, 34 }, nil 35 } 36 37 type TracetestRunner struct { 38 Params envs.Params 39 Scraper scraper.Scraper 40 coreExecutor TracetestCLIExecutor 41 cloudExecutor TracetestCLIExecutor 42 } 43 44 type TracetestCLIExecutor interface { 45 RequiredEnvVars() []string 46 HasEnvVarsDefined(*env.Manager) bool 47 Execute(*env.Manager, testkube.Execution, string) (model.Result, error) 48 } 49 50 func (r *TracetestRunner) Run(ctx context.Context, execution testkube.Execution) (result testkube.ExecutionResult, err error) { 51 if r.Scraper != nil { 52 defer r.Scraper.Close() 53 } 54 55 outputPkg.PrintLog(fmt.Sprintf("%s [TracetestRunner]: Preparing test run", ui.IconTruck)) 56 57 // Get execution content file path 58 testFilePath, _, err := content.GetPathAndWorkingDir(execution.Content, r.Params.DataDir) 59 if err != nil { 60 outputPkg.PrintLogf("%s Failed to resolve absolute directory for %s, using the path directly", ui.IconWarning, r.Params.DataDir) 61 } 62 63 envManager := env.NewManagerWithVars(execution.Variables) 64 envManager.GetReferenceVars(envManager.Variables) 65 66 // Get a CLI test executor 67 cliExecutor, err := r.getCLIExecutor(envManager) 68 if err != nil { 69 outputPkg.PrintLogf("%s Failed to get a Tracetest CLI executor %s", ui.IconWarning, err) 70 return testkube.ExecutionResult{}, fmt.Errorf("failed to get a Tracetest CLI executor %s", err) 71 } 72 73 // Run CLI executor 74 cliExecutionResult, err := cliExecutor.Execute(envManager, execution, testFilePath) 75 if err != nil { 76 result = cliExecutionResult.ToFailedExecutionResult(err) 77 } else { 78 result = cliExecutionResult.ToSuccessfulExecutionResult() 79 } 80 81 var rerr error 82 if execution.PostRunScript != "" && execution.ExecutePostRunScriptBeforeScraping { 83 outputPkg.PrintLog(fmt.Sprintf("%s Running post run script...", ui.IconCheckMark)) 84 85 if rerr = agent.RunScript(execution.PostRunScript, r.Params.WorkingDir); rerr != nil { 86 outputPkg.PrintLogf("%s Failed to execute post run script %s", ui.IconWarning, rerr) 87 } 88 } 89 90 // scrape artifacts first even if there are errors above 91 if r.Params.ScrapperEnabled && execution.ArtifactRequest != nil && len(execution.ArtifactRequest.Dirs) != 0 { 92 outputPkg.PrintLogf("Scraping directories: %v with masks: %v", execution.ArtifactRequest.Dirs, execution.ArtifactRequest.Masks) 93 94 if err := r.Scraper.Scrape(ctx, execution.ArtifactRequest.Dirs, execution.ArtifactRequest.Masks, execution); err != nil { 95 return testkube.ExecutionResult{}, fmt.Errorf("could not scrape tracetest directories: %w", err) 96 } 97 } 98 99 if rerr != nil { 100 return testkube.ExecutionResult{}, rerr 101 } 102 103 return result, nil 104 } 105 106 // GetType returns runner type 107 func (r *TracetestRunner) GetType() runner.Type { 108 return runner.TypeMain 109 } 110 111 func (r *TracetestRunner) getCLIExecutor(envManager *env.Manager) (TracetestCLIExecutor, error) { 112 if r.cloudExecutor.HasEnvVarsDefined(envManager) { 113 return r.cloudExecutor, nil 114 } 115 116 if r.coreExecutor.HasEnvVarsDefined(envManager) { 117 return r.coreExecutor, nil 118 } 119 120 outputPkg.PrintLogf("%s [TracetestRunner]: Could not find variables to run the test with Tracetest or Tracetest Cloud.", ui.IconCross) 121 outputPkg.PrintLogf("%s [TracetestRunner]: Please define the [%s] variables to run a test with Tracetest", ui.IconCross, strings.Join(r.cloudExecutor.RequiredEnvVars(), ", ")) 122 outputPkg.PrintLogf("%s [TracetestRunner]: Or define the [%s] variables to run a test with Tracetest Core", ui.IconCross, strings.Join(r.coreExecutor.RequiredEnvVars(), ", ")) 123 return nil, fmt.Errorf("could not find variables to run the test with Tracetest or Tracetest Cloud") 124 } 125 126 // Get variable from EnvManager 127 func getVariable(envManager *env.Manager, variableName string) (string, error) { 128 return getVariableWithWarning(envManager, variableName, true) 129 } 130 131 func getOptionalVariable(envManager *env.Manager, variableName string) (string, error) { 132 return getVariableWithWarning(envManager, variableName, false) 133 } 134 135 func getVariableWithWarning(envManager *env.Manager, variableName string, required bool) (string, error) { 136 v, ok := envManager.Variables[variableName] 137 138 warningMessage := fmt.Sprintf("%s [TracetestRunner]: %s variable was not found", ui.IconCross, variableName) 139 if !required { 140 warningMessage = fmt.Sprintf("[TracetestRunner]: %s variable was not found, assuming empty value", variableName) 141 } 142 143 if !ok { 144 outputPkg.PrintLog(warningMessage) 145 return "", fmt.Errorf(variableName + " variable was not found") 146 } 147 148 return strings.ReplaceAll(v.Value, "\"", ""), nil 149 }