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  })