434 lines
11 KiB
Go
434 lines
11 KiB
Go
package builder_test
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"time"
|
|
|
|
"code.cloudfoundry.org/clock/fakeclock"
|
|
"code.cloudfoundry.org/lager"
|
|
"code.cloudfoundry.org/lager/lagertest"
|
|
"github.com/concourse/concourse/atc"
|
|
"github.com/concourse/concourse/atc/db"
|
|
"github.com/concourse/concourse/atc/db/dbfakes"
|
|
"github.com/concourse/concourse/atc/engine/builder"
|
|
"github.com/concourse/concourse/atc/event"
|
|
"github.com/concourse/concourse/atc/exec"
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("DelegateFactory", func() {
|
|
var (
|
|
logger *lagertest.TestLogger
|
|
fakeBuild *dbfakes.FakeBuild
|
|
fakePipeline *dbfakes.FakePipeline
|
|
fakeResource *dbfakes.FakeResource
|
|
fakeClock *fakeclock.FakeClock
|
|
)
|
|
|
|
BeforeEach(func() {
|
|
logger = lagertest.NewTestLogger("test")
|
|
|
|
fakeBuild = new(dbfakes.FakeBuild)
|
|
fakePipeline = new(dbfakes.FakePipeline)
|
|
fakeResource = new(dbfakes.FakeResource)
|
|
fakeClock = fakeclock.NewFakeClock(time.Unix(123456789, 0))
|
|
})
|
|
|
|
Describe("GetDelegate", func() {
|
|
var (
|
|
delegate exec.GetDelegate
|
|
info exec.VersionInfo
|
|
exitStatus exec.ExitStatus
|
|
)
|
|
|
|
BeforeEach(func() {
|
|
info = exec.VersionInfo{
|
|
Version: atc.Version{"foo": "bar"},
|
|
Metadata: []atc.MetadataField{{Name: "baz", Value: "shmaz"}},
|
|
}
|
|
|
|
delegate = builder.NewGetDelegate(fakeBuild, "some-plan-id", fakeClock)
|
|
})
|
|
|
|
Describe("Finished", func() {
|
|
JustBeforeEach(func() {
|
|
delegate.Finished(logger, exitStatus, info)
|
|
})
|
|
|
|
It("saves an event", func() {
|
|
Expect(fakeBuild.SaveEventCallCount()).To(Equal(1))
|
|
Expect(fakeBuild.SaveEventArgsForCall(0)).To(Equal(event.FinishGet{
|
|
Origin: event.Origin{ID: event.OriginID("some-plan-id")},
|
|
Time: 123456789,
|
|
ExitStatus: int(exitStatus),
|
|
FetchedVersion: info.Version,
|
|
FetchedMetadata: info.Metadata,
|
|
}))
|
|
})
|
|
})
|
|
|
|
Describe("UpdateVersion", func() {
|
|
JustBeforeEach(func() {
|
|
plan := atc.GetPlan{Resource: "some-resource"}
|
|
delegate.UpdateVersion(logger, plan, info)
|
|
})
|
|
|
|
Context("when retrieving the pipeline fails", func() {
|
|
BeforeEach(func() {
|
|
fakeBuild.PipelineReturns(nil, false, errors.New("nope"))
|
|
})
|
|
|
|
It("doesn't update the metadata", func() {
|
|
Expect(fakeResource.UpdateMetadataCallCount()).To(Equal(0))
|
|
})
|
|
})
|
|
|
|
Context("when retrieving the pipeline succeeds", func() {
|
|
|
|
Context("when the pipeline is not found", func() {
|
|
BeforeEach(func() {
|
|
fakeBuild.PipelineReturns(nil, false, nil)
|
|
})
|
|
|
|
It("doesn't update the metadata", func() {
|
|
Expect(fakeResource.UpdateMetadataCallCount()).To(Equal(0))
|
|
})
|
|
})
|
|
|
|
Context("when the pipeline is found", func() {
|
|
BeforeEach(func() {
|
|
fakeBuild.PipelineReturns(fakePipeline, true, nil)
|
|
})
|
|
|
|
Context("when retrieving the resource fails", func() {
|
|
BeforeEach(func() {
|
|
fakePipeline.ResourceReturns(nil, false, errors.New("nope"))
|
|
})
|
|
|
|
It("doesn't update the metadata", func() {
|
|
Expect(fakeResource.UpdateMetadataCallCount()).To(Equal(0))
|
|
})
|
|
})
|
|
|
|
Context("when retrieving the resource succeeds", func() {
|
|
|
|
It("retrives the resource by name", func() {
|
|
Expect(fakePipeline.ResourceArgsForCall(0)).To(Equal("some-resource"))
|
|
})
|
|
|
|
Context("when the resource is not found", func() {
|
|
BeforeEach(func() {
|
|
fakePipeline.ResourceReturns(nil, false, nil)
|
|
})
|
|
|
|
It("doesn't update the metadata", func() {
|
|
Expect(fakeResource.UpdateMetadataCallCount()).To(Equal(0))
|
|
})
|
|
})
|
|
|
|
Context("when the resource is found", func() {
|
|
BeforeEach(func() {
|
|
fakePipeline.ResourceReturns(fakeResource, true, nil)
|
|
})
|
|
|
|
It("updates the metadata", func() {
|
|
Expect(fakeResource.UpdateMetadataCallCount()).To(Equal(1))
|
|
version, metadata := fakeResource.UpdateMetadataArgsForCall(0)
|
|
Expect(version).To(Equal(info.Version))
|
|
Expect(metadata).To(Equal(db.NewResourceConfigMetadataFields(info.Metadata)))
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
Describe("PutDelegate", func() {
|
|
var (
|
|
delegate exec.PutDelegate
|
|
info exec.VersionInfo
|
|
exitStatus exec.ExitStatus
|
|
)
|
|
|
|
BeforeEach(func() {
|
|
info = exec.VersionInfo{
|
|
Version: atc.Version{"foo": "bar"},
|
|
Metadata: []atc.MetadataField{{Name: "baz", Value: "shmaz"}},
|
|
}
|
|
|
|
delegate = builder.NewPutDelegate(fakeBuild, "some-plan-id", fakeClock)
|
|
})
|
|
|
|
Describe("Finished", func() {
|
|
JustBeforeEach(func() {
|
|
delegate.Finished(logger, exitStatus, info)
|
|
})
|
|
|
|
It("saves an event", func() {
|
|
Expect(fakeBuild.SaveEventCallCount()).To(Equal(1))
|
|
Expect(fakeBuild.SaveEventArgsForCall(0)).To(Equal(event.FinishPut{
|
|
Origin: event.Origin{ID: event.OriginID("some-plan-id")},
|
|
Time: 123456789,
|
|
ExitStatus: int(exitStatus),
|
|
CreatedVersion: info.Version,
|
|
CreatedMetadata: info.Metadata,
|
|
}))
|
|
})
|
|
})
|
|
|
|
Describe("SaveOutput", func() {
|
|
var plan atc.PutPlan
|
|
var source atc.Source
|
|
var resourceTypes atc.VersionedResourceTypes
|
|
|
|
JustBeforeEach(func() {
|
|
plan = atc.PutPlan{
|
|
Name: "some-name",
|
|
Type: "some-type",
|
|
Resource: "some-resource",
|
|
}
|
|
source = atc.Source{"some": "source"}
|
|
resourceTypes = atc.VersionedResourceTypes{}
|
|
|
|
delegate.SaveOutput(logger, plan, source, resourceTypes, info)
|
|
})
|
|
|
|
It("saves the build output", func() {
|
|
Expect(fakeBuild.SaveOutputCallCount()).To(Equal(1))
|
|
resourceType, sourceArg, resourceTypesArg, version, metadata, name, resource := fakeBuild.SaveOutputArgsForCall(0)
|
|
Expect(resourceType).To(Equal(plan.Type))
|
|
Expect(sourceArg).To(Equal(source))
|
|
Expect(resourceTypesArg).To(Equal(resourceTypes))
|
|
Expect(version).To(Equal(info.Version))
|
|
Expect(metadata).To(Equal(db.NewResourceConfigMetadataFields(info.Metadata)))
|
|
Expect(name).To(Equal(plan.Name))
|
|
Expect(resource).To(Equal(plan.Resource))
|
|
})
|
|
})
|
|
})
|
|
|
|
Describe("TaskDelegate", func() {
|
|
var (
|
|
delegate exec.TaskDelegate
|
|
config atc.TaskConfig
|
|
exitStatus exec.ExitStatus
|
|
)
|
|
|
|
BeforeEach(func() {
|
|
delegate = builder.NewTaskDelegate(fakeBuild, "some-plan-id", fakeClock)
|
|
})
|
|
|
|
Describe("Initializing", func() {
|
|
JustBeforeEach(func() {
|
|
delegate.Initializing(logger, config)
|
|
})
|
|
|
|
It("saves an event", func() {
|
|
Expect(fakeBuild.SaveEventCallCount()).To(Equal(1))
|
|
event := fakeBuild.SaveEventArgsForCall(0)
|
|
Expect(event.EventType()).To(Equal(atc.EventType("initialize-task")))
|
|
})
|
|
})
|
|
|
|
Describe("Starting", func() {
|
|
JustBeforeEach(func() {
|
|
delegate.Starting(logger, config)
|
|
})
|
|
|
|
It("saves an event", func() {
|
|
Expect(fakeBuild.SaveEventCallCount()).To(Equal(1))
|
|
event := fakeBuild.SaveEventArgsForCall(0)
|
|
Expect(event.EventType()).To(Equal(atc.EventType("start-task")))
|
|
})
|
|
})
|
|
|
|
Describe("Finished", func() {
|
|
JustBeforeEach(func() {
|
|
delegate.Finished(logger, exitStatus)
|
|
})
|
|
|
|
It("saves an event", func() {
|
|
Expect(fakeBuild.SaveEventCallCount()).To(Equal(1))
|
|
event := fakeBuild.SaveEventArgsForCall(0)
|
|
Expect(event.EventType()).To(Equal(atc.EventType("finish-task")))
|
|
})
|
|
})
|
|
})
|
|
|
|
Describe("BuildStepDelegate", func() {
|
|
var (
|
|
delegate exec.BuildStepDelegate
|
|
)
|
|
|
|
BeforeEach(func() {
|
|
delegate = builder.NewBuildStepDelegate(fakeBuild, "some-plan-id", fakeClock)
|
|
})
|
|
|
|
Describe("ImageVersionDetermined", func() {
|
|
var fakeResourceCache *dbfakes.FakeUsedResourceCache
|
|
|
|
BeforeEach(func() {
|
|
fakeResourceCache = new(dbfakes.FakeUsedResourceCache)
|
|
fakeResourceCache.IDReturns(42)
|
|
})
|
|
|
|
JustBeforeEach(func() {
|
|
Expect(delegate.ImageVersionDetermined(fakeResourceCache)).To(Succeed())
|
|
})
|
|
|
|
It("records the resource cache as an image resource for the build", func() {
|
|
Expect(fakeBuild.SaveImageResourceVersionCallCount()).To(Equal(1))
|
|
Expect(fakeBuild.SaveImageResourceVersionArgsForCall(0)).To(Equal(fakeResourceCache))
|
|
})
|
|
})
|
|
|
|
Describe("Stdout", func() {
|
|
var writer io.Writer
|
|
|
|
BeforeEach(func() {
|
|
writer = delegate.Stdout()
|
|
})
|
|
|
|
Describe("writing to the writer", func() {
|
|
var writtenBytes int
|
|
var writeErr error
|
|
|
|
JustBeforeEach(func() {
|
|
writtenBytes, writeErr = writer.Write([]byte("hello"))
|
|
})
|
|
|
|
Context("when saving the event succeeds", func() {
|
|
BeforeEach(func() {
|
|
fakeBuild.SaveEventReturns(nil)
|
|
})
|
|
|
|
It("returns the length of the string, and no error", func() {
|
|
Expect(writtenBytes).To(Equal(len("hello")))
|
|
Expect(writeErr).ToNot(HaveOccurred())
|
|
})
|
|
|
|
It("saves a log event", func() {
|
|
Expect(fakeBuild.SaveEventCallCount()).To(Equal(1))
|
|
Expect(fakeBuild.SaveEventArgsForCall(0)).To(Equal(event.Log{
|
|
Time: 123456789,
|
|
Payload: "hello",
|
|
Origin: event.Origin{
|
|
Source: event.OriginSourceStdout,
|
|
ID: "some-plan-id",
|
|
},
|
|
}))
|
|
})
|
|
})
|
|
|
|
Context("when saving the event succeeds", func() {
|
|
disaster := errors.New("nope")
|
|
|
|
BeforeEach(func() {
|
|
fakeBuild.SaveEventReturns(disaster)
|
|
})
|
|
|
|
It("returns 0 length, and the error", func() {
|
|
Expect(writtenBytes).To(Equal(0))
|
|
Expect(writeErr).To(Equal(disaster))
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
Describe("Stderr", func() {
|
|
var writer io.Writer
|
|
|
|
BeforeEach(func() {
|
|
writer = delegate.Stderr()
|
|
})
|
|
|
|
Describe("writing to the writer", func() {
|
|
var writtenBytes int
|
|
var writeErr error
|
|
|
|
JustBeforeEach(func() {
|
|
writtenBytes, writeErr = writer.Write([]byte("hello"))
|
|
})
|
|
|
|
Context("when saving the event succeeds", func() {
|
|
BeforeEach(func() {
|
|
fakeBuild.SaveEventReturns(nil)
|
|
})
|
|
|
|
It("returns the length of the string, and no error", func() {
|
|
Expect(writtenBytes).To(Equal(len("hello")))
|
|
Expect(writeErr).ToNot(HaveOccurred())
|
|
})
|
|
|
|
It("saves a log event", func() {
|
|
Expect(fakeBuild.SaveEventCallCount()).To(Equal(1))
|
|
Expect(fakeBuild.SaveEventArgsForCall(0)).To(Equal(event.Log{
|
|
Time: 123456789,
|
|
Payload: "hello",
|
|
Origin: event.Origin{
|
|
Source: event.OriginSourceStderr,
|
|
ID: "some-plan-id",
|
|
},
|
|
}))
|
|
})
|
|
})
|
|
|
|
Context("when saving the event fails", func() {
|
|
disaster := errors.New("nope")
|
|
|
|
BeforeEach(func() {
|
|
fakeBuild.SaveEventReturns(disaster)
|
|
})
|
|
|
|
It("returns 0 length, and the error", func() {
|
|
Expect(writtenBytes).To(Equal(0))
|
|
Expect(writeErr).To(Equal(disaster))
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
Describe("Errored", func() {
|
|
JustBeforeEach(func() {
|
|
delegate.Errored(logger, "fake error message")
|
|
})
|
|
|
|
Context("when saving the event succeeds", func() {
|
|
BeforeEach(func() {
|
|
fakeBuild.SaveEventReturns(nil)
|
|
})
|
|
|
|
It("saves it with the current time", func() {
|
|
Expect(fakeBuild.SaveEventCallCount()).To(Equal(1))
|
|
Expect(fakeBuild.SaveEventArgsForCall(0)).To(Equal(event.Error{
|
|
Time: 123456789,
|
|
Message: "fake error message",
|
|
Origin: event.Origin{
|
|
ID: "some-plan-id",
|
|
},
|
|
}))
|
|
})
|
|
})
|
|
|
|
Context("when saving the event fails", func() {
|
|
disaster := errors.New("nope")
|
|
|
|
BeforeEach(func() {
|
|
fakeBuild.SaveEventReturns(disaster)
|
|
})
|
|
|
|
It("logs an error", func() {
|
|
logs := logger.Logs()
|
|
Expect(len(logs)).To(Equal(1))
|
|
Expect(logs[0].Message).To(Equal("test.failed-to-save-error-event"))
|
|
Expect(logs[0].Data).To(Equal(lager.Data{"error": "nope"}))
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|