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  }