github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/config/stepmeta_test.go (about) 1 //go:build unit 2 // +build unit 3 4 package config 5 6 import ( 7 "fmt" 8 "io" 9 "os" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestReadPipelineStepData(t *testing.T) { 18 var s StepData 19 20 t.Run("Success case", func(t *testing.T) { 21 myMeta := strings.NewReader("metadata:\n name: testIt\nspec:\n inputs:\n params:\n - name: testParamName\n secrets:\n - name: testSecret") 22 err := s.ReadPipelineStepData(io.NopCloser(myMeta)) // NopCloser "no-ops" the closing interface since strings do not need to be closed 23 24 if err != nil { 25 t.Errorf("Got error although no error expected: %v", err) 26 } 27 28 t.Run("step name", func(t *testing.T) { 29 if s.Metadata.Name != "testIt" { 30 t.Errorf("Meta name - got: %v, expected: %v", s.Metadata.Name, "testIt") 31 } 32 }) 33 34 t.Run("param name", func(t *testing.T) { 35 if s.Spec.Inputs.Parameters[0].Name != "testParamName" { 36 t.Errorf("Step name - got: %v, expected: %v", s.Spec.Inputs.Parameters[0].Name, "testParamName") 37 } 38 }) 39 40 t.Run("secret name", func(t *testing.T) { 41 if s.Spec.Inputs.Secrets[0].Name != "testSecret" { 42 t.Errorf("Step name - got: %v, expected: %v", s.Spec.Inputs.Secrets[0].Name, "testSecret") 43 } 44 }) 45 }) 46 47 t.Run("Read failure", func(t *testing.T) { 48 var rc errReadCloser 49 err := s.ReadPipelineStepData(rc) 50 if err == nil { 51 t.Errorf("Got no error although error expected.") 52 } 53 }) 54 55 t.Run("Unmarshalling failure", func(t *testing.T) { 56 myMeta := strings.NewReader("metadata:\n\tname: testIt") 57 err := s.ReadPipelineStepData(io.NopCloser(myMeta)) 58 if err == nil { 59 t.Errorf("Got no error although error expected.") 60 } 61 }) 62 } 63 64 func TestGetParameterFilters(t *testing.T) { 65 metadata1 := StepData{ 66 Spec: StepSpec{ 67 Inputs: StepInputs{ 68 Parameters: []StepParameters{ 69 {Name: "paramOne", Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS", "ENV"}}, 70 {Name: "paramTwo", Scope: []string{"STEPS", "STAGES", "PARAMETERS", "ENV"}}, 71 {Name: "paramThree", Scope: []string{"STAGES", "PARAMETERS", "ENV"}}, 72 {Name: "paramFour", Scope: []string{"PARAMETERS", "ENV"}}, 73 {Name: "paramFive", Scope: []string{"ENV"}}, 74 {Name: "paramSix"}, 75 {Name: "paramSeven", Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"}, Conditions: []Condition{{Params: []Param{{Name: "buildTool", Value: "mta"}}}}}, 76 }, 77 }, 78 }, 79 } 80 81 metadata2 := StepData{ 82 Spec: StepSpec{ 83 Inputs: StepInputs{ 84 Parameters: []StepParameters{ 85 {Name: "paramOne", Scope: []string{"GENERAL"}}, 86 {Name: "paramTwo", Scope: []string{"STEPS"}}, 87 {Name: "paramThree", Scope: []string{"STAGES"}}, 88 {Name: "paramFour", Scope: []string{"PARAMETERS"}}, 89 {Name: "paramFive", Scope: []string{"ENV"}}, 90 {Name: "paramSix"}, 91 }, 92 }, 93 }, 94 } 95 96 metadata3 := StepData{ 97 Spec: StepSpec{ 98 Inputs: StepInputs{ 99 Parameters: []StepParameters{}, 100 }, 101 }, 102 } 103 104 testTable := []struct { 105 Metadata StepData 106 ExpectedAll []string 107 ExpectedGeneral []string 108 ExpectedStages []string 109 ExpectedSteps []string 110 ExpectedParameters []string 111 ExpectedEnv []string 112 NotExpectedAll []string 113 NotExpectedGeneral []string 114 NotExpectedStages []string 115 NotExpectedSteps []string 116 NotExpectedParameters []string 117 NotExpectedEnv []string 118 }{ 119 { 120 Metadata: metadata1, 121 ExpectedGeneral: []string{"verbose", "paramOne", "paramSeven", "mta"}, 122 ExpectedSteps: []string{"verbose", "paramOne", "paramTwo", "paramSeven", "mta"}, 123 ExpectedStages: []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramSeven", "mta"}, 124 ExpectedParameters: []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramSeven", "mta"}, 125 ExpectedEnv: []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramFive", "paramSeven", "mta"}, 126 ExpectedAll: []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramFive", "paramSix", "paramSeven", "mta"}, 127 NotExpectedGeneral: []string{"paramTwo", "paramThree", "paramFour", "paramFive", "paramSix"}, 128 NotExpectedSteps: []string{"paramThree", "paramFour", "paramFive", "paramSix"}, 129 NotExpectedStages: []string{"paramFour", "paramFive", "paramSix"}, 130 NotExpectedParameters: []string{"paramFive", "paramSix"}, 131 NotExpectedEnv: []string{"verbose", "paramSix", "mta"}, 132 NotExpectedAll: []string{}, 133 }, 134 { 135 Metadata: metadata2, 136 ExpectedGeneral: []string{"verbose", "paramOne"}, 137 ExpectedSteps: []string{"verbose", "paramTwo"}, 138 ExpectedStages: []string{"verbose", "paramThree"}, 139 ExpectedParameters: []string{"verbose", "paramFour"}, 140 ExpectedEnv: []string{"paramFive"}, 141 ExpectedAll: []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramFive", "paramSix"}, 142 NotExpectedGeneral: []string{"paramTwo", "paramThree", "paramFour", "paramFive", "paramSix"}, 143 NotExpectedSteps: []string{"paramOne", "paramThree", "paramFour", "paramFive", "paramSix"}, 144 NotExpectedStages: []string{"paramOne", "paramTwo", "paramFour", "paramFive", "paramSix"}, 145 NotExpectedParameters: []string{"paramOne", "paramTwo", "paramThree", "paramFive", "paramSix"}, 146 NotExpectedEnv: []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramSix"}, 147 NotExpectedAll: []string{}, 148 }, 149 { 150 Metadata: metadata3, 151 ExpectedGeneral: []string{"verbose"}, 152 ExpectedStages: []string{"verbose"}, 153 ExpectedSteps: []string{"verbose"}, 154 ExpectedParameters: []string{"verbose"}, 155 ExpectedEnv: []string{}, 156 ExpectedAll: []string{"verbose"}, 157 }, 158 } 159 160 for key, row := range testTable { 161 t.Run(fmt.Sprintf("Metadata%v", key), func(t *testing.T) { 162 filters := row.Metadata.GetParameterFilters() 163 t.Run("General", func(t *testing.T) { 164 for _, val := range filters.General { 165 if !sliceContains(row.ExpectedGeneral, val) { 166 t.Errorf("Creation of parameter filter failed, expected: %v to be contained in %v", val, filters.General) 167 } 168 if sliceContains(row.NotExpectedGeneral, val) { 169 t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in %v", val, filters.General) 170 } 171 } 172 }) 173 t.Run("Steps", func(t *testing.T) { 174 for _, val := range filters.Steps { 175 if !sliceContains(row.ExpectedSteps, val) { 176 t.Errorf("Creation of parameter filter failed, expected: %v to be contained in %v", val, filters.Steps) 177 } 178 if sliceContains(row.NotExpectedSteps, val) { 179 t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in %v", val, filters.Steps) 180 } 181 } 182 }) 183 t.Run("Stages", func(t *testing.T) { 184 for _, val := range filters.Stages { 185 if !sliceContains(row.ExpectedStages, val) { 186 t.Errorf("Creation of parameter filter failed, expected: %v to be contained in %v", val, filters.Stages) 187 } 188 if sliceContains(row.NotExpectedStages, val) { 189 t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in %v", val, filters.Stages) 190 } 191 } 192 }) 193 t.Run("Parameters", func(t *testing.T) { 194 for _, val := range filters.Parameters { 195 if !sliceContains(row.ExpectedParameters, val) { 196 t.Errorf("Creation of parameter filter failed, expected: %v to be contained in %v", val, filters.Parameters) 197 } 198 if sliceContains(row.NotExpectedParameters, val) { 199 t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in %v", val, filters.Parameters) 200 } 201 } 202 }) 203 t.Run("Env", func(t *testing.T) { 204 for _, val := range filters.Env { 205 if !sliceContains(row.ExpectedEnv, val) { 206 t.Errorf("Creation of parameter filter failed, expected: %v to be contained in %v", val, filters.Env) 207 } 208 if sliceContains(row.NotExpectedEnv, val) { 209 t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in %v", val, filters.Env) 210 } 211 } 212 }) 213 t.Run("All", func(t *testing.T) { 214 for _, val := range filters.All { 215 if !sliceContains(row.ExpectedAll, val) { 216 t.Errorf("Creation of parameter filter failed, expected: %v to be contained in %v", val, filters.All) 217 } 218 if sliceContains(row.NotExpectedAll, val) { 219 t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in %v", val, filters.All) 220 } 221 } 222 }) 223 }) 224 } 225 } 226 227 func TestGetContextParameterFilters(t *testing.T) { 228 metadata1 := StepData{ 229 Spec: StepSpec{ 230 Inputs: StepInputs{ 231 Secrets: []StepSecrets{ 232 {Name: "testSecret1", Type: "jenkins"}, 233 {Name: "testSecret2", Type: "jenkins"}, 234 }, 235 Resources: []StepResources{ 236 {Name: "buildDescriptor", Type: "stash"}, 237 }, 238 }, 239 }, 240 } 241 242 metadata2 := StepData{ 243 Spec: StepSpec{ 244 Containers: []Container{ 245 {Name: "testcontainer"}, 246 {Conditions: []Condition{ 247 {Params: []Param{ 248 {Name: "scanType", Value: "pip"}, 249 }}, 250 }}, 251 }, 252 }, 253 } 254 255 metadata3 := StepData{ 256 Spec: StepSpec{ 257 Sidecars: []Container{ 258 {Name: "testsidecar"}, 259 }, 260 }, 261 } 262 263 metadata4 := StepData{ 264 Spec: StepSpec{ 265 Inputs: StepInputs{ 266 Parameters: []StepParameters{ 267 {ResourceRef: []ResourceReference{{Type: "vaultSecret"}}}, 268 }, 269 }, 270 }, 271 } 272 273 metadata5 := StepData{ 274 Spec: StepSpec{ 275 Inputs: StepInputs{ 276 Parameters: []StepParameters{ 277 {ResourceRef: []ResourceReference{{Type: "vaultSecretFile"}}}, 278 }, 279 }, 280 }, 281 } 282 283 t.Run("Secrets and stashes", func(t *testing.T) { 284 filters := metadata1.GetContextParameterFilters() 285 params := defaultParams("testSecret1", "testSecret2", "stashContent") 286 assert.Equal(t, params, filters.General, "incorrect filter General") 287 assert.Equal(t, params, filters.All, "incorrect filter All") 288 assert.Equal(t, params, filters.Steps, "incorrect filter Steps") 289 assert.Equal(t, params, filters.Stages, "incorrect filter Stages") 290 assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters") 291 assert.Equal(t, params, filters.Env, "incorrect filter Env") 292 }) 293 294 t.Run("Containers", func(t *testing.T) { 295 filters := metadata2.GetContextParameterFilters() 296 params := defaultParams("containerCommand", "containerShell", "dockerEnvVars", "dockerImage", "dockerName", "dockerOptions", "dockerPullImage", "dockerVolumeBind", "dockerWorkspace", "dockerRegistryUrl", "dockerRegistryCredentialsId", "pip", "scanType") 297 298 assert.Equal(t, params, filters.All, "incorrect filter All") 299 assert.Equal(t, params, filters.General, "incorrect filter General") 300 assert.Equal(t, params, filters.Steps, "incorrect filter Steps") 301 assert.Equal(t, params, filters.Stages, "incorrect filter Stages") 302 assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters") 303 assert.Equal(t, params, filters.Env, "incorrect filter Env") 304 }) 305 306 t.Run("Sidecars", func(t *testing.T) { 307 filters := metadata3.GetContextParameterFilters() 308 params := defaultParams("containerName", "containerPortMappings", "dockerName", "sidecarEnvVars", "sidecarImage", "sidecarName", "sidecarOptions", "sidecarPullImage", "sidecarReadyCommand", "sidecarVolumeBind", "sidecarWorkspace") 309 assert.Equal(t, params, filters.All, "incorrect filter All") 310 assert.Equal(t, params, filters.General, "incorrect filter General") 311 assert.Equal(t, params, filters.Steps, "incorrect filter Steps") 312 assert.Equal(t, params, filters.Stages, "incorrect filter Stages") 313 assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters") 314 assert.Equal(t, params, filters.Env, "incorrect filter Env") 315 }) 316 317 t.Run("Vault", func(t *testing.T) { 318 filters := metadata4.GetContextParameterFilters() 319 params := defaultParams() 320 assert.Equal(t, params, filters.All, "incorrect filter All") 321 assert.Equal(t, params, filters.General, "incorrect filter General") 322 assert.Equal(t, params, filters.Steps, "incorrect filter Steps") 323 assert.Equal(t, params, filters.Stages, "incorrect filter Stages") 324 assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters") 325 assert.Equal(t, params, filters.Env, "incorrect filter Env") 326 }) 327 328 t.Run("Vault", func(t *testing.T) { 329 filters := metadata5.GetContextParameterFilters() 330 params := defaultParams() 331 assert.Equal(t, params, filters.All, "incorrect filter All") 332 assert.Equal(t, params, filters.General, "incorrect filter General") 333 assert.Equal(t, params, filters.Steps, "incorrect filter Steps") 334 assert.Equal(t, params, filters.Stages, "incorrect filter Stages") 335 assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters") 336 assert.Equal(t, params, filters.Env, "incorrect filter Env") 337 }) 338 } 339 340 func TestGetContextDefaults(t *testing.T) { 341 342 t.Run("Positive case", func(t *testing.T) { 343 metadata := StepData{ 344 Spec: StepSpec{ 345 Inputs: StepInputs{ 346 Resources: []StepResources{ 347 { 348 Name: "buildDescriptor", 349 Type: "stash", 350 Conditions: []Condition{ 351 {Params: []Param{ 352 {Name: "scanType", Value: "abc"}, 353 }}, 354 }, 355 }, 356 { 357 Name: "source", 358 Type: "stash", 359 Conditions: []Condition{ 360 {Params: []Param{ 361 {Name: "scanType", Value: "abc"}, 362 }}, 363 }, 364 }, 365 { 366 Name: "test", 367 Type: "nonce", 368 }, 369 { 370 Name: "test2", 371 Type: "stash", 372 Conditions: []Condition{ 373 {Params: []Param{ 374 {Name: "scanType", Value: "def"}, 375 }}, 376 }, 377 }, 378 { 379 Name: "test3", 380 Type: "stash", 381 }, 382 }, 383 }, 384 Containers: []Container{ 385 { 386 Command: []string{"test/command"}, 387 EnvVars: []EnvVar{ 388 {Name: "env1", Value: "val1"}, 389 {Name: "env2", Value: "val2"}, 390 }, 391 Name: "testcontainer", 392 Image: "testImage:tag", 393 ImagePullPolicy: "Always", 394 Shell: "/bin/bash", 395 WorkingDir: "/test/dir", 396 Options: []Option{ 397 {Name: "opt1", Value: "optValue1"}, 398 {Name: "opt2", Value: "optValue2"}, 399 }, 400 //VolumeMounts: []VolumeMount{ 401 // {MountPath: "mp1", Name: "mn1"}, 402 // {MountPath: "mp2", Name: "mn2"}, 403 //}, 404 }, 405 }, 406 Sidecars: []Container{ 407 { 408 Command: []string{"/sidecar/command"}, 409 EnvVars: []EnvVar{ 410 {Name: "env3", Value: "val3"}, 411 {Name: "env4", Value: "val4"}, 412 }, 413 Name: "testsidecar", 414 Image: "testSidecarImage:tag", 415 ImagePullPolicy: "Never", 416 ReadyCommand: "/sidecar/command", 417 WorkingDir: "/sidecar/dir", 418 Options: []Option{ 419 {Name: "opt3", Value: "optValue3"}, 420 {Name: "opt4", Value: "optValue4"}, 421 }, 422 //VolumeMounts: []VolumeMount{ 423 // {MountPath: "mp3", Name: "mn3"}, 424 // {MountPath: "mp4", Name: "mn4"}, 425 //}, 426 }, 427 }, 428 }, 429 } 430 431 cd, err := metadata.GetContextDefaults("testStep") 432 433 t.Run("No error", func(t *testing.T) { 434 if err != nil { 435 t.Errorf("No error expected but got error '%v'", err) 436 } 437 }) 438 439 var d PipelineDefaults 440 d.ReadPipelineDefaults([]io.ReadCloser{cd}) 441 442 assert.Equal(t, []interface{}{"buildDescriptor", "source"}, d.Defaults[0].Steps["testStep"]["abc"].(map[string]interface{})["stashContent"], "stashContent default not available") 443 assert.Equal(t, []interface{}{"test2"}, d.Defaults[0].Steps["testStep"]["def"].(map[string]interface{})["stashContent"], "stashContent default not available") 444 assert.Equal(t, []interface{}{"test3"}, d.Defaults[0].Steps["testStep"]["stashContent"], "stashContent default not available") 445 assert.Equal(t, "test/command", d.Defaults[0].Steps["testStep"]["containerCommand"], "containerCommand default not available") 446 assert.Equal(t, "testcontainer", d.Defaults[0].Steps["testStep"]["containerName"], "containerName default not available") 447 assert.Equal(t, "/bin/bash", d.Defaults[0].Steps["testStep"]["containerShell"], "containerShell default not available") 448 assert.Equal(t, map[string]interface{}{"env1": "val1", "env2": "val2"}, d.Defaults[0].Steps["testStep"]["dockerEnvVars"], "dockerEnvVars default not available") 449 assert.Equal(t, "testImage:tag", d.Defaults[0].Steps["testStep"]["dockerImage"], "dockerImage default not available") 450 assert.Equal(t, "testcontainer", d.Defaults[0].Steps["testStep"]["dockerName"], "dockerName default not available") 451 assert.Equal(t, true, d.Defaults[0].Steps["testStep"]["dockerPullImage"], "dockerPullImage default not available") 452 assert.Equal(t, "/test/dir", d.Defaults[0].Steps["testStep"]["dockerWorkspace"], "dockerWorkspace default not available") 453 assert.Equal(t, []interface{}{"opt1 optValue1", "opt2 optValue2"}, d.Defaults[0].Steps["testStep"]["dockerOptions"], "dockerOptions default not available") 454 //assert.Equal(t, []interface{}{"mn1:mp1", "mn2:mp2"}, d.Defaults[0].Steps["testStep"]["dockerVolumeBind"], "dockerVolumeBind default not available") 455 456 assert.Equal(t, "/sidecar/command", d.Defaults[0].Steps["testStep"]["sidecarCommand"], "sidecarCommand default not available") 457 assert.Equal(t, map[string]interface{}{"env3": "val3", "env4": "val4"}, d.Defaults[0].Steps["testStep"]["sidecarEnvVars"], "sidecarEnvVars default not available") 458 assert.Equal(t, "testSidecarImage:tag", d.Defaults[0].Steps["testStep"]["sidecarImage"], "sidecarImage default not available") 459 assert.Equal(t, "testsidecar", d.Defaults[0].Steps["testStep"]["sidecarName"], "sidecarName default not available") 460 assert.Equal(t, false, d.Defaults[0].Steps["testStep"]["sidecarPullImage"], "sidecarPullImage default not available") 461 assert.Equal(t, "/sidecar/command", d.Defaults[0].Steps["testStep"]["sidecarReadyCommand"], "sidecarReadyCommand default not available") 462 assert.Equal(t, "/sidecar/dir", d.Defaults[0].Steps["testStep"]["sidecarWorkspace"], "sidecarWorkspace default not available") 463 assert.Equal(t, []interface{}{"opt3 optValue3", "opt4 optValue4"}, d.Defaults[0].Steps["testStep"]["sidecarOptions"], "sidecarOptions default not available") 464 //assert.Equal(t, []interface{}{"mn3:mp3", "mn4:mp4"}, d.Defaults[0].Steps["testStep"]["sidecarVolumeBind"], "sidecarVolumeBind default not available") 465 }) 466 467 t.Run("Container conditions", func(t *testing.T) { 468 metadata := StepData{ 469 Spec: StepSpec{ 470 Inputs: StepInputs{ 471 Parameters: []StepParameters{ 472 {Name: "testParameter", Default: "test"}, 473 {Name: "testConditionParameter", Default: "testConditionMet"}, 474 }, 475 }, 476 Containers: []Container{ 477 { 478 Image: "testImage1:tag", 479 Conditions: []Condition{ 480 { 481 ConditionRef: "strings-equal", 482 Params: []Param{{Name: "testConditionParameter", Value: "testConditionNotMet"}}, 483 }, 484 }, 485 }, 486 { 487 Image: "testImage2:tag", 488 Conditions: []Condition{ 489 { 490 ConditionRef: "strings-equal", 491 Params: []Param{{Name: "testConditionParameter", Value: "testConditionMet"}}, 492 }, 493 }, 494 }, 495 }, 496 }, 497 } 498 499 cd, err := metadata.GetContextDefaults("testStep") 500 501 assert.NoError(t, err) 502 503 var d PipelineDefaults 504 d.ReadPipelineDefaults([]io.ReadCloser{cd}) 505 506 assert.Equal(t, "testConditionMet", d.Defaults[0].Steps["testStep"]["testConditionParameter"]) 507 assert.Nil(t, d.Defaults[0].Steps["testStep"]["dockerImage"]) 508 509 metParameter := d.Defaults[0].Steps["testStep"]["testConditionMet"].(map[string]interface{}) 510 assert.Equal(t, "testImage2:tag", metParameter["dockerImage"]) 511 512 notMetParameter := d.Defaults[0].Steps["testStep"]["testConditionNotMet"].(map[string]interface{}) 513 assert.Equal(t, "testImage1:tag", notMetParameter["dockerImage"]) 514 }) 515 516 t.Run("If ImagePullPolicy not defined pullImage parameter not set", func(t *testing.T) { 517 metadata := StepData{ 518 Spec: StepSpec{ 519 Containers: []Container{ 520 { 521 Image: "testImage1:tag", 522 }, 523 }, 524 Sidecars: []Container{ 525 { 526 Image: "testImage1:tag", 527 }, 528 }, 529 }, 530 } 531 532 cd, err := metadata.GetContextDefaults("testStep") 533 534 assert.NoError(t, err) 535 536 var d PipelineDefaults 537 d.ReadPipelineDefaults([]io.ReadCloser{cd}) 538 539 assert.Equal(t, nil, d.Defaults[0].Steps["testStep"]["dockerPullImage"], "dockerPullImage default not available") 540 assert.Equal(t, nil, d.Defaults[0].Steps["testStep"]["sidecarPullImage"], "sidecarPullImage default not available") 541 }) 542 543 t.Run("Empty docker parameter values", func(t *testing.T) { 544 metadata := StepData{ 545 Spec: StepSpec{ 546 Containers: []Container{ 547 { 548 Image: "testImage1:tag", 549 Options: []Option{{Name: "entrypoint", Value: ""}}, 550 }, 551 }, 552 }, 553 } 554 555 cd, err := metadata.GetContextDefaults("testStep") 556 557 assert.NoError(t, err) 558 559 var d PipelineDefaults 560 d.ReadPipelineDefaults([]io.ReadCloser{cd}) 561 562 assert.Equal(t, []interface{}{"entrypoint="}, d.Defaults[0].Steps["testStep"]["dockerOptions"]) 563 }) 564 565 t.Run("Negative case", func(t *testing.T) { 566 metadataErr := []StepData{ 567 {}, 568 { 569 Spec: StepSpec{}, 570 }, 571 { 572 Spec: StepSpec{ 573 Containers: []Container{}, 574 Sidecars: []Container{}, 575 }, 576 }, 577 } 578 579 t.Run("No containers/sidecars", func(t *testing.T) { 580 cd, _ := metadataErr[0].GetContextDefaults("testStep") 581 582 var d PipelineDefaults 583 d.ReadPipelineDefaults([]io.ReadCloser{cd}) 584 585 //no assert since we just want to make sure that no panic occurs 586 }) 587 588 t.Run("No command", func(t *testing.T) { 589 cd, _ := metadataErr[1].GetContextDefaults("testStep") 590 591 var d PipelineDefaults 592 d.ReadPipelineDefaults([]io.ReadCloser{cd}) 593 594 //no assert since we just want to make sure that no panic occurs 595 }) 596 }) 597 } 598 599 func TestGetResourceParameters(t *testing.T) { 600 tt := []struct { 601 in StepData 602 expected map[string]interface{} 603 }{ 604 { 605 in: StepData{Spec: StepSpec{Inputs: StepInputs{}}}, 606 expected: map[string]interface{}{}, 607 }, 608 { 609 in: StepData{ 610 Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{ 611 {Name: "param1"}, 612 {Name: "param2"}, 613 }}}}, 614 expected: map[string]interface{}{}, 615 }, 616 { 617 in: StepData{ 618 Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{ 619 {Name: "param1", ResourceRef: []ResourceReference{}}, 620 {Name: "param2", ResourceRef: []ResourceReference{}}, 621 }}}}, 622 expected: map[string]interface{}{}, 623 }, 624 { 625 in: StepData{ 626 Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{ 627 {Name: "param1", ResourceRef: []ResourceReference{{Name: "notAvailable", Param: "envparam1"}}}, 628 {Name: "param2", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam2"}}, Type: "string"}, 629 }}}}, 630 expected: map[string]interface{}{"param2": "val2"}, 631 }, 632 { 633 in: StepData{ 634 Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{ 635 {Name: "param2", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam2"}}, Type: "string"}, 636 {Name: "param3", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "jsonList"}}, Type: "[]string"}, 637 }}}}, 638 expected: map[string]interface{}{"param2": "val2", "param3": []interface{}{"value1", "value2"}}, 639 }, 640 { 641 in: StepData{ 642 Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{ 643 {Name: "param4", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "jsonKeyValue"}}, Type: "map[string]interface{}"}, 644 }}}}, 645 expected: map[string]interface{}{"param4": map[string]interface{}{"key": "value"}}, 646 }, 647 { 648 in: StepData{ 649 Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{ 650 {Name: "param1", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam1"}}, Type: "noString"}, 651 {Name: "param4", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "jsonKeyValueString"}}, Type: "string"}, 652 }}}}, 653 expected: map[string]interface{}{"param4": "{\"key\":\"valueString\"}"}, 654 }, 655 { 656 in: StepData{ 657 Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{ 658 {Name: "param1", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam1"}, {Name: "commonPipelineEnvironment", Param: "envparam2"}}, Type: "string"}, 659 }}}}, 660 expected: map[string]interface{}{"param1": "val1"}, 661 }, 662 { 663 in: StepData{ 664 Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{ 665 {Name: "param1", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "sthwhichclearlydoesntexist"}, {Name: "commonPipelineEnvironment", Param: "envparam2"}}, Type: "string"}, 666 }}}}, 667 expected: map[string]interface{}{"param1": "val2"}, 668 }, 669 } 670 671 dir := t.TempDir() 672 673 cpeDir := filepath.Join(dir, "commonPipelineEnvironment") 674 err := os.MkdirAll(cpeDir, 0700) 675 if err != nil { 676 t.Fatal("Failed to create sub directory") 677 } 678 679 os.WriteFile(filepath.Join(cpeDir, "envparam1"), []byte("val1"), 0700) 680 os.WriteFile(filepath.Join(cpeDir, "envparam2"), []byte("val2"), 0700) 681 os.WriteFile(filepath.Join(cpeDir, "jsonList.json"), []byte("[\"value1\",\"value2\"]"), 0700) 682 os.WriteFile(filepath.Join(cpeDir, "jsonKeyValue.json"), []byte("{\"key\":\"value\"}"), 0700) 683 os.WriteFile(filepath.Join(cpeDir, "jsonKeyValueString"), []byte("{\"key\":\"valueString\"}"), 0700) 684 685 for run, test := range tt { 686 t.Run(fmt.Sprintf("Run %v", run), func(t *testing.T) { 687 got := test.in.GetResourceParameters(dir, "commonPipelineEnvironment") 688 assert.Equal(t, test.expected, got) 689 }) 690 } 691 } 692 693 func TestAvoidEmptyFields(t *testing.T) { 694 t.Parallel() 695 t.Run("ignore empty string", func(t *testing.T) { 696 t.Parallel() 697 m := make(map[string]interface{}) 698 putStringIfNotEmpty(m, "key", "") 699 assert.Len(t, m, 0) 700 }) 701 t.Run("add non-empty string", func(t *testing.T) { 702 t.Parallel() 703 m := make(map[string]interface{}) 704 putStringIfNotEmpty(m, "key", "value") 705 assert.Equal(t, "value", m["key"]) 706 }) 707 t.Run("ignore empty slice", func(t *testing.T) { 708 t.Parallel() 709 m := make(map[string]interface{}) 710 putSliceIfNotEmpty(m, "key", []string{}) 711 assert.Len(t, m, 0) 712 }) 713 t.Run("add non-empty slice", func(t *testing.T) { 714 t.Parallel() 715 m := make(map[string]interface{}) 716 putSliceIfNotEmpty(m, "key", []string{"value"}) 717 assert.Equal(t, []string{"value"}, m["key"]) 718 }) 719 t.Run("ignore empty map", func(t *testing.T) { 720 t.Parallel() 721 m := make(map[string]interface{}) 722 value := make(map[string]string) 723 putMapIfNotEmpty(m, "key", value) 724 assert.Len(t, m, 0) 725 }) 726 t.Run("add non-empty map", func(t *testing.T) { 727 t.Parallel() 728 m := make(map[string]interface{}) 729 value := make(map[string]string) 730 value["param"] = "value" 731 putMapIfNotEmpty(m, "key", value) 732 assert.Equal(t, value, m["key"]) 733 }) 734 } 735 736 func TestOptionsAsStringSlice(t *testing.T) { 737 tt := []struct { 738 options []Option 739 expected []string 740 }{ 741 {options: []Option{}, expected: []string{}}, 742 {options: []Option{{Name: "name1", Value: "value1"}}, expected: []string{"name1 value1"}}, 743 {options: []Option{{Name: "name1", Value: "value1"}, {Name: "name2", Value: "value2"}}, expected: []string{"name1 value1", "name2 value2"}}, 744 {options: []Option{{Name: "empty", Value: ""}}, expected: []string{"empty="}}, 745 } 746 747 for _, test := range tt { 748 assert.Equal(t, test.expected, OptionsAsStringSlice(test.options)) 749 } 750 } 751 752 func defaultParams(params ...string) []string { 753 vaultParams := []string{ 754 "vaultAppRoleTokenCredentialsId", 755 "vaultAppRoleSecretTokenCredentialsId", 756 "vaultTokenCredentialsId", 757 } 758 759 stepParams := make([]string, 0, len(params)+len(vaultParams)) 760 stepParams = append(stepParams, params...) 761 stepParams = append(stepParams, vaultParams...) 762 763 return stepParams 764 } 765 766 func testMetadataResolver() map[string]StepData { 767 return map[string]StepData{ 768 "githubCreateIssue": { 769 Metadata: StepMetadata{ 770 Name: "githubCreateIssue", 771 }, 772 }, 773 } 774 } 775 776 func TestResolveMetadata(t *testing.T) { 777 778 t.Run("Succes - stepName", func(t *testing.T) { 779 stepName := "githubCreateIssue" 780 stepData, err := ResolveMetadata(map[string]string{}, testMetadataResolver, "", stepName) 781 assert.NoError(t, err) 782 assert.Equal(t, "githubCreateIssue", stepData.Metadata.Name) 783 }) 784 785 t.Run("Error - wrong stepName", func(t *testing.T) { 786 stepName := "notExisting" 787 _, err := ResolveMetadata(map[string]string{}, testMetadataResolver, "", stepName) 788 assert.EqualError(t, err, "could not retrieve by stepName notExisting") 789 }) 790 791 t.Run("Error - missing input", func(t *testing.T) { 792 stepName := "" 793 _, err := ResolveMetadata(map[string]string{}, testMetadataResolver, "", stepName) 794 assert.EqualError(t, err, "either one of stepMetadata or stepName parameter has to be passed") 795 }) 796 }