github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/worker/fetch_source_test.go (about) 1 package worker_test 2 3 import ( 4 "context" 5 "errors" 6 7 "code.cloudfoundry.org/garden" 8 "code.cloudfoundry.org/garden/gardenfakes" 9 "code.cloudfoundry.org/lager/lagertest" 10 "github.com/pf-qiu/concourse/v6/atc" 11 "github.com/pf-qiu/concourse/v6/atc/db" 12 "github.com/pf-qiu/concourse/v6/atc/db/dbfakes" 13 "github.com/pf-qiu/concourse/v6/atc/resource" 14 "github.com/pf-qiu/concourse/v6/atc/resource/resourcefakes" 15 "github.com/pf-qiu/concourse/v6/atc/runtime" 16 "github.com/pf-qiu/concourse/v6/atc/worker" 17 "github.com/pf-qiu/concourse/v6/atc/worker/workerfakes" 18 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 ) 22 23 var _ = Describe("FetchSource", func() { 24 var ( 25 fetchSourceFactory worker.FetchSourceFactory 26 fetchSource worker.FetchSource 27 28 fakeContainer *workerfakes.FakeContainer 29 fakeVolume *workerfakes.FakeVolume 30 fakeWorker *workerfakes.FakeWorker 31 fakeResourceCacheFactory *dbfakes.FakeResourceCacheFactory 32 fakeUsedResourceCache *dbfakes.FakeUsedResourceCache 33 fakeResource *resourcefakes.FakeResource 34 metadata db.ContainerMetadata 35 owner db.ContainerOwner 36 37 ctx context.Context 38 cancel func() 39 ) 40 41 BeforeEach(func() { 42 logger := lagertest.NewTestLogger("test") 43 fakeContainer = new(workerfakes.FakeContainer) 44 45 ctx, cancel = context.WithCancel(context.Background()) 46 47 fakeContainer.PropertyReturns("", errors.New("nope")) 48 inProcess := new(gardenfakes.FakeProcess) 49 inProcess.IDReturns("process-id") 50 inProcess.WaitStub = func() (int, error) { 51 return 0, nil 52 } 53 54 fakeContainer.AttachReturns(nil, errors.New("process not found")) 55 56 fakeContainer.RunStub = func(ctx context.Context, spec garden.ProcessSpec, io garden.ProcessIO) (garden.Process, error) { 57 _, err := io.Stdout.Write([]byte("{}")) 58 Expect(err).NotTo(HaveOccurred()) 59 60 return inProcess, nil 61 } 62 63 fakeVolume = new(workerfakes.FakeVolume) 64 fakeVolume.HandleReturns("some-handle") 65 fakeContainer.VolumeMountsReturns([]worker.VolumeMount{ 66 { 67 Volume: fakeVolume, 68 MountPath: resource.ResourcesDir("get"), 69 }, 70 }) 71 72 fakeWorker = new(workerfakes.FakeWorker) 73 fakeWorker.FindOrCreateContainerReturns(fakeContainer, nil) 74 75 fakeResourceCacheFactory = new(dbfakes.FakeResourceCacheFactory) 76 fakeUsedResourceCache = new(dbfakes.FakeUsedResourceCache) 77 fakeUsedResourceCache.IDReturns(42) 78 fakeResourceCacheFactory.FindOrCreateResourceCacheReturns(fakeUsedResourceCache, nil) 79 80 owner = db.NewBuildStepContainerOwner(43, atc.PlanID("some-plan-id"), 42) 81 metadata = db.ContainerMetadata{Type: db.ContainerTypeGet} 82 83 fakeResource = new(resourcefakes.FakeResource) 84 fakeResourceCacheFactory = new(dbfakes.FakeResourceCacheFactory) 85 fakeResourceCacheFactory.UpdateResourceCacheMetadataReturns(nil) 86 fakeResourceCacheFactory.ResourceCacheMetadataReturns([]db.ResourceConfigMetadataField{ 87 {Name: "some", Value: "metadata"}, 88 }, nil) 89 90 getProcessSpec := runtime.ProcessSpec{ 91 Path: "/opt/resource/in", 92 Args: []string{resource.ResourcesDir("get")}, 93 } 94 95 fetchSourceFactory = worker.NewFetchSourceFactory(fakeResourceCacheFactory) 96 fetchSource = fetchSourceFactory.NewFetchSource( 97 logger, 98 fakeWorker, 99 owner, 100 fakeUsedResourceCache, 101 fakeResource, 102 worker.ContainerSpec{ 103 TeamID: 42, 104 ImageSpec: worker.ImageSpec{ 105 ResourceType: "fake-resource-type", 106 }, 107 Outputs: map[string]string{ 108 "resource": resource.ResourcesDir("get"), 109 }, 110 }, 111 getProcessSpec, 112 metadata, 113 ) 114 }) 115 116 AfterEach(func() { 117 cancel() 118 }) 119 120 Describe("Find", func() { 121 var expectedGetResult worker.GetResult 122 123 Context("when there is volume", func() { 124 BeforeEach(func() { 125 fakeWorker.FindVolumeForResourceCacheReturns(fakeVolume, true, nil) 126 127 expectedMetadata := []atc.MetadataField{ 128 {Name: "some", Value: "metadata"}, 129 } 130 expectedGetResult = worker.GetResult{ 131 ExitStatus: 0, 132 VersionResult: runtime.VersionResult{Metadata: expectedMetadata}, 133 GetArtifact: runtime.GetArtifact{VolumeHandle: fakeVolume.Handle()}, 134 } 135 }) 136 137 It("finds the resource cache volume and returns the correct result", func() { 138 getResult, volume, found, err := fetchSource.Find() 139 Expect(err).NotTo(HaveOccurred()) 140 Expect(found).To(BeTrue()) 141 Expect(volume).To(Equal(fakeVolume)) 142 Expect(getResult).To(Equal(expectedGetResult)) 143 }) 144 }) 145 146 Context("when there is no volume", func() { 147 BeforeEach(func() { 148 fakeWorker.FindVolumeForResourceCacheReturns(nil, false, nil) 149 expectedGetResult = worker.GetResult{} 150 }) 151 152 It("does not find volume", func() { 153 getResult, volume, found, err := fetchSource.Find() 154 Expect(err).NotTo(HaveOccurred()) 155 Expect(found).To(BeFalse()) 156 Expect(volume).To(BeNil()) 157 Expect(getResult).To(Equal(expectedGetResult)) 158 }) 159 }) 160 }) 161 162 Describe("Create", func() { 163 var ( 164 err error 165 getResult worker.GetResult 166 expectedGetResult worker.GetResult 167 volume worker.Volume 168 ) 169 170 JustBeforeEach(func() { 171 getResult, volume, err = fetchSource.Create(ctx) 172 }) 173 174 Context("when there is initialized volume", func() { 175 BeforeEach(func() { 176 fakeWorker.FindVolumeForResourceCacheReturns(fakeVolume, true, nil) 177 178 expectedMetadata := []atc.MetadataField{ 179 {Name: "some", Value: "metadata"}, 180 } 181 expectedGetResult = worker.GetResult{ 182 ExitStatus: 0, 183 VersionResult: runtime.VersionResult{Metadata: expectedMetadata}, 184 GetArtifact: runtime.GetArtifact{VolumeHandle: fakeVolume.Handle()}, 185 } 186 }) 187 188 It("does not fetch resource", func() { 189 Expect(err).NotTo(HaveOccurred()) 190 Expect(fakeWorker.FindOrCreateContainerCallCount()).To(Equal(0)) 191 Expect(fakeResource.GetCallCount()).To(Equal(0)) 192 }) 193 194 It("finds initialized volume and returns a successful GetResult", func() { 195 Expect(err).NotTo(HaveOccurred()) 196 Expect(getResult).To(Equal(expectedGetResult)) 197 Expect(volume).ToNot(BeNil()) 198 }) 199 }) 200 201 Context("when there is no initialized volume", func() { 202 var atcMetadata []atc.MetadataField 203 BeforeEach(func() { 204 atcMetadata = []atc.MetadataField{{Name: "foo", Value: "bar"}} 205 fakeWorker.FindVolumeForResourceCacheReturns(nil, false, nil) 206 fakeResource.GetReturns(runtime.VersionResult{Metadata: atcMetadata}, nil) 207 }) 208 209 It("creates container with volume and worker", func() { 210 Expect(err).NotTo(HaveOccurred()) 211 212 Expect(fakeWorker.FindOrCreateContainerCallCount()).To(Equal(1)) 213 _, logger, owner, actualMetadata, containerSpec := fakeWorker.FindOrCreateContainerArgsForCall(0) 214 Expect(owner).To(Equal(db.NewBuildStepContainerOwner(43, atc.PlanID("some-plan-id"), 42))) 215 Expect(actualMetadata).To(Equal(metadata)) 216 Expect(containerSpec).To(Equal( 217 worker.ContainerSpec{ 218 TeamID: 42, 219 ImageSpec: worker.ImageSpec{ 220 ResourceType: "fake-resource-type", 221 }, 222 BindMounts: []worker.BindMountSource{&worker.CertsVolumeMount{Logger: logger}}, 223 Outputs: map[string]string{ 224 "resource": resource.ResourcesDir("get"), 225 }, 226 })) 227 }) 228 229 It("executes the get script", func() { 230 Expect(err).NotTo(HaveOccurred()) 231 Expect(fakeResource.GetCallCount()).To(Equal(1)) 232 }) 233 234 It("initializes cache", func() { 235 Expect(err).NotTo(HaveOccurred()) 236 Expect(fakeVolume.InitializeResourceCacheCallCount()).To(Equal(1)) 237 rc := fakeVolume.InitializeResourceCacheArgsForCall(0) 238 Expect(rc).To(Equal(fakeUsedResourceCache)) 239 }) 240 241 It("updates resource cache metadata", func() { 242 Expect(fakeResourceCacheFactory.UpdateResourceCacheMetadataCallCount()).To(Equal(1)) 243 passedResourceCache, versionResultMetadata := fakeResourceCacheFactory.UpdateResourceCacheMetadataArgsForCall(0) 244 Expect(passedResourceCache).To(Equal(fakeUsedResourceCache)) 245 Expect(versionResultMetadata).To(Equal(atcMetadata)) 246 }) 247 248 Context("when getting resource fails with other error", func() { 249 var disaster error 250 251 BeforeEach(func() { 252 disaster = errors.New("failed") 253 fakeResource.GetReturns(runtime.VersionResult{}, disaster) 254 }) 255 256 It("returns the error", func() { 257 Expect(err).To(HaveOccurred()) 258 Expect(err).To(Equal(disaster)) 259 }) 260 }) 261 262 It("returns a successful GetResult and volume with fetched bits", func() { 263 Expect(getResult.ExitStatus).To(BeZero()) 264 Expect(getResult.GetArtifact.VolumeHandle).To(Equal(fakeVolume.Handle())) 265 Expect(volume).ToNot(BeNil()) 266 }) 267 }) 268 }) 269 })