github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/cmd/newmanExecute_test.go (about) 1 //go:build unit 2 // +build unit 3 4 package cmd 5 6 import ( 7 "os" 8 "path/filepath" 9 "strings" 10 "testing" 11 12 sliceUtils "github.com/SAP/jenkins-library/pkg/piperutils" 13 "github.com/google/uuid" 14 "github.com/pkg/errors" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 type executedExecutables struct { 19 executable string 20 params []string 21 } 22 23 type newmanExecuteMockUtils struct { 24 // *mock.ExecMockRunner 25 // *mock.FilesMock 26 errorOnGlob bool 27 errorOnNewmanInstall bool 28 errorOnRunShell bool 29 errorOnNewmanExecution bool 30 errorOnLoggingNode bool 31 errorOnLoggingNpm bool 32 executedExecutables []executedExecutables 33 filesToFind []string 34 commandIndex int 35 } 36 37 func newNewmanExecuteMockUtils() newmanExecuteMockUtils { 38 return newmanExecuteMockUtils{ 39 filesToFind: []string{"localFile.json", "localFile2.json"}, 40 } 41 } 42 43 func TestRunNewmanExecute(t *testing.T) { 44 t.Parallel() 45 46 allFineConfig := newmanExecuteOptions{ 47 NewmanCollection: "**.json", 48 NewmanEnvironment: "env.json", 49 NewmanGlobals: "globals.json", 50 NewmanInstallCommand: "npm install newman --global --quiet", 51 NewmanRunCommand: "run {{.NewmanCollection}} --environment {{.Config.NewmanEnvironment}} --globals {{.Config.NewmanGlobals}} --reporters junit,html --reporter-junit-export target/newman/TEST-{{.CollectionDisplayName}}.xml --reporter-html-export target/newman/TEST-{{.CollectionDisplayName}}.html", 52 } 53 54 t.Run("happy path", func(t *testing.T) { 55 t.Parallel() 56 // init 57 58 utils := newNewmanExecuteMockUtils() 59 60 // test 61 err := runNewmanExecute(&allFineConfig, &utils) 62 63 // assert 64 assert.NoError(t, err) 65 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "node", params: []string{"--version"}}) 66 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"--version"}}) 67 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"install", "newman", "--global", "--quiet", "--prefix=~/.npm-global"}}) 68 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: filepath.FromSlash("/home/node/.npm-global/bin/newman"), params: []string{"run", "localFile.json", "--environment", "env.json", "--globals", "globals.json", "--reporters", "junit,html", "--reporter-junit-export", "target/newman/TEST-localFile.xml", "--reporter-html-export", "target/newman/TEST-localFile.html", "--suppress-exit-code"}}) 69 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: filepath.FromSlash("/home/node/.npm-global/bin/newman"), params: []string{"run", "localFile2.json", "--environment", "env.json", "--globals", "globals.json", "--reporters", "junit,html", "--reporter-junit-export", "target/newman/TEST-localFile2.xml", "--reporter-html-export", "target/newman/TEST-localFile2.html", "--suppress-exit-code"}}) 70 }) 71 72 t.Run("happy path with fail on error", func(t *testing.T) { 73 t.Parallel() 74 // init 75 76 utils := newNewmanExecuteMockUtils() 77 fineConfig := allFineConfig 78 fineConfig.FailOnError = true 79 80 // test 81 err := runNewmanExecute(&fineConfig, &utils) 82 83 // assert 84 assert.NoError(t, err) 85 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "node", params: []string{"--version"}}) 86 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"--version"}}) 87 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"install", "newman", "--global", "--quiet", "--prefix=~/.npm-global"}}) 88 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: filepath.FromSlash("/home/node/.npm-global/bin/newman"), params: []string{"run", "localFile.json", "--environment", "env.json", "--globals", "globals.json", "--reporters", "junit,html", "--reporter-junit-export", "target/newman/TEST-localFile.xml", "--reporter-html-export", "target/newman/TEST-localFile.html"}}) 89 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: filepath.FromSlash("/home/node/.npm-global/bin/newman"), params: []string{"run", "localFile2.json", "--environment", "env.json", "--globals", "globals.json", "--reporters", "junit,html", "--reporter-junit-export", "target/newman/TEST-localFile2.xml", "--reporter-html-export", "target/newman/TEST-localFile2.html"}}) 90 }) 91 92 t.Run("error on newman execution", func(t *testing.T) { 93 t.Parallel() 94 // init 95 96 utils := newNewmanExecuteMockUtils() 97 utils.errorOnNewmanExecution = true 98 99 // test 100 err := runNewmanExecute(&allFineConfig, &utils) 101 102 // assert 103 assert.EqualError(t, err, "The execution of the newman tests failed, see the log for details.: error on newman execution") 104 }) 105 106 t.Run("error on newman installation", func(t *testing.T) { 107 t.Parallel() 108 // init 109 110 utils := newNewmanExecuteMockUtils() 111 utils.errorOnNewmanInstall = true 112 113 // test 114 err := runNewmanExecute(&allFineConfig, &utils) 115 116 // assert 117 assert.EqualError(t, err, "error installing newman: error on newman install") 118 }) 119 120 t.Run("error on npm version logging", func(t *testing.T) { 121 t.Parallel() 122 // init 123 124 utils := newNewmanExecuteMockUtils() 125 utils.errorOnLoggingNpm = true 126 127 // test 128 err := runNewmanExecute(&allFineConfig, &utils) 129 130 // assert 131 assert.EqualError(t, err, "error logging npm version: error on RunExecutable") 132 }) 133 134 t.Run("error on template resolution", func(t *testing.T) { 135 t.Parallel() 136 // init 137 138 utils := newNewmanExecuteMockUtils() 139 config := allFineConfig 140 config.NewmanRunCommand = "this is my erroneous command {{.collectionDisplayName}" 141 142 // test 143 err := runNewmanExecute(&config, &utils) 144 145 // assert 146 assert.EqualError(t, err, "could not parse newman command template: template: template:1: bad character U+007D '}'") 147 }) 148 149 t.Run("error on file search", func(t *testing.T) { 150 t.Parallel() 151 // init 152 153 utils := newNewmanExecuteMockUtils() 154 utils.filesToFind = nil 155 156 // test 157 err := runNewmanExecute(&allFineConfig, &utils) 158 159 // assert 160 assert.EqualError(t, err, "no collection found with pattern '**.json'") 161 }) 162 163 t.Run("no newman file", func(t *testing.T) { 164 t.Parallel() 165 // init 166 167 utils := newNewmanExecuteMockUtils() 168 utils.errorOnGlob = true 169 170 // test 171 err := runNewmanExecute(&allFineConfig, &utils) 172 173 // assert 174 assert.EqualError(t, err, "Could not execute global search for '**.json': error on Glob") 175 }) 176 } 177 178 func TestDefineCollectionDisplayName(t *testing.T) { 179 t.Parallel() 180 181 t.Run("normal path", func(t *testing.T) { 182 t.Parallel() 183 184 path := filepath.Join("dir1", "dir2", "fancyFile.txt") 185 result := defineCollectionDisplayName(path) 186 assert.Equal(t, "dir1_dir2_fancyFile", result) 187 }) 188 189 t.Run("directory", func(t *testing.T) { 190 t.Parallel() 191 192 path := filepath.Join("dir1", "dir2", "dir3") 193 result := defineCollectionDisplayName(path) 194 assert.Equal(t, "dir1_dir2_dir3", result) 195 }) 196 197 t.Run("directory with dot prefix", func(t *testing.T) { 198 t.Parallel() 199 200 path := filepath.Join(".dir1", "dir2", "dir3", "file.json") 201 result := defineCollectionDisplayName(path) 202 assert.Equal(t, "dir1_dir2_dir3_file", result) 203 }) 204 205 t.Run("empty path", func(t *testing.T) { 206 t.Parallel() 207 208 path := filepath.Join(".") 209 result := defineCollectionDisplayName(path) 210 assert.Equal(t, "", result) 211 }) 212 } 213 214 func TestResolveTemplate(t *testing.T) { 215 t.Parallel() 216 217 t.Run("nothing to replace", func(t *testing.T) { 218 t.Parallel() 219 220 // config := newmanExecuteOptions{NewmanRunCommand: "this is my fancy command"} 221 config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command"}} 222 223 cmd, err := resolveTemplate(&config, "collectionsDisplayName") 224 assert.NoError(t, err) 225 assert.Equal(t, []string{"this", "is", "my", "fancy", "command"}, cmd) 226 }) 227 228 t.Run("replace display name", func(t *testing.T) { 229 t.Parallel() 230 231 config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command", "{{.CollectionDisplayName}}"}} 232 233 cmd, err := resolveTemplate(&config, "theDisplayName") 234 assert.NoError(t, err) 235 assert.Equal(t, []string{"this", "is", "my", "fancy", "command", "theDisplayName"}, cmd) 236 }) 237 238 t.Run("get environment variable", func(t *testing.T) { 239 t.Parallel() 240 241 temporaryEnvVarName := uuid.New().String() 242 os.Setenv(temporaryEnvVarName, "myEnvVar") 243 defer os.Unsetenv(temporaryEnvVarName) 244 config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command", "with", "--env-var", "{{getenv \"" + temporaryEnvVarName + "\"}}"}} 245 246 cmd, err := resolveTemplate(&config, "collectionsDisplayName") 247 assert.NoError(t, err) 248 assert.Equal(t, []string{"this", "is", "my", "fancy", "command", "with", "--env-var", "myEnvVar"}, cmd) 249 }) 250 251 t.Run("error when parameter cannot be resolved", func(t *testing.T) { 252 t.Parallel() 253 254 config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command", "{{.collectionDisplayName}}"}} 255 256 _, err := resolveTemplate(&config, "theDisplayName") 257 assert.EqualError(t, err, "error on executing template: template: template:1:2: executing \"template\" at <.collectionDisplayName>: can't evaluate field collectionDisplayName in type cmd.TemplateConfig") 258 }) 259 260 t.Run("error when template cannot be parsed", func(t *testing.T) { 261 t.Parallel() 262 263 config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command", "{{.collectionDisplayName}"}} 264 265 _, err := resolveTemplate(&config, "theDisplayName") 266 assert.EqualError(t, err, "could not parse newman command template: template: template:1: bad character U+007D '}'") 267 }) 268 } 269 270 func TestLogVersions(t *testing.T) { 271 t.Parallel() 272 273 t.Run("happy path", func(t *testing.T) { 274 utils := newNewmanExecuteMockUtils() 275 276 err := logVersions(&utils) 277 assert.NoError(t, err) 278 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"--version"}}) 279 }) 280 281 t.Run("error in node execution", func(t *testing.T) { 282 utils := newNewmanExecuteMockUtils() 283 utils.errorOnLoggingNode = true 284 285 err := logVersions(&utils) 286 assert.EqualError(t, err, "error logging node version: error on RunExecutable") 287 }) 288 289 t.Run("error in npm execution", func(t *testing.T) { 290 utils := newNewmanExecuteMockUtils() 291 utils.errorOnLoggingNpm = true 292 293 err := logVersions(&utils) 294 assert.EqualError(t, err, "error logging npm version: error on RunExecutable") 295 assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "node", params: []string{"--version"}}) 296 }) 297 } 298 299 func (e *newmanExecuteMockUtils) Glob(string) (matches []string, err error) { 300 if e.errorOnGlob { 301 return nil, errors.New("error on Glob") 302 } 303 304 return e.filesToFind, nil 305 } 306 307 func (e *newmanExecuteMockUtils) RunExecutable(executable string, params ...string) error { 308 if e.errorOnRunShell { 309 return errors.New("error on RunExecutable") 310 } 311 if e.errorOnLoggingNode && executable == "node" && params[0] == "--version" { 312 return errors.New("error on RunExecutable") 313 } 314 if e.errorOnLoggingNpm && executable == "npm" && params[0] == "--version" { 315 return errors.New("error on RunExecutable") 316 } 317 if e.errorOnNewmanExecution && strings.Contains(executable, "newman") { 318 return errors.New("error on newman execution") 319 } 320 if e.errorOnNewmanInstall && sliceUtils.ContainsString(params, "install") { 321 return errors.New("error on newman install") 322 } 323 324 length := len(e.executedExecutables) 325 if length < e.commandIndex+1 { 326 e.executedExecutables = append(e.executedExecutables, executedExecutables{}) 327 length++ 328 } 329 330 e.executedExecutables[length-1].executable = executable 331 e.executedExecutables[length-1].params = params 332 e.commandIndex++ 333 334 return nil 335 } 336 337 func (e *newmanExecuteMockUtils) Getenv(key string) string { 338 if key == "HOME" { 339 return "/home/node" 340 } 341 return "" 342 }