github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/exec/load_var_step_test.go (about) 1 package exec_test 2 3 import ( 4 "context" 5 "strings" 6 7 "code.cloudfoundry.org/lager/lagerctx" 8 "code.cloudfoundry.org/lager/lagertest" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 "github.com/onsi/gomega/gbytes" 12 "go.opentelemetry.io/otel/api/trace" 13 14 "github.com/pf-qiu/concourse/v6/atc" 15 "github.com/pf-qiu/concourse/v6/atc/exec" 16 "github.com/pf-qiu/concourse/v6/atc/exec/build" 17 "github.com/pf-qiu/concourse/v6/atc/exec/build/buildfakes" 18 "github.com/pf-qiu/concourse/v6/atc/exec/execfakes" 19 "github.com/pf-qiu/concourse/v6/atc/worker/workerfakes" 20 ) 21 22 const plainString = " pv \n\n" 23 24 const yamlString = ` 25 k1: yv1 26 k2: yv2 27 ` 28 29 const jsonString = ` 30 { 31 "k1": "jv1", "k2": "jv2" 32 } 33 ` 34 35 var _ = Describe("LoadVarStep", func() { 36 37 var ( 38 ctx context.Context 39 cancel func() 40 testLogger *lagertest.TestLogger 41 42 fakeDelegate *execfakes.FakeBuildStepDelegate 43 fakeDelegateFactory *execfakes.FakeBuildStepDelegateFactory 44 45 fakeWorkerClient *workerfakes.FakeClient 46 47 spanCtx context.Context 48 49 loadVarPlan *atc.LoadVarPlan 50 artifactRepository *build.Repository 51 state *execfakes.FakeRunState 52 fakeSource *buildfakes.FakeRegisterableArtifact 53 54 spStep exec.Step 55 stepOk bool 56 stepErr error 57 58 stepMetadata = exec.StepMetadata{ 59 TeamID: 123, 60 TeamName: "some-team", 61 BuildID: 42, 62 BuildName: "some-build", 63 PipelineID: 4567, 64 PipelineName: "some-pipeline", 65 } 66 67 stdout, stderr *gbytes.Buffer 68 69 planID = "56" 70 ) 71 72 BeforeEach(func() { 73 testLogger = lagertest.NewTestLogger("var-step-test") 74 ctx, cancel = context.WithCancel(context.Background()) 75 ctx = lagerctx.NewContext(ctx, testLogger) 76 77 artifactRepository = build.NewRepository() 78 state = new(execfakes.FakeRunState) 79 state.ArtifactRepositoryReturns(artifactRepository) 80 81 fakeSource = new(buildfakes.FakeRegisterableArtifact) 82 artifactRepository.RegisterArtifact("some-resource", fakeSource) 83 84 stdout = gbytes.NewBuffer() 85 stderr = gbytes.NewBuffer() 86 87 fakeDelegate = new(execfakes.FakeBuildStepDelegate) 88 fakeDelegate.StdoutReturns(stdout) 89 fakeDelegate.StderrReturns(stderr) 90 91 spanCtx = context.Background() 92 fakeDelegate.StartSpanReturns(spanCtx, trace.NoopSpan{}) 93 94 fakeDelegateFactory = new(execfakes.FakeBuildStepDelegateFactory) 95 fakeDelegateFactory.BuildStepDelegateReturns(fakeDelegate) 96 97 fakeWorkerClient = new(workerfakes.FakeClient) 98 }) 99 100 expectLocalVarAdded := func(expectKey string, expectValue interface{}, expectRedact bool) { 101 Expect(state.AddLocalVarCallCount()).To(Equal(1)) 102 k, v, redact := state.AddLocalVarArgsForCall(0) 103 Expect(k).To(Equal(expectKey)) 104 Expect(v).To(Equal(expectValue)) 105 Expect(redact).To(Equal(expectRedact)) 106 } 107 108 AfterEach(func() { 109 cancel() 110 }) 111 112 JustBeforeEach(func() { 113 plan := atc.Plan{ 114 ID: atc.PlanID(planID), 115 LoadVar: loadVarPlan, 116 } 117 118 spStep = exec.NewLoadVarStep( 119 plan.ID, 120 *plan.LoadVar, 121 stepMetadata, 122 fakeDelegateFactory, 123 fakeWorkerClient, 124 ) 125 126 stepOk, stepErr = spStep.Run(ctx, state) 127 }) 128 129 Context("when format is specified", func() { 130 Context("when format is invalid", func() { 131 BeforeEach(func() { 132 loadVarPlan = &atc.LoadVarPlan{ 133 Name: "some-var", 134 File: "some-resource/a.diff", 135 Format: "diff", 136 } 137 }) 138 139 It("step should fail", func() { 140 Expect(stepErr).To(HaveOccurred()) 141 Expect(stepErr.Error()).To(Equal("invalid format diff")) 142 }) 143 }) 144 145 Context("when format is trim", func() { 146 BeforeEach(func() { 147 loadVarPlan = &atc.LoadVarPlan{ 148 Name: "some-var", 149 File: "some-resource/a.diff", 150 Format: "trim", 151 } 152 153 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: plainString}, nil) 154 }) 155 156 It("succeeds", func() { 157 Expect(stepErr).ToNot(HaveOccurred()) 158 Expect(stepOk).To(BeTrue()) 159 }) 160 161 It("should var parsed correctly", func() { 162 expectLocalVarAdded("some-var", strings.TrimSpace(plainString), true) 163 }) 164 }) 165 166 Context("when format is raw", func() { 167 BeforeEach(func() { 168 loadVarPlan = &atc.LoadVarPlan{ 169 Name: "some-var", 170 File: "some-resource/a.diff", 171 Format: "raw", 172 } 173 174 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: plainString}, nil) 175 }) 176 177 It("succeeds", func() { 178 Expect(stepErr).ToNot(HaveOccurred()) 179 Expect(stepOk).To(BeTrue()) 180 }) 181 182 It("should var parsed correctly", func() { 183 expectLocalVarAdded("some-var", plainString, true) 184 }) 185 }) 186 187 Context("when format is json", func() { 188 BeforeEach(func() { 189 loadVarPlan = &atc.LoadVarPlan{ 190 Name: "some-var", 191 File: "some-resource/a.diff", 192 Format: "json", 193 } 194 195 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: jsonString}, nil) 196 }) 197 198 It("succeeds", func() { 199 Expect(stepErr).ToNot(HaveOccurred()) 200 Expect(stepOk).To(BeTrue()) 201 }) 202 203 It("should var parsed correctly", func() { 204 expectLocalVarAdded("some-var", map[string]interface{}{"k1": "jv1", "k2": "jv2"}, true) 205 }) 206 }) 207 208 Context("when format is yml", func() { 209 BeforeEach(func() { 210 loadVarPlan = &atc.LoadVarPlan{ 211 Name: "some-var", 212 File: "some-resource/a.diff", 213 Format: "yml", 214 } 215 216 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: yamlString}, nil) 217 }) 218 219 It("succeeds", func() { 220 Expect(stepErr).ToNot(HaveOccurred()) 221 Expect(stepOk).To(BeTrue()) 222 }) 223 224 It("should var parsed correctly", func() { 225 expectLocalVarAdded("some-var", map[string]interface{}{"k1": "yv1", "k2": "yv2"}, true) 226 }) 227 }) 228 229 Context("when format is yaml", func() { 230 BeforeEach(func() { 231 loadVarPlan = &atc.LoadVarPlan{ 232 Name: "some-var", 233 File: "some-resource/a.diff", 234 Format: "yaml", 235 } 236 237 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: yamlString}, nil) 238 }) 239 240 It("succeeds", func() { 241 Expect(stepErr).ToNot(HaveOccurred()) 242 Expect(stepOk).To(BeTrue()) 243 }) 244 245 It("should var parsed correctly", func() { 246 expectLocalVarAdded("some-var", map[string]interface{}{"k1": "yv1", "k2": "yv2"}, true) 247 }) 248 }) 249 }) 250 251 Context("when format is not specified", func() { 252 Context("when file extension is other than json, yml and yaml", func() { 253 BeforeEach(func() { 254 loadVarPlan = &atc.LoadVarPlan{ 255 Name: "some-var", 256 File: "some-resource/a.diff", 257 } 258 259 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: plainString}, nil) 260 }) 261 262 It("succeeds", func() { 263 Expect(stepErr).ToNot(HaveOccurred()) 264 Expect(stepOk).To(BeTrue()) 265 }) 266 267 It("should var parsed correctly as trim", func() { 268 expectLocalVarAdded("some-var", strings.TrimSpace(plainString), true) 269 }) 270 }) 271 272 Context("when format is json", func() { 273 BeforeEach(func() { 274 loadVarPlan = &atc.LoadVarPlan{ 275 Name: "some-var", 276 File: "some-resource/a.json", 277 } 278 279 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: jsonString}, nil) 280 }) 281 282 It("succeeds", func() { 283 Expect(stepErr).ToNot(HaveOccurred()) 284 Expect(stepOk).To(BeTrue()) 285 }) 286 287 It("should var parsed correctly", func() { 288 expectLocalVarAdded("some-var", map[string]interface{}{"k1": "jv1", "k2": "jv2"}, true) 289 }) 290 }) 291 292 Context("when format is yml", func() { 293 BeforeEach(func() { 294 loadVarPlan = &atc.LoadVarPlan{ 295 Name: "some-var", 296 File: "some-resource/a.yml", 297 } 298 299 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: yamlString}, nil) 300 }) 301 302 It("succeeds", func() { 303 Expect(stepErr).ToNot(HaveOccurred()) 304 Expect(stepOk).To(BeTrue()) 305 }) 306 307 It("should var parsed correctly", func() { 308 expectLocalVarAdded("some-var", map[string]interface{}{"k1": "yv1", "k2": "yv2"}, true) 309 }) 310 }) 311 312 Context("when format is yaml", func() { 313 BeforeEach(func() { 314 loadVarPlan = &atc.LoadVarPlan{ 315 Name: "some-var", 316 File: "some-resource/a.yaml", 317 } 318 319 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: yamlString}, nil) 320 }) 321 322 It("succeeds", func() { 323 Expect(stepErr).ToNot(HaveOccurred()) 324 Expect(stepOk).To(BeTrue()) 325 }) 326 327 It("should var parsed correctly", func() { 328 expectLocalVarAdded("some-var", map[string]interface{}{"k1": "yv1", "k2": "yv2"}, true) 329 }) 330 }) 331 }) 332 333 Context("when file is bad", func() { 334 Context("when json file is bad", func() { 335 BeforeEach(func() { 336 loadVarPlan = &atc.LoadVarPlan{ 337 Name: "some-var", 338 File: "some-resource/a.json", 339 } 340 341 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: plainString}, nil) 342 }) 343 344 It("step should fail", func() { 345 Expect(stepErr).To(HaveOccurred()) 346 Expect(stepErr).To(MatchError(ContainSubstring("failed to parse some-resource/a.json in format json"))) 347 }) 348 }) 349 350 Context("when yaml file is bad", func() { 351 BeforeEach(func() { 352 loadVarPlan = &atc.LoadVarPlan{ 353 Name: "some-var", 354 File: "some-resource/a.yaml", 355 } 356 357 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: "a:\nb"}, nil) 358 }) 359 360 It("step should fail", func() { 361 Expect(stepErr).To(HaveOccurred()) 362 Expect(stepErr).To(MatchError(ContainSubstring("failed to parse some-resource/a.yaml in format yaml"))) 363 }) 364 }) 365 }) 366 367 Context("reveal", func() { 368 Context("when reveal is not specified", func() { 369 BeforeEach(func() { 370 loadVarPlan = &atc.LoadVarPlan{ 371 Name: "some-var", 372 File: "some-resource/a.diff", 373 } 374 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: plainString}, nil) 375 }) 376 377 It("local var should be redacted", func() { 378 expectLocalVarAdded("some-var", strings.TrimSpace(plainString), true) 379 }) 380 }) 381 382 Context("when reveal is false", func() { 383 BeforeEach(func() { 384 loadVarPlan = &atc.LoadVarPlan{ 385 Name: "some-var", 386 File: "some-resource/a.diff", 387 Reveal: false, 388 } 389 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: plainString}, nil) 390 }) 391 392 It("local var should be redacted", func() { 393 expectLocalVarAdded("some-var", strings.TrimSpace(plainString), true) 394 }) 395 }) 396 397 Context("when reveal is true", func() { 398 BeforeEach(func() { 399 loadVarPlan = &atc.LoadVarPlan{ 400 Name: "some-var", 401 File: "some-resource/a.diff", 402 Reveal: true, 403 } 404 fakeWorkerClient.StreamFileFromArtifactReturns(&fakeReadCloser{str: plainString}, nil) 405 }) 406 407 It("local var should not be redacted", func() { 408 expectLocalVarAdded("some-var", strings.TrimSpace(plainString), false) 409 }) 410 }) 411 }) 412 })