github.com/kubeshop/testkube@v1.17.23/contrib/executor/jmeterd/pkg/runner/helpers.go (about) 1 package runner 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 8 "github.com/pkg/errors" 9 10 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 11 "github.com/kubeshop/testkube/pkg/executor/content" 12 "github.com/kubeshop/testkube/pkg/executor/output" 13 "github.com/kubeshop/testkube/pkg/filesystem" 14 "github.com/kubeshop/testkube/pkg/ui" 15 ) 16 17 const ( 18 envVarPrefix = "$" 19 ) 20 21 var ( 22 ErrParamMissingValue = errors.New("no value found for parameter") 23 ErrMissingParam = errors.New("parameter not found") 24 ) 25 26 func getTestPathAndWorkingDir(fs filesystem.FileSystem, execution *testkube.Execution, dataDir string) (testPath string, workingDir, testFile string, err error) { 27 testPath, workingDir, err = content.GetPathAndWorkingDir(execution.Content, dataDir) 28 if err != nil { 29 output.PrintLogf("%s Failed to resolve absolute directory for %s, using the path directly", ui.IconWarning, dataDir) 30 } 31 32 fileInfo, err := fs.Stat(testPath) 33 if err != nil { 34 return "", "", "", err 35 } 36 37 testFlag := "" 38 for i, arg := range execution.Args { 39 if arg == jmeterTestFileFlag { 40 if (i + 1) < len(execution.Args) { 41 if execution.Args[i+1] != "<runPath>" { 42 testFlag = execution.Args[i+1] 43 i++ 44 continue 45 } 46 } 47 } 48 } 49 50 if workingDir == "" { 51 workingDir = dataDir 52 } 53 54 sanityCheck := false 55 if testFlag != "" { 56 if filepath.IsAbs(testFlag) { 57 testPath = testFlag 58 } else { 59 testPath = filepath.Join(workingDir, testFlag) 60 } 61 62 testFile = filepath.Base(testPath) 63 sanityCheck = true 64 } else if fileInfo.IsDir() { 65 testFile, err = findTestFile(fs, execution, testPath, jmxExtension) 66 if err != nil { 67 return "", "", "", errors.Wrapf(err, "error searching for %s file in test path %s", jmxExtension, testPath) 68 } 69 70 testPath = filepath.Join(testPath, testFile) 71 sanityCheck = true 72 } 73 74 if sanityCheck { 75 // sanity checking for test script 76 fileInfo, err = fs.Stat(testPath) 77 if err != nil || fileInfo.IsDir() { 78 output.PrintLogf("%s Could not find file %s in the directory, error: %s", ui.IconCross, testFile, err) 79 return "", "", "", errors.Wrapf(err, "could not find file %s in the directory", testFile) 80 } 81 } 82 83 return 84 } 85 86 // findTestFile tries to find test file in args or in testPath directory. 87 func findTestFile(fs filesystem.FileSystem, execution *testkube.Execution, testPath, testExtension string) (testFile string, err error) { 88 if len(execution.Args) > 0 { 89 testFile = execution.Args[len(execution.Args)-1] 90 if strings.HasPrefix(testFile, envVarPrefix) { 91 testFile = os.ExpandEnv(testFile) 92 } 93 if !strings.HasSuffix(testFile, testExtension) { 94 testFile = "" 95 } else { 96 output.PrintLogf("%s %s file provided as last argument: %s", ui.IconWorld, testExtension, testFile) 97 execution.Args = execution.Args[:len(execution.Args)-1] 98 } 99 if testFile == "" { 100 testFile, err = searchInDir(fs, testPath, testExtension) 101 if err != nil { 102 return "", errors.Wrapf(err, "error searching for %s file in test path %s", testExtension, testPath) 103 } 104 if testFile != "" { 105 output.PrintLogf("%s %s file found in test path: %s", ui.IconWorld, testExtension, testFile) 106 } 107 } 108 } 109 if testFile == "" { 110 output.PrintLogf("%s %s file not found in args or test path!", ui.IconCross, testExtension) 111 return "", errors.Errorf("no %s file found", testExtension) 112 } 113 return testFile, nil 114 } 115 116 // searchInDir searches for file with given extension in given directory. 117 func searchInDir(fs filesystem.FileSystem, dir, extension string) (string, error) { 118 files, err := fs.ReadDir(dir) 119 if err != nil { 120 return "", err 121 } 122 123 for _, file := range files { 124 if !file.IsDir() && strings.HasSuffix(file.Name(), "."+extension) { 125 return file.Name(), nil 126 } 127 } 128 return "", nil 129 } 130 131 // injectAndExpandEnvVars injects variables from params into args and expands them if args contains <envVars> placeholder. 132 // Returns new args with injected and expanded variables. 133 func injectAndExpandEnvVars(args []string, params []string) []string { 134 copied := make([]string, len(args)) 135 copy(copied, args) 136 for i := range copied { 137 if copied[i] == "<envVars>" { 138 newArgs := make([]string, len(copied)+len(params)-1) 139 copy(newArgs, copied[:i]) 140 copy(newArgs[i:], params) 141 copy(newArgs[i+len(params):], copied[i+1:]) 142 copied = newArgs 143 break 144 } 145 } 146 147 for i := range copied { 148 copied[i] = os.ExpandEnv(copied[i]) 149 } 150 151 return copied 152 } 153 154 // getParamValue searches for a parameter in the args slice and returns its value. 155 // It returns an error if the parameter is not found or if it does not have an associated value. 156 func getParamValue(args []string, param string) (string, error) { 157 for i, arg := range args { 158 if arg == param { 159 // Check if the next element exists 160 if i+1 < len(args) { 161 return args[i+1], nil 162 } 163 return "", errors.WithStack(ErrParamMissingValue) 164 } 165 } 166 return "", errors.WithStack(ErrMissingParam) 167 }