github.com/chenbh/concourse/v6@v6.4.2/atc/steps_test.go (about) 1 package atc_test 2 3 import ( 4 "encoding/json" 5 "strings" 6 7 "github.com/chenbh/concourse/v6/atc" 8 "github.com/stretchr/testify/require" 9 "github.com/stretchr/testify/suite" 10 "sigs.k8s.io/yaml" 11 ) 12 13 type StepsSuite struct { 14 suite.Suite 15 *require.Assertions 16 } 17 18 type StepTest struct { 19 Title string 20 21 ConfigYAML string 22 StepConfig atc.StepConfig 23 24 UnknownFields map[string]*json.RawMessage 25 Err string 26 } 27 28 var factoryTests = []StepTest{ 29 { 30 Title: "get step", 31 ConfigYAML: ` 32 get: some-name 33 resource: some-resource 34 params: {some: params} 35 version: {some: version} 36 tags: [tag-1, tag-2] 37 `, 38 StepConfig: &atc.GetStep{ 39 Name: "some-name", 40 Resource: "some-resource", 41 Params: atc.Params{"some": "params"}, 42 Version: &atc.VersionConfig{Pinned: atc.Version{"some": "version"}}, 43 Tags: []string{"tag-1", "tag-2"}, 44 }, 45 }, 46 { 47 Title: "put step", 48 49 ConfigYAML: ` 50 put: some-name 51 resource: some-resource 52 params: {some: params} 53 tags: [tag-1, tag-2] 54 inputs: all 55 get_params: {some: get-params} 56 `, 57 StepConfig: &atc.PutStep{ 58 Name: "some-name", 59 Resource: "some-resource", 60 Params: atc.Params{"some": "params"}, 61 Tags: []string{"tag-1", "tag-2"}, 62 Inputs: &atc.InputsConfig{All: true}, 63 GetParams: atc.Params{"some": "get-params"}, 64 }, 65 }, 66 { 67 Title: "task step", 68 69 ConfigYAML: ` 70 task: some-task 71 privileged: true 72 config: 73 platform: linux 74 run: {path: hello} 75 file: some-task-file 76 vars: {some: vars} 77 params: {SOME: PARAMS} 78 tags: [tag-1, tag-2] 79 input_mapping: {generic: specific} 80 output_mapping: {specific: generic} 81 image: some-image 82 `, 83 84 StepConfig: &atc.TaskStep{ 85 Name: "some-task", 86 Privileged: true, 87 Config: &atc.TaskConfig{ 88 Platform: "linux", 89 Run: atc.TaskRunConfig{Path: "hello"}, 90 }, 91 ConfigPath: "some-task-file", 92 Vars: atc.Params{"some": "vars"}, 93 Params: atc.Params{"SOME": "PARAMS"}, 94 Tags: []string{"tag-1", "tag-2"}, 95 InputMapping: map[string]string{"generic": "specific"}, 96 OutputMapping: map[string]string{"specific": "generic"}, 97 ImageArtifactName: "some-image", 98 }, 99 }, 100 { 101 Title: "set_pipeline step", 102 103 ConfigYAML: ` 104 set_pipeline: some-pipeline 105 file: some-pipeline-file 106 vars: {some: vars} 107 var_files: [file-1, file-2] 108 `, 109 110 StepConfig: &atc.SetPipelineStep{ 111 Name: "some-pipeline", 112 File: "some-pipeline-file", 113 Vars: atc.Params{"some": "vars"}, 114 VarFiles: []string{"file-1", "file-2"}, 115 }, 116 }, 117 { 118 Title: "load_var step", 119 120 ConfigYAML: ` 121 load_var: some-var 122 file: some-var-file 123 format: raw 124 reveal: true 125 `, 126 127 StepConfig: &atc.LoadVarStep{ 128 Name: "some-var", 129 File: "some-var-file", 130 Format: "raw", 131 Reveal: true, 132 }, 133 }, 134 { 135 Title: "try step", 136 137 ConfigYAML: ` 138 try: 139 load_var: some-var 140 file: some-file 141 `, 142 143 StepConfig: &atc.TryStep{ 144 Step: atc.Step{ 145 Config: &atc.LoadVarStep{ 146 Name: "some-var", 147 File: "some-file", 148 }, 149 }, 150 }, 151 }, 152 { 153 Title: "do step", 154 155 ConfigYAML: ` 156 do: 157 - load_var: some-var 158 file: some-file 159 - load_var: some-other-var 160 file: some-other-file 161 `, 162 163 StepConfig: &atc.DoStep{ 164 Steps: []atc.Step{ 165 { 166 Config: &atc.LoadVarStep{ 167 Name: "some-var", 168 File: "some-file", 169 }, 170 }, 171 { 172 Config: &atc.LoadVarStep{ 173 Name: "some-other-var", 174 File: "some-other-file", 175 }, 176 }, 177 }, 178 }, 179 }, 180 { 181 Title: "in_parallel step with simple list", 182 183 ConfigYAML: ` 184 in_parallel: 185 - load_var: some-var 186 file: some-file 187 - load_var: some-other-var 188 file: some-other-file 189 `, 190 191 StepConfig: &atc.InParallelStep{ 192 Config: atc.InParallelConfig{ 193 Steps: []atc.Step{ 194 { 195 Config: &atc.LoadVarStep{ 196 Name: "some-var", 197 File: "some-file", 198 }, 199 }, 200 { 201 Config: &atc.LoadVarStep{ 202 Name: "some-other-var", 203 File: "some-other-file", 204 }, 205 }, 206 }, 207 }, 208 }, 209 }, 210 { 211 Title: "in_parallel step with config", 212 213 ConfigYAML: ` 214 in_parallel: 215 steps: 216 - load_var: some-var 217 file: some-file 218 - load_var: some-other-var 219 file: some-other-file 220 limit: 3 221 fail_fast: true 222 `, 223 224 StepConfig: &atc.InParallelStep{ 225 Config: atc.InParallelConfig{ 226 Steps: []atc.Step{ 227 { 228 Config: &atc.LoadVarStep{ 229 Name: "some-var", 230 File: "some-file", 231 }, 232 }, 233 { 234 Config: &atc.LoadVarStep{ 235 Name: "some-other-var", 236 File: "some-other-file", 237 }, 238 }, 239 }, 240 Limit: 3, 241 FailFast: true, 242 }, 243 }, 244 }, 245 { 246 Title: "aggregate step", 247 248 ConfigYAML: ` 249 aggregate: 250 - load_var: some-var 251 file: some-file 252 - load_var: some-other-var 253 file: some-other-file 254 `, 255 256 StepConfig: &atc.AggregateStep{ 257 Steps: []atc.Step{ 258 { 259 Config: &atc.LoadVarStep{ 260 Name: "some-var", 261 File: "some-file", 262 }, 263 }, 264 { 265 Config: &atc.LoadVarStep{ 266 Name: "some-other-var", 267 File: "some-other-file", 268 }, 269 }, 270 }, 271 }, 272 }, 273 { 274 Title: "timeout modifier", 275 276 ConfigYAML: ` 277 load_var: some-var 278 file: some-file 279 timeout: 1h 280 `, 281 282 StepConfig: &atc.TimeoutStep{ 283 Step: &atc.LoadVarStep{ 284 Name: "some-var", 285 File: "some-file", 286 }, 287 Duration: "1h", 288 }, 289 }, 290 { 291 Title: "attempts modifier", 292 293 ConfigYAML: ` 294 load_var: some-var 295 file: some-file 296 attempts: 3 297 `, 298 299 StepConfig: &atc.RetryStep{ 300 Step: &atc.LoadVarStep{ 301 Name: "some-var", 302 File: "some-file", 303 }, 304 Attempts: 3, 305 }, 306 }, 307 { 308 Title: "precedence of all hooks and modifiers", 309 310 ConfigYAML: ` 311 load_var: some-var 312 file: some-file 313 timeout: 1h 314 attempts: 3 315 on_success: 316 load_var: success-var 317 file: success-file 318 on_failure: 319 load_var: failure-var 320 file: failure-file 321 on_abort: 322 load_var: abort-var 323 file: abort-file 324 on_error: 325 load_var: error-var 326 file: error-file 327 ensure: 328 load_var: ensure-var 329 file: ensure-file 330 `, 331 332 StepConfig: &atc.EnsureStep{ 333 Step: &atc.OnErrorStep{ 334 Step: &atc.OnAbortStep{ 335 Step: &atc.OnFailureStep{ 336 Step: &atc.OnSuccessStep{ 337 Step: &atc.RetryStep{ 338 Step: &atc.TimeoutStep{ 339 Step: &atc.LoadVarStep{ 340 Name: "some-var", 341 File: "some-file", 342 }, 343 Duration: "1h", 344 }, 345 Attempts: 3, 346 }, 347 Hook: atc.Step{ 348 Config: &atc.LoadVarStep{ 349 Name: "success-var", 350 File: "success-file", 351 }, 352 }, 353 }, 354 Hook: atc.Step{ 355 Config: &atc.LoadVarStep{ 356 Name: "failure-var", 357 File: "failure-file", 358 }, 359 }, 360 }, 361 Hook: atc.Step{ 362 Config: &atc.LoadVarStep{ 363 Name: "abort-var", 364 File: "abort-file", 365 }, 366 }, 367 }, 368 Hook: atc.Step{ 369 Config: &atc.LoadVarStep{ 370 Name: "error-var", 371 File: "error-file", 372 }, 373 }, 374 }, 375 Hook: atc.Step{ 376 Config: &atc.LoadVarStep{ 377 Name: "ensure-var", 378 File: "ensure-file", 379 }, 380 }, 381 }, 382 }, 383 { 384 Title: "unknown field with get step", 385 386 ConfigYAML: ` 387 get: some-name 388 bogus: foo 389 `, 390 391 StepConfig: &atc.GetStep{ 392 Name: "some-name", 393 }, 394 395 UnknownFields: map[string]*json.RawMessage{"bogus": rawMessage(`"foo"`)}, 396 }, 397 { 398 Title: "multiple steps defined", 399 400 ConfigYAML: ` 401 put: some-name 402 get: some-other-name 403 `, 404 405 StepConfig: &atc.PutStep{ 406 Name: "some-name", 407 }, 408 409 UnknownFields: map[string]*json.RawMessage{"get": rawMessage(`"some-other-name"`)}, 410 }, 411 { 412 Title: "step cannot contain only modifiers", 413 414 ConfigYAML: ` 415 attempts: 2 416 `, 417 418 StepConfig: &atc.RetryStep{ 419 Attempts: 2, 420 }, 421 422 Err: "no core step type declared (e.g. get, put, task, etc.)", 423 }, 424 } 425 426 func (test StepTest) Run(s *StepsSuite) { 427 cleanIndents := strings.ReplaceAll(test.ConfigYAML, "\t", "") 428 429 var step atc.Step 430 actualErr := yaml.Unmarshal([]byte(cleanIndents), &step) 431 if test.Err != "" { 432 s.Contains(actualErr.Error(), test.Err) 433 return 434 } else { 435 s.NoError(actualErr) 436 } 437 438 s.Equal(test.StepConfig, step.Config) 439 s.Equal(test.UnknownFields, step.UnknownFields) 440 441 remarshalled, err := json.Marshal(step) 442 s.NoError(err) 443 444 var reStep atc.Step 445 err = yaml.Unmarshal(remarshalled, &reStep) 446 s.NoError(err) 447 448 s.Equal(test.StepConfig, reStep.Config) 449 } 450 451 func (s *StepsSuite) TestFactory() { 452 for _, test := range factoryTests { 453 s.Run(test.Title, func() { 454 test.Run(s) 455 }) 456 } 457 } 458 459 func rawMessage(s string) *json.RawMessage { 460 raw := json.RawMessage(s) 461 return &raw 462 }