Merge pull request #4202 from concourse/feature/3788-checks
lidar: tracking checks in the database
This commit is contained in:
commit
ba9bad2c15
|
@ -146,6 +146,7 @@ var requiredRoles = map[string]string{
|
|||
atc.GetConfig: "viewer",
|
||||
atc.GetCC: "viewer",
|
||||
atc.GetBuild: "viewer",
|
||||
atc.GetCheck: "viewer",
|
||||
atc.GetBuildPlan: "viewer",
|
||||
atc.CreateBuild: "member",
|
||||
atc.ListBuilds: "viewer",
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/concourse/concourse/atc/api/accessor/accessorfakes"
|
||||
"github.com/concourse/concourse/atc/api/auth"
|
||||
"github.com/concourse/concourse/atc/api/containerserver/containerserverfakes"
|
||||
"github.com/concourse/concourse/atc/api/resourceserver/resourceserverfakes"
|
||||
"github.com/concourse/concourse/atc/auditor/auditorfakes"
|
||||
"github.com/concourse/concourse/atc/creds"
|
||||
"github.com/concourse/concourse/atc/creds/credsfakes"
|
||||
|
@ -51,8 +50,8 @@ var (
|
|||
build *dbfakes.FakeBuild
|
||||
dbBuildFactory *dbfakes.FakeBuildFactory
|
||||
dbUserFactory *dbfakes.FakeUserFactory
|
||||
dbCheckFactory *dbfakes.FakeCheckFactory
|
||||
dbTeam *dbfakes.FakeTeam
|
||||
fakeScannerFactory *resourceserverfakes.FakeScannerFactory
|
||||
fakeSecretManager *credsfakes.FakeSecrets
|
||||
credsManagers creds.Managers
|
||||
interceptTimeoutFactory *containerserverfakes.FakeInterceptTimeoutFactory
|
||||
|
@ -96,6 +95,7 @@ var _ = BeforeEach(func() {
|
|||
dbResourceConfigFactory = new(dbfakes.FakeResourceConfigFactory)
|
||||
dbBuildFactory = new(dbfakes.FakeBuildFactory)
|
||||
dbUserFactory = new(dbfakes.FakeUserFactory)
|
||||
dbCheckFactory = new(dbfakes.FakeCheckFactory)
|
||||
|
||||
interceptTimeoutFactory = new(containerserverfakes.FakeInterceptTimeoutFactory)
|
||||
interceptTimeout = new(containerserverfakes.FakeInterceptTimeout)
|
||||
|
@ -118,8 +118,6 @@ var _ = BeforeEach(func() {
|
|||
|
||||
fakeWorkerClient = new(workerfakes.FakeClient)
|
||||
|
||||
fakeScannerFactory = new(resourceserverfakes.FakeScannerFactory)
|
||||
|
||||
fakeVolumeRepository = new(dbfakes.FakeVolumeRepository)
|
||||
fakeContainerRepository = new(dbfakes.FakeContainerRepository)
|
||||
fakeDestroyer = new(gcfakes.FakeDestroyer)
|
||||
|
@ -173,6 +171,7 @@ var _ = BeforeEach(func() {
|
|||
fakeContainerRepository,
|
||||
fakeDestroyer,
|
||||
dbBuildFactory,
|
||||
dbCheckFactory,
|
||||
dbResourceConfigFactory,
|
||||
dbUserFactory,
|
||||
|
||||
|
@ -180,8 +179,6 @@ var _ = BeforeEach(func() {
|
|||
|
||||
fakeWorkerClient,
|
||||
|
||||
fakeScannerFactory,
|
||||
|
||||
sink,
|
||||
|
||||
isTLSEnabled,
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
package api_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/dbfakes"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Checks API", func() {
|
||||
Describe("GET /api/v1/checks/:check_id", func() {
|
||||
var err error
|
||||
var path string
|
||||
var response *http.Response
|
||||
|
||||
BeforeEach(func() {
|
||||
path = "/api/v1/checks/10"
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
response, err = client.Get(server.URL + path)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
Context("when not authenticated", func() {
|
||||
BeforeEach(func() {
|
||||
fakeAccess.HasTokenReturns(true)
|
||||
fakeAccess.IsAuthenticatedReturns(false)
|
||||
})
|
||||
|
||||
It("returns 401", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusUnauthorized))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when authenticated", func() {
|
||||
BeforeEach(func() {
|
||||
fakeAccess.IsAuthenticatedReturns(true)
|
||||
})
|
||||
|
||||
Context("when parsing the check_id fails", func() {
|
||||
BeforeEach(func() {
|
||||
path = "/api/v1/checks/nope"
|
||||
})
|
||||
|
||||
It("returns 400", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when parsing the check_id succeeds", func() {
|
||||
BeforeEach(func() {
|
||||
path = "/api/v1/checks/10"
|
||||
})
|
||||
|
||||
Context("when calling the database fails", func() {
|
||||
BeforeEach(func() {
|
||||
dbCheckFactory.CheckReturns(nil, false, errors.New("disaster"))
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the check cannot be found", func() {
|
||||
BeforeEach(func() {
|
||||
dbCheckFactory.CheckReturns(nil, false, nil)
|
||||
})
|
||||
|
||||
It("returns 404", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusNotFound))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the check can be found", func() {
|
||||
var fakeCheck *dbfakes.FakeCheck
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheck = new(dbfakes.FakeCheck)
|
||||
fakeCheck.IDReturns(10)
|
||||
fakeCheck.StatusReturns("errored")
|
||||
fakeCheck.CreateTimeReturns(time.Date(2000, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.StartTimeReturns(time.Date(2001, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.EndTimeReturns(time.Date(2002, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.CheckErrorReturns(errors.New("nope"))
|
||||
|
||||
dbCheckFactory.CheckReturns(fakeCheck, true, nil)
|
||||
})
|
||||
|
||||
Context("when fetching checkables errors", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheck.AllCheckablesReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when fetching checkables returns no results", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheck.AllCheckablesReturns([]db.Checkable{}, nil)
|
||||
})
|
||||
|
||||
It("returns 403", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusForbidden))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when fetching checkables returns results", func() {
|
||||
var fakeResource1 *dbfakes.FakeResource
|
||||
var fakeResource2 *dbfakes.FakeResource
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeResource1 = new(dbfakes.FakeResource)
|
||||
fakeResource2 = new(dbfakes.FakeResource)
|
||||
|
||||
fakeCheck.AllCheckablesReturns([]db.Checkable{fakeResource1, fakeResource2}, nil)
|
||||
})
|
||||
|
||||
Context("when not authorized for either team", func() {
|
||||
BeforeEach(func() {
|
||||
fakeAccess.IsAuthorizedReturns(false)
|
||||
})
|
||||
|
||||
It("returns 403", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusForbidden))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when authorized for any team", func() {
|
||||
BeforeEach(func() {
|
||||
fakeAccess.IsAuthorizedReturns(true)
|
||||
})
|
||||
|
||||
It("returns 200", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusOK))
|
||||
})
|
||||
|
||||
It("returns application/json", func() {
|
||||
Expect(response.Header.Get("Content-Type")).To(Equal("application/json"))
|
||||
})
|
||||
|
||||
It("returns the check", func() {
|
||||
Expect(ioutil.ReadAll(response.Body)).To(MatchJSON(`{
|
||||
"id": 10,
|
||||
"status": "errored",
|
||||
"create_time": 946684800,
|
||||
"start_time": 978307200,
|
||||
"end_time": 1009843200,
|
||||
"check_error": "nope"
|
||||
}`))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,60 @@
|
|||
package checkserver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/concourse/concourse/atc/api/accessor"
|
||||
"github.com/concourse/concourse/atc/api/present"
|
||||
)
|
||||
|
||||
func (s *Server) GetCheck(w http.ResponseWriter, r *http.Request) {
|
||||
logger := s.logger.Session("get-check")
|
||||
|
||||
checkID, err := strconv.Atoi(r.FormValue(":check_id"))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
check, found, err := s.checkFactory.Check(checkID)
|
||||
if err != nil {
|
||||
logger.Error("could-not-get-check", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if !found {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
checkables, err := check.AllCheckables()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-checkables", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
acc := accessor.GetAccessor(r)
|
||||
|
||||
for _, checkable := range checkables {
|
||||
|
||||
if acc.IsAuthorized(checkable.TeamName()) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
err = json.NewEncoder(w).Encode(present.Check(check))
|
||||
if err != nil {
|
||||
logger.Error("failed-to-encode-check", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package checkserver
|
||||
|
||||
import (
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
logger lager.Logger
|
||||
|
||||
checkFactory db.CheckFactory
|
||||
}
|
||||
|
||||
func NewServer(
|
||||
logger lager.Logger,
|
||||
checkFactory db.CheckFactory,
|
||||
) *Server {
|
||||
return &Server{
|
||||
logger: logger,
|
||||
|
||||
checkFactory: checkFactory,
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/concourse/concourse/atc/api/artifactserver"
|
||||
"github.com/concourse/concourse/atc/api/buildserver"
|
||||
"github.com/concourse/concourse/atc/api/ccserver"
|
||||
"github.com/concourse/concourse/atc/api/checkserver"
|
||||
"github.com/concourse/concourse/atc/api/cliserver"
|
||||
"github.com/concourse/concourse/atc/api/configserver"
|
||||
"github.com/concourse/concourse/atc/api/containerserver"
|
||||
|
@ -49,6 +50,7 @@ func NewHandler(
|
|||
containerRepository db.ContainerRepository,
|
||||
destroyer gc.Destroyer,
|
||||
dbBuildFactory db.BuildFactory,
|
||||
dbCheckFactory db.CheckFactory,
|
||||
dbResourceConfigFactory db.ResourceConfigFactory,
|
||||
dbUserFactory db.UserFactory,
|
||||
|
||||
|
@ -56,8 +58,6 @@ func NewHandler(
|
|||
|
||||
workerClient worker.Client,
|
||||
|
||||
scannerFactory resourceserver.ScannerFactory,
|
||||
|
||||
sink *lager.ReconfigurableSink,
|
||||
|
||||
isTLSEnabled bool,
|
||||
|
@ -80,8 +80,9 @@ func NewHandler(
|
|||
teamHandlerFactory := NewTeamScopedHandlerFactory(logger, dbTeamFactory)
|
||||
|
||||
buildServer := buildserver.NewServer(logger, externalURL, dbTeamFactory, dbBuildFactory, eventHandlerFactory)
|
||||
jobServer := jobserver.NewServer(logger, externalURL, secretManager, dbJobFactory)
|
||||
resourceServer := resourceserver.NewServer(logger, scannerFactory, secretManager, dbResourceFactory, dbResourceConfigFactory)
|
||||
checkServer := checkserver.NewServer(logger, dbCheckFactory)
|
||||
jobServer := jobserver.NewServer(logger, externalURL, secretManager, dbJobFactory, dbCheckFactory)
|
||||
resourceServer := resourceserver.NewServer(logger, secretManager, dbCheckFactory, dbResourceFactory, dbResourceConfigFactory)
|
||||
|
||||
versionServer := versionserver.NewServer(logger, externalURL)
|
||||
pipelineServer := pipelineserver.NewServer(logger, dbTeamFactory, dbPipelineFactory, externalURL)
|
||||
|
@ -113,6 +114,8 @@ func NewHandler(
|
|||
atc.BuildEvents: buildHandlerFactory.HandlerFor(buildServer.BuildEvents),
|
||||
atc.ListBuildArtifacts: buildHandlerFactory.HandlerFor(buildServer.GetBuildArtifacts),
|
||||
|
||||
atc.GetCheck: http.HandlerFunc(checkServer.GetCheck),
|
||||
|
||||
atc.ListAllJobs: http.HandlerFunc(jobServer.ListAllJobs),
|
||||
atc.ListJobs: pipelineHandlerFactory.HandlerFor(jobServer.ListJobs),
|
||||
atc.GetJob: pipelineHandlerFactory.HandlerFor(jobServer.GetJob),
|
||||
|
|
|
@ -1527,27 +1527,57 @@ var _ = Describe("Jobs API", func() {
|
|||
BeforeEach(func() {
|
||||
fakeResource = new(dbfakes.FakeResource)
|
||||
fakeResource.NameReturns("some-input")
|
||||
fakeResource.CurrentPinnedVersionReturns(atc.Version{"some": "version"})
|
||||
|
||||
fakePipeline.ResourcesReturns([]db.Resource{fakeResource}, nil)
|
||||
})
|
||||
|
||||
It("returns 200 OK", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusOK))
|
||||
Context("when finding the pipeline resource types fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakePipeline.ResourceTypesReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("returns a 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
It("returns Content-Type 'application/json'", func() {
|
||||
Expect(response.Header.Get("Content-Type")).To(Equal("application/json"))
|
||||
})
|
||||
Context("when finding the pipeline resources types succeeds", func() {
|
||||
var fakeResourceType *dbfakes.FakeResourceType
|
||||
|
||||
It("notifies a scan of the resource", func() {
|
||||
Expect(fakeResource.NotifyScanCallCount()).To(Equal(1))
|
||||
})
|
||||
BeforeEach(func() {
|
||||
fakeResourceType = new(dbfakes.FakeResourceType)
|
||||
fakeResourceType.NameReturns("some-input")
|
||||
|
||||
It("returns the build", func() {
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
fakePipeline.ResourceTypesReturns([]db.ResourceType{fakeResourceType}, nil)
|
||||
})
|
||||
|
||||
Expect(body).To(MatchJSON(`{
|
||||
It("returns 200 OK", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusOK))
|
||||
})
|
||||
|
||||
It("returns Content-Type 'application/json'", func() {
|
||||
Expect(response.Header.Get("Content-Type")).To(Equal("application/json"))
|
||||
})
|
||||
|
||||
It("creates a check for the resource", func() {
|
||||
Expect(dbCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
It("runs the check from the current pinned version", func() {
|
||||
_, _, fromVersion, _ := dbCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(fromVersion).To(Equal(atc.Version{"some": "version"}))
|
||||
})
|
||||
|
||||
It("notifies the checker to run", func() {
|
||||
Expect(dbCheckFactory.NotifyCheckerCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
It("returns the build", func() {
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(body).To(MatchJSON(`{
|
||||
"id": 42,
|
||||
"name": "1",
|
||||
"job_name": "some-job",
|
||||
|
@ -1558,6 +1588,7 @@ var _ = Describe("Jobs API", func() {
|
|||
"start_time": 1,
|
||||
"end_time": 100
|
||||
}`))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -41,7 +41,14 @@ func (s *Server) CreateJobBuild(pipeline db.Pipeline) http.Handler {
|
|||
|
||||
resources, err := pipeline.Resources()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-create-job-build", err)
|
||||
logger.Error("failed-to-get-resources", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
resourceTypes, err := pipeline.ResourceTypes()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-resource-types", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
@ -49,12 +56,19 @@ func (s *Server) CreateJobBuild(pipeline db.Pipeline) http.Handler {
|
|||
for _, input := range job.Config().Inputs() {
|
||||
resource, found := resources.Lookup(input.Resource)
|
||||
if found {
|
||||
if err = resource.NotifyScan(); err != nil {
|
||||
logger.Error("failed-to-notify-scan", err)
|
||||
version := resource.CurrentPinnedVersion()
|
||||
_, _, err := s.checkFactory.TryCreateCheck(resource, resourceTypes, version, true)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-create-check", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = s.checkFactory.NotifyChecker()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-notify-checker", err)
|
||||
}
|
||||
|
||||
err = json.NewEncoder(w).Encode(present.Build(build))
|
||||
if err != nil {
|
||||
logger.Error("failed-to-encode-build", err)
|
||||
|
|
|
@ -14,6 +14,7 @@ type Server struct {
|
|||
rejector auth.Rejector
|
||||
secretManager creds.Secrets
|
||||
jobFactory db.JobFactory
|
||||
checkFactory db.CheckFactory
|
||||
}
|
||||
|
||||
func NewServer(
|
||||
|
@ -21,6 +22,7 @@ func NewServer(
|
|||
externalURL string,
|
||||
secretManager creds.Secrets,
|
||||
jobFactory db.JobFactory,
|
||||
checkFactory db.CheckFactory,
|
||||
) *Server {
|
||||
return &Server{
|
||||
logger: logger,
|
||||
|
@ -28,5 +30,6 @@ func NewServer(
|
|||
rejector: auth.UnauthorizedRejector{},
|
||||
secretManager: secretManager,
|
||||
jobFactory: jobFactory,
|
||||
checkFactory: checkFactory,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package present
|
||||
|
||||
import (
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
)
|
||||
|
||||
func Check(check db.Check) atc.Check {
|
||||
|
||||
atcCheck := atc.Check{
|
||||
ID: check.ID(),
|
||||
Status: string(check.Status()),
|
||||
}
|
||||
|
||||
if !check.CreateTime().IsZero() {
|
||||
atcCheck.CreateTime = check.CreateTime().Unix()
|
||||
}
|
||||
|
||||
if !check.StartTime().IsZero() {
|
||||
atcCheck.StartTime = check.StartTime().Unix()
|
||||
}
|
||||
|
||||
if !check.EndTime().IsZero() {
|
||||
atcCheck.EndTime = check.EndTime().Unix()
|
||||
}
|
||||
|
||||
if err := check.CheckError(); err != nil {
|
||||
atcCheck.CheckError = err.Error()
|
||||
}
|
||||
|
||||
return atcCheck
|
||||
}
|
|
@ -9,7 +9,6 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/google/jsonapi"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
|
@ -18,8 +17,6 @@ import (
|
|||
"github.com/concourse/concourse/atc/creds"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/dbfakes"
|
||||
"github.com/concourse/concourse/atc/radar/radarfakes"
|
||||
"github.com/concourse/concourse/atc/resource"
|
||||
"github.com/concourse/concourse/vars"
|
||||
)
|
||||
|
||||
|
@ -561,14 +558,10 @@ var _ = Describe("Resources API", func() {
|
|||
})
|
||||
|
||||
Describe("POST /api/v1/teams/:team_name/pipelines/:pipeline_name/resources/:resource_name/check", func() {
|
||||
var fakeScanner *radarfakes.FakeScanner
|
||||
var checkRequestBody atc.CheckRequestBody
|
||||
var response *http.Response
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeScanner = new(radarfakes.FakeScanner)
|
||||
fakeScannerFactory.NewResourceScannerReturns(fakeScanner)
|
||||
|
||||
checkRequestBody = atc.CheckRequestBody{}
|
||||
})
|
||||
|
||||
|
@ -609,108 +602,107 @@ var _ = Describe("Resources API", func() {
|
|||
})
|
||||
|
||||
Context("when it finds the resource", func() {
|
||||
var fakeResource *dbfakes.FakeResource
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeResource := new(dbfakes.FakeResource)
|
||||
fakeResource = new(dbfakes.FakeResource)
|
||||
fakeResource.IDReturns(1)
|
||||
fakePipeline.ResourceReturns(fakeResource, true, nil)
|
||||
})
|
||||
|
||||
It("injects the proper pipelineDB", func() {
|
||||
Expect(dbTeam.PipelineCallCount()).To(Equal(1))
|
||||
pipelineName := dbTeam.PipelineArgsForCall(0)
|
||||
Expect(pipelineName).To(Equal("a-pipeline"))
|
||||
})
|
||||
|
||||
It("tries to scan with no version specified", func() {
|
||||
Expect(fakeScanner.ScanFromVersionCallCount()).To(Equal(1))
|
||||
_, actualResourceID, actualFromVersion := fakeScanner.ScanFromVersionArgsForCall(0)
|
||||
Expect(actualResourceID).To(Equal(1))
|
||||
Expect(actualFromVersion).To(BeNil())
|
||||
})
|
||||
|
||||
It("returns 200", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusOK))
|
||||
})
|
||||
|
||||
Context("when checking with a version specified", func() {
|
||||
Context("when looking up the resource types fails", func() {
|
||||
BeforeEach(func() {
|
||||
checkRequestBody = atc.CheckRequestBody{
|
||||
From: atc.Version{
|
||||
"some-version-key": "some-version-value",
|
||||
},
|
||||
}
|
||||
fakePipeline.ResourceTypesReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("tries to scan with the version specified", func() {
|
||||
Expect(fakeScanner.ScanFromVersionCallCount()).To(Equal(1))
|
||||
_, actualResourceID, actualFromVersion := fakeScanner.ScanFromVersionArgsForCall(0)
|
||||
Expect(actualResourceID).To(Equal(1))
|
||||
Expect(actualFromVersion).To(Equal(checkRequestBody.From))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking fails with ResourceNotFoundError", func() {
|
||||
BeforeEach(func() {
|
||||
fakeScanner.ScanFromVersionReturns(db.ResourceNotFoundError{})
|
||||
})
|
||||
|
||||
It("returns 404", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusNotFound))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking the resource fails with ResourceTypeNotFoundError", func() {
|
||||
BeforeEach(func() {
|
||||
fakeScanner.ScanFromVersionReturns(db.ResourceTypeNotFoundError{ID: 13})
|
||||
})
|
||||
|
||||
It("returns jsonapi 400", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusBadRequest))
|
||||
Expect(response.Header.Get("Content-Type")).To(Equal(jsonapi.MediaType))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking the resource fails internally", func() {
|
||||
BeforeEach(func() {
|
||||
fakeScanner.ScanFromVersionReturns(errors.New("welp"))
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
buf := new(bytes.Buffer)
|
||||
_, err := buf.ReadFrom(response.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
body := buf.String()
|
||||
Expect(body).To(Equal("welp"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking the resource fails with ErrResourceScriptFailed", func() {
|
||||
Context("when looking up the resource types succeeds", func() {
|
||||
var fakeResourceTypes db.ResourceTypes
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeScanner.ScanFromVersionReturns(
|
||||
resource.ErrResourceScriptFailed{
|
||||
ExitStatus: 42,
|
||||
Stderr: "my tooth",
|
||||
},
|
||||
)
|
||||
fakeResourceTypes = db.ResourceTypes{}
|
||||
fakePipeline.ResourceTypesReturns(fakeResourceTypes, nil)
|
||||
})
|
||||
|
||||
It("returns 400", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusBadRequest))
|
||||
It("checks with no version specified", func() {
|
||||
Expect(dbCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
actualResource, actualResourceTypes, actualFromVersion, manuallyTriggered := dbCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(actualResource).To(Equal(fakeResource))
|
||||
Expect(actualResourceTypes).To(Equal(fakeResourceTypes))
|
||||
Expect(actualFromVersion).To(BeNil())
|
||||
Expect(manuallyTriggered).To(BeTrue())
|
||||
})
|
||||
|
||||
It("returns the script's exit status and stderr", func() {
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Context("when checking with a version specified", func() {
|
||||
BeforeEach(func() {
|
||||
checkRequestBody = atc.CheckRequestBody{
|
||||
From: atc.Version{
|
||||
"some-version-key": "some-version-value",
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
Expect(body).To(MatchJSON(`{
|
||||
"exit_status": 42,
|
||||
"stderr": "my tooth"
|
||||
}`))
|
||||
It("checks with the version specified", func() {
|
||||
Expect(dbCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
actualResource, actualResourceTypes, actualFromVersion, manuallyTriggered := dbCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(actualResource).To(Equal(fakeResource))
|
||||
Expect(actualResourceTypes).To(Equal(fakeResourceTypes))
|
||||
Expect(actualFromVersion).To(Equal(checkRequestBody.From))
|
||||
Expect(manuallyTriggered).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
It("returns application/json", func() {
|
||||
Expect(response.Header.Get("Content-Type")).To(Equal("application/json"))
|
||||
Context("when checking fails", func() {
|
||||
BeforeEach(func() {
|
||||
dbCheckFactory.TryCreateCheckReturns(nil, false, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking does not create a new check", func() {
|
||||
BeforeEach(func() {
|
||||
dbCheckFactory.TryCreateCheckReturns(nil, false, nil)
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking creates a new check", func() {
|
||||
var fakeCheck *dbfakes.FakeCheck
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheck = new(dbfakes.FakeCheck)
|
||||
fakeCheck.IDReturns(10)
|
||||
fakeCheck.StatusReturns("started")
|
||||
fakeCheck.CreateTimeReturns(time.Date(2000, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.StartTimeReturns(time.Date(2001, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.EndTimeReturns(time.Date(2002, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
|
||||
dbCheckFactory.TryCreateCheckReturns(fakeCheck, true, nil)
|
||||
})
|
||||
|
||||
It("notify checker", func() {
|
||||
Expect(dbCheckFactory.NotifyCheckerCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
It("returns 201", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusCreated))
|
||||
Expect(ioutil.ReadAll(response.Body)).To(MatchJSON(`{
|
||||
"id": 10,
|
||||
"status": "started",
|
||||
"create_time": 946684800,
|
||||
"start_time": 978307200,
|
||||
"end_time": 1009843200
|
||||
}`))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1228,14 +1220,10 @@ var _ = Describe("Resources API", func() {
|
|||
})
|
||||
|
||||
Context("when authenticated and authorized", func() {
|
||||
var fakeScanner *radarfakes.FakeScanner
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeaccess.IsAuthenticatedReturns(true)
|
||||
fakeaccess.IsAuthorizedReturns(true)
|
||||
|
||||
fakeScanner = new(radarfakes.FakeScanner)
|
||||
fakeScannerFactory.NewResourceTypeScannerReturns(fakeScanner)
|
||||
})
|
||||
|
||||
Context("when looking up the resource type fails", func() {
|
||||
|
@ -1257,83 +1245,128 @@ var _ = Describe("Resources API", func() {
|
|||
})
|
||||
|
||||
Context("when it finds the resource type", func() {
|
||||
var fakeResourceType *dbfakes.FakeResourceType
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeResourceType := new(dbfakes.FakeResourceType)
|
||||
fakeResourceType = new(dbfakes.FakeResourceType)
|
||||
fakeResourceType.IDReturns(1)
|
||||
fakePipeline.ResourceTypeReturns(fakeResourceType, true, nil)
|
||||
})
|
||||
|
||||
It("returns 200", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusOK))
|
||||
})
|
||||
|
||||
It("calls Scan", func() {
|
||||
Expect(fakeScanner.ScanFromVersionCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
Context("when checking with a version specified", func() {
|
||||
Context("when looking up the resource types fails", func() {
|
||||
BeforeEach(func() {
|
||||
checkRequestBody = atc.CheckRequestBody{
|
||||
From: atc.Version{
|
||||
"some-version-key": "some-version-value",
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
It("tries to scan with the version specified", func() {
|
||||
Expect(fakeScanner.ScanFromVersionCallCount()).To(Equal(1))
|
||||
_, actualResourceID, actualFromVersion := fakeScanner.ScanFromVersionArgsForCall(0)
|
||||
Expect(actualResourceID).To(Equal(1))
|
||||
Expect(actualFromVersion).To(Equal(checkRequestBody.From))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when resource type checking fails with ResourceNotFoundError", func() {
|
||||
BeforeEach(func() {
|
||||
fakeScanner.ScanFromVersionReturns(db.ResourceTypeNotFoundError{})
|
||||
})
|
||||
|
||||
It("returns 404", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusNotFound))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when resource type fails with unexpected error", func() {
|
||||
BeforeEach(func() {
|
||||
err := errors.New("some-error")
|
||||
fakeScanner.ScanFromVersionReturns(err)
|
||||
fakePipeline.ResourceTypesReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when looking up the resource types succeeds", func() {
|
||||
var fakeResourceTypes db.ResourceTypes
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeResourceTypes = db.ResourceTypes{}
|
||||
fakePipeline.ResourceTypesReturns(fakeResourceTypes, nil)
|
||||
})
|
||||
|
||||
It("checks with no version specified", func() {
|
||||
Expect(dbCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
actualResourceType, actualResourceTypes, actualFromVersion, manuallyTriggered := dbCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(actualResourceType).To(Equal(fakeResourceType))
|
||||
Expect(actualResourceTypes).To(Equal(fakeResourceTypes))
|
||||
Expect(actualFromVersion).To(BeNil())
|
||||
Expect(manuallyTriggered).To(BeTrue())
|
||||
})
|
||||
|
||||
Context("when checking with a version specified", func() {
|
||||
BeforeEach(func() {
|
||||
checkRequestBody = atc.CheckRequestBody{
|
||||
From: atc.Version{
|
||||
"some-version-key": "some-version-value",
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
It("checks with no version specified", func() {
|
||||
Expect(dbCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
actualResourceType, actualResourceTypes, actualFromVersion, manuallyTriggered := dbCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(actualResourceType).To(Equal(fakeResourceType))
|
||||
Expect(actualResourceTypes).To(Equal(fakeResourceTypes))
|
||||
Expect(actualFromVersion).To(Equal(checkRequestBody.From))
|
||||
Expect(manuallyTriggered).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking fails", func() {
|
||||
BeforeEach(func() {
|
||||
dbCheckFactory.TryCreateCheckReturns(nil, false, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking does not create a new check", func() {
|
||||
BeforeEach(func() {
|
||||
dbCheckFactory.TryCreateCheckReturns(nil, false, nil)
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking creates a new check", func() {
|
||||
var fakeCheck *dbfakes.FakeCheck
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheck = new(dbfakes.FakeCheck)
|
||||
fakeCheck.IDReturns(10)
|
||||
fakeCheck.StatusReturns("started")
|
||||
fakeCheck.CreateTimeReturns(time.Date(2000, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.StartTimeReturns(time.Date(2001, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.EndTimeReturns(time.Date(2002, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
|
||||
dbCheckFactory.TryCreateCheckReturns(fakeCheck, true, nil)
|
||||
})
|
||||
|
||||
It("notify checker", func() {
|
||||
Expect(dbCheckFactory.NotifyCheckerCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
It("returns 201", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusCreated))
|
||||
Expect(ioutil.ReadAll(response.Body)).To(MatchJSON(`{
|
||||
"id": 10,
|
||||
"status": "started",
|
||||
"create_time": 946684800,
|
||||
"start_time": 978307200,
|
||||
"end_time": 1009843200
|
||||
}`))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("POST /api/v1/teams/:team_name/pipelines/:pipeline_name/resources/:resource_name/check/webhook", func() {
|
||||
var (
|
||||
fakeScanner *radarfakes.FakeScanner
|
||||
checkRequestBody atc.CheckRequestBody
|
||||
response *http.Response
|
||||
fakeResource *dbfakes.FakeResource
|
||||
fakeResourceConfig *dbfakes.FakeResourceConfig
|
||||
fakeResourceConfigVersion *dbfakes.FakeResourceConfigVersion
|
||||
fakeResourceConfigScope *dbfakes.FakeResourceConfigScope
|
||||
checkRequestBody atc.CheckRequestBody
|
||||
response *http.Response
|
||||
fakeResource *dbfakes.FakeResource
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeScanner = new(radarfakes.FakeScanner)
|
||||
fakeScannerFactory.NewResourceScannerReturns(fakeScanner)
|
||||
checkRequestBody = atc.CheckRequestBody{}
|
||||
|
||||
fakeResource = new(dbfakes.FakeResource)
|
||||
fakeResource.NameReturns("resource-name")
|
||||
fakeResource.IDReturns(10)
|
||||
fakeResourceConfig = new(dbfakes.FakeResourceConfig)
|
||||
fakeResourceConfigVersion = new(dbfakes.FakeResourceConfigVersion)
|
||||
fakeResourceConfigScope = new(dbfakes.FakeResourceConfigScope)
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
|
@ -1377,101 +1410,81 @@ var _ = Describe("Resources API", func() {
|
|||
fakePipeline.ResourceReturns(fakeResource, true, nil)
|
||||
})
|
||||
|
||||
It("tries to find the resource config using the resource config id", func() {
|
||||
Eventually(dbResourceConfigFactory.FindResourceConfigByIDCallCount).Should(Equal(1))
|
||||
Expect(dbResourceConfigFactory.FindResourceConfigByIDArgsForCall(0)).To(Equal(1))
|
||||
})
|
||||
|
||||
Context("when finding the resource config succeeds", func() {
|
||||
Context("when finding the resource types fails", func() {
|
||||
BeforeEach(func() {
|
||||
dbResourceConfigFactory.FindResourceConfigByIDReturns(fakeResourceConfig, true, nil)
|
||||
fakePipeline.ResourceTypesReturns(nil, errors.New("oops"))
|
||||
})
|
||||
|
||||
It("tries to find the resource config scope using the resource config scope id", func() {
|
||||
Eventually(fakeResourceConfig.FindResourceConfigScopeByIDCallCount).Should(Equal(1))
|
||||
resourceConfigScopeID, resource := fakeResourceConfig.FindResourceConfigScopeByIDArgsForCall(0)
|
||||
Expect(resourceConfigScopeID).To(Equal(2))
|
||||
Expect(resource).To(Equal(fakeResource))
|
||||
})
|
||||
|
||||
Context("when finding the resource config scope succeeds", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeResourceConfig.FindResourceConfigScopeByIDReturns(fakeResourceConfigScope, true, nil)
|
||||
})
|
||||
|
||||
Context("when the latest version is found", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceConfigVersion.IDReturns(4)
|
||||
fakeResourceConfigVersion.VersionReturns(db.Version{"some": "version"})
|
||||
fakeResourceConfigVersion.MetadataReturns([]db.ResourceConfigMetadataField{
|
||||
{
|
||||
Name: "some",
|
||||
Value: "metadata",
|
||||
},
|
||||
})
|
||||
|
||||
fakeResourceConfigScope.LatestVersionReturns(fakeResourceConfigVersion, true, nil)
|
||||
})
|
||||
|
||||
It("tries to scan with the latest version", func() {
|
||||
Eventually(fakeScanner.ScanFromVersionCallCount).Should(Equal(1))
|
||||
_, actualResourceID, actualFromVersion := fakeScanner.ScanFromVersionArgsForCall(0)
|
||||
Expect(actualResourceID).To(Equal(10))
|
||||
Expect(actualFromVersion).To(Equal(atc.Version{"some": "version"}))
|
||||
})
|
||||
|
||||
It("returns 200", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusOK))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the latest version is not found", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceConfigScope.LatestVersionReturns(nil, false, nil)
|
||||
})
|
||||
|
||||
It("tries to scan with no version specified", func() {
|
||||
Eventually(fakeScanner.ScanFromVersionCallCount).Should(Equal(1))
|
||||
_, actualResourceID, actualFromVersion := fakeScanner.ScanFromVersionArgsForCall(0)
|
||||
Expect(actualResourceID).To(Equal(10))
|
||||
Expect(actualFromVersion).To(BeNil())
|
||||
})
|
||||
|
||||
It("returns 200", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusOK))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when failing to get latest version for resource", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceConfigScope.LatestVersionReturns(nil, false, errors.New("disaster"))
|
||||
})
|
||||
|
||||
It("does not scan from version", func() {
|
||||
Consistently(fakeScanner.ScanFromVersionCallCount).Should(Equal(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the resource config scope is not found", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceConfig.FindResourceConfigScopeByIDReturns(nil, false, nil)
|
||||
})
|
||||
|
||||
It("tries to scan", func() {
|
||||
Eventually(fakeScanner.ScanFromVersionCallCount).Should(Equal(1))
|
||||
})
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the resource config is not found", func() {
|
||||
Context("when finding the resource types succeeds", func() {
|
||||
var fakeResourceTypes db.ResourceTypes
|
||||
|
||||
BeforeEach(func() {
|
||||
dbResourceConfigFactory.FindResourceConfigByIDReturns(nil, false, nil)
|
||||
fakeResourceTypes = db.ResourceTypes{}
|
||||
fakePipeline.ResourceTypesReturns(fakeResourceTypes, nil)
|
||||
})
|
||||
|
||||
It("tries to scan", func() {
|
||||
Eventually(fakeScanner.ScanFromVersionCallCount).Should(Equal(1))
|
||||
It("checks with a nil version", func() {
|
||||
Expect(dbCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
actualResource, actualResourceTypes, actualFromVersion, manuallyTriggered := dbCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(actualResource).To(Equal(fakeResource))
|
||||
Expect(actualResourceTypes).To(Equal(fakeResourceTypes))
|
||||
Expect(actualFromVersion).To(BeNil())
|
||||
Expect(manuallyTriggered).To(BeTrue())
|
||||
})
|
||||
|
||||
Context("when checking fails", func() {
|
||||
BeforeEach(func() {
|
||||
dbCheckFactory.TryCreateCheckReturns(nil, false, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking does not create a new check", func() {
|
||||
BeforeEach(func() {
|
||||
dbCheckFactory.TryCreateCheckReturns(nil, false, nil)
|
||||
})
|
||||
|
||||
It("returns 500", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when checking creates a new check", func() {
|
||||
var fakeCheck *dbfakes.FakeCheck
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheck = new(dbfakes.FakeCheck)
|
||||
fakeCheck.IDReturns(10)
|
||||
fakeCheck.StatusReturns("started")
|
||||
fakeCheck.CreateTimeReturns(time.Date(2000, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.StartTimeReturns(time.Date(2001, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
fakeCheck.EndTimeReturns(time.Date(2002, 01, 01, 0, 0, 0, 0, time.UTC))
|
||||
|
||||
dbCheckFactory.TryCreateCheckReturns(fakeCheck, true, nil)
|
||||
})
|
||||
|
||||
It("notify checker", func() {
|
||||
Expect(dbCheckFactory.NotifyCheckerCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
It("returns 201", func() {
|
||||
Expect(response.StatusCode).To(Equal(http.StatusCreated))
|
||||
Expect(ioutil.ReadAll(response.Body)).To(MatchJSON(`{
|
||||
"id": 10,
|
||||
"status": "started",
|
||||
"create_time": 946684800,
|
||||
"start_time": 978307200,
|
||||
"end_time": 1009843200
|
||||
}`))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1495,7 +1508,6 @@ var _ = Describe("Resources API", func() {
|
|||
Expect(response.StatusCode).To(Equal(http.StatusNotFound))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
Context("when unauthorized", func() {
|
||||
|
|
|
@ -6,9 +6,8 @@ import (
|
|||
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/api/present"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/resource"
|
||||
"github.com/google/jsonapi"
|
||||
"github.com/tedsuo/rata"
|
||||
)
|
||||
|
||||
|
@ -39,39 +38,40 @@ func (s *Server) CheckResource(dbPipeline db.Pipeline) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
scanner := s.scannerFactory.NewResourceScanner(dbPipeline)
|
||||
|
||||
err = scanner.ScanFromVersion(logger, dbResource.ID(), reqBody.From)
|
||||
switch scanErr := err.(type) {
|
||||
case resource.ErrResourceScriptFailed:
|
||||
checkResponseBody := atc.CheckResponseBody{
|
||||
ExitStatus: scanErr.ExitStatus,
|
||||
Stderr: scanErr.Stderr,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err = json.NewEncoder(w).Encode(checkResponseBody)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-encode-check-response-body", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
}
|
||||
case db.ResourceNotFoundError:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case db.ResourceTypeNotFoundError:
|
||||
w.Header().Set("Content-Type", jsonapi.MediaType)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_ = jsonapi.MarshalErrors(w, []*jsonapi.ErrorObject{{
|
||||
Title: "Resource Type Not Found Error",
|
||||
Detail: err.Error(),
|
||||
Status: "400",
|
||||
}})
|
||||
case error:
|
||||
dbResourceTypes, err := dbPipeline.ResourceTypes()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-resource-types", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
check, created, err := s.checkFactory.TryCreateCheck(dbResource, dbResourceTypes, reqBody.From, true)
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-create-check", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if !created {
|
||||
s.logger.Info("check-not-created")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = s.checkFactory.NotifyChecker()
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-notify-checker", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
|
||||
err = json.NewEncoder(w).Encode(present.Check(check))
|
||||
if err != nil {
|
||||
logger.Error("failed-to-encode-check", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
default:
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/api/present"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/tedsuo/rata"
|
||||
)
|
||||
|
@ -37,17 +38,40 @@ func (s *Server) CheckResourceType(dbPipeline db.Pipeline) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
scanner := s.scannerFactory.NewResourceTypeScanner(dbPipeline)
|
||||
|
||||
err = scanner.ScanFromVersion(logger, dbResourceType.ID(), reqBody.From)
|
||||
switch err.(type) {
|
||||
case db.ResourceTypeNotFoundError:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
case error:
|
||||
dbResourceTypes, err := dbPipeline.ResourceTypes()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-resource-types", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
check, created, err := s.checkFactory.TryCreateCheck(dbResourceType, dbResourceTypes, reqBody.From, true)
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-create-check", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if !created {
|
||||
s.logger.Info("check-not-created")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = s.checkFactory.NotifyChecker()
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-notify-checker", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
|
||||
err = json.NewEncoder(w).Encode(present.Check(check))
|
||||
if err != nil {
|
||||
logger.Error("failed-to-encode-check", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
default:
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package resourceserver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/api/present"
|
||||
"github.com/concourse/concourse/atc/creds"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/tedsuo/rata"
|
||||
|
@ -25,7 +26,7 @@ func (s *Server) CheckResourceWebHook(dbPipeline db.Pipeline) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
pipelineResource, found, err := dbPipeline.Resource(resourceName)
|
||||
dbResource, found, err := dbPipeline.Resource(resourceName)
|
||||
if err != nil {
|
||||
logger.Error("database-error", err, lager.Data{"resource-name": resourceName})
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
@ -39,45 +40,47 @@ func (s *Server) CheckResourceWebHook(dbPipeline db.Pipeline) http.Handler {
|
|||
}
|
||||
|
||||
variables := creds.NewVariables(s.secretManager, dbPipeline.TeamName(), dbPipeline.Name())
|
||||
token, err := creds.NewString(variables, pipelineResource.WebhookToken()).Evaluate()
|
||||
token, err := creds.NewString(variables, dbResource.WebhookToken()).Evaluate()
|
||||
if token != webhookToken {
|
||||
logger.Info("invalid-token", lager.Data{"error": fmt.Sprintf("invalid token for webhook %s", webhookToken)})
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
var fromVersion atc.Version
|
||||
resourceConfigID := pipelineResource.ResourceConfigID()
|
||||
resourceConfig, found, err := s.resourceConfigFactory.FindResourceConfigByID(resourceConfigID)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-resource-config", err, lager.Data{"resource-config-id": resourceConfigID})
|
||||
return
|
||||
}
|
||||
dbResourceTypes, err := dbPipeline.ResourceTypes()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-resource-types", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if found {
|
||||
resourceConfigScope, found, err := resourceConfig.FindResourceConfigScopeByID(pipelineResource.ResourceConfigScopeID(), pipelineResource)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-resource-config-scope", err, lager.Data{"resource-config-scope-id": pipelineResource.ResourceConfigScopeID()})
|
||||
return
|
||||
}
|
||||
check, created, err := s.checkFactory.TryCreateCheck(dbResource, dbResourceTypes, nil, true)
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-create-check", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if found {
|
||||
latestVersion, found, err := resourceConfigScope.LatestVersion()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-latest-resource-version", err, lager.Data{"resource-config-id": resourceConfigID})
|
||||
return
|
||||
}
|
||||
if found {
|
||||
fromVersion = atc.Version(latestVersion.Version())
|
||||
}
|
||||
}
|
||||
}
|
||||
if !created {
|
||||
s.logger.Info("check-not-created")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
scanner := s.scannerFactory.NewResourceScanner(dbPipeline)
|
||||
scanner.ScanFromVersion(logger, pipelineResource.ID(), fromVersion)
|
||||
}()
|
||||
err = s.checkFactory.NotifyChecker()
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-notify-checker", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
|
||||
err = json.NewEncoder(w).Encode(present.Check(check))
|
||||
if err != nil {
|
||||
logger.Error("failed-to-encode-check", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package resourceserver_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResourceserver(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Resourceserver Suite")
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package resourceserverfakes
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/concourse/concourse/atc/api/resourceserver"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/radar"
|
||||
)
|
||||
|
||||
type FakeScannerFactory struct {
|
||||
NewResourceScannerStub func(db.Pipeline) radar.Scanner
|
||||
newResourceScannerMutex sync.RWMutex
|
||||
newResourceScannerArgsForCall []struct {
|
||||
arg1 db.Pipeline
|
||||
}
|
||||
newResourceScannerReturns struct {
|
||||
result1 radar.Scanner
|
||||
}
|
||||
newResourceScannerReturnsOnCall map[int]struct {
|
||||
result1 radar.Scanner
|
||||
}
|
||||
NewResourceTypeScannerStub func(db.Pipeline) radar.Scanner
|
||||
newResourceTypeScannerMutex sync.RWMutex
|
||||
newResourceTypeScannerArgsForCall []struct {
|
||||
arg1 db.Pipeline
|
||||
}
|
||||
newResourceTypeScannerReturns struct {
|
||||
result1 radar.Scanner
|
||||
}
|
||||
newResourceTypeScannerReturnsOnCall map[int]struct {
|
||||
result1 radar.Scanner
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceScanner(arg1 db.Pipeline) radar.Scanner {
|
||||
fake.newResourceScannerMutex.Lock()
|
||||
ret, specificReturn := fake.newResourceScannerReturnsOnCall[len(fake.newResourceScannerArgsForCall)]
|
||||
fake.newResourceScannerArgsForCall = append(fake.newResourceScannerArgsForCall, struct {
|
||||
arg1 db.Pipeline
|
||||
}{arg1})
|
||||
fake.recordInvocation("NewResourceScanner", []interface{}{arg1})
|
||||
fake.newResourceScannerMutex.Unlock()
|
||||
if fake.NewResourceScannerStub != nil {
|
||||
return fake.NewResourceScannerStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.newResourceScannerReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceScannerCallCount() int {
|
||||
fake.newResourceScannerMutex.RLock()
|
||||
defer fake.newResourceScannerMutex.RUnlock()
|
||||
return len(fake.newResourceScannerArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceScannerCalls(stub func(db.Pipeline) radar.Scanner) {
|
||||
fake.newResourceScannerMutex.Lock()
|
||||
defer fake.newResourceScannerMutex.Unlock()
|
||||
fake.NewResourceScannerStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceScannerArgsForCall(i int) db.Pipeline {
|
||||
fake.newResourceScannerMutex.RLock()
|
||||
defer fake.newResourceScannerMutex.RUnlock()
|
||||
argsForCall := fake.newResourceScannerArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceScannerReturns(result1 radar.Scanner) {
|
||||
fake.newResourceScannerMutex.Lock()
|
||||
defer fake.newResourceScannerMutex.Unlock()
|
||||
fake.NewResourceScannerStub = nil
|
||||
fake.newResourceScannerReturns = struct {
|
||||
result1 radar.Scanner
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceScannerReturnsOnCall(i int, result1 radar.Scanner) {
|
||||
fake.newResourceScannerMutex.Lock()
|
||||
defer fake.newResourceScannerMutex.Unlock()
|
||||
fake.NewResourceScannerStub = nil
|
||||
if fake.newResourceScannerReturnsOnCall == nil {
|
||||
fake.newResourceScannerReturnsOnCall = make(map[int]struct {
|
||||
result1 radar.Scanner
|
||||
})
|
||||
}
|
||||
fake.newResourceScannerReturnsOnCall[i] = struct {
|
||||
result1 radar.Scanner
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceTypeScanner(arg1 db.Pipeline) radar.Scanner {
|
||||
fake.newResourceTypeScannerMutex.Lock()
|
||||
ret, specificReturn := fake.newResourceTypeScannerReturnsOnCall[len(fake.newResourceTypeScannerArgsForCall)]
|
||||
fake.newResourceTypeScannerArgsForCall = append(fake.newResourceTypeScannerArgsForCall, struct {
|
||||
arg1 db.Pipeline
|
||||
}{arg1})
|
||||
fake.recordInvocation("NewResourceTypeScanner", []interface{}{arg1})
|
||||
fake.newResourceTypeScannerMutex.Unlock()
|
||||
if fake.NewResourceTypeScannerStub != nil {
|
||||
return fake.NewResourceTypeScannerStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.newResourceTypeScannerReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceTypeScannerCallCount() int {
|
||||
fake.newResourceTypeScannerMutex.RLock()
|
||||
defer fake.newResourceTypeScannerMutex.RUnlock()
|
||||
return len(fake.newResourceTypeScannerArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceTypeScannerCalls(stub func(db.Pipeline) radar.Scanner) {
|
||||
fake.newResourceTypeScannerMutex.Lock()
|
||||
defer fake.newResourceTypeScannerMutex.Unlock()
|
||||
fake.NewResourceTypeScannerStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceTypeScannerArgsForCall(i int) db.Pipeline {
|
||||
fake.newResourceTypeScannerMutex.RLock()
|
||||
defer fake.newResourceTypeScannerMutex.RUnlock()
|
||||
argsForCall := fake.newResourceTypeScannerArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceTypeScannerReturns(result1 radar.Scanner) {
|
||||
fake.newResourceTypeScannerMutex.Lock()
|
||||
defer fake.newResourceTypeScannerMutex.Unlock()
|
||||
fake.NewResourceTypeScannerStub = nil
|
||||
fake.newResourceTypeScannerReturns = struct {
|
||||
result1 radar.Scanner
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) NewResourceTypeScannerReturnsOnCall(i int, result1 radar.Scanner) {
|
||||
fake.newResourceTypeScannerMutex.Lock()
|
||||
defer fake.newResourceTypeScannerMutex.Unlock()
|
||||
fake.NewResourceTypeScannerStub = nil
|
||||
if fake.newResourceTypeScannerReturnsOnCall == nil {
|
||||
fake.newResourceTypeScannerReturnsOnCall = make(map[int]struct {
|
||||
result1 radar.Scanner
|
||||
})
|
||||
}
|
||||
fake.newResourceTypeScannerReturnsOnCall[i] = struct {
|
||||
result1 radar.Scanner
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.newResourceScannerMutex.RLock()
|
||||
defer fake.newResourceScannerMutex.RUnlock()
|
||||
fake.newResourceTypeScannerMutex.RLock()
|
||||
defer fake.newResourceTypeScannerMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakeScannerFactory) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ resourceserver.ScannerFactory = new(FakeScannerFactory)
|
|
@ -4,35 +4,27 @@ import (
|
|||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc/creds"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/radar"
|
||||
)
|
||||
|
||||
//go:generate counterfeiter . ScannerFactory
|
||||
|
||||
type ScannerFactory interface {
|
||||
NewResourceScanner(pipeline db.Pipeline) radar.Scanner
|
||||
NewResourceTypeScanner(dbPipeline db.Pipeline) radar.Scanner
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
logger lager.Logger
|
||||
scannerFactory ScannerFactory
|
||||
secretManager creds.Secrets
|
||||
checkFactory db.CheckFactory
|
||||
resourceFactory db.ResourceFactory
|
||||
resourceConfigFactory db.ResourceConfigFactory
|
||||
}
|
||||
|
||||
func NewServer(
|
||||
logger lager.Logger,
|
||||
scannerFactory ScannerFactory,
|
||||
secretManager creds.Secrets,
|
||||
checkFactory db.CheckFactory,
|
||||
resourceFactory db.ResourceFactory,
|
||||
resourceConfigFactory db.ResourceConfigFactory,
|
||||
) *Server {
|
||||
return &Server{
|
||||
logger: logger,
|
||||
scannerFactory: scannerFactory,
|
||||
secretManager: secretManager,
|
||||
checkFactory: checkFactory,
|
||||
resourceFactory: resourceFactory,
|
||||
resourceConfigFactory: resourceConfigFactory,
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/concourse/concourse/atc/engine/builder"
|
||||
"github.com/concourse/concourse/atc/fetcher"
|
||||
"github.com/concourse/concourse/atc/gc"
|
||||
"github.com/concourse/concourse/atc/lidar"
|
||||
"github.com/concourse/concourse/atc/lockrunner"
|
||||
"github.com/concourse/concourse/atc/metric"
|
||||
"github.com/concourse/concourse/atc/pipelines"
|
||||
|
@ -113,6 +114,7 @@ type RunCommand struct {
|
|||
InterceptIdleTimeout time.Duration `long:"intercept-idle-timeout" default:"0m" description:"Length of time for a intercepted session to be idle before terminating."`
|
||||
|
||||
EnableGlobalResources bool `long:"enable-global-resources" description:"Enable equivalent resources across pipelines and teams to share a single version history."`
|
||||
EnableLidar bool `long:"enable-lidar" description:"The Future™ of resource checking."`
|
||||
|
||||
GlobalResourceCheckTimeout time.Duration `long:"global-resource-check-timeout" default:"1h" description:"Time limit on checking for new versions of resources."`
|
||||
ResourceCheckingInterval time.Duration `long:"resource-checking-interval" default:"1m" description:"Interval on which to check for new versions of resources."`
|
||||
|
@ -153,6 +155,7 @@ type RunCommand struct {
|
|||
|
||||
OneOffBuildGracePeriod time.Duration `long:"one-off-grace-period" default:"5m" description:"Period after which one-off build containers will be garbage-collected."`
|
||||
MissingGracePeriod time.Duration `long:"missing-grace-period" default:"5m" description:"Period after which to reap containers and volumes that were created but went missing from the worker."`
|
||||
CheckRecyclePeriod time.Duration `long:"check-recycle-period" default:"6h" description:"Period after which to reap checks that are completed."`
|
||||
} `group:"Garbage Collection" namespace:"gc"`
|
||||
|
||||
BuildTrackerInterval time.Duration `long:"build-tracker-interval" default:"10s" description:"Interval on which to run build tracking."`
|
||||
|
@ -571,19 +574,6 @@ func (cmd *RunCommand) constructAPIMembers(
|
|||
pool := worker.NewPool(workerProvider)
|
||||
workerClient := worker.NewClient(pool, workerProvider)
|
||||
|
||||
checkContainerStrategy := worker.NewRandomPlacementStrategy()
|
||||
|
||||
radarScannerFactory := radar.NewScannerFactory(
|
||||
pool,
|
||||
resourceFactory,
|
||||
dbResourceConfigFactory,
|
||||
cmd.ResourceTypeCheckingInterval,
|
||||
cmd.ResourceCheckingInterval,
|
||||
cmd.ExternalURL.String(),
|
||||
secretManager,
|
||||
checkContainerStrategy,
|
||||
)
|
||||
|
||||
credsManagers := cmd.CredentialManagers
|
||||
dbPipelineFactory := db.NewPipelineFactory(dbConn, lockFactory)
|
||||
dbJobFactory := db.NewJobFactory(dbConn, lockFactory)
|
||||
|
@ -591,6 +581,7 @@ func (cmd *RunCommand) constructAPIMembers(
|
|||
dbContainerRepository := db.NewContainerRepository(dbConn)
|
||||
gcContainerDestroyer := gc.NewDestroyer(logger, dbContainerRepository, dbVolumeRepository)
|
||||
dbBuildFactory := db.NewBuildFactory(dbConn, lockFactory, cmd.GC.OneOffBuildGracePeriod)
|
||||
dbCheckFactory := db.NewCheckFactory(dbConn, lockFactory, secretManager, cmd.GlobalResourceCheckTimeout)
|
||||
accessFactory := accessor.NewAccessFactory(authHandler.PublicKey())
|
||||
|
||||
apiHandler, err := cmd.constructAPIHandler(
|
||||
|
@ -605,10 +596,10 @@ func (cmd *RunCommand) constructAPIMembers(
|
|||
dbContainerRepository,
|
||||
gcContainerDestroyer,
|
||||
dbBuildFactory,
|
||||
dbCheckFactory,
|
||||
dbResourceConfigFactory,
|
||||
userFactory,
|
||||
workerClient,
|
||||
radarScannerFactory,
|
||||
secretManager,
|
||||
credsManagers,
|
||||
accessFactory,
|
||||
|
@ -787,10 +778,14 @@ func (cmd *RunCommand) constructBackendMembers(
|
|||
dbResourceCacheLifecycle := db.NewResourceCacheLifecycle(dbConn)
|
||||
dbContainerRepository := db.NewContainerRepository(dbConn)
|
||||
dbArtifactLifecycle := db.NewArtifactLifecycle(dbConn)
|
||||
dbCheckLifecycle := db.NewCheckLifecycle(dbConn)
|
||||
resourceConfigCheckSessionLifecycle := db.NewResourceConfigCheckSessionLifecycle(dbConn)
|
||||
dbBuildFactory := db.NewBuildFactory(dbConn, lockFactory, cmd.GC.OneOffBuildGracePeriod)
|
||||
bus := dbConn.Bus()
|
||||
dbCheckFactory := db.NewCheckFactory(dbConn, lockFactory, secretManager, cmd.GlobalResourceCheckTimeout)
|
||||
dbPipelineFactory := db.NewPipelineFactory(dbConn, lockFactory)
|
||||
|
||||
bus := dbConn.Bus()
|
||||
|
||||
members := []grouper.Member{
|
||||
{Name: "pipelines", Runner: pipelines.SyncRunner{
|
||||
Syncer: cmd.constructPipelineSyncer(
|
||||
|
@ -823,6 +818,10 @@ func (cmd *RunCommand) constructBackendMembers(
|
|||
gc.NewResourceConfigCollector(dbResourceConfigFactory),
|
||||
gc.NewResourceCacheCollector(dbResourceCacheLifecycle),
|
||||
gc.NewArtifactCollector(dbArtifactLifecycle),
|
||||
gc.NewCheckCollector(
|
||||
dbCheckLifecycle,
|
||||
cmd.GC.CheckRecyclePeriod,
|
||||
),
|
||||
gc.NewVolumeCollector(
|
||||
dbVolumeRepository,
|
||||
cmd.GC.MissingGracePeriod,
|
||||
|
@ -866,7 +865,46 @@ func (cmd *RunCommand) constructBackendMembers(
|
|||
)},
|
||||
}
|
||||
|
||||
//Syslog Drainer Configuration
|
||||
var lidarRunner ifrit.Runner
|
||||
|
||||
if cmd.EnableLidar {
|
||||
lidarRunner = lidar.NewRunner(
|
||||
logger.Session("lidar"),
|
||||
clock.NewClock(),
|
||||
lidar.NewScanner(
|
||||
logger.Session("lidar-scanner"),
|
||||
dbCheckFactory,
|
||||
secretManager,
|
||||
cmd.GlobalResourceCheckTimeout,
|
||||
cmd.ResourceCheckingInterval,
|
||||
),
|
||||
time.Minute,
|
||||
lidar.NewChecker(
|
||||
logger.Session("lidar-checker"),
|
||||
dbCheckFactory,
|
||||
engine,
|
||||
),
|
||||
10*time.Second,
|
||||
bus,
|
||||
)
|
||||
} else {
|
||||
lidarRunner = lidar.NewCheckerRunner(
|
||||
logger.Session("lidar"),
|
||||
clock.NewClock(),
|
||||
lidar.NewChecker(
|
||||
logger.Session("lidar-checker"),
|
||||
dbCheckFactory,
|
||||
engine,
|
||||
),
|
||||
10*time.Second,
|
||||
bus,
|
||||
)
|
||||
}
|
||||
|
||||
members = append(members, grouper.Member{
|
||||
Name: "lidar", Runner: lidarRunner,
|
||||
})
|
||||
|
||||
if syslogDrainConfigured {
|
||||
members = append(members, grouper.Member{
|
||||
Name: "syslog", Runner: lockrunner.NewRunner(
|
||||
|
@ -1267,13 +1305,13 @@ func (cmd *RunCommand) constructEngine(
|
|||
defaultLimits,
|
||||
strategy,
|
||||
resourceFactory,
|
||||
lockFactory,
|
||||
)
|
||||
|
||||
stepBuilder := builder.NewStepBuilder(
|
||||
stepFactory,
|
||||
builder.NewDelegateFactory(),
|
||||
cmd.ExternalURL.String(),
|
||||
lockFactory,
|
||||
)
|
||||
|
||||
return engine.NewEngine(stepBuilder)
|
||||
|
@ -1322,10 +1360,10 @@ func (cmd *RunCommand) constructAPIHandler(
|
|||
dbContainerRepository db.ContainerRepository,
|
||||
gcContainerDestroyer gc.Destroyer,
|
||||
dbBuildFactory db.BuildFactory,
|
||||
dbCheckFactory db.CheckFactory,
|
||||
resourceConfigFactory db.ResourceConfigFactory,
|
||||
dbUserFactory db.UserFactory,
|
||||
workerClient worker.Client,
|
||||
radarScannerFactory radar.ScannerFactory,
|
||||
secretManager creds.Secrets,
|
||||
credsManagers creds.Managers,
|
||||
accessFactory accessor.AccessFactory,
|
||||
|
@ -1375,13 +1413,13 @@ func (cmd *RunCommand) constructAPIHandler(
|
|||
dbContainerRepository,
|
||||
gcContainerDestroyer,
|
||||
dbBuildFactory,
|
||||
dbCheckFactory,
|
||||
resourceConfigFactory,
|
||||
dbUserFactory,
|
||||
|
||||
buildserver.NewEventHandler,
|
||||
|
||||
workerClient,
|
||||
radarScannerFactory,
|
||||
|
||||
reconfigurableSink,
|
||||
|
||||
|
@ -1437,7 +1475,7 @@ func (cmd *RunCommand) constructPipelineSyncer(
|
|||
"team": pipeline.TeamName(),
|
||||
"pipeline": pipeline.Name(),
|
||||
}),
|
||||
cmd.Developer.Noop,
|
||||
(cmd.Developer.Noop || cmd.EnableLidar),
|
||||
radarSchedulerFactory.BuildScanRunnerFactory(pipeline, cmd.ExternalURL.String(), variables, bus),
|
||||
pipeline,
|
||||
1*time.Minute,
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package atc
|
||||
|
||||
type Check struct {
|
||||
ID int `json:"id"`
|
||||
Status string `json:"status"`
|
||||
CreateTime int64 `json:"create_time,omitempty"`
|
||||
StartTime int64 `json:"start_time,omitempty"`
|
||||
EndTime int64 `json:"end_time,omitempty"`
|
||||
CheckError string `json:"check_error,omitempty"`
|
||||
}
|
|
@ -886,7 +886,7 @@ func (b *build) SaveOutput(
|
|||
return err
|
||||
}
|
||||
|
||||
newVersion, err := saveResourceVersion(tx, resourceConfigScope, version, metadata)
|
||||
newVersion, err := saveResourceVersion(tx, resourceConfigScope.ID(), version, metadata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -899,7 +899,7 @@ func (b *build) SaveOutput(
|
|||
versionJSON := string(versionBytes)
|
||||
|
||||
if newVersion {
|
||||
err = incrementCheckOrder(tx, resourceConfigScope, versionJSON)
|
||||
err = incrementCheckOrder(tx, resourceConfigScope.ID(), versionJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/lager"
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db/lock"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
type CheckStatus string
|
||||
|
||||
const (
|
||||
CheckStatusStarted CheckStatus = "started"
|
||||
CheckStatusSucceeded CheckStatus = "succeeded"
|
||||
CheckStatusErrored CheckStatus = "errored"
|
||||
)
|
||||
|
||||
//go:generate counterfeiter . Check
|
||||
|
||||
type Check interface {
|
||||
ID() int
|
||||
TeamID() int
|
||||
ResourceConfigScopeID() int
|
||||
ResourceConfigID() int
|
||||
BaseResourceTypeID() int
|
||||
Schema() string
|
||||
Plan() atc.Plan
|
||||
CreateTime() time.Time
|
||||
StartTime() time.Time
|
||||
EndTime() time.Time
|
||||
Status() CheckStatus
|
||||
CheckError() error
|
||||
|
||||
Start() error
|
||||
Finish() error
|
||||
FinishWithError(err error) error
|
||||
|
||||
SaveVersions([]atc.Version) error
|
||||
AllCheckables() ([]Checkable, error)
|
||||
AcquireTrackingLock(lager.Logger) (lock.Lock, bool, error)
|
||||
Reload() (bool, error)
|
||||
}
|
||||
|
||||
var checksQuery = psql.Select(
|
||||
"c.id",
|
||||
"c.resource_config_scope_id",
|
||||
"c.status",
|
||||
"c.schema",
|
||||
"c.create_time",
|
||||
"c.start_time",
|
||||
"c.end_time",
|
||||
"c.plan",
|
||||
"c.nonce",
|
||||
"c.check_error",
|
||||
"(c.metadata->>'team_id')::int",
|
||||
"(c.metadata->>'resource_config_id')::int",
|
||||
"(c.metadata->>'base_resource_type_id')::int",
|
||||
).
|
||||
From("checks c")
|
||||
|
||||
type check struct {
|
||||
id int
|
||||
teamID int
|
||||
resourceConfigScopeID int
|
||||
resourceConfigID int
|
||||
baseResourceTypeID int
|
||||
|
||||
status CheckStatus
|
||||
schema string
|
||||
plan atc.Plan
|
||||
checkError error
|
||||
|
||||
createTime time.Time
|
||||
startTime time.Time
|
||||
endTime time.Time
|
||||
|
||||
conn Conn
|
||||
lockFactory lock.LockFactory
|
||||
}
|
||||
|
||||
func (c *check) ID() int { return c.id }
|
||||
func (c *check) TeamID() int { return c.teamID }
|
||||
func (c *check) ResourceConfigScopeID() int { return c.resourceConfigScopeID }
|
||||
func (c *check) ResourceConfigID() int { return c.resourceConfigID }
|
||||
func (c *check) BaseResourceTypeID() int { return c.baseResourceTypeID }
|
||||
func (c *check) Status() CheckStatus { return c.status }
|
||||
func (c *check) Schema() string { return c.schema }
|
||||
func (c *check) Plan() atc.Plan { return c.plan }
|
||||
func (c *check) CreateTime() time.Time { return c.createTime }
|
||||
func (c *check) StartTime() time.Time { return c.startTime }
|
||||
func (c *check) EndTime() time.Time { return c.endTime }
|
||||
func (c *check) CheckError() error { return c.checkError }
|
||||
|
||||
func (c *check) Reload() (bool, error) {
|
||||
row := checksQuery.Where(sq.Eq{"c.id": c.id}).
|
||||
RunWith(c.conn).
|
||||
QueryRow()
|
||||
|
||||
err := scanCheck(c, row)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (c *check) Start() error {
|
||||
tx, err := c.conn.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer Rollback(tx)
|
||||
|
||||
_, err = psql.Update("checks").
|
||||
Set("start_time", sq.Expr("now()")).
|
||||
Where(sq.Eq{
|
||||
"id": c.id,
|
||||
}).
|
||||
RunWith(tx).
|
||||
Exec()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = psql.Update("resource_config_scopes").
|
||||
Set("last_check_start_time", sq.Expr("now()")).
|
||||
Where(sq.Eq{
|
||||
"id": c.resourceConfigScopeID,
|
||||
}).
|
||||
RunWith(tx).
|
||||
Exec()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *check) Finish() error {
|
||||
return c.finish(CheckStatusSucceeded, nil)
|
||||
}
|
||||
|
||||
func (c *check) FinishWithError(err error) error {
|
||||
return c.finish(CheckStatusErrored, err)
|
||||
}
|
||||
|
||||
func (c *check) finish(status CheckStatus, checkError error) error {
|
||||
tx, err := c.conn.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer Rollback(tx)
|
||||
|
||||
builder := psql.Update("checks").
|
||||
Set("status", status).
|
||||
Set("end_time", sq.Expr("now()")).
|
||||
Where(sq.Eq{
|
||||
"id": c.id,
|
||||
})
|
||||
|
||||
if checkError != nil {
|
||||
builder = builder.Set("check_error", checkError.Error())
|
||||
}
|
||||
|
||||
_, err = builder.
|
||||
RunWith(tx).
|
||||
Exec()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
builder = psql.Update("resource_config_scopes").
|
||||
Set("last_check_end_time", sq.Expr("now()")).
|
||||
Where(sq.Eq{
|
||||
"id": c.resourceConfigScopeID,
|
||||
})
|
||||
|
||||
if checkError != nil {
|
||||
builder = builder.Set("check_error", checkError.Error())
|
||||
} else {
|
||||
builder = builder.Set("check_error", nil)
|
||||
}
|
||||
|
||||
_, err = builder.
|
||||
RunWith(tx).
|
||||
Exec()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *check) AcquireTrackingLock(logger lager.Logger) (lock.Lock, bool, error) {
|
||||
return c.lockFactory.Acquire(
|
||||
logger,
|
||||
lock.NewResourceConfigCheckingLockID(c.ResourceConfigID()),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *check) AllCheckables() ([]Checkable, error) {
|
||||
var checkables []Checkable
|
||||
|
||||
rows, err := resourcesQuery.
|
||||
Where(sq.Eq{
|
||||
"r.resource_config_scope_id": c.resourceConfigScopeID,
|
||||
}).
|
||||
RunWith(c.conn).
|
||||
Query()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer Close(rows)
|
||||
|
||||
for rows.Next() {
|
||||
r := &resource{
|
||||
conn: c.conn,
|
||||
lockFactory: c.lockFactory,
|
||||
}
|
||||
|
||||
err = scanResource(r, rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
checkables = append(checkables, r)
|
||||
}
|
||||
|
||||
rows, err = resourceTypesQuery.
|
||||
Where(sq.Eq{
|
||||
"ro.id": c.resourceConfigScopeID,
|
||||
}).
|
||||
RunWith(c.conn).
|
||||
Query()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer Close(rows)
|
||||
|
||||
for rows.Next() {
|
||||
r := &resourceType{
|
||||
conn: c.conn,
|
||||
lockFactory: c.lockFactory,
|
||||
}
|
||||
|
||||
err = scanResourceType(r, rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
checkables = append(checkables, r)
|
||||
}
|
||||
|
||||
return checkables, nil
|
||||
}
|
||||
|
||||
func (c *check) SaveVersions(versions []atc.Version) error {
|
||||
return saveVersions(c.conn, c.resourceConfigScopeID, versions)
|
||||
}
|
||||
|
||||
func scanCheck(c *check, row scannable) error {
|
||||
var (
|
||||
createTime, startTime, endTime pq.NullTime
|
||||
schema, plan, nonce, checkError sql.NullString
|
||||
status string
|
||||
teamID, resourceConfigID, baseResourceTypeID sql.NullInt64
|
||||
)
|
||||
|
||||
err := row.Scan(&c.id, &c.resourceConfigScopeID, &status, &schema, &createTime, &startTime, &endTime, &plan, &nonce, &checkError, &teamID, &resourceConfigID, &baseResourceTypeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var noncense *string
|
||||
if nonce.Valid {
|
||||
noncense = &nonce.String
|
||||
}
|
||||
|
||||
es := c.conn.EncryptionStrategy()
|
||||
decryptedPlan, err := es.Decrypt(string(plan.String), noncense)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(decryptedPlan) > 0 {
|
||||
err = json.Unmarshal(decryptedPlan, &c.plan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if checkError.Valid {
|
||||
c.checkError = errors.New(checkError.String)
|
||||
} else {
|
||||
c.checkError = nil
|
||||
}
|
||||
|
||||
c.status = CheckStatus(status)
|
||||
c.schema = schema.String
|
||||
c.createTime = createTime.Time
|
||||
c.startTime = startTime.Time
|
||||
c.endTime = endTime.Time
|
||||
c.teamID = int(teamID.Int64)
|
||||
c.resourceConfigID = int(resourceConfigID.Int64)
|
||||
c.baseResourceTypeID = int(baseResourceTypeID.Int64)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,360 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/lager"
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/creds"
|
||||
"github.com/concourse/concourse/atc/db/lock"
|
||||
)
|
||||
|
||||
//go:generate counterfeiter . Checkable
|
||||
|
||||
type Checkable interface {
|
||||
Name() string
|
||||
TeamID() int
|
||||
TeamName() string
|
||||
PipelineID() int
|
||||
PipelineName() string
|
||||
Type() string
|
||||
Source() atc.Source
|
||||
Tags() atc.Tags
|
||||
CheckEvery() string
|
||||
CheckTimeout() string
|
||||
LastCheckEndTime() time.Time
|
||||
CurrentPinnedVersion() atc.Version
|
||||
|
||||
SetResourceConfig(
|
||||
atc.Source,
|
||||
atc.VersionedResourceTypes,
|
||||
) (ResourceConfigScope, error)
|
||||
|
||||
SetCheckSetupError(error) error
|
||||
}
|
||||
|
||||
//go:generate counterfeiter . CheckFactory
|
||||
|
||||
type CheckFactory interface {
|
||||
Check(int) (Check, bool, error)
|
||||
StartedChecks() ([]Check, error)
|
||||
CreateCheck(int, int, int, int, bool, atc.Plan) (Check, bool, error)
|
||||
TryCreateCheck(Checkable, ResourceTypes, atc.Version, bool) (Check, bool, error)
|
||||
Resources() ([]Resource, error)
|
||||
ResourceTypes() ([]ResourceType, error)
|
||||
AcquireScanningLock(lager.Logger) (lock.Lock, bool, error)
|
||||
NotifyChecker() error
|
||||
}
|
||||
|
||||
type checkFactory struct {
|
||||
conn Conn
|
||||
lockFactory lock.LockFactory
|
||||
|
||||
secrets creds.Secrets
|
||||
defaultCheckTimeout time.Duration
|
||||
}
|
||||
|
||||
func NewCheckFactory(
|
||||
conn Conn,
|
||||
lockFactory lock.LockFactory,
|
||||
secrets creds.Secrets,
|
||||
defaultCheckTimeout time.Duration,
|
||||
) CheckFactory {
|
||||
return &checkFactory{
|
||||
conn: conn,
|
||||
lockFactory: lockFactory,
|
||||
|
||||
secrets: secrets,
|
||||
defaultCheckTimeout: defaultCheckTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *checkFactory) NotifyChecker() error {
|
||||
return c.conn.Bus().Notify("checker")
|
||||
}
|
||||
|
||||
func (c *checkFactory) AcquireScanningLock(
|
||||
logger lager.Logger,
|
||||
) (lock.Lock, bool, error) {
|
||||
return c.lockFactory.Acquire(
|
||||
logger,
|
||||
lock.NewResourceScanningLockID(),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *checkFactory) Check(id int) (Check, bool, error) {
|
||||
check := &check{
|
||||
conn: c.conn,
|
||||
lockFactory: c.lockFactory,
|
||||
}
|
||||
|
||||
row := checksQuery.
|
||||
Where(sq.Eq{"c.id": id}).
|
||||
RunWith(c.conn).
|
||||
QueryRow()
|
||||
|
||||
err := scanCheck(check, row)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return check, true, nil
|
||||
}
|
||||
func (c *checkFactory) StartedChecks() ([]Check, error) {
|
||||
rows, err := checksQuery.
|
||||
Where(sq.Eq{"status": CheckStatusStarted}).
|
||||
OrderBy("c.id").
|
||||
RunWith(c.conn).
|
||||
Query()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var checks []Check
|
||||
|
||||
for rows.Next() {
|
||||
check := &check{conn: c.conn, lockFactory: c.lockFactory}
|
||||
|
||||
err := scanCheck(check, rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
checks = append(checks, check)
|
||||
}
|
||||
|
||||
return checks, nil
|
||||
}
|
||||
|
||||
func (c *checkFactory) TryCreateCheck(checkable Checkable, resourceTypes ResourceTypes, fromVersion atc.Version, manuallyTriggered bool) (Check, bool, error) {
|
||||
|
||||
var err error
|
||||
|
||||
parentType, found := resourceTypes.Parent(checkable)
|
||||
if found {
|
||||
if parentType.Version() == nil {
|
||||
return nil, false, errors.New("parent type has no version")
|
||||
}
|
||||
}
|
||||
|
||||
timeout := c.defaultCheckTimeout
|
||||
if to := checkable.CheckTimeout(); to != "" {
|
||||
timeout, err = time.ParseDuration(to)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
}
|
||||
|
||||
variables := creds.NewVariables(
|
||||
c.secrets,
|
||||
checkable.TeamName(),
|
||||
checkable.PipelineName(),
|
||||
)
|
||||
|
||||
source, err := creds.NewSource(variables, checkable.Source()).Evaluate()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
filteredTypes := resourceTypes.Filter(checkable).Deserialize()
|
||||
versionedResourceTypes, err := creds.NewVersionedResourceTypes(variables, filteredTypes).Evaluate()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
// This could have changed based on new variable interpolation so update it
|
||||
resourceConfigScope, err := checkable.SetResourceConfig(source, versionedResourceTypes)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if fromVersion == nil {
|
||||
rcv, found, err := resourceConfigScope.LatestVersion()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if found {
|
||||
fromVersion = atc.Version(rcv.Version())
|
||||
}
|
||||
}
|
||||
|
||||
plan := atc.Plan{
|
||||
Check: &atc.CheckPlan{
|
||||
Name: checkable.Name(),
|
||||
Type: checkable.Type(),
|
||||
Source: source,
|
||||
Tags: checkable.Tags(),
|
||||
Timeout: timeout.String(),
|
||||
FromVersion: fromVersion,
|
||||
|
||||
VersionedResourceTypes: versionedResourceTypes,
|
||||
},
|
||||
}
|
||||
|
||||
check, created, err := c.CreateCheck(
|
||||
resourceConfigScope.ID(),
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
checkable.TeamID(),
|
||||
manuallyTriggered,
|
||||
plan,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return check, created, nil
|
||||
}
|
||||
|
||||
func (c *checkFactory) CreateCheck(resourceConfigScopeID, resourceConfigID, baseResourceTypeID, teamID int, manuallyTriggered bool, plan atc.Plan) (Check, bool, error) {
|
||||
tx, err := c.conn.Begin()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
defer Rollback(tx)
|
||||
|
||||
planPayload, err := json.Marshal(plan)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
es := c.conn.EncryptionStrategy()
|
||||
encryptedPayload, nonce, err := es.Encrypt(planPayload)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
metadata, err := json.Marshal(map[string]interface{}{
|
||||
"team_id": teamID,
|
||||
"resource_config_id": resourceConfigID,
|
||||
"base_resource_type_id": baseResourceTypeID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
var id int
|
||||
var createTime time.Time
|
||||
err = psql.Insert("checks").
|
||||
Columns(
|
||||
"resource_config_scope_id",
|
||||
"schema",
|
||||
"status",
|
||||
"manually_triggered",
|
||||
"plan",
|
||||
"nonce",
|
||||
"metadata",
|
||||
).
|
||||
Values(
|
||||
resourceConfigScopeID,
|
||||
schema,
|
||||
CheckStatusStarted,
|
||||
manuallyTriggered,
|
||||
encryptedPayload,
|
||||
nonce,
|
||||
metadata,
|
||||
).
|
||||
Suffix(`
|
||||
ON CONFLICT DO NOTHING
|
||||
RETURNING id, create_time
|
||||
`).
|
||||
RunWith(tx).
|
||||
QueryRow().
|
||||
Scan(&id, &createTime)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return &check{
|
||||
id: id,
|
||||
teamID: teamID,
|
||||
resourceConfigScopeID: resourceConfigScopeID,
|
||||
resourceConfigID: resourceConfigID,
|
||||
baseResourceTypeID: baseResourceTypeID,
|
||||
schema: schema,
|
||||
status: CheckStatusStarted,
|
||||
plan: plan,
|
||||
createTime: createTime,
|
||||
|
||||
conn: c.conn,
|
||||
lockFactory: c.lockFactory,
|
||||
}, true, err
|
||||
}
|
||||
|
||||
func (c *checkFactory) Resources() ([]Resource, error) {
|
||||
var resources []Resource
|
||||
|
||||
rows, err := resourcesQuery.
|
||||
Where(sq.Eq{"p.paused": false}).
|
||||
RunWith(c.conn).
|
||||
Query()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer Close(rows)
|
||||
|
||||
for rows.Next() {
|
||||
r := &resource{
|
||||
conn: c.conn,
|
||||
lockFactory: c.lockFactory,
|
||||
}
|
||||
|
||||
err = scanResource(r, rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resources = append(resources, r)
|
||||
}
|
||||
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func (c *checkFactory) ResourceTypes() ([]ResourceType, error) {
|
||||
var resourceTypes []ResourceType
|
||||
|
||||
rows, err := resourceTypesQuery.
|
||||
RunWith(c.conn).
|
||||
Query()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer Close(rows)
|
||||
|
||||
for rows.Next() {
|
||||
r := &resourceType{
|
||||
conn: c.conn,
|
||||
lockFactory: c.lockFactory,
|
||||
}
|
||||
|
||||
err = scanResourceType(r, rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resourceTypes = append(resourceTypes, r)
|
||||
}
|
||||
|
||||
return resourceTypes, nil
|
||||
}
|
|
@ -0,0 +1,481 @@
|
|||
package db_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/dbfakes"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("CheckFactory", func() {
|
||||
|
||||
var (
|
||||
err error
|
||||
resourceConfigScope db.ResourceConfigScope
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
setupTx, err := dbConn.Begin()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
brt := db.BaseResourceType{
|
||||
Name: "some-base-resource-type",
|
||||
}
|
||||
|
||||
_, err = brt.FindOrCreate(setupTx, false)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(setupTx.Commit()).To(Succeed())
|
||||
|
||||
resourceConfigScope, err = defaultResource.SetResourceConfig(atc.Source{"some": "repository"}, atc.VersionedResourceTypes{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
Describe("Check", func() {
|
||||
var created, found bool
|
||||
var check, foundCheck db.Check
|
||||
|
||||
BeforeEach(func() {
|
||||
check, created, err = checkFactory.CreateCheck(
|
||||
resourceConfigScope.ID(),
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
defaultTeam.ID(),
|
||||
false,
|
||||
atc.Plan{Check: &atc.CheckPlan{Name: "some-name", Type: "some-type"}},
|
||||
)
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
foundCheck, found, err = checkFactory.Check(check.ID())
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(found).To(BeTrue())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("returns the db check", func() {
|
||||
Expect(foundCheck).To(Equal(check))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("TryCreateCheck", func() {
|
||||
|
||||
var (
|
||||
created bool
|
||||
check db.Check
|
||||
|
||||
fakeResource *dbfakes.FakeResource
|
||||
fakeResourceType *dbfakes.FakeResourceType
|
||||
fakeResourceTypes []db.ResourceType
|
||||
fromVersion atc.Version
|
||||
manuallyTriggered bool
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fromVersion = atc.Version{"from": "version"}
|
||||
|
||||
fakeResource = new(dbfakes.FakeResource)
|
||||
fakeResource.NameReturns("some-name")
|
||||
fakeResource.TagsReturns([]string{"tag-a", "tag-b"})
|
||||
fakeResource.SourceReturns(atc.Source{"some": "source"})
|
||||
|
||||
fakeResourceType = new(dbfakes.FakeResourceType)
|
||||
fakeResourceType.NameReturns("some-type")
|
||||
fakeResourceType.TypeReturns("some-base-type")
|
||||
fakeResourceType.TagsReturns([]string{"some-tag"})
|
||||
fakeResourceType.SourceReturns(atc.Source{"some": "type-source"})
|
||||
|
||||
fakeResourceTypes = []db.ResourceType{fakeResourceType}
|
||||
manuallyTriggered = true
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
check, created, err = checkFactory.TryCreateCheck(fakeResource, fakeResourceTypes, fromVersion, manuallyTriggered)
|
||||
})
|
||||
|
||||
Context("when the resource parent type is not a custom type", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.TypeReturns("base-type")
|
||||
})
|
||||
|
||||
Context("when the configured timeout is not parseable", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.CheckTimeoutReturns("not-a-duration")
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the configured timeout is parseable", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.CheckTimeoutReturns("10s")
|
||||
})
|
||||
|
||||
Context("when evaluating the source fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.SourceReturns(atc.Source{"some": "((secret))"})
|
||||
fakeSecrets.GetReturns("", nil, false, nil)
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when evaluating the source succeeds", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.SourceReturns(atc.Source{"some": "((secret))"})
|
||||
fakeSecrets.GetReturns("source", nil, true, nil)
|
||||
})
|
||||
|
||||
Context("when evaluating the resource types source fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceType.SourceReturns(atc.Source{"some": "((other-secret))"})
|
||||
fakeSecrets.GetReturns("", nil, false, nil)
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when evaluating the resource types source succeeds", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceType.SourceReturns(atc.Source{"some": "((other-secret))"})
|
||||
fakeSecrets.GetReturns("source", nil, true, nil)
|
||||
})
|
||||
|
||||
Context("when updating the resource config scope fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.SetResourceConfigReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when updating the resource config scope succeeds", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.SetResourceConfigReturns(resourceConfigScope, nil)
|
||||
})
|
||||
|
||||
Context("when fromVersion is not nil", func() {
|
||||
BeforeEach(func() {
|
||||
fromVersion = atc.Version{"version": "a"}
|
||||
})
|
||||
|
||||
It("creates a check", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(check).NotTo(BeNil())
|
||||
})
|
||||
|
||||
It("creates a plan with a version", func() {
|
||||
Expect(check.Plan().Check.FromVersion).To(Equal(atc.Version{"version": "a"}))
|
||||
Expect(check.Plan().Check.Name).To(Equal("some-name"))
|
||||
Expect(check.Plan().Check.Type).To(Equal("base-type"))
|
||||
Expect(check.Plan().Check.Source).To(Equal(atc.Source{"some": "source"}))
|
||||
Expect(check.Plan().Check.Tags).To(ConsistOf("tag-a", "tag-b"))
|
||||
Expect(check.Plan().Check.Timeout).To(Equal("10s"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when fromVersion is nil", func() {
|
||||
BeforeEach(func() {
|
||||
fromVersion = nil
|
||||
})
|
||||
|
||||
Context("when fetching the latest version returns not found", func() {
|
||||
BeforeEach(func() {
|
||||
_, err = dbConn.Exec("DELETE FROM resource_config_versions")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("creates a check", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(check).NotTo(BeNil())
|
||||
})
|
||||
|
||||
It("creates a plan with a nil version", func() {
|
||||
Expect(check.Plan().Check.FromVersion).To(BeNil())
|
||||
Expect(check.Plan().Check.Name).To(Equal("some-name"))
|
||||
Expect(check.Plan().Check.Type).To(Equal("base-type"))
|
||||
Expect(check.Plan().Check.Source).To(Equal(atc.Source{"some": "source"}))
|
||||
Expect(check.Plan().Check.Tags).To(ConsistOf("tag-a", "tag-b"))
|
||||
Expect(check.Plan().Check.Timeout).To(Equal("10s"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when fetching the latest version returns a version", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
err = resourceConfigScope.SaveVersions([]atc.Version{{"some": "version"}})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("creates a check", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(check).NotTo(BeNil())
|
||||
})
|
||||
|
||||
It("creates a plan with a version", func() {
|
||||
Expect(check.Plan().Check.FromVersion).To(Equal(atc.Version{"some": "version"}))
|
||||
Expect(check.Plan().Check.Name).To(Equal("some-name"))
|
||||
Expect(check.Plan().Check.Type).To(Equal("base-type"))
|
||||
Expect(check.Plan().Check.Source).To(Equal(atc.Source{"some": "source"}))
|
||||
Expect(check.Plan().Check.Tags).To(ConsistOf("tag-a", "tag-b"))
|
||||
Expect(check.Plan().Check.Timeout).To(Equal("10s"))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the resource has a parent type", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.TypeReturns("custom-type")
|
||||
fakeResource.PipelineIDReturns(1)
|
||||
fakeResourceType.NameReturns("custom-type")
|
||||
fakeResourceType.PipelineIDReturns(1)
|
||||
|
||||
})
|
||||
|
||||
Context("when the resource and type are properly configured", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceType.LastCheckEndTimeReturns(time.Now().Add(-time.Hour))
|
||||
fakeResource.LastCheckEndTimeReturns(time.Now().Add(-time.Hour))
|
||||
|
||||
fakeResource.SetResourceConfigReturns(resourceConfigScope, nil)
|
||||
})
|
||||
|
||||
Context("when the parent type has no version", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceType.VersionReturns(nil)
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the parent type has a version", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceType.VersionReturns(atc.Version{"some": "version"})
|
||||
})
|
||||
|
||||
It("creates a check", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(check).NotTo(BeNil())
|
||||
})
|
||||
|
||||
It("creates a plan for the resource", func() {
|
||||
Expect(check.Plan().Check.FromVersion).To(Equal(atc.Version{"from": "version"}))
|
||||
Expect(check.Plan().Check.Name).To(Equal("some-name"))
|
||||
Expect(check.Plan().Check.Type).To(Equal("custom-type"))
|
||||
Expect(check.Plan().Check.Source).To(Equal(atc.Source{"some": "source"}))
|
||||
Expect(check.Plan().Check.Tags).To(ConsistOf("tag-a", "tag-b"))
|
||||
Expect(check.Plan().Check.Timeout).To(Equal("1m0s"))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("CreateCheck", func() {
|
||||
var created bool
|
||||
var check db.Check
|
||||
|
||||
JustBeforeEach(func() {
|
||||
check, created, err = checkFactory.CreateCheck(
|
||||
resourceConfigScope.ID(),
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
defaultTeam.ID(),
|
||||
false,
|
||||
atc.Plan{Check: &atc.CheckPlan{Name: "some-name", Type: "some-type"}},
|
||||
)
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("returns the resource check", func() {
|
||||
Expect(check.ID()).To(Equal(1))
|
||||
Expect(check.TeamID()).To(Equal(defaultTeam.ID()))
|
||||
Expect(check.Status()).To(Equal(db.CheckStatusStarted))
|
||||
Expect(check.Schema()).To(Equal("exec.v2"))
|
||||
Expect(check.Plan().Check.Name).To(Equal("some-name"))
|
||||
Expect(check.Plan().Check.Type).To(Equal("some-type"))
|
||||
Expect(check.CreateTime()).To(BeTemporally("~", time.Now(), time.Second))
|
||||
Expect(check.ResourceConfigScopeID()).To(Equal(resourceConfigScope.ID()))
|
||||
Expect(check.ResourceConfigID()).To(Equal(resourceConfigScope.ResourceConfig().ID()))
|
||||
Expect(check.BaseResourceTypeID()).To(Equal(resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID))
|
||||
})
|
||||
|
||||
Context("when a check is already pending", func() {
|
||||
BeforeEach(func() {
|
||||
_, created, err := checkFactory.CreateCheck(
|
||||
resourceConfigScope.ID(),
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
defaultTeam.ID(),
|
||||
false,
|
||||
atc.Plan{},
|
||||
)
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("doesn't create a check", func() {
|
||||
Expect(created).To(BeFalse())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("StartedChecks", func() {
|
||||
var (
|
||||
checks []db.Check
|
||||
)
|
||||
|
||||
JustBeforeEach(func() {
|
||||
checks, err = checkFactory.StartedChecks()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
Context("when looking up the resource check returns no results", func() {
|
||||
BeforeEach(func() {
|
||||
_, err = dbConn.Exec(`DELETE FROM checks`)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("is not found", func() {
|
||||
Expect(checks).To(HaveLen(0))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when a check has no metadata", func() {
|
||||
BeforeEach(func() {
|
||||
_, err = dbConn.Exec(`INSERT INTO checks(resource_config_scope_id, status, schema) VALUES ($1, 'started', 'some-schema')`, resourceConfigScope.ID())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("returns the check", func() {
|
||||
Expect(checks).To(HaveLen(1))
|
||||
Expect(checks[0].ID()).To(Equal(1))
|
||||
Expect(checks[0].Status()).To(Equal(db.CheckStatusStarted))
|
||||
Expect(checks[0].Schema()).To(Equal("some-schema"))
|
||||
Expect(checks[0].TeamID()).To(Equal(0))
|
||||
Expect(checks[0].ResourceConfigScopeID()).To(Equal(resourceConfigScope.ID()))
|
||||
Expect(checks[0].ResourceConfigID()).To(Equal(0))
|
||||
Expect(checks[0].BaseResourceTypeID()).To(Equal(0))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when looking up the resource check succeeds", func() {
|
||||
var check db.Check
|
||||
|
||||
BeforeEach(func() {
|
||||
var created bool
|
||||
check, created, err = checkFactory.CreateCheck(
|
||||
resourceConfigScope.ID(),
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
defaultTeam.ID(),
|
||||
false,
|
||||
atc.Plan{},
|
||||
)
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("returns the resource checks", func() {
|
||||
Expect(checks).To(HaveLen(1))
|
||||
Expect(checks[0]).To(Equal(check))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Resources", func() {
|
||||
var (
|
||||
resources []db.Resource
|
||||
)
|
||||
|
||||
JustBeforeEach(func() {
|
||||
resources, err = checkFactory.Resources()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("include resources in return", func() {
|
||||
Expect(resources).To(HaveLen(1))
|
||||
Expect(resources[0].Name()).To(Equal("some-resource"))
|
||||
})
|
||||
|
||||
Context("when the resource is not active", func() {
|
||||
BeforeEach(func() {
|
||||
_, err = dbConn.Exec(`UPDATE resources SET active = false`)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("does not return the resource", func() {
|
||||
Expect(resources).To(HaveLen(0))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the resource pipeline is paused", func() {
|
||||
BeforeEach(func() {
|
||||
_, err = dbConn.Exec(`UPDATE pipelines SET paused = true`)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("does not return the resource", func() {
|
||||
Expect(resources).To(HaveLen(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("ResourceTypes", func() {
|
||||
var (
|
||||
resourceTypes db.ResourceTypes
|
||||
)
|
||||
|
||||
JustBeforeEach(func() {
|
||||
resourceTypes, err = checkFactory.ResourceTypes()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("include resource types in return", func() {
|
||||
Expect(resourceTypes).To(HaveLen(1))
|
||||
Expect(resourceTypes[0].Name()).To(Equal("some-type"))
|
||||
})
|
||||
|
||||
Context("when the resource type is not active", func() {
|
||||
BeforeEach(func() {
|
||||
_, err = dbConn.Exec(`UPDATE resource_types SET active = false`)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("does not return the resource type", func() {
|
||||
Expect(resourceTypes).To(HaveLen(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,41 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
)
|
||||
|
||||
//go:generate counterfeiter . CheckLifecycle
|
||||
|
||||
type CheckLifecycle interface {
|
||||
RemoveExpiredChecks(time.Duration) error
|
||||
}
|
||||
|
||||
type checkLifecycle struct {
|
||||
conn Conn
|
||||
}
|
||||
|
||||
func NewCheckLifecycle(conn Conn) *checkLifecycle {
|
||||
return &checkLifecycle{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
func (lifecycle *checkLifecycle) RemoveExpiredChecks(recyclePeriod time.Duration) error {
|
||||
|
||||
_, err := psql.Delete("checks").
|
||||
Where(
|
||||
sq.And{
|
||||
sq.Gt{
|
||||
"Now() - create_time": fmt.Sprintf("%.0f seconds", recyclePeriod.Seconds()),
|
||||
},
|
||||
sq.NotEq{"status": CheckStatusStarted},
|
||||
},
|
||||
).
|
||||
RunWith(lifecycle.conn).
|
||||
Exec()
|
||||
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package db_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("CheckLifecycle", func() {
|
||||
var checkLifecycle db.CheckLifecycle
|
||||
|
||||
BeforeEach(func() {
|
||||
checkLifecycle = db.NewCheckLifecycle(dbConn)
|
||||
})
|
||||
|
||||
Describe("RemoveExpiredChecks", func() {
|
||||
JustBeforeEach(func() {
|
||||
err := checkLifecycle.RemoveExpiredChecks(time.Hour * 24)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
Context("removes checks created more than 24 hours ago", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
_, err := dbConn.Exec("INSERT INTO checks(schema, status, create_time) VALUES('some-schema', 'succeeded', NOW() - '25 hours'::interval)")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("removes the record", func() {
|
||||
var count int
|
||||
err := dbConn.QueryRow("SELECT count(*) from checks").Scan(&count)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(count).To(Equal(0))
|
||||
})
|
||||
})
|
||||
|
||||
Context("doesn't remove check is not finished", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
_, err := dbConn.Exec("INSERT INTO checks(schema, status, create_time) VALUES('some-schema', 'started', NOW() - '25 hours'::interval)")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("does not remove the record", func() {
|
||||
var count int
|
||||
err := dbConn.QueryRow("SELECT count(*) from checks").Scan(&count)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(count).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("keeps checks for 24 hours", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
_, err := dbConn.Exec("INSERT INTO checks(schema, status, create_time) VALUES('some-schema', 'succeeded', NOW() - '25 hours'::interval)")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
_, err = dbConn.Exec("INSERT INTO checks(schema, status, create_time) VALUES('some-schema', 'succeeded', NOW() - '23 hours'::interval)")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("does not remove the record", func() {
|
||||
var count int
|
||||
err := dbConn.QueryRow("SELECT count(*) from checks").Scan(&count)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(count).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,197 @@
|
|||
package db_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Check", func() {
|
||||
var (
|
||||
err error
|
||||
created bool
|
||||
check db.Check
|
||||
resourceConfigScope db.ResourceConfigScope
|
||||
resourceTypeConfigScope db.ResourceConfigScope
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
|
||||
setupTx, err := dbConn.Begin()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
brt := db.BaseResourceType{
|
||||
Name: "some-base-resource-type",
|
||||
}
|
||||
|
||||
_, err = brt.FindOrCreate(setupTx, false)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(setupTx.Commit()).To(Succeed())
|
||||
|
||||
resourceConfigScope, err = defaultResource.SetResourceConfig(atc.Source{"some": "repository"}, atc.VersionedResourceTypes{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resourceTypeConfigScope, err = defaultResourceType.SetResourceConfig(atc.Source{"some": "type-repository"}, atc.VersionedResourceTypes{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
check, created, err = checkFactory.CreateCheck(
|
||||
resourceConfigScope.ID(),
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
defaultTeam.ID(),
|
||||
false,
|
||||
atc.Plan{},
|
||||
)
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
Describe("Start", func() {
|
||||
JustBeforeEach(func() {
|
||||
err = check.Start()
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("starts the check", func() {
|
||||
check.Reload()
|
||||
|
||||
Expect(check.StartTime()).To(BeTemporally("~", time.Now(), time.Second))
|
||||
})
|
||||
|
||||
It("updates resource last check start time", func() {
|
||||
defaultResource.Reload()
|
||||
|
||||
Expect(defaultResource.LastCheckStartTime()).To(BeTemporally("~", time.Now(), time.Second))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Finish", func() {
|
||||
JustBeforeEach(func() {
|
||||
err = check.Finish()
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("finishes the check", func() {
|
||||
check.Reload()
|
||||
|
||||
Expect(check.Status()).To(Equal(db.CheckStatusSucceeded))
|
||||
Expect(check.EndTime()).To(BeTemporally("~", time.Now(), time.Second))
|
||||
Expect(check.CheckError()).To(BeNil())
|
||||
})
|
||||
|
||||
It("updates resource last check end time", func() {
|
||||
defaultResource.Reload()
|
||||
|
||||
Expect(defaultResource.LastCheckEndTime()).To(BeTemporally("~", time.Now(), time.Second))
|
||||
})
|
||||
|
||||
It("clears out the check error", func() {
|
||||
defaultResource.Reload()
|
||||
|
||||
Expect(defaultResource.CheckError()).To(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("FinishWithError", func() {
|
||||
JustBeforeEach(func() {
|
||||
err = check.FinishWithError(errors.New("nope"))
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("finishes the check", func() {
|
||||
check.Reload()
|
||||
|
||||
Expect(check.Status()).To(Equal(db.CheckStatusErrored))
|
||||
Expect(check.EndTime()).To(BeTemporally("~", time.Now(), time.Second))
|
||||
Expect(check.CheckError()).To(Equal(errors.New("nope")))
|
||||
})
|
||||
|
||||
It("updates resource last check end time", func() {
|
||||
defaultResource.Reload()
|
||||
|
||||
Expect(defaultResource.LastCheckEndTime()).To(BeTemporally("~", time.Now(), time.Second))
|
||||
Expect(defaultResource.CheckError()).To(Equal(errors.New("nope")))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("AllCheckables", func() {
|
||||
var checkables []db.Checkable
|
||||
|
||||
Context("with resources", func() {
|
||||
JustBeforeEach(func() {
|
||||
checkables, err = check.AllCheckables()
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("includes any resources that point to the scope", func() {
|
||||
defaultResource.Reload()
|
||||
|
||||
Expect(checkables).To(HaveLen(1))
|
||||
Expect(checkables[0]).To(Equal(defaultResource))
|
||||
})
|
||||
})
|
||||
|
||||
Context("with resource types", func() {
|
||||
BeforeEach(func() {
|
||||
check, created, err = checkFactory.CreateCheck(
|
||||
resourceTypeConfigScope.ID(),
|
||||
resourceTypeConfigScope.ResourceConfig().ID(),
|
||||
resourceTypeConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
defaultTeam.ID(),
|
||||
false,
|
||||
atc.Plan{},
|
||||
)
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
checkables, err = check.AllCheckables()
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("includes any resource type that point to the scope", func() {
|
||||
defaultResourceType.Reload()
|
||||
|
||||
Expect(checkables).To(HaveLen(1))
|
||||
Expect(checkables[0]).To(Equal(defaultResourceType))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("SaveVersions", func() {
|
||||
JustBeforeEach(func() {
|
||||
err = check.SaveVersions([]atc.Version{{"some": "version"}})
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("saves the versions on the resource config scope", func() {
|
||||
version, found, err := resourceConfigScope.LatestVersion()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(found).To(BeTrue())
|
||||
Expect(version.Version()).To(Equal(db.Version{"some": "version"}))
|
||||
})
|
||||
})
|
||||
})
|
|
@ -125,18 +125,21 @@ func (c buildStepContainerOwner) sqlMap() map[string]interface{} {
|
|||
// worker base resource type disappear, or the expiry is reached, the container
|
||||
// can be removed.
|
||||
func NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig ResourceConfig,
|
||||
resourceConfigID int,
|
||||
baseResourceTypeID int,
|
||||
expiries ContainerOwnerExpiries,
|
||||
) ContainerOwner {
|
||||
return resourceConfigCheckSessionContainerOwner{
|
||||
resourceConfig: resourceConfig,
|
||||
expiries: expiries,
|
||||
resourceConfigID: resourceConfigID,
|
||||
baseResourceTypeID: baseResourceTypeID,
|
||||
expiries: expiries,
|
||||
}
|
||||
}
|
||||
|
||||
type resourceConfigCheckSessionContainerOwner struct {
|
||||
resourceConfig ResourceConfig
|
||||
expiries ContainerOwnerExpiries
|
||||
resourceConfigID int
|
||||
baseResourceTypeID int
|
||||
expiries ContainerOwnerExpiries
|
||||
}
|
||||
|
||||
type ContainerOwnerExpiries struct {
|
||||
|
@ -149,7 +152,7 @@ func (c resourceConfigCheckSessionContainerOwner) Find(conn Conn) (sq.Eq, bool,
|
|||
rows, err := psql.Select("id").
|
||||
From("resource_config_check_sessions").
|
||||
Where(sq.And{
|
||||
sq.Eq{"resource_config_id": c.resourceConfig.ID()},
|
||||
sq.Eq{"resource_config_id": c.resourceConfigID},
|
||||
sq.Expr("expires_at > NOW()"),
|
||||
}).
|
||||
RunWith(conn).
|
||||
|
@ -183,7 +186,7 @@ func (c resourceConfigCheckSessionContainerOwner) Create(tx Tx, workerName strin
|
|||
From("worker_base_resource_types").
|
||||
Where(sq.Eq{
|
||||
"worker_name": workerName,
|
||||
"base_resource_type_id": c.resourceConfig.OriginBaseResourceType().ID,
|
||||
"base_resource_type_id": c.baseResourceTypeID,
|
||||
}).
|
||||
Suffix("FOR SHARE").
|
||||
RunWith(tx).
|
||||
|
@ -202,7 +205,7 @@ func (c resourceConfigCheckSessionContainerOwner) Create(tx Tx, workerName strin
|
|||
var rccsID int
|
||||
err = psql.Insert("resource_config_check_sessions").
|
||||
SetMap(map[string]interface{}{
|
||||
"resource_config_id": c.resourceConfig.ID(),
|
||||
"resource_config_id": c.resourceConfigID,
|
||||
"worker_base_resource_type_id": wbrtID,
|
||||
"expires_at": sq.Expr("(SELECT " + expiryStmt + " FROM workers)"),
|
||||
}).
|
||||
|
@ -211,7 +214,7 @@ func (c resourceConfigCheckSessionContainerOwner) Create(tx Tx, workerName strin
|
|||
resource_config_id = ?,
|
||||
worker_base_resource_type_id = ?
|
||||
RETURNING id
|
||||
`, c.resourceConfig.ID(), wbrtID).
|
||||
`, c.resourceConfigID, wbrtID).
|
||||
RunWith(tx).
|
||||
QueryRow().
|
||||
Scan(&rccsID)
|
||||
|
|
|
@ -52,7 +52,8 @@ var _ = Describe("ContainerOwner", func() {
|
|||
|
||||
JustBeforeEach(func() {
|
||||
owner = db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig,
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
ownerExpiries,
|
||||
)
|
||||
})
|
||||
|
@ -71,7 +72,8 @@ var _ = Describe("ContainerOwner", func() {
|
|||
|
||||
BeforeEach(func() {
|
||||
existingOwner := db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig,
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
ownerExpiries,
|
||||
)
|
||||
|
||||
|
@ -97,7 +99,8 @@ var _ = Describe("ContainerOwner", func() {
|
|||
|
||||
BeforeEach(func() {
|
||||
existingOwner := db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig,
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
ownerExpiries,
|
||||
)
|
||||
|
||||
|
|
|
@ -34,7 +34,14 @@ var _ = Describe("ContainerRepository", func() {
|
|||
)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
creatingContainer, err = defaultWorker.CreateContainer(db.NewResourceConfigCheckSessionContainerOwner(resourceConfig, expiries), fullMetadata)
|
||||
creatingContainer, err = defaultWorker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
fullMetadata,
|
||||
)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/creds/credsfakes"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/lock"
|
||||
"github.com/concourse/concourse/atc/metric"
|
||||
|
@ -29,6 +30,7 @@ var (
|
|||
dbProcess ifrit.Process
|
||||
|
||||
dbConn db.Conn
|
||||
fakeSecrets *credsfakes.FakeSecrets
|
||||
buildFactory db.BuildFactory
|
||||
volumeRepository db.VolumeRepository
|
||||
containerRepository db.ContainerRepository
|
||||
|
@ -39,6 +41,7 @@ var (
|
|||
resourceConfigFactory db.ResourceConfigFactory
|
||||
resourceCacheFactory db.ResourceCacheFactory
|
||||
taskCacheFactory db.TaskCacheFactory
|
||||
checkFactory db.CheckFactory
|
||||
workerBaseResourceTypeFactory db.WorkerBaseResourceTypeFactory
|
||||
workerTaskCacheFactory db.WorkerTaskCacheFactory
|
||||
userFactory db.UserFactory
|
||||
|
@ -94,6 +97,7 @@ var _ = BeforeEach(func() {
|
|||
|
||||
lockFactory = lock.NewLockFactory(postgresRunner.OpenSingleton(), metric.LogLockAcquired, metric.LogLockReleased)
|
||||
|
||||
fakeSecrets = new(credsfakes.FakeSecrets)
|
||||
buildFactory = db.NewBuildFactory(dbConn, lockFactory, 5*time.Minute)
|
||||
volumeRepository = db.NewVolumeRepository(dbConn)
|
||||
containerRepository = db.NewContainerRepository(dbConn)
|
||||
|
@ -104,6 +108,7 @@ var _ = BeforeEach(func() {
|
|||
resourceConfigFactory = db.NewResourceConfigFactory(dbConn, lockFactory)
|
||||
resourceCacheFactory = db.NewResourceCacheFactory(dbConn, lockFactory)
|
||||
taskCacheFactory = db.NewTaskCacheFactory(dbConn)
|
||||
checkFactory = db.NewCheckFactory(dbConn, lockFactory, fakeSecrets, time.Minute)
|
||||
workerBaseResourceTypeFactory = db.NewWorkerBaseResourceTypeFactory(dbConn)
|
||||
workerTaskCacheFactory = db.NewWorkerTaskCacheFactory(dbConn)
|
||||
userFactory = db.NewUserFactory(dbConn)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,659 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package dbfakes
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/lock"
|
||||
)
|
||||
|
||||
type FakeCheckFactory struct {
|
||||
AcquireScanningLockStub func(lager.Logger) (lock.Lock, bool, error)
|
||||
acquireScanningLockMutex sync.RWMutex
|
||||
acquireScanningLockArgsForCall []struct {
|
||||
arg1 lager.Logger
|
||||
}
|
||||
acquireScanningLockReturns struct {
|
||||
result1 lock.Lock
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
acquireScanningLockReturnsOnCall map[int]struct {
|
||||
result1 lock.Lock
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
CheckStub func(int) (db.Check, bool, error)
|
||||
checkMutex sync.RWMutex
|
||||
checkArgsForCall []struct {
|
||||
arg1 int
|
||||
}
|
||||
checkReturns struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
checkReturnsOnCall map[int]struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
CreateCheckStub func(int, int, int, int, bool, atc.Plan) (db.Check, bool, error)
|
||||
createCheckMutex sync.RWMutex
|
||||
createCheckArgsForCall []struct {
|
||||
arg1 int
|
||||
arg2 int
|
||||
arg3 int
|
||||
arg4 int
|
||||
arg5 bool
|
||||
arg6 atc.Plan
|
||||
}
|
||||
createCheckReturns struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
createCheckReturnsOnCall map[int]struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
NotifyCheckerStub func() error
|
||||
notifyCheckerMutex sync.RWMutex
|
||||
notifyCheckerArgsForCall []struct {
|
||||
}
|
||||
notifyCheckerReturns struct {
|
||||
result1 error
|
||||
}
|
||||
notifyCheckerReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
ResourceTypesStub func() ([]db.ResourceType, error)
|
||||
resourceTypesMutex sync.RWMutex
|
||||
resourceTypesArgsForCall []struct {
|
||||
}
|
||||
resourceTypesReturns struct {
|
||||
result1 []db.ResourceType
|
||||
result2 error
|
||||
}
|
||||
resourceTypesReturnsOnCall map[int]struct {
|
||||
result1 []db.ResourceType
|
||||
result2 error
|
||||
}
|
||||
ResourcesStub func() ([]db.Resource, error)
|
||||
resourcesMutex sync.RWMutex
|
||||
resourcesArgsForCall []struct {
|
||||
}
|
||||
resourcesReturns struct {
|
||||
result1 []db.Resource
|
||||
result2 error
|
||||
}
|
||||
resourcesReturnsOnCall map[int]struct {
|
||||
result1 []db.Resource
|
||||
result2 error
|
||||
}
|
||||
StartedChecksStub func() ([]db.Check, error)
|
||||
startedChecksMutex sync.RWMutex
|
||||
startedChecksArgsForCall []struct {
|
||||
}
|
||||
startedChecksReturns struct {
|
||||
result1 []db.Check
|
||||
result2 error
|
||||
}
|
||||
startedChecksReturnsOnCall map[int]struct {
|
||||
result1 []db.Check
|
||||
result2 error
|
||||
}
|
||||
TryCreateCheckStub func(db.Checkable, db.ResourceTypes, atc.Version, bool) (db.Check, bool, error)
|
||||
tryCreateCheckMutex sync.RWMutex
|
||||
tryCreateCheckArgsForCall []struct {
|
||||
arg1 db.Checkable
|
||||
arg2 db.ResourceTypes
|
||||
arg3 atc.Version
|
||||
arg4 bool
|
||||
}
|
||||
tryCreateCheckReturns struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
tryCreateCheckReturnsOnCall map[int]struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) AcquireScanningLock(arg1 lager.Logger) (lock.Lock, bool, error) {
|
||||
fake.acquireScanningLockMutex.Lock()
|
||||
ret, specificReturn := fake.acquireScanningLockReturnsOnCall[len(fake.acquireScanningLockArgsForCall)]
|
||||
fake.acquireScanningLockArgsForCall = append(fake.acquireScanningLockArgsForCall, struct {
|
||||
arg1 lager.Logger
|
||||
}{arg1})
|
||||
fake.recordInvocation("AcquireScanningLock", []interface{}{arg1})
|
||||
fake.acquireScanningLockMutex.Unlock()
|
||||
if fake.AcquireScanningLockStub != nil {
|
||||
return fake.AcquireScanningLockStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2, ret.result3
|
||||
}
|
||||
fakeReturns := fake.acquireScanningLockReturns
|
||||
return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) AcquireScanningLockCallCount() int {
|
||||
fake.acquireScanningLockMutex.RLock()
|
||||
defer fake.acquireScanningLockMutex.RUnlock()
|
||||
return len(fake.acquireScanningLockArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) AcquireScanningLockCalls(stub func(lager.Logger) (lock.Lock, bool, error)) {
|
||||
fake.acquireScanningLockMutex.Lock()
|
||||
defer fake.acquireScanningLockMutex.Unlock()
|
||||
fake.AcquireScanningLockStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) AcquireScanningLockArgsForCall(i int) lager.Logger {
|
||||
fake.acquireScanningLockMutex.RLock()
|
||||
defer fake.acquireScanningLockMutex.RUnlock()
|
||||
argsForCall := fake.acquireScanningLockArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) AcquireScanningLockReturns(result1 lock.Lock, result2 bool, result3 error) {
|
||||
fake.acquireScanningLockMutex.Lock()
|
||||
defer fake.acquireScanningLockMutex.Unlock()
|
||||
fake.AcquireScanningLockStub = nil
|
||||
fake.acquireScanningLockReturns = struct {
|
||||
result1 lock.Lock
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) AcquireScanningLockReturnsOnCall(i int, result1 lock.Lock, result2 bool, result3 error) {
|
||||
fake.acquireScanningLockMutex.Lock()
|
||||
defer fake.acquireScanningLockMutex.Unlock()
|
||||
fake.AcquireScanningLockStub = nil
|
||||
if fake.acquireScanningLockReturnsOnCall == nil {
|
||||
fake.acquireScanningLockReturnsOnCall = make(map[int]struct {
|
||||
result1 lock.Lock
|
||||
result2 bool
|
||||
result3 error
|
||||
})
|
||||
}
|
||||
fake.acquireScanningLockReturnsOnCall[i] = struct {
|
||||
result1 lock.Lock
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) Check(arg1 int) (db.Check, bool, error) {
|
||||
fake.checkMutex.Lock()
|
||||
ret, specificReturn := fake.checkReturnsOnCall[len(fake.checkArgsForCall)]
|
||||
fake.checkArgsForCall = append(fake.checkArgsForCall, struct {
|
||||
arg1 int
|
||||
}{arg1})
|
||||
fake.recordInvocation("Check", []interface{}{arg1})
|
||||
fake.checkMutex.Unlock()
|
||||
if fake.CheckStub != nil {
|
||||
return fake.CheckStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2, ret.result3
|
||||
}
|
||||
fakeReturns := fake.checkReturns
|
||||
return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CheckCallCount() int {
|
||||
fake.checkMutex.RLock()
|
||||
defer fake.checkMutex.RUnlock()
|
||||
return len(fake.checkArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CheckCalls(stub func(int) (db.Check, bool, error)) {
|
||||
fake.checkMutex.Lock()
|
||||
defer fake.checkMutex.Unlock()
|
||||
fake.CheckStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CheckArgsForCall(i int) int {
|
||||
fake.checkMutex.RLock()
|
||||
defer fake.checkMutex.RUnlock()
|
||||
argsForCall := fake.checkArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CheckReturns(result1 db.Check, result2 bool, result3 error) {
|
||||
fake.checkMutex.Lock()
|
||||
defer fake.checkMutex.Unlock()
|
||||
fake.CheckStub = nil
|
||||
fake.checkReturns = struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CheckReturnsOnCall(i int, result1 db.Check, result2 bool, result3 error) {
|
||||
fake.checkMutex.Lock()
|
||||
defer fake.checkMutex.Unlock()
|
||||
fake.CheckStub = nil
|
||||
if fake.checkReturnsOnCall == nil {
|
||||
fake.checkReturnsOnCall = make(map[int]struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
})
|
||||
}
|
||||
fake.checkReturnsOnCall[i] = struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CreateCheck(arg1 int, arg2 int, arg3 int, arg4 int, arg5 bool, arg6 atc.Plan) (db.Check, bool, error) {
|
||||
fake.createCheckMutex.Lock()
|
||||
ret, specificReturn := fake.createCheckReturnsOnCall[len(fake.createCheckArgsForCall)]
|
||||
fake.createCheckArgsForCall = append(fake.createCheckArgsForCall, struct {
|
||||
arg1 int
|
||||
arg2 int
|
||||
arg3 int
|
||||
arg4 int
|
||||
arg5 bool
|
||||
arg6 atc.Plan
|
||||
}{arg1, arg2, arg3, arg4, arg5, arg6})
|
||||
fake.recordInvocation("CreateCheck", []interface{}{arg1, arg2, arg3, arg4, arg5, arg6})
|
||||
fake.createCheckMutex.Unlock()
|
||||
if fake.CreateCheckStub != nil {
|
||||
return fake.CreateCheckStub(arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2, ret.result3
|
||||
}
|
||||
fakeReturns := fake.createCheckReturns
|
||||
return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CreateCheckCallCount() int {
|
||||
fake.createCheckMutex.RLock()
|
||||
defer fake.createCheckMutex.RUnlock()
|
||||
return len(fake.createCheckArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CreateCheckCalls(stub func(int, int, int, int, bool, atc.Plan) (db.Check, bool, error)) {
|
||||
fake.createCheckMutex.Lock()
|
||||
defer fake.createCheckMutex.Unlock()
|
||||
fake.CreateCheckStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CreateCheckArgsForCall(i int) (int, int, int, int, bool, atc.Plan) {
|
||||
fake.createCheckMutex.RLock()
|
||||
defer fake.createCheckMutex.RUnlock()
|
||||
argsForCall := fake.createCheckArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5, argsForCall.arg6
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CreateCheckReturns(result1 db.Check, result2 bool, result3 error) {
|
||||
fake.createCheckMutex.Lock()
|
||||
defer fake.createCheckMutex.Unlock()
|
||||
fake.CreateCheckStub = nil
|
||||
fake.createCheckReturns = struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) CreateCheckReturnsOnCall(i int, result1 db.Check, result2 bool, result3 error) {
|
||||
fake.createCheckMutex.Lock()
|
||||
defer fake.createCheckMutex.Unlock()
|
||||
fake.CreateCheckStub = nil
|
||||
if fake.createCheckReturnsOnCall == nil {
|
||||
fake.createCheckReturnsOnCall = make(map[int]struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
})
|
||||
}
|
||||
fake.createCheckReturnsOnCall[i] = struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) NotifyChecker() error {
|
||||
fake.notifyCheckerMutex.Lock()
|
||||
ret, specificReturn := fake.notifyCheckerReturnsOnCall[len(fake.notifyCheckerArgsForCall)]
|
||||
fake.notifyCheckerArgsForCall = append(fake.notifyCheckerArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("NotifyChecker", []interface{}{})
|
||||
fake.notifyCheckerMutex.Unlock()
|
||||
if fake.NotifyCheckerStub != nil {
|
||||
return fake.NotifyCheckerStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.notifyCheckerReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) NotifyCheckerCallCount() int {
|
||||
fake.notifyCheckerMutex.RLock()
|
||||
defer fake.notifyCheckerMutex.RUnlock()
|
||||
return len(fake.notifyCheckerArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) NotifyCheckerCalls(stub func() error) {
|
||||
fake.notifyCheckerMutex.Lock()
|
||||
defer fake.notifyCheckerMutex.Unlock()
|
||||
fake.NotifyCheckerStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) NotifyCheckerReturns(result1 error) {
|
||||
fake.notifyCheckerMutex.Lock()
|
||||
defer fake.notifyCheckerMutex.Unlock()
|
||||
fake.NotifyCheckerStub = nil
|
||||
fake.notifyCheckerReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) NotifyCheckerReturnsOnCall(i int, result1 error) {
|
||||
fake.notifyCheckerMutex.Lock()
|
||||
defer fake.notifyCheckerMutex.Unlock()
|
||||
fake.NotifyCheckerStub = nil
|
||||
if fake.notifyCheckerReturnsOnCall == nil {
|
||||
fake.notifyCheckerReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.notifyCheckerReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourceTypes() ([]db.ResourceType, error) {
|
||||
fake.resourceTypesMutex.Lock()
|
||||
ret, specificReturn := fake.resourceTypesReturnsOnCall[len(fake.resourceTypesArgsForCall)]
|
||||
fake.resourceTypesArgsForCall = append(fake.resourceTypesArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("ResourceTypes", []interface{}{})
|
||||
fake.resourceTypesMutex.Unlock()
|
||||
if fake.ResourceTypesStub != nil {
|
||||
return fake.ResourceTypesStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
fakeReturns := fake.resourceTypesReturns
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourceTypesCallCount() int {
|
||||
fake.resourceTypesMutex.RLock()
|
||||
defer fake.resourceTypesMutex.RUnlock()
|
||||
return len(fake.resourceTypesArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourceTypesCalls(stub func() ([]db.ResourceType, error)) {
|
||||
fake.resourceTypesMutex.Lock()
|
||||
defer fake.resourceTypesMutex.Unlock()
|
||||
fake.ResourceTypesStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourceTypesReturns(result1 []db.ResourceType, result2 error) {
|
||||
fake.resourceTypesMutex.Lock()
|
||||
defer fake.resourceTypesMutex.Unlock()
|
||||
fake.ResourceTypesStub = nil
|
||||
fake.resourceTypesReturns = struct {
|
||||
result1 []db.ResourceType
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourceTypesReturnsOnCall(i int, result1 []db.ResourceType, result2 error) {
|
||||
fake.resourceTypesMutex.Lock()
|
||||
defer fake.resourceTypesMutex.Unlock()
|
||||
fake.ResourceTypesStub = nil
|
||||
if fake.resourceTypesReturnsOnCall == nil {
|
||||
fake.resourceTypesReturnsOnCall = make(map[int]struct {
|
||||
result1 []db.ResourceType
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.resourceTypesReturnsOnCall[i] = struct {
|
||||
result1 []db.ResourceType
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) Resources() ([]db.Resource, error) {
|
||||
fake.resourcesMutex.Lock()
|
||||
ret, specificReturn := fake.resourcesReturnsOnCall[len(fake.resourcesArgsForCall)]
|
||||
fake.resourcesArgsForCall = append(fake.resourcesArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("Resources", []interface{}{})
|
||||
fake.resourcesMutex.Unlock()
|
||||
if fake.ResourcesStub != nil {
|
||||
return fake.ResourcesStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
fakeReturns := fake.resourcesReturns
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourcesCallCount() int {
|
||||
fake.resourcesMutex.RLock()
|
||||
defer fake.resourcesMutex.RUnlock()
|
||||
return len(fake.resourcesArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourcesCalls(stub func() ([]db.Resource, error)) {
|
||||
fake.resourcesMutex.Lock()
|
||||
defer fake.resourcesMutex.Unlock()
|
||||
fake.ResourcesStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourcesReturns(result1 []db.Resource, result2 error) {
|
||||
fake.resourcesMutex.Lock()
|
||||
defer fake.resourcesMutex.Unlock()
|
||||
fake.ResourcesStub = nil
|
||||
fake.resourcesReturns = struct {
|
||||
result1 []db.Resource
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) ResourcesReturnsOnCall(i int, result1 []db.Resource, result2 error) {
|
||||
fake.resourcesMutex.Lock()
|
||||
defer fake.resourcesMutex.Unlock()
|
||||
fake.ResourcesStub = nil
|
||||
if fake.resourcesReturnsOnCall == nil {
|
||||
fake.resourcesReturnsOnCall = make(map[int]struct {
|
||||
result1 []db.Resource
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.resourcesReturnsOnCall[i] = struct {
|
||||
result1 []db.Resource
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) StartedChecks() ([]db.Check, error) {
|
||||
fake.startedChecksMutex.Lock()
|
||||
ret, specificReturn := fake.startedChecksReturnsOnCall[len(fake.startedChecksArgsForCall)]
|
||||
fake.startedChecksArgsForCall = append(fake.startedChecksArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("StartedChecks", []interface{}{})
|
||||
fake.startedChecksMutex.Unlock()
|
||||
if fake.StartedChecksStub != nil {
|
||||
return fake.StartedChecksStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
fakeReturns := fake.startedChecksReturns
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) StartedChecksCallCount() int {
|
||||
fake.startedChecksMutex.RLock()
|
||||
defer fake.startedChecksMutex.RUnlock()
|
||||
return len(fake.startedChecksArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) StartedChecksCalls(stub func() ([]db.Check, error)) {
|
||||
fake.startedChecksMutex.Lock()
|
||||
defer fake.startedChecksMutex.Unlock()
|
||||
fake.StartedChecksStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) StartedChecksReturns(result1 []db.Check, result2 error) {
|
||||
fake.startedChecksMutex.Lock()
|
||||
defer fake.startedChecksMutex.Unlock()
|
||||
fake.StartedChecksStub = nil
|
||||
fake.startedChecksReturns = struct {
|
||||
result1 []db.Check
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) StartedChecksReturnsOnCall(i int, result1 []db.Check, result2 error) {
|
||||
fake.startedChecksMutex.Lock()
|
||||
defer fake.startedChecksMutex.Unlock()
|
||||
fake.StartedChecksStub = nil
|
||||
if fake.startedChecksReturnsOnCall == nil {
|
||||
fake.startedChecksReturnsOnCall = make(map[int]struct {
|
||||
result1 []db.Check
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.startedChecksReturnsOnCall[i] = struct {
|
||||
result1 []db.Check
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) TryCreateCheck(arg1 db.Checkable, arg2 db.ResourceTypes, arg3 atc.Version, arg4 bool) (db.Check, bool, error) {
|
||||
fake.tryCreateCheckMutex.Lock()
|
||||
ret, specificReturn := fake.tryCreateCheckReturnsOnCall[len(fake.tryCreateCheckArgsForCall)]
|
||||
fake.tryCreateCheckArgsForCall = append(fake.tryCreateCheckArgsForCall, struct {
|
||||
arg1 db.Checkable
|
||||
arg2 db.ResourceTypes
|
||||
arg3 atc.Version
|
||||
arg4 bool
|
||||
}{arg1, arg2, arg3, arg4})
|
||||
fake.recordInvocation("TryCreateCheck", []interface{}{arg1, arg2, arg3, arg4})
|
||||
fake.tryCreateCheckMutex.Unlock()
|
||||
if fake.TryCreateCheckStub != nil {
|
||||
return fake.TryCreateCheckStub(arg1, arg2, arg3, arg4)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2, ret.result3
|
||||
}
|
||||
fakeReturns := fake.tryCreateCheckReturns
|
||||
return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) TryCreateCheckCallCount() int {
|
||||
fake.tryCreateCheckMutex.RLock()
|
||||
defer fake.tryCreateCheckMutex.RUnlock()
|
||||
return len(fake.tryCreateCheckArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) TryCreateCheckCalls(stub func(db.Checkable, db.ResourceTypes, atc.Version, bool) (db.Check, bool, error)) {
|
||||
fake.tryCreateCheckMutex.Lock()
|
||||
defer fake.tryCreateCheckMutex.Unlock()
|
||||
fake.TryCreateCheckStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) TryCreateCheckArgsForCall(i int) (db.Checkable, db.ResourceTypes, atc.Version, bool) {
|
||||
fake.tryCreateCheckMutex.RLock()
|
||||
defer fake.tryCreateCheckMutex.RUnlock()
|
||||
argsForCall := fake.tryCreateCheckArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) TryCreateCheckReturns(result1 db.Check, result2 bool, result3 error) {
|
||||
fake.tryCreateCheckMutex.Lock()
|
||||
defer fake.tryCreateCheckMutex.Unlock()
|
||||
fake.TryCreateCheckStub = nil
|
||||
fake.tryCreateCheckReturns = struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) TryCreateCheckReturnsOnCall(i int, result1 db.Check, result2 bool, result3 error) {
|
||||
fake.tryCreateCheckMutex.Lock()
|
||||
defer fake.tryCreateCheckMutex.Unlock()
|
||||
fake.TryCreateCheckStub = nil
|
||||
if fake.tryCreateCheckReturnsOnCall == nil {
|
||||
fake.tryCreateCheckReturnsOnCall = make(map[int]struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
})
|
||||
}
|
||||
fake.tryCreateCheckReturnsOnCall[i] = struct {
|
||||
result1 db.Check
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.acquireScanningLockMutex.RLock()
|
||||
defer fake.acquireScanningLockMutex.RUnlock()
|
||||
fake.checkMutex.RLock()
|
||||
defer fake.checkMutex.RUnlock()
|
||||
fake.createCheckMutex.RLock()
|
||||
defer fake.createCheckMutex.RUnlock()
|
||||
fake.notifyCheckerMutex.RLock()
|
||||
defer fake.notifyCheckerMutex.RUnlock()
|
||||
fake.resourceTypesMutex.RLock()
|
||||
defer fake.resourceTypesMutex.RUnlock()
|
||||
fake.resourcesMutex.RLock()
|
||||
defer fake.resourcesMutex.RUnlock()
|
||||
fake.startedChecksMutex.RLock()
|
||||
defer fake.startedChecksMutex.RUnlock()
|
||||
fake.tryCreateCheckMutex.RLock()
|
||||
defer fake.tryCreateCheckMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakeCheckFactory) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ db.CheckFactory = new(FakeCheckFactory)
|
|
@ -0,0 +1,111 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package dbfakes
|
||||
|
||||
import (
|
||||
sync "sync"
|
||||
time "time"
|
||||
|
||||
db "github.com/concourse/concourse/atc/db"
|
||||
)
|
||||
|
||||
type FakeCheckLifecycle struct {
|
||||
RemoveExpiredChecksStub func(time.Duration) error
|
||||
removeExpiredChecksMutex sync.RWMutex
|
||||
removeExpiredChecksArgsForCall []struct {
|
||||
arg1 time.Duration
|
||||
}
|
||||
removeExpiredChecksReturns struct {
|
||||
result1 error
|
||||
}
|
||||
removeExpiredChecksReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeCheckLifecycle) RemoveExpiredChecks(arg1 time.Duration) error {
|
||||
fake.removeExpiredChecksMutex.Lock()
|
||||
ret, specificReturn := fake.removeExpiredChecksReturnsOnCall[len(fake.removeExpiredChecksArgsForCall)]
|
||||
fake.removeExpiredChecksArgsForCall = append(fake.removeExpiredChecksArgsForCall, struct {
|
||||
arg1 time.Duration
|
||||
}{arg1})
|
||||
fake.recordInvocation("RemoveExpiredChecks", []interface{}{arg1})
|
||||
fake.removeExpiredChecksMutex.Unlock()
|
||||
if fake.RemoveExpiredChecksStub != nil {
|
||||
return fake.RemoveExpiredChecksStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.removeExpiredChecksReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckLifecycle) RemoveExpiredChecksCallCount() int {
|
||||
fake.removeExpiredChecksMutex.RLock()
|
||||
defer fake.removeExpiredChecksMutex.RUnlock()
|
||||
return len(fake.removeExpiredChecksArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckLifecycle) RemoveExpiredChecksCalls(stub func(time.Duration) error) {
|
||||
fake.removeExpiredChecksMutex.Lock()
|
||||
defer fake.removeExpiredChecksMutex.Unlock()
|
||||
fake.RemoveExpiredChecksStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckLifecycle) RemoveExpiredChecksArgsForCall(i int) time.Duration {
|
||||
fake.removeExpiredChecksMutex.RLock()
|
||||
defer fake.removeExpiredChecksMutex.RUnlock()
|
||||
argsForCall := fake.removeExpiredChecksArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckLifecycle) RemoveExpiredChecksReturns(result1 error) {
|
||||
fake.removeExpiredChecksMutex.Lock()
|
||||
defer fake.removeExpiredChecksMutex.Unlock()
|
||||
fake.RemoveExpiredChecksStub = nil
|
||||
fake.removeExpiredChecksReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckLifecycle) RemoveExpiredChecksReturnsOnCall(i int, result1 error) {
|
||||
fake.removeExpiredChecksMutex.Lock()
|
||||
defer fake.removeExpiredChecksMutex.Unlock()
|
||||
fake.RemoveExpiredChecksStub = nil
|
||||
if fake.removeExpiredChecksReturnsOnCall == nil {
|
||||
fake.removeExpiredChecksReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.removeExpiredChecksReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckLifecycle) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.removeExpiredChecksMutex.RLock()
|
||||
defer fake.removeExpiredChecksMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakeCheckLifecycle) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ db.CheckLifecycle = new(FakeCheckLifecycle)
|
|
@ -332,6 +332,16 @@ type FakeResource struct {
|
|||
tagsReturnsOnCall map[int]struct {
|
||||
result1 atc.Tags
|
||||
}
|
||||
TeamIDStub func() int
|
||||
teamIDMutex sync.RWMutex
|
||||
teamIDArgsForCall []struct {
|
||||
}
|
||||
teamIDReturns struct {
|
||||
result1 int
|
||||
}
|
||||
teamIDReturnsOnCall map[int]struct {
|
||||
result1 int
|
||||
}
|
||||
TeamNameStub func() string
|
||||
teamNameMutex sync.RWMutex
|
||||
teamNameArgsForCall []struct {
|
||||
|
@ -2051,6 +2061,58 @@ func (fake *FakeResource) TagsReturnsOnCall(i int, result1 atc.Tags) {
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResource) TeamID() int {
|
||||
fake.teamIDMutex.Lock()
|
||||
ret, specificReturn := fake.teamIDReturnsOnCall[len(fake.teamIDArgsForCall)]
|
||||
fake.teamIDArgsForCall = append(fake.teamIDArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("TeamID", []interface{}{})
|
||||
fake.teamIDMutex.Unlock()
|
||||
if fake.TeamIDStub != nil {
|
||||
return fake.TeamIDStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.teamIDReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResource) TeamIDCallCount() int {
|
||||
fake.teamIDMutex.RLock()
|
||||
defer fake.teamIDMutex.RUnlock()
|
||||
return len(fake.teamIDArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResource) TeamIDCalls(stub func() int) {
|
||||
fake.teamIDMutex.Lock()
|
||||
defer fake.teamIDMutex.Unlock()
|
||||
fake.TeamIDStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResource) TeamIDReturns(result1 int) {
|
||||
fake.teamIDMutex.Lock()
|
||||
defer fake.teamIDMutex.Unlock()
|
||||
fake.TeamIDStub = nil
|
||||
fake.teamIDReturns = struct {
|
||||
result1 int
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResource) TeamIDReturnsOnCall(i int, result1 int) {
|
||||
fake.teamIDMutex.Lock()
|
||||
defer fake.teamIDMutex.Unlock()
|
||||
fake.TeamIDStub = nil
|
||||
if fake.teamIDReturnsOnCall == nil {
|
||||
fake.teamIDReturnsOnCall = make(map[int]struct {
|
||||
result1 int
|
||||
})
|
||||
}
|
||||
fake.teamIDReturnsOnCall[i] = struct {
|
||||
result1 int
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResource) TeamName() string {
|
||||
fake.teamNameMutex.Lock()
|
||||
ret, specificReturn := fake.teamNameReturnsOnCall[len(fake.teamNameArgsForCall)]
|
||||
|
@ -2456,6 +2518,8 @@ func (fake *FakeResource) Invocations() map[string][][]interface{} {
|
|||
defer fake.sourceMutex.RUnlock()
|
||||
fake.tagsMutex.RLock()
|
||||
defer fake.tagsMutex.RUnlock()
|
||||
fake.teamIDMutex.RLock()
|
||||
defer fake.teamIDMutex.RUnlock()
|
||||
fake.teamNameMutex.RLock()
|
||||
defer fake.teamNameMutex.RUnlock()
|
||||
fake.typeMutex.RLock()
|
||||
|
|
|
@ -27,6 +27,18 @@ type FakeResourceConfigScope struct {
|
|||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
AnyResourceStub func() (db.Resource, error)
|
||||
anyResourceMutex sync.RWMutex
|
||||
anyResourceArgsForCall []struct {
|
||||
}
|
||||
anyResourceReturns struct {
|
||||
result1 db.Resource
|
||||
result2 error
|
||||
}
|
||||
anyResourceReturnsOnCall map[int]struct {
|
||||
result1 db.Resource
|
||||
result2 error
|
||||
}
|
||||
CheckErrorStub func() error
|
||||
checkErrorMutex sync.RWMutex
|
||||
checkErrorArgsForCall []struct {
|
||||
|
@ -214,6 +226,61 @@ func (fake *FakeResourceConfigScope) AcquireResourceCheckingLockReturnsOnCall(i
|
|||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceConfigScope) AnyResource() (db.Resource, error) {
|
||||
fake.anyResourceMutex.Lock()
|
||||
ret, specificReturn := fake.anyResourceReturnsOnCall[len(fake.anyResourceArgsForCall)]
|
||||
fake.anyResourceArgsForCall = append(fake.anyResourceArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("AnyResource", []interface{}{})
|
||||
fake.anyResourceMutex.Unlock()
|
||||
if fake.AnyResourceStub != nil {
|
||||
return fake.AnyResourceStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
fakeReturns := fake.anyResourceReturns
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeResourceConfigScope) AnyResourceCallCount() int {
|
||||
fake.anyResourceMutex.RLock()
|
||||
defer fake.anyResourceMutex.RUnlock()
|
||||
return len(fake.anyResourceArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceConfigScope) AnyResourceCalls(stub func() (db.Resource, error)) {
|
||||
fake.anyResourceMutex.Lock()
|
||||
defer fake.anyResourceMutex.Unlock()
|
||||
fake.AnyResourceStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceConfigScope) AnyResourceReturns(result1 db.Resource, result2 error) {
|
||||
fake.anyResourceMutex.Lock()
|
||||
defer fake.anyResourceMutex.Unlock()
|
||||
fake.AnyResourceStub = nil
|
||||
fake.anyResourceReturns = struct {
|
||||
result1 db.Resource
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceConfigScope) AnyResourceReturnsOnCall(i int, result1 db.Resource, result2 error) {
|
||||
fake.anyResourceMutex.Lock()
|
||||
defer fake.anyResourceMutex.Unlock()
|
||||
fake.AnyResourceStub = nil
|
||||
if fake.anyResourceReturnsOnCall == nil {
|
||||
fake.anyResourceReturnsOnCall = make(map[int]struct {
|
||||
result1 db.Resource
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.anyResourceReturnsOnCall[i] = struct {
|
||||
result1 db.Resource
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceConfigScope) CheckError() error {
|
||||
fake.checkErrorMutex.Lock()
|
||||
ret, specificReturn := fake.checkErrorReturnsOnCall[len(fake.checkErrorArgsForCall)]
|
||||
|
@ -795,6 +862,8 @@ func (fake *FakeResourceConfigScope) Invocations() map[string][][]interface{} {
|
|||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.acquireResourceCheckingLockMutex.RLock()
|
||||
defer fake.acquireResourceCheckingLockMutex.RUnlock()
|
||||
fake.anyResourceMutex.RLock()
|
||||
defer fake.anyResourceMutex.RUnlock()
|
||||
fake.checkErrorMutex.RLock()
|
||||
defer fake.checkErrorMutex.RUnlock()
|
||||
fake.findVersionMutex.RLock()
|
||||
|
|
|
@ -20,6 +20,21 @@ type FakeResourceFactory struct {
|
|||
result1 []db.Resource
|
||||
result2 error
|
||||
}
|
||||
ResourceStub func(int) (db.Resource, bool, error)
|
||||
resourceMutex sync.RWMutex
|
||||
resourceArgsForCall []struct {
|
||||
arg1 int
|
||||
}
|
||||
resourceReturns struct {
|
||||
result1 db.Resource
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
resourceReturnsOnCall map[int]struct {
|
||||
result1 db.Resource
|
||||
result2 bool
|
||||
result3 error
|
||||
}
|
||||
VisibleResourcesStub func([]string) ([]db.Resource, error)
|
||||
visibleResourcesMutex sync.RWMutex
|
||||
visibleResourcesArgsForCall []struct {
|
||||
|
@ -92,6 +107,72 @@ func (fake *FakeResourceFactory) AllResourcesReturnsOnCall(i int, result1 []db.R
|
|||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceFactory) Resource(arg1 int) (db.Resource, bool, error) {
|
||||
fake.resourceMutex.Lock()
|
||||
ret, specificReturn := fake.resourceReturnsOnCall[len(fake.resourceArgsForCall)]
|
||||
fake.resourceArgsForCall = append(fake.resourceArgsForCall, struct {
|
||||
arg1 int
|
||||
}{arg1})
|
||||
fake.recordInvocation("Resource", []interface{}{arg1})
|
||||
fake.resourceMutex.Unlock()
|
||||
if fake.ResourceStub != nil {
|
||||
return fake.ResourceStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2, ret.result3
|
||||
}
|
||||
fakeReturns := fake.resourceReturns
|
||||
return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3
|
||||
}
|
||||
|
||||
func (fake *FakeResourceFactory) ResourceCallCount() int {
|
||||
fake.resourceMutex.RLock()
|
||||
defer fake.resourceMutex.RUnlock()
|
||||
return len(fake.resourceArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceFactory) ResourceCalls(stub func(int) (db.Resource, bool, error)) {
|
||||
fake.resourceMutex.Lock()
|
||||
defer fake.resourceMutex.Unlock()
|
||||
fake.ResourceStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceFactory) ResourceArgsForCall(i int) int {
|
||||
fake.resourceMutex.RLock()
|
||||
defer fake.resourceMutex.RUnlock()
|
||||
argsForCall := fake.resourceArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceFactory) ResourceReturns(result1 db.Resource, result2 bool, result3 error) {
|
||||
fake.resourceMutex.Lock()
|
||||
defer fake.resourceMutex.Unlock()
|
||||
fake.ResourceStub = nil
|
||||
fake.resourceReturns = struct {
|
||||
result1 db.Resource
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceFactory) ResourceReturnsOnCall(i int, result1 db.Resource, result2 bool, result3 error) {
|
||||
fake.resourceMutex.Lock()
|
||||
defer fake.resourceMutex.Unlock()
|
||||
fake.ResourceStub = nil
|
||||
if fake.resourceReturnsOnCall == nil {
|
||||
fake.resourceReturnsOnCall = make(map[int]struct {
|
||||
result1 db.Resource
|
||||
result2 bool
|
||||
result3 error
|
||||
})
|
||||
}
|
||||
fake.resourceReturnsOnCall[i] = struct {
|
||||
result1 db.Resource
|
||||
result2 bool
|
||||
result3 error
|
||||
}{result1, result2, result3}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceFactory) VisibleResources(arg1 []string) ([]db.Resource, error) {
|
||||
var arg1Copy []string
|
||||
if arg1 != nil {
|
||||
|
@ -165,6 +246,8 @@ func (fake *FakeResourceFactory) Invocations() map[string][][]interface{} {
|
|||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.allResourcesMutex.RLock()
|
||||
defer fake.allResourcesMutex.RUnlock()
|
||||
fake.resourceMutex.RLock()
|
||||
defer fake.resourceMutex.RUnlock()
|
||||
fake.visibleResourcesMutex.RLock()
|
||||
defer fake.visibleResourcesMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
|
|
|
@ -3,6 +3,7 @@ package dbfakes
|
|||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
|
@ -39,6 +40,26 @@ type FakeResourceType struct {
|
|||
checkSetupErrorReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
CheckTimeoutStub func() string
|
||||
checkTimeoutMutex sync.RWMutex
|
||||
checkTimeoutArgsForCall []struct {
|
||||
}
|
||||
checkTimeoutReturns struct {
|
||||
result1 string
|
||||
}
|
||||
checkTimeoutReturnsOnCall map[int]struct {
|
||||
result1 string
|
||||
}
|
||||
CurrentPinnedVersionStub func() atc.Version
|
||||
currentPinnedVersionMutex sync.RWMutex
|
||||
currentPinnedVersionArgsForCall []struct {
|
||||
}
|
||||
currentPinnedVersionReturns struct {
|
||||
result1 atc.Version
|
||||
}
|
||||
currentPinnedVersionReturnsOnCall map[int]struct {
|
||||
result1 atc.Version
|
||||
}
|
||||
IDStub func() int
|
||||
iDMutex sync.RWMutex
|
||||
iDArgsForCall []struct {
|
||||
|
@ -49,6 +70,26 @@ type FakeResourceType struct {
|
|||
iDReturnsOnCall map[int]struct {
|
||||
result1 int
|
||||
}
|
||||
LastCheckEndTimeStub func() time.Time
|
||||
lastCheckEndTimeMutex sync.RWMutex
|
||||
lastCheckEndTimeArgsForCall []struct {
|
||||
}
|
||||
lastCheckEndTimeReturns struct {
|
||||
result1 time.Time
|
||||
}
|
||||
lastCheckEndTimeReturnsOnCall map[int]struct {
|
||||
result1 time.Time
|
||||
}
|
||||
LastCheckStartTimeStub func() time.Time
|
||||
lastCheckStartTimeMutex sync.RWMutex
|
||||
lastCheckStartTimeArgsForCall []struct {
|
||||
}
|
||||
lastCheckStartTimeReturns struct {
|
||||
result1 time.Time
|
||||
}
|
||||
lastCheckStartTimeReturnsOnCall map[int]struct {
|
||||
result1 time.Time
|
||||
}
|
||||
NameStub func() string
|
||||
nameMutex sync.RWMutex
|
||||
nameArgsForCall []struct {
|
||||
|
@ -69,6 +110,26 @@ type FakeResourceType struct {
|
|||
paramsReturnsOnCall map[int]struct {
|
||||
result1 atc.Params
|
||||
}
|
||||
PipelineIDStub func() int
|
||||
pipelineIDMutex sync.RWMutex
|
||||
pipelineIDArgsForCall []struct {
|
||||
}
|
||||
pipelineIDReturns struct {
|
||||
result1 int
|
||||
}
|
||||
pipelineIDReturnsOnCall map[int]struct {
|
||||
result1 int
|
||||
}
|
||||
PipelineNameStub func() string
|
||||
pipelineNameMutex sync.RWMutex
|
||||
pipelineNameArgsForCall []struct {
|
||||
}
|
||||
pipelineNameReturns struct {
|
||||
result1 string
|
||||
}
|
||||
pipelineNameReturnsOnCall map[int]struct {
|
||||
result1 string
|
||||
}
|
||||
PrivilegedStub func() bool
|
||||
privilegedMutex sync.RWMutex
|
||||
privilegedArgsForCall []struct {
|
||||
|
@ -136,6 +197,26 @@ type FakeResourceType struct {
|
|||
tagsReturnsOnCall map[int]struct {
|
||||
result1 atc.Tags
|
||||
}
|
||||
TeamIDStub func() int
|
||||
teamIDMutex sync.RWMutex
|
||||
teamIDArgsForCall []struct {
|
||||
}
|
||||
teamIDReturns struct {
|
||||
result1 int
|
||||
}
|
||||
teamIDReturnsOnCall map[int]struct {
|
||||
result1 int
|
||||
}
|
||||
TeamNameStub func() string
|
||||
teamNameMutex sync.RWMutex
|
||||
teamNameArgsForCall []struct {
|
||||
}
|
||||
teamNameReturns struct {
|
||||
result1 string
|
||||
}
|
||||
teamNameReturnsOnCall map[int]struct {
|
||||
result1 string
|
||||
}
|
||||
TypeStub func() string
|
||||
typeMutex sync.RWMutex
|
||||
typeArgsForCall []struct {
|
||||
|
@ -326,6 +407,110 @@ func (fake *FakeResourceType) CheckSetupErrorReturnsOnCall(i int, result1 error)
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CheckTimeout() string {
|
||||
fake.checkTimeoutMutex.Lock()
|
||||
ret, specificReturn := fake.checkTimeoutReturnsOnCall[len(fake.checkTimeoutArgsForCall)]
|
||||
fake.checkTimeoutArgsForCall = append(fake.checkTimeoutArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("CheckTimeout", []interface{}{})
|
||||
fake.checkTimeoutMutex.Unlock()
|
||||
if fake.CheckTimeoutStub != nil {
|
||||
return fake.CheckTimeoutStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.checkTimeoutReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CheckTimeoutCallCount() int {
|
||||
fake.checkTimeoutMutex.RLock()
|
||||
defer fake.checkTimeoutMutex.RUnlock()
|
||||
return len(fake.checkTimeoutArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CheckTimeoutCalls(stub func() string) {
|
||||
fake.checkTimeoutMutex.Lock()
|
||||
defer fake.checkTimeoutMutex.Unlock()
|
||||
fake.CheckTimeoutStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CheckTimeoutReturns(result1 string) {
|
||||
fake.checkTimeoutMutex.Lock()
|
||||
defer fake.checkTimeoutMutex.Unlock()
|
||||
fake.CheckTimeoutStub = nil
|
||||
fake.checkTimeoutReturns = struct {
|
||||
result1 string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CheckTimeoutReturnsOnCall(i int, result1 string) {
|
||||
fake.checkTimeoutMutex.Lock()
|
||||
defer fake.checkTimeoutMutex.Unlock()
|
||||
fake.CheckTimeoutStub = nil
|
||||
if fake.checkTimeoutReturnsOnCall == nil {
|
||||
fake.checkTimeoutReturnsOnCall = make(map[int]struct {
|
||||
result1 string
|
||||
})
|
||||
}
|
||||
fake.checkTimeoutReturnsOnCall[i] = struct {
|
||||
result1 string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CurrentPinnedVersion() atc.Version {
|
||||
fake.currentPinnedVersionMutex.Lock()
|
||||
ret, specificReturn := fake.currentPinnedVersionReturnsOnCall[len(fake.currentPinnedVersionArgsForCall)]
|
||||
fake.currentPinnedVersionArgsForCall = append(fake.currentPinnedVersionArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("CurrentPinnedVersion", []interface{}{})
|
||||
fake.currentPinnedVersionMutex.Unlock()
|
||||
if fake.CurrentPinnedVersionStub != nil {
|
||||
return fake.CurrentPinnedVersionStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.currentPinnedVersionReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CurrentPinnedVersionCallCount() int {
|
||||
fake.currentPinnedVersionMutex.RLock()
|
||||
defer fake.currentPinnedVersionMutex.RUnlock()
|
||||
return len(fake.currentPinnedVersionArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CurrentPinnedVersionCalls(stub func() atc.Version) {
|
||||
fake.currentPinnedVersionMutex.Lock()
|
||||
defer fake.currentPinnedVersionMutex.Unlock()
|
||||
fake.CurrentPinnedVersionStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CurrentPinnedVersionReturns(result1 atc.Version) {
|
||||
fake.currentPinnedVersionMutex.Lock()
|
||||
defer fake.currentPinnedVersionMutex.Unlock()
|
||||
fake.CurrentPinnedVersionStub = nil
|
||||
fake.currentPinnedVersionReturns = struct {
|
||||
result1 atc.Version
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) CurrentPinnedVersionReturnsOnCall(i int, result1 atc.Version) {
|
||||
fake.currentPinnedVersionMutex.Lock()
|
||||
defer fake.currentPinnedVersionMutex.Unlock()
|
||||
fake.CurrentPinnedVersionStub = nil
|
||||
if fake.currentPinnedVersionReturnsOnCall == nil {
|
||||
fake.currentPinnedVersionReturnsOnCall = make(map[int]struct {
|
||||
result1 atc.Version
|
||||
})
|
||||
}
|
||||
fake.currentPinnedVersionReturnsOnCall[i] = struct {
|
||||
result1 atc.Version
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) ID() int {
|
||||
fake.iDMutex.Lock()
|
||||
ret, specificReturn := fake.iDReturnsOnCall[len(fake.iDArgsForCall)]
|
||||
|
@ -378,6 +563,110 @@ func (fake *FakeResourceType) IDReturnsOnCall(i int, result1 int) {
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckEndTime() time.Time {
|
||||
fake.lastCheckEndTimeMutex.Lock()
|
||||
ret, specificReturn := fake.lastCheckEndTimeReturnsOnCall[len(fake.lastCheckEndTimeArgsForCall)]
|
||||
fake.lastCheckEndTimeArgsForCall = append(fake.lastCheckEndTimeArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("LastCheckEndTime", []interface{}{})
|
||||
fake.lastCheckEndTimeMutex.Unlock()
|
||||
if fake.LastCheckEndTimeStub != nil {
|
||||
return fake.LastCheckEndTimeStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.lastCheckEndTimeReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckEndTimeCallCount() int {
|
||||
fake.lastCheckEndTimeMutex.RLock()
|
||||
defer fake.lastCheckEndTimeMutex.RUnlock()
|
||||
return len(fake.lastCheckEndTimeArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckEndTimeCalls(stub func() time.Time) {
|
||||
fake.lastCheckEndTimeMutex.Lock()
|
||||
defer fake.lastCheckEndTimeMutex.Unlock()
|
||||
fake.LastCheckEndTimeStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckEndTimeReturns(result1 time.Time) {
|
||||
fake.lastCheckEndTimeMutex.Lock()
|
||||
defer fake.lastCheckEndTimeMutex.Unlock()
|
||||
fake.LastCheckEndTimeStub = nil
|
||||
fake.lastCheckEndTimeReturns = struct {
|
||||
result1 time.Time
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckEndTimeReturnsOnCall(i int, result1 time.Time) {
|
||||
fake.lastCheckEndTimeMutex.Lock()
|
||||
defer fake.lastCheckEndTimeMutex.Unlock()
|
||||
fake.LastCheckEndTimeStub = nil
|
||||
if fake.lastCheckEndTimeReturnsOnCall == nil {
|
||||
fake.lastCheckEndTimeReturnsOnCall = make(map[int]struct {
|
||||
result1 time.Time
|
||||
})
|
||||
}
|
||||
fake.lastCheckEndTimeReturnsOnCall[i] = struct {
|
||||
result1 time.Time
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckStartTime() time.Time {
|
||||
fake.lastCheckStartTimeMutex.Lock()
|
||||
ret, specificReturn := fake.lastCheckStartTimeReturnsOnCall[len(fake.lastCheckStartTimeArgsForCall)]
|
||||
fake.lastCheckStartTimeArgsForCall = append(fake.lastCheckStartTimeArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("LastCheckStartTime", []interface{}{})
|
||||
fake.lastCheckStartTimeMutex.Unlock()
|
||||
if fake.LastCheckStartTimeStub != nil {
|
||||
return fake.LastCheckStartTimeStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.lastCheckStartTimeReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckStartTimeCallCount() int {
|
||||
fake.lastCheckStartTimeMutex.RLock()
|
||||
defer fake.lastCheckStartTimeMutex.RUnlock()
|
||||
return len(fake.lastCheckStartTimeArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckStartTimeCalls(stub func() time.Time) {
|
||||
fake.lastCheckStartTimeMutex.Lock()
|
||||
defer fake.lastCheckStartTimeMutex.Unlock()
|
||||
fake.LastCheckStartTimeStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckStartTimeReturns(result1 time.Time) {
|
||||
fake.lastCheckStartTimeMutex.Lock()
|
||||
defer fake.lastCheckStartTimeMutex.Unlock()
|
||||
fake.LastCheckStartTimeStub = nil
|
||||
fake.lastCheckStartTimeReturns = struct {
|
||||
result1 time.Time
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) LastCheckStartTimeReturnsOnCall(i int, result1 time.Time) {
|
||||
fake.lastCheckStartTimeMutex.Lock()
|
||||
defer fake.lastCheckStartTimeMutex.Unlock()
|
||||
fake.LastCheckStartTimeStub = nil
|
||||
if fake.lastCheckStartTimeReturnsOnCall == nil {
|
||||
fake.lastCheckStartTimeReturnsOnCall = make(map[int]struct {
|
||||
result1 time.Time
|
||||
})
|
||||
}
|
||||
fake.lastCheckStartTimeReturnsOnCall[i] = struct {
|
||||
result1 time.Time
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) Name() string {
|
||||
fake.nameMutex.Lock()
|
||||
ret, specificReturn := fake.nameReturnsOnCall[len(fake.nameArgsForCall)]
|
||||
|
@ -482,6 +771,110 @@ func (fake *FakeResourceType) ParamsReturnsOnCall(i int, result1 atc.Params) {
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineID() int {
|
||||
fake.pipelineIDMutex.Lock()
|
||||
ret, specificReturn := fake.pipelineIDReturnsOnCall[len(fake.pipelineIDArgsForCall)]
|
||||
fake.pipelineIDArgsForCall = append(fake.pipelineIDArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("PipelineID", []interface{}{})
|
||||
fake.pipelineIDMutex.Unlock()
|
||||
if fake.PipelineIDStub != nil {
|
||||
return fake.PipelineIDStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.pipelineIDReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineIDCallCount() int {
|
||||
fake.pipelineIDMutex.RLock()
|
||||
defer fake.pipelineIDMutex.RUnlock()
|
||||
return len(fake.pipelineIDArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineIDCalls(stub func() int) {
|
||||
fake.pipelineIDMutex.Lock()
|
||||
defer fake.pipelineIDMutex.Unlock()
|
||||
fake.PipelineIDStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineIDReturns(result1 int) {
|
||||
fake.pipelineIDMutex.Lock()
|
||||
defer fake.pipelineIDMutex.Unlock()
|
||||
fake.PipelineIDStub = nil
|
||||
fake.pipelineIDReturns = struct {
|
||||
result1 int
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineIDReturnsOnCall(i int, result1 int) {
|
||||
fake.pipelineIDMutex.Lock()
|
||||
defer fake.pipelineIDMutex.Unlock()
|
||||
fake.PipelineIDStub = nil
|
||||
if fake.pipelineIDReturnsOnCall == nil {
|
||||
fake.pipelineIDReturnsOnCall = make(map[int]struct {
|
||||
result1 int
|
||||
})
|
||||
}
|
||||
fake.pipelineIDReturnsOnCall[i] = struct {
|
||||
result1 int
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineName() string {
|
||||
fake.pipelineNameMutex.Lock()
|
||||
ret, specificReturn := fake.pipelineNameReturnsOnCall[len(fake.pipelineNameArgsForCall)]
|
||||
fake.pipelineNameArgsForCall = append(fake.pipelineNameArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("PipelineName", []interface{}{})
|
||||
fake.pipelineNameMutex.Unlock()
|
||||
if fake.PipelineNameStub != nil {
|
||||
return fake.PipelineNameStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.pipelineNameReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineNameCallCount() int {
|
||||
fake.pipelineNameMutex.RLock()
|
||||
defer fake.pipelineNameMutex.RUnlock()
|
||||
return len(fake.pipelineNameArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineNameCalls(stub func() string) {
|
||||
fake.pipelineNameMutex.Lock()
|
||||
defer fake.pipelineNameMutex.Unlock()
|
||||
fake.PipelineNameStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineNameReturns(result1 string) {
|
||||
fake.pipelineNameMutex.Lock()
|
||||
defer fake.pipelineNameMutex.Unlock()
|
||||
fake.PipelineNameStub = nil
|
||||
fake.pipelineNameReturns = struct {
|
||||
result1 string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) PipelineNameReturnsOnCall(i int, result1 string) {
|
||||
fake.pipelineNameMutex.Lock()
|
||||
defer fake.pipelineNameMutex.Unlock()
|
||||
fake.PipelineNameStub = nil
|
||||
if fake.pipelineNameReturnsOnCall == nil {
|
||||
fake.pipelineNameReturnsOnCall = make(map[int]struct {
|
||||
result1 string
|
||||
})
|
||||
}
|
||||
fake.pipelineNameReturnsOnCall[i] = struct {
|
||||
result1 string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) Privileged() bool {
|
||||
fake.privilegedMutex.Lock()
|
||||
ret, specificReturn := fake.privilegedReturnsOnCall[len(fake.privilegedArgsForCall)]
|
||||
|
@ -817,6 +1210,110 @@ func (fake *FakeResourceType) TagsReturnsOnCall(i int, result1 atc.Tags) {
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamID() int {
|
||||
fake.teamIDMutex.Lock()
|
||||
ret, specificReturn := fake.teamIDReturnsOnCall[len(fake.teamIDArgsForCall)]
|
||||
fake.teamIDArgsForCall = append(fake.teamIDArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("TeamID", []interface{}{})
|
||||
fake.teamIDMutex.Unlock()
|
||||
if fake.TeamIDStub != nil {
|
||||
return fake.TeamIDStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.teamIDReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamIDCallCount() int {
|
||||
fake.teamIDMutex.RLock()
|
||||
defer fake.teamIDMutex.RUnlock()
|
||||
return len(fake.teamIDArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamIDCalls(stub func() int) {
|
||||
fake.teamIDMutex.Lock()
|
||||
defer fake.teamIDMutex.Unlock()
|
||||
fake.TeamIDStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamIDReturns(result1 int) {
|
||||
fake.teamIDMutex.Lock()
|
||||
defer fake.teamIDMutex.Unlock()
|
||||
fake.TeamIDStub = nil
|
||||
fake.teamIDReturns = struct {
|
||||
result1 int
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamIDReturnsOnCall(i int, result1 int) {
|
||||
fake.teamIDMutex.Lock()
|
||||
defer fake.teamIDMutex.Unlock()
|
||||
fake.TeamIDStub = nil
|
||||
if fake.teamIDReturnsOnCall == nil {
|
||||
fake.teamIDReturnsOnCall = make(map[int]struct {
|
||||
result1 int
|
||||
})
|
||||
}
|
||||
fake.teamIDReturnsOnCall[i] = struct {
|
||||
result1 int
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamName() string {
|
||||
fake.teamNameMutex.Lock()
|
||||
ret, specificReturn := fake.teamNameReturnsOnCall[len(fake.teamNameArgsForCall)]
|
||||
fake.teamNameArgsForCall = append(fake.teamNameArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("TeamName", []interface{}{})
|
||||
fake.teamNameMutex.Unlock()
|
||||
if fake.TeamNameStub != nil {
|
||||
return fake.TeamNameStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.teamNameReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamNameCallCount() int {
|
||||
fake.teamNameMutex.RLock()
|
||||
defer fake.teamNameMutex.RUnlock()
|
||||
return len(fake.teamNameArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamNameCalls(stub func() string) {
|
||||
fake.teamNameMutex.Lock()
|
||||
defer fake.teamNameMutex.Unlock()
|
||||
fake.TeamNameStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamNameReturns(result1 string) {
|
||||
fake.teamNameMutex.Lock()
|
||||
defer fake.teamNameMutex.Unlock()
|
||||
fake.TeamNameStub = nil
|
||||
fake.teamNameReturns = struct {
|
||||
result1 string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) TeamNameReturnsOnCall(i int, result1 string) {
|
||||
fake.teamNameMutex.Lock()
|
||||
defer fake.teamNameMutex.Unlock()
|
||||
fake.TeamNameStub = nil
|
||||
if fake.teamNameReturnsOnCall == nil {
|
||||
fake.teamNameReturnsOnCall = make(map[int]struct {
|
||||
result1 string
|
||||
})
|
||||
}
|
||||
fake.teamNameReturnsOnCall[i] = struct {
|
||||
result1 string
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeResourceType) Type() string {
|
||||
fake.typeMutex.Lock()
|
||||
ret, specificReturn := fake.typeReturnsOnCall[len(fake.typeArgsForCall)]
|
||||
|
@ -982,12 +1479,24 @@ func (fake *FakeResourceType) Invocations() map[string][][]interface{} {
|
|||
defer fake.checkEveryMutex.RUnlock()
|
||||
fake.checkSetupErrorMutex.RLock()
|
||||
defer fake.checkSetupErrorMutex.RUnlock()
|
||||
fake.checkTimeoutMutex.RLock()
|
||||
defer fake.checkTimeoutMutex.RUnlock()
|
||||
fake.currentPinnedVersionMutex.RLock()
|
||||
defer fake.currentPinnedVersionMutex.RUnlock()
|
||||
fake.iDMutex.RLock()
|
||||
defer fake.iDMutex.RUnlock()
|
||||
fake.lastCheckEndTimeMutex.RLock()
|
||||
defer fake.lastCheckEndTimeMutex.RUnlock()
|
||||
fake.lastCheckStartTimeMutex.RLock()
|
||||
defer fake.lastCheckStartTimeMutex.RUnlock()
|
||||
fake.nameMutex.RLock()
|
||||
defer fake.nameMutex.RUnlock()
|
||||
fake.paramsMutex.RLock()
|
||||
defer fake.paramsMutex.RUnlock()
|
||||
fake.pipelineIDMutex.RLock()
|
||||
defer fake.pipelineIDMutex.RUnlock()
|
||||
fake.pipelineNameMutex.RLock()
|
||||
defer fake.pipelineNameMutex.RUnlock()
|
||||
fake.privilegedMutex.RLock()
|
||||
defer fake.privilegedMutex.RUnlock()
|
||||
fake.reloadMutex.RLock()
|
||||
|
@ -1000,6 +1509,10 @@ func (fake *FakeResourceType) Invocations() map[string][][]interface{} {
|
|||
defer fake.sourceMutex.RUnlock()
|
||||
fake.tagsMutex.RLock()
|
||||
defer fake.tagsMutex.RUnlock()
|
||||
fake.teamIDMutex.RLock()
|
||||
defer fake.teamIDMutex.RUnlock()
|
||||
fake.teamNameMutex.RLock()
|
||||
defer fake.teamNameMutex.RUnlock()
|
||||
fake.typeMutex.RLock()
|
||||
defer fake.typeMutex.RUnlock()
|
||||
fake.uniqueVersionHistoryMutex.RLock()
|
||||
|
|
|
@ -21,6 +21,7 @@ const (
|
|||
LockTypeContainerCreating
|
||||
LockTypeDatabaseMigration
|
||||
LockTypeActiveTasks
|
||||
LockTypeResourceScanning
|
||||
)
|
||||
|
||||
var ErrLostLock = errors.New("lock was lost while held, possibly due to connection breakage")
|
||||
|
@ -53,6 +54,10 @@ func NewActiveTasksLockID() LockID {
|
|||
return LockID{LockTypeActiveTasks}
|
||||
}
|
||||
|
||||
func NewResourceScanningLockID() LockID {
|
||||
return LockID{LockTypeResourceScanning}
|
||||
}
|
||||
|
||||
//go:generate counterfeiter . LockFactory
|
||||
|
||||
type LockFactory interface {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
BEGIN;
|
||||
DROP TABLE checks;
|
||||
COMMIT;
|
|
@ -0,0 +1,20 @@
|
|||
BEGIN;
|
||||
|
||||
CREATE TABLE checks (
|
||||
id bigserial PRIMARY KEY,
|
||||
resource_config_scope_id integer REFERENCES resource_config_scopes(id) ON DELETE CASCADE,
|
||||
schema text NOT NULL,
|
||||
status text NOT NULL,
|
||||
manually_triggered boolean DEFAULT false,
|
||||
plan text,
|
||||
nonce text,
|
||||
check_error text,
|
||||
metadata jsonb,
|
||||
create_time timestamp WITH TIME ZONE DEFAULT now() NOT NULL,
|
||||
start_time timestamp WITH TIME ZONE,
|
||||
end_time timestamp WITH TIME ZONE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX resource_config_scope_id_key ON checks (resource_config_scope_id) WHERE status = 'started' AND manually_triggered = false;
|
||||
|
||||
COMMIT;
|
|
@ -127,6 +127,7 @@ var encryptedColumns = []encryptedColumn{
|
|||
{"resource_types", "config", "id"},
|
||||
{"builds", "private_plan", "id"},
|
||||
{"cert_cache", "cert", "domain"},
|
||||
{"checks", "plan", "id"},
|
||||
}
|
||||
|
||||
func encryptPlaintext(logger lager.Logger, sqlDB *sql.DB, key *encryption.Key) error {
|
||||
|
|
|
@ -22,6 +22,7 @@ type Resource interface {
|
|||
Public() bool
|
||||
PipelineID() int
|
||||
PipelineName() string
|
||||
TeamID() int
|
||||
TeamName() string
|
||||
Type() string
|
||||
Source() atc.Source
|
||||
|
@ -61,7 +62,25 @@ type Resource interface {
|
|||
Reload() (bool, error)
|
||||
}
|
||||
|
||||
var resourcesQuery = psql.Select("r.id, r.name, r.type, r.config, r.check_error, rs.last_check_start_time, rs.last_check_end_time, r.pipeline_id, r.nonce, r.resource_config_id, r.resource_config_scope_id, p.name, t.name, rs.check_error, rp.version, rp.comment_text").
|
||||
var resourcesQuery = psql.Select(
|
||||
"r.id",
|
||||
"r.name",
|
||||
"r.type",
|
||||
"r.config",
|
||||
"r.check_error",
|
||||
"rs.last_check_start_time",
|
||||
"rs.last_check_end_time",
|
||||
"r.pipeline_id",
|
||||
"r.nonce",
|
||||
"r.resource_config_id",
|
||||
"r.resource_config_scope_id",
|
||||
"p.name",
|
||||
"t.id",
|
||||
"t.name",
|
||||
"rs.check_error",
|
||||
"rp.version",
|
||||
"rp.comment_text",
|
||||
).
|
||||
From("resources r").
|
||||
Join("pipelines p ON p.id = r.pipeline_id").
|
||||
Join("teams t ON t.id = p.team_id").
|
||||
|
@ -75,6 +94,7 @@ type resource struct {
|
|||
public bool
|
||||
pipelineID int
|
||||
pipelineName string
|
||||
teamID int
|
||||
teamName string
|
||||
type_ string
|
||||
source atc.Source
|
||||
|
@ -142,6 +162,7 @@ func (r *resource) Name() string { return r.name }
|
|||
func (r *resource) Public() bool { return r.public }
|
||||
func (r *resource) PipelineID() int { return r.pipelineID }
|
||||
func (r *resource) PipelineName() string { return r.pipelineName }
|
||||
func (r *resource) TeamID() int { return r.teamID }
|
||||
func (r *resource) TeamName() string { return r.teamName }
|
||||
func (r *resource) Type() string { return r.type_ }
|
||||
func (r *resource) Source() atc.Source { return r.source }
|
||||
|
@ -265,15 +286,7 @@ func (r *resource) SetCheckSetupError(cause error) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// SaveUncheckedVersion is used by the "get" and "put" step to find or create of a
|
||||
// resource config version. We want to do an upsert because there will be cases
|
||||
// where resource config versions can become outdated while the versions
|
||||
// associated to it are still valid. This will be special case where we save
|
||||
// the version with a check order of 0 in order to avoid using this version
|
||||
// until we do a proper check. Note that this method will not bump the cache
|
||||
// index for the pipeline because we want to ignore these versions until the
|
||||
// check orders get updated. The bumping of the index will be done in
|
||||
// SaveOutput for the put step.
|
||||
// XXX: only used for tests
|
||||
func (r *resource) SaveUncheckedVersion(version atc.Version, metadata ResourceConfigMetadataFields, resourceConfig ResourceConfig, resourceTypes atc.VersionedResourceTypes) (bool, error) {
|
||||
tx, err := r.conn.Begin()
|
||||
if err != nil {
|
||||
|
@ -287,7 +300,7 @@ func (r *resource) SaveUncheckedVersion(version atc.Version, metadata ResourceCo
|
|||
return false, err
|
||||
}
|
||||
|
||||
newVersion, err := saveResourceVersion(tx, resourceConfigScope, version, metadata)
|
||||
newVersion, err := saveResourceVersion(tx, resourceConfigScope.ID(), version, metadata)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -650,7 +663,7 @@ func scanResource(r *resource, row scannable) error {
|
|||
lastCheckStartTime, lastCheckEndTime pq.NullTime
|
||||
)
|
||||
|
||||
err := row.Scan(&r.id, &r.name, &r.type_, &configBlob, &checkErr, &lastCheckStartTime, &lastCheckEndTime, &r.pipelineID, &nonce, &rcID, &rcScopeID, &r.pipelineName, &r.teamName, &rcsCheckErr, &apiPinnedVersion, &pinComment)
|
||||
err := row.Scan(&r.id, &r.name, &r.type_, &configBlob, &checkErr, &lastCheckStartTime, &lastCheckEndTime, &r.pipelineID, &nonce, &rcID, &rcScopeID, &r.pipelineName, &r.teamID, &r.teamName, &rcsCheckErr, &apiPinnedVersion, &pinComment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -181,7 +181,11 @@ var _ = Describe("ResourceCacheLifecycle", func() {
|
|||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
containerOwner = db.NewResourceConfigCheckSessionContainerOwner(resourceConfig, db.ContainerOwnerExpiries{})
|
||||
containerOwner = db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
db.ContainerOwnerExpiries{},
|
||||
)
|
||||
|
||||
container, err = defaultWorker.CreateContainer(containerOwner, db.ContainerMetadata{})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -297,7 +301,11 @@ var _ = Describe("ResourceCacheLifecycle", func() {
|
|||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
containerOwner := db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), db.ContainerOwnerExpiries{})
|
||||
containerOwner := db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
db.ContainerOwnerExpiries{},
|
||||
)
|
||||
|
||||
container, err := defaultWorker.CreateContainer(containerOwner, db.ContainerMetadata{})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
|
@ -31,7 +31,11 @@ var _ = Describe("ResourceConfigCheckSessionLifecycle", func() {
|
|||
resourceConfigScope, err := defaultResource.SetResourceConfig(defaultResource.Source(), atc.VersionedResourceTypes{})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), expiry)
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
expiry,
|
||||
)
|
||||
|
||||
var query sq.Eq
|
||||
var found bool
|
||||
|
@ -128,7 +132,11 @@ var _ = Describe("ResourceConfigCheckSessionLifecycle", func() {
|
|||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), expiry)
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
expiry,
|
||||
)
|
||||
|
||||
var query sq.Eq
|
||||
var found bool
|
||||
|
|
|
@ -67,7 +67,11 @@ func (r *resourceConfigScope) CheckError() error { return r.checkEr
|
|||
// that already exist in the DB will be re-ordered using
|
||||
// incrementCheckOrderWhenNewerVersion to input the correct check order
|
||||
func (r *resourceConfigScope) SaveVersions(versions []atc.Version) error {
|
||||
tx, err := r.conn.Begin()
|
||||
return saveVersions(r.conn, r.ID(), versions)
|
||||
}
|
||||
|
||||
func saveVersions(conn Conn, rcsID int, versions []atc.Version) error {
|
||||
tx, err := conn.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -75,7 +79,7 @@ func (r *resourceConfigScope) SaveVersions(versions []atc.Version) error {
|
|||
defer Rollback(tx)
|
||||
|
||||
for _, version := range versions {
|
||||
_, err = saveResourceVersion(tx, r, version, nil)
|
||||
_, err = saveResourceVersion(tx, rcsID, version, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -85,7 +89,7 @@ func (r *resourceConfigScope) SaveVersions(versions []atc.Version) error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = incrementCheckOrder(tx, r, string(versionJSON))
|
||||
err = incrementCheckOrder(tx, rcsID, string(versionJSON))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -96,7 +100,7 @@ func (r *resourceConfigScope) SaveVersions(versions []atc.Version) error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = bumpCacheIndexForPipelinesUsingResourceConfigScope(r.conn, r.id)
|
||||
err = bumpCacheIndexForPipelinesUsingResourceConfigScope(conn, rcsID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -256,7 +260,7 @@ func (r *resourceConfigScope) UpdateLastCheckEndTime() (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
func saveResourceVersion(tx Tx, r ResourceConfigScope, version atc.Version, metadata ResourceConfigMetadataFields) (bool, error) {
|
||||
func saveResourceVersion(tx Tx, rcsID int, version atc.Version, metadata ResourceConfigMetadataFields) (bool, error) {
|
||||
versionJSON, err := json.Marshal(version)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@ -274,7 +278,7 @@ func saveResourceVersion(tx Tx, r ResourceConfigScope, version atc.Version, meta
|
|||
ON CONFLICT (resource_config_scope_id, version_md5)
|
||||
DO UPDATE SET metadata = COALESCE(NULLIF(excluded.metadata, 'null'::jsonb), resource_config_versions.metadata)
|
||||
RETURNING check_order
|
||||
`, r.ID(), string(versionJSON), string(versionJSON), string(metadataJSON)).Scan(&checkOrder)
|
||||
`, rcsID, string(versionJSON), string(versionJSON), string(metadataJSON)).Scan(&checkOrder)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -286,7 +290,7 @@ func saveResourceVersion(tx Tx, r ResourceConfigScope, version atc.Version, meta
|
|||
// current max. This will fix the case of a check from an old version causing
|
||||
// the desired order to change; existing versions will be re-ordered since
|
||||
// we add them in the desired order.
|
||||
func incrementCheckOrder(tx Tx, r ResourceConfigScope, version string) error {
|
||||
func incrementCheckOrder(tx Tx, rcsID int, version string) error {
|
||||
_, err := tx.Exec(`
|
||||
WITH max_checkorder AS (
|
||||
SELECT max(check_order) co
|
||||
|
@ -299,7 +303,7 @@ func incrementCheckOrder(tx Tx, r ResourceConfigScope, version string) error {
|
|||
FROM max_checkorder mc
|
||||
WHERE resource_config_scope_id = $1
|
||||
AND version = $2
|
||||
AND check_order <= mc.co;`, r.ID(), version)
|
||||
AND check_order <= mc.co;`, rcsID, version)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
//go:generate counterfeiter . ResourceFactory
|
||||
|
||||
type ResourceFactory interface {
|
||||
Resource(int) (Resource, bool, error)
|
||||
VisibleResources([]string) ([]Resource, error)
|
||||
AllResources() ([]Resource, error)
|
||||
}
|
||||
|
@ -26,16 +27,37 @@ func NewResourceFactory(conn Conn, lockFactory lock.LockFactory) ResourceFactory
|
|||
}
|
||||
}
|
||||
|
||||
func (r *resourceFactory) Resource(resourceID int) (Resource, bool, error) {
|
||||
resource := &resource{
|
||||
conn: r.conn,
|
||||
lockFactory: r.lockFactory,
|
||||
}
|
||||
|
||||
row := resourcesQuery.
|
||||
Where(sq.Eq{"r.id": resourceID}).
|
||||
RunWith(r.conn).
|
||||
QueryRow()
|
||||
|
||||
err := scanResource(resource, row)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return resource, true, nil
|
||||
}
|
||||
|
||||
func (r *resourceFactory) VisibleResources(teamNames []string) ([]Resource, error) {
|
||||
rows, err := resourcesQuery.
|
||||
Where(
|
||||
sq.Or{
|
||||
sq.Eq{"t.name": teamNames},
|
||||
sq.And{
|
||||
sq.NotEq{"t.name": teamNames},
|
||||
sq.Eq{"p.public": true},
|
||||
},
|
||||
}).
|
||||
Where(sq.Or{
|
||||
sq.Eq{"t.name": teamNames},
|
||||
sq.And{
|
||||
sq.NotEq{"t.name": teamNames},
|
||||
sq.Eq{"p.public": true},
|
||||
},
|
||||
}).
|
||||
OrderBy("r.id ASC").
|
||||
RunWith(r.conn).
|
||||
Query()
|
||||
|
|
|
@ -5,10 +5,12 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db/lock"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
type ResourceTypeNotFoundError struct {
|
||||
|
@ -23,6 +25,10 @@ func (e ResourceTypeNotFoundError) Error() string {
|
|||
|
||||
type ResourceType interface {
|
||||
ID() int
|
||||
PipelineID() int
|
||||
PipelineName() string
|
||||
TeamID() int
|
||||
TeamName() string
|
||||
Name() string
|
||||
Type() string
|
||||
Privileged() bool
|
||||
|
@ -30,9 +36,13 @@ type ResourceType interface {
|
|||
Params() atc.Params
|
||||
Tags() atc.Tags
|
||||
CheckEvery() string
|
||||
CheckTimeout() string
|
||||
LastCheckStartTime() time.Time
|
||||
LastCheckEndTime() time.Time
|
||||
CheckSetupError() error
|
||||
CheckError() error
|
||||
UniqueVersionHistory() bool
|
||||
CurrentPinnedVersion() atc.Version
|
||||
|
||||
SetResourceConfig(atc.Source, atc.VersionedResourceTypes) (ResourceConfigScope, error)
|
||||
SetCheckSetupError(error) error
|
||||
|
@ -44,6 +54,31 @@ type ResourceType interface {
|
|||
|
||||
type ResourceTypes []ResourceType
|
||||
|
||||
func (resourceTypes ResourceTypes) Parent(checkable Checkable) (ResourceType, bool) {
|
||||
for _, t := range resourceTypes {
|
||||
if t.PipelineID() == checkable.PipelineID() {
|
||||
if t.Name() != checkable.Name() && t.Name() == checkable.Type() {
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (resourceTypes ResourceTypes) Filter(checkable Checkable) ResourceTypes {
|
||||
var result ResourceTypes
|
||||
|
||||
for {
|
||||
resourceType, found := resourceTypes.Parent(checkable)
|
||||
if !found {
|
||||
return result
|
||||
}
|
||||
|
||||
result = append(result, resourceType)
|
||||
checkable = resourceType
|
||||
}
|
||||
}
|
||||
|
||||
func (resourceTypes ResourceTypes) Deserialize() atc.VersionedResourceTypes {
|
||||
var versionedResourceTypes atc.VersionedResourceTypes
|
||||
|
||||
|
@ -85,8 +120,25 @@ func (resourceTypes ResourceTypes) Configs() atc.ResourceTypes {
|
|||
return configs
|
||||
}
|
||||
|
||||
var resourceTypesQuery = psql.Select("r.id, r.name, r.type, r.config, rcv.version, r.nonce, r.check_error, ro.check_error").
|
||||
var resourceTypesQuery = psql.Select(
|
||||
"r.id",
|
||||
"r.pipeline_id",
|
||||
"r.name",
|
||||
"r.type",
|
||||
"r.config",
|
||||
"rcv.version",
|
||||
"r.nonce",
|
||||
"r.check_error",
|
||||
"p.name",
|
||||
"t.id",
|
||||
"t.name",
|
||||
"ro.check_error",
|
||||
"ro.last_check_start_time",
|
||||
"ro.last_check_end_time",
|
||||
).
|
||||
From("resource_types r").
|
||||
Join("pipelines p ON p.id = r.pipeline_id").
|
||||
Join("teams t ON t.id = p.team_id").
|
||||
LeftJoin("resource_configs c ON c.id = r.resource_config_id").
|
||||
LeftJoin("resource_config_scopes ro ON ro.resource_config_id = c.id").
|
||||
LeftJoin(`LATERAL (
|
||||
|
@ -100,6 +152,10 @@ var resourceTypesQuery = psql.Select("r.id, r.name, r.type, r.config, rcv.versio
|
|||
|
||||
type resourceType struct {
|
||||
id int
|
||||
pipelineID int
|
||||
pipelineName string
|
||||
teamID int
|
||||
teamName string
|
||||
name string
|
||||
type_ string
|
||||
privileged bool
|
||||
|
@ -108,6 +164,8 @@ type resourceType struct {
|
|||
tags atc.Tags
|
||||
version atc.Version
|
||||
checkEvery string
|
||||
lastCheckStartTime time.Time
|
||||
lastCheckEndTime time.Time
|
||||
checkSetupError error
|
||||
checkError error
|
||||
uniqueVersionHistory bool
|
||||
|
@ -116,19 +174,27 @@ type resourceType struct {
|
|||
lockFactory lock.LockFactory
|
||||
}
|
||||
|
||||
func (t *resourceType) ID() int { return t.id }
|
||||
func (t *resourceType) Name() string { return t.name }
|
||||
func (t *resourceType) Type() string { return t.type_ }
|
||||
func (t *resourceType) Privileged() bool { return t.privileged }
|
||||
func (t *resourceType) CheckEvery() string { return t.checkEvery }
|
||||
func (t *resourceType) Source() atc.Source { return t.source }
|
||||
func (t *resourceType) Params() atc.Params { return t.params }
|
||||
func (t *resourceType) Tags() atc.Tags { return t.tags }
|
||||
func (t *resourceType) CheckSetupError() error { return t.checkSetupError }
|
||||
func (t *resourceType) CheckError() error { return t.checkError }
|
||||
func (t *resourceType) UniqueVersionHistory() bool { return t.uniqueVersionHistory }
|
||||
func (t *resourceType) ID() int { return t.id }
|
||||
func (t *resourceType) PipelineID() int { return t.pipelineID }
|
||||
func (t *resourceType) PipelineName() string { return t.pipelineName }
|
||||
func (t *resourceType) TeamID() int { return t.teamID }
|
||||
func (t *resourceType) TeamName() string { return t.teamName }
|
||||
func (t *resourceType) Name() string { return t.name }
|
||||
func (t *resourceType) Type() string { return t.type_ }
|
||||
func (t *resourceType) Privileged() bool { return t.privileged }
|
||||
func (t *resourceType) CheckEvery() string { return t.checkEvery }
|
||||
func (t *resourceType) CheckTimeout() string { return "" }
|
||||
func (r *resourceType) LastCheckStartTime() time.Time { return r.lastCheckStartTime }
|
||||
func (r *resourceType) LastCheckEndTime() time.Time { return r.lastCheckEndTime }
|
||||
func (t *resourceType) Source() atc.Source { return t.source }
|
||||
func (t *resourceType) Params() atc.Params { return t.params }
|
||||
func (t *resourceType) Tags() atc.Tags { return t.tags }
|
||||
func (t *resourceType) CheckSetupError() error { return t.checkSetupError }
|
||||
func (t *resourceType) CheckError() error { return t.checkError }
|
||||
func (t *resourceType) UniqueVersionHistory() bool { return t.uniqueVersionHistory }
|
||||
|
||||
func (t *resourceType) Version() atc.Version { return t.version }
|
||||
func (t *resourceType) Version() atc.Version { return t.version }
|
||||
func (t *resourceType) CurrentPinnedVersion() atc.Version { return nil }
|
||||
|
||||
func (t *resourceType) Reload() (bool, error) {
|
||||
row := resourceTypesQuery.Where(sq.Eq{"r.id": t.id}).RunWith(t.conn).QueryRow()
|
||||
|
@ -211,13 +277,17 @@ func scanResourceType(t *resourceType, row scannable) error {
|
|||
var (
|
||||
configJSON []byte
|
||||
checkErr, rcsCheckErr, version, nonce sql.NullString
|
||||
lastCheckStartTime, lastCheckEndTime pq.NullTime
|
||||
)
|
||||
|
||||
err := row.Scan(&t.id, &t.name, &t.type_, &configJSON, &version, &nonce, &checkErr, &rcsCheckErr)
|
||||
err := row.Scan(&t.id, &t.pipelineID, &t.name, &t.type_, &configJSON, &version, &nonce, &checkErr, &t.pipelineName, &t.teamID, &t.teamName, &rcsCheckErr, &lastCheckStartTime, &lastCheckEndTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.lastCheckStartTime = lastCheckStartTime.Time
|
||||
t.lastCheckEndTime = lastCheckEndTime.Time
|
||||
|
||||
if version.Valid {
|
||||
err = json.Unmarshal([]byte(version.String), &t.version)
|
||||
if err != nil {
|
||||
|
|
|
@ -55,7 +55,7 @@ var _ = Describe("ResourceType", func() {
|
|||
})
|
||||
|
||||
Describe("(Pipeline).ResourceTypes", func() {
|
||||
var resourceTypes []db.ResourceType
|
||||
var resourceTypes db.ResourceTypes
|
||||
|
||||
JustBeforeEach(func() {
|
||||
var err error
|
||||
|
@ -129,6 +129,109 @@ var _ = Describe("ResourceType", func() {
|
|||
Expect(resourceTypes[0].Name()).To(Equal("some-type"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when building the dependency tree from resource types list", func() {
|
||||
BeforeEach(func() {
|
||||
var (
|
||||
created bool
|
||||
err error
|
||||
)
|
||||
|
||||
otherPipeline, created, err := defaultTeam.SavePipeline(
|
||||
"pipeline-with-duplicate-type-name",
|
||||
atc.Config{
|
||||
ResourceTypes: atc.ResourceTypes{
|
||||
{
|
||||
Name: "some-custom-type",
|
||||
Type: "some-different-foo-type",
|
||||
Source: atc.Source{"some": "repository"},
|
||||
CheckEvery: "10ms",
|
||||
},
|
||||
},
|
||||
},
|
||||
db.ConfigVersion(0),
|
||||
false,
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(created).To(BeTrue())
|
||||
Expect(otherPipeline).NotTo(BeNil())
|
||||
|
||||
pipeline, created, err = defaultTeam.SavePipeline(
|
||||
"pipeline-with-types",
|
||||
atc.Config{
|
||||
Resources: atc.ResourceConfigs{
|
||||
{
|
||||
Name: "some-resource",
|
||||
Type: "some-custom-type",
|
||||
Source: atc.Source{},
|
||||
},
|
||||
},
|
||||
ResourceTypes: atc.ResourceTypes{
|
||||
{
|
||||
Name: "registry-image",
|
||||
Type: "registry-image",
|
||||
Source: atc.Source{"some": "repository"},
|
||||
},
|
||||
{
|
||||
Name: "some-other-type",
|
||||
Type: "registry-image",
|
||||
Privileged: true,
|
||||
Source: atc.Source{"some": "other-repository"},
|
||||
},
|
||||
{
|
||||
Name: "some-type-with-params",
|
||||
Type: "s3",
|
||||
Source: atc.Source{"some": "repository"},
|
||||
Params: atc.Params{"unpack": "true"},
|
||||
},
|
||||
{
|
||||
Name: "some-type-with-custom-check",
|
||||
Type: "registry-image",
|
||||
Source: atc.Source{"some": "repository"},
|
||||
CheckEvery: "10ms",
|
||||
},
|
||||
{
|
||||
Name: "some-custom-type",
|
||||
Type: "some-other-foo-type",
|
||||
Source: atc.Source{"some": "repository"},
|
||||
CheckEvery: "10ms",
|
||||
},
|
||||
{
|
||||
Name: "some-other-foo-type",
|
||||
Type: "some-other-type",
|
||||
Source: atc.Source{"some": "repository"},
|
||||
CheckEvery: "10ms",
|
||||
},
|
||||
},
|
||||
},
|
||||
pipeline.ConfigVersion(),
|
||||
false,
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(created).To(BeFalse())
|
||||
})
|
||||
|
||||
It("returns the resource types tree given a resource", func() {
|
||||
resource, found, err := pipeline.Resource("some-resource")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(found).To(BeTrue())
|
||||
|
||||
tree := resourceTypes.Filter(resource)
|
||||
Expect(len(tree)).To(Equal(4))
|
||||
|
||||
Expect(tree[0].Name()).To(Equal("some-custom-type"))
|
||||
Expect(tree[0].Type()).To(Equal("some-other-foo-type"))
|
||||
|
||||
Expect(tree[1].Name()).To(Equal("some-other-foo-type"))
|
||||
Expect(tree[1].Type()).To(Equal("some-other-type"))
|
||||
|
||||
Expect(tree[2].Name()).To(Equal("some-other-type"))
|
||||
Expect(tree[2].Type()).To(Equal("registry-image"))
|
||||
|
||||
Expect(tree[3].Name()).To(Equal("registry-image"))
|
||||
Expect(tree[3].Type()).To(Equal("registry-image"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("SetCheckError", func() {
|
||||
|
|
|
@ -439,7 +439,11 @@ var _ = Describe("Team", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
resourceContainer, err = defaultWorker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), expiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
db.ContainerMetadata{},
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -485,12 +489,15 @@ var _ = Describe("Team", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
resourceContainer, err = worker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), expiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
db.ContainerMetadata{
|
||||
Type: "check",
|
||||
},
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("finds the container", func() {
|
||||
|
@ -563,12 +570,15 @@ var _ = Describe("Team", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
resource2Container, err = worker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), expiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
db.ContainerMetadata{
|
||||
Type: "check",
|
||||
},
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("returns the container only from the team", func() {
|
||||
|
@ -595,7 +605,11 @@ var _ = Describe("Team", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
globalResourceContainer, err = defaultWorker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), expiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
db.ContainerMetadata{
|
||||
Type: "check",
|
||||
},
|
||||
|
@ -626,7 +640,11 @@ var _ = Describe("Team", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
resourceContainer, err = defaultWorker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), expiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
db.ContainerMetadata{
|
||||
Type: "check",
|
||||
},
|
||||
|
@ -2484,7 +2502,11 @@ var _ = Describe("Team", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
resourceContainer, err = defaultWorker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfig, expiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
db.ContainerMetadata{},
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -2534,7 +2556,11 @@ var _ = Describe("Team", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
otherResourceContainer, _, err = defaultWorker.FindContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfig, expiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
@ -2597,7 +2623,11 @@ var _ = Describe("Team", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
resourceContainer, err = defaultWorker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), expiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
db.ContainerMetadata{},
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
|
@ -22,7 +22,14 @@ var _ = Describe("Volume", func() {
|
|||
resourceConfig, err := resourceConfigFactory.FindOrCreateResourceConfig("some-base-resource-type", atc.Source{}, atc.VersionedResourceTypes{})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
defaultCreatingContainer, err = defaultWorker.CreateContainer(db.NewResourceConfigCheckSessionContainerOwner(resourceConfig, expiries), db.ContainerMetadata{Type: "check"})
|
||||
defaultCreatingContainer, err = defaultWorker.CreateContainer(
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
),
|
||||
db.ContainerMetadata{Type: "check"},
|
||||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
defaultCreatedContainer, err = defaultCreatingContainer.Created()
|
||||
|
|
|
@ -626,7 +626,11 @@ var _ = Describe("WorkerFactory", func() {
|
|||
rcs, err := otherResource.SetResourceConfig(atc.Source{"some": "source"}, atc.VersionedResourceTypes{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
owner = db.NewResourceConfigCheckSessionContainerOwner(rcs.ResourceConfig(), ownerExpiries)
|
||||
owner = db.NewResourceConfigCheckSessionContainerOwner(
|
||||
rcs.ResourceConfig().ID(),
|
||||
rcs.ResourceConfig().OriginBaseResourceType().ID,
|
||||
ownerExpiries,
|
||||
)
|
||||
|
||||
_, err = defaultWorker.CreateContainer(owner, containerMetadata)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
|
@ -242,7 +242,11 @@ var _ = Describe("Worker", func() {
|
|||
)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
containerOwner = NewResourceConfigCheckSessionContainerOwner(resourceConfig, expiries)
|
||||
containerOwner = NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfig.ID(),
|
||||
resourceConfig.OriginBaseResourceType().ID,
|
||||
expiries,
|
||||
)
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/lock"
|
||||
"github.com/concourse/concourse/atc/exec"
|
||||
)
|
||||
|
||||
|
@ -18,7 +17,8 @@ const supportedSchema = "exec.v2"
|
|||
type StepFactory interface {
|
||||
GetStep(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.GetDelegate) exec.Step
|
||||
PutStep(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.PutDelegate) exec.Step
|
||||
TaskStep(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.TaskDelegate, lock.LockFactory) exec.Step
|
||||
TaskStep(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.TaskDelegate) exec.Step
|
||||
CheckStep(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.CheckDelegate) exec.Step
|
||||
ArtifactInputStep(atc.Plan, db.Build, exec.BuildStepDelegate) exec.Step
|
||||
ArtifactOutputStep(atc.Plan, db.Build, exec.BuildStepDelegate) exec.Step
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ type DelegateFactory interface {
|
|||
GetDelegate(db.Build, atc.PlanID) exec.GetDelegate
|
||||
PutDelegate(db.Build, atc.PlanID) exec.PutDelegate
|
||||
TaskDelegate(db.Build, atc.PlanID) exec.TaskDelegate
|
||||
CheckDelegate(db.Check, atc.PlanID) exec.CheckDelegate
|
||||
BuildStepDelegate(db.Build, atc.PlanID) exec.BuildStepDelegate
|
||||
}
|
||||
|
||||
|
@ -36,13 +37,11 @@ func NewStepBuilder(
|
|||
stepFactory StepFactory,
|
||||
delegateFactory DelegateFactory,
|
||||
externalURL string,
|
||||
lockFactory lock.LockFactory,
|
||||
) *stepBuilder {
|
||||
return &stepBuilder{
|
||||
stepFactory: stepFactory,
|
||||
delegateFactory: delegateFactory,
|
||||
externalURL: externalURL,
|
||||
lockFactory: lockFactory,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +49,6 @@ type stepBuilder struct {
|
|||
stepFactory StepFactory
|
||||
delegateFactory DelegateFactory
|
||||
externalURL string
|
||||
lockFactory lock.LockFactory
|
||||
}
|
||||
|
||||
func (builder *stepBuilder) BuildStep(build db.Build) (exec.Step, error) {
|
||||
|
@ -66,6 +64,19 @@ func (builder *stepBuilder) BuildStep(build db.Build) (exec.Step, error) {
|
|||
return builder.buildStep(build, build.PrivatePlan()), nil
|
||||
}
|
||||
|
||||
func (builder *stepBuilder) CheckStep(check db.Check) (exec.Step, error) {
|
||||
|
||||
if check == nil {
|
||||
return exec.IdentityStep{}, errors.New("Must provide a check")
|
||||
}
|
||||
|
||||
if check.Schema() != supportedSchema {
|
||||
return exec.IdentityStep{}, errors.New("Schema not supported")
|
||||
}
|
||||
|
||||
return builder.buildCheckStep(check, check.Plan()), nil
|
||||
}
|
||||
|
||||
func (builder *stepBuilder) buildStep(build db.Build, plan atc.Plan) exec.Step {
|
||||
if plan.Aggregate != nil {
|
||||
return builder.buildAggregateStep(build, plan)
|
||||
|
@ -285,6 +296,28 @@ func (builder *stepBuilder) buildPutStep(build db.Build, plan atc.Plan) exec.Ste
|
|||
)
|
||||
}
|
||||
|
||||
func (builder *stepBuilder) buildCheckStep(check db.Check, plan atc.Plan) exec.Step {
|
||||
|
||||
containerMetadata := db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
}
|
||||
|
||||
stepMetadata := exec.StepMetadata{
|
||||
TeamID: check.TeamID(),
|
||||
ResourceConfigScopeID: check.ResourceConfigScopeID(),
|
||||
ResourceConfigID: check.ResourceConfigID(),
|
||||
BaseResourceTypeID: check.BaseResourceTypeID(),
|
||||
ExternalURL: builder.externalURL,
|
||||
}
|
||||
|
||||
return builder.stepFactory.CheckStep(
|
||||
plan,
|
||||
stepMetadata,
|
||||
containerMetadata,
|
||||
builder.delegateFactory.CheckDelegate(check, plan.ID),
|
||||
)
|
||||
}
|
||||
|
||||
func (builder *stepBuilder) buildTaskStep(build db.Build, plan atc.Plan) exec.Step {
|
||||
|
||||
containerMetadata := builder.containerMetadata(
|
||||
|
@ -304,7 +337,6 @@ func (builder *stepBuilder) buildTaskStep(build db.Build, plan atc.Plan) exec.St
|
|||
stepMetadata,
|
||||
containerMetadata,
|
||||
builder.delegateFactory.TaskDelegate(build, plan.ID),
|
||||
builder.lockFactory,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/dbfakes"
|
||||
"github.com/concourse/concourse/atc/db/lock"
|
||||
"github.com/concourse/concourse/atc/db/lock/lockfakes"
|
||||
"github.com/concourse/concourse/atc/engine/builder"
|
||||
"github.com/concourse/concourse/atc/engine/builder/builderfakes"
|
||||
"github.com/concourse/concourse/atc/exec"
|
||||
|
@ -16,6 +14,7 @@ import (
|
|||
|
||||
type StepBuilder interface {
|
||||
BuildStep(db.Build) (exec.Step, error)
|
||||
CheckStep(db.Check) (exec.Step, error)
|
||||
}
|
||||
|
||||
var _ = Describe("Builder", func() {
|
||||
|
@ -27,8 +26,6 @@ var _ = Describe("Builder", func() {
|
|||
|
||||
fakeStepFactory *builderfakes.FakeStepFactory
|
||||
fakeDelegateFactory *builderfakes.FakeDelegateFactory
|
||||
fakeLockDB *lockfakes.FakeLockDB
|
||||
fakeLockFactory lock.LockFactory
|
||||
|
||||
planFactory atc.PlanFactory
|
||||
stepBuilder StepBuilder
|
||||
|
@ -37,13 +34,11 @@ var _ = Describe("Builder", func() {
|
|||
BeforeEach(func() {
|
||||
fakeStepFactory = new(builderfakes.FakeStepFactory)
|
||||
fakeDelegateFactory = new(builderfakes.FakeDelegateFactory)
|
||||
fakeLockFactory = lock.NewTestLockFactory(fakeLockDB)
|
||||
|
||||
stepBuilder = builder.NewStepBuilder(
|
||||
fakeStepFactory,
|
||||
fakeDelegateFactory,
|
||||
"http://example.com",
|
||||
fakeLockFactory,
|
||||
)
|
||||
|
||||
planFactory = atc.NewPlanFactory(123)
|
||||
|
@ -361,7 +356,7 @@ var _ = Describe("Builder", func() {
|
|||
})
|
||||
|
||||
It("constructs nested steps correctly", func() {
|
||||
plan, stepMetadata, containerMetadata, _, _ := fakeStepFactory.TaskStepArgsForCall(0)
|
||||
plan, stepMetadata, containerMetadata, _ := fakeStepFactory.TaskStepArgsForCall(0)
|
||||
expectedPlan := taskPlan
|
||||
expectedPlan.Attempts = []int{2, 1}
|
||||
Expect(plan).To(Equal(expectedPlan))
|
||||
|
@ -378,7 +373,7 @@ var _ = Describe("Builder", func() {
|
|||
Attempt: "2.1",
|
||||
}))
|
||||
|
||||
plan, stepMetadata, containerMetadata, _, _ = fakeStepFactory.TaskStepArgsForCall(1)
|
||||
plan, stepMetadata, containerMetadata, _ = fakeStepFactory.TaskStepArgsForCall(1)
|
||||
expectedPlan = taskPlan
|
||||
expectedPlan.Attempts = []int{2, 2}
|
||||
Expect(plan).To(Equal(expectedPlan))
|
||||
|
@ -448,15 +443,15 @@ var _ = Describe("Builder", func() {
|
|||
It("constructs nested steps correctly", func() {
|
||||
Expect(fakeStepFactory.TaskStepCallCount()).To(Equal(6))
|
||||
|
||||
_, _, containerMetadata, _, _ := fakeStepFactory.TaskStepArgsForCall(0)
|
||||
_, _, containerMetadata, _ := fakeStepFactory.TaskStepArgsForCall(0)
|
||||
Expect(containerMetadata.Attempt).To(Equal("1"))
|
||||
_, _, containerMetadata, _, _ = fakeStepFactory.TaskStepArgsForCall(1)
|
||||
_, _, containerMetadata, _ = fakeStepFactory.TaskStepArgsForCall(1)
|
||||
Expect(containerMetadata.Attempt).To(Equal("1"))
|
||||
_, _, containerMetadata, _, _ = fakeStepFactory.TaskStepArgsForCall(2)
|
||||
_, _, containerMetadata, _ = fakeStepFactory.TaskStepArgsForCall(2)
|
||||
Expect(containerMetadata.Attempt).To(Equal("1"))
|
||||
_, _, containerMetadata, _, _ = fakeStepFactory.TaskStepArgsForCall(3)
|
||||
_, _, containerMetadata, _ = fakeStepFactory.TaskStepArgsForCall(3)
|
||||
Expect(containerMetadata.Attempt).To(Equal("1"))
|
||||
_, _, containerMetadata, _, _ = fakeStepFactory.TaskStepArgsForCall(4)
|
||||
_, _, containerMetadata, _ = fakeStepFactory.TaskStepArgsForCall(4)
|
||||
Expect(containerMetadata.Attempt).To(Equal("1"))
|
||||
})
|
||||
})
|
||||
|
@ -504,7 +499,7 @@ var _ = Describe("Builder", func() {
|
|||
})
|
||||
|
||||
It("constructs tasks correctly", func() {
|
||||
plan, stepMetadata, containerMetadata, _, _ := fakeStepFactory.TaskStepArgsForCall(0)
|
||||
plan, stepMetadata, containerMetadata, _ := fakeStepFactory.TaskStepArgsForCall(0)
|
||||
Expect(plan).To(Equal(expectedPlan))
|
||||
Expect(stepMetadata).To(Equal(expectedMetadata))
|
||||
Expect(containerMetadata).To(Equal(db.ContainerMetadata{
|
||||
|
@ -651,7 +646,7 @@ var _ = Describe("Builder", func() {
|
|||
|
||||
It("constructs the completion hook correctly", func() {
|
||||
Expect(fakeStepFactory.TaskStepCallCount()).To(Equal(4))
|
||||
plan, stepMetadata, containerMetadata, _, _ := fakeStepFactory.TaskStepArgsForCall(2)
|
||||
plan, stepMetadata, containerMetadata, _ := fakeStepFactory.TaskStepArgsForCall(2)
|
||||
Expect(plan).To(Equal(completionTaskPlan))
|
||||
Expect(stepMetadata).To(Equal(expectedMetadata))
|
||||
Expect(containerMetadata).To(Equal(db.ContainerMetadata{
|
||||
|
@ -668,7 +663,7 @@ var _ = Describe("Builder", func() {
|
|||
|
||||
It("constructs the failure hook correctly", func() {
|
||||
Expect(fakeStepFactory.TaskStepCallCount()).To(Equal(4))
|
||||
plan, stepMetadata, containerMetadata, _, _ := fakeStepFactory.TaskStepArgsForCall(0)
|
||||
plan, stepMetadata, containerMetadata, _ := fakeStepFactory.TaskStepArgsForCall(0)
|
||||
Expect(plan).To(Equal(failureTaskPlan))
|
||||
Expect(stepMetadata).To(Equal(expectedMetadata))
|
||||
Expect(containerMetadata).To(Equal(db.ContainerMetadata{
|
||||
|
@ -685,7 +680,7 @@ var _ = Describe("Builder", func() {
|
|||
|
||||
It("constructs the success hook correctly", func() {
|
||||
Expect(fakeStepFactory.TaskStepCallCount()).To(Equal(4))
|
||||
plan, stepMetadata, containerMetadata, _, _ := fakeStepFactory.TaskStepArgsForCall(1)
|
||||
plan, stepMetadata, containerMetadata, _ := fakeStepFactory.TaskStepArgsForCall(1)
|
||||
Expect(plan).To(Equal(successTaskPlan))
|
||||
Expect(stepMetadata).To(Equal(expectedMetadata))
|
||||
Expect(containerMetadata).To(Equal(db.ContainerMetadata{
|
||||
|
@ -702,7 +697,7 @@ var _ = Describe("Builder", func() {
|
|||
|
||||
It("constructs the next step correctly", func() {
|
||||
Expect(fakeStepFactory.TaskStepCallCount()).To(Equal(4))
|
||||
plan, stepMetadata, containerMetadata, _, _ := fakeStepFactory.TaskStepArgsForCall(3)
|
||||
plan, stepMetadata, containerMetadata, _ := fakeStepFactory.TaskStepArgsForCall(3)
|
||||
Expect(plan).To(Equal(nextTaskPlan))
|
||||
Expect(stepMetadata).To(Equal(expectedMetadata))
|
||||
Expect(containerMetadata).To(Equal(db.ContainerMetadata{
|
||||
|
@ -753,4 +748,106 @@ var _ = Describe("Builder", func() {
|
|||
})
|
||||
})
|
||||
|
||||
Describe("CheckStep", func() {
|
||||
|
||||
var (
|
||||
err error
|
||||
|
||||
fakeStepFactory *builderfakes.FakeStepFactory
|
||||
fakeDelegateFactory *builderfakes.FakeDelegateFactory
|
||||
|
||||
planFactory atc.PlanFactory
|
||||
stepBuilder StepBuilder
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeStepFactory = new(builderfakes.FakeStepFactory)
|
||||
fakeDelegateFactory = new(builderfakes.FakeDelegateFactory)
|
||||
|
||||
stepBuilder = builder.NewStepBuilder(
|
||||
fakeStepFactory,
|
||||
fakeDelegateFactory,
|
||||
"http://example.com",
|
||||
)
|
||||
|
||||
planFactory = atc.NewPlanFactory(123)
|
||||
})
|
||||
|
||||
Context("with no check", func() {
|
||||
JustBeforeEach(func() {
|
||||
_, err = stepBuilder.CheckStep(nil)
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("with a check", func() {
|
||||
var (
|
||||
fakeCheck *dbfakes.FakeCheck
|
||||
|
||||
expectedPlan atc.Plan
|
||||
expectedMetadata exec.StepMetadata
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheck = new(dbfakes.FakeCheck)
|
||||
fakeCheck.ResourceConfigScopeIDReturns(4444)
|
||||
fakeCheck.BaseResourceTypeIDReturns(2222)
|
||||
|
||||
expectedMetadata = exec.StepMetadata{
|
||||
ResourceConfigScopeID: 4444,
|
||||
BaseResourceTypeID: 2222,
|
||||
ExternalURL: "http://example.com",
|
||||
}
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
fakeCheck.PlanReturns(expectedPlan)
|
||||
|
||||
_, err = stepBuilder.CheckStep(fakeCheck)
|
||||
})
|
||||
|
||||
Context("when the check has the wrong schema", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheck.SchemaReturns("not-schema")
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the build has the right schema", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheck.SchemaReturns("exec.v2")
|
||||
})
|
||||
|
||||
It("always returns a plan", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
Context("with a check plan", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
expectedPlan = planFactory.NewPlan(atc.CheckPlan{
|
||||
Name: "some-check",
|
||||
Type: "git",
|
||||
Source: atc.Source{"some": "source"},
|
||||
})
|
||||
})
|
||||
|
||||
It("constructs the put correctly", func() {
|
||||
plan, stepMetadata, containerMetadata, _ := fakeStepFactory.CheckStepArgsForCall(0)
|
||||
Expect(plan).To(Equal(expectedPlan))
|
||||
Expect(stepMetadata).To(Equal(expectedMetadata))
|
||||
Expect(containerMetadata).To(Equal(db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
}))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -23,6 +23,18 @@ type FakeDelegateFactory struct {
|
|||
buildStepDelegateReturnsOnCall map[int]struct {
|
||||
result1 exec.BuildStepDelegate
|
||||
}
|
||||
CheckDelegateStub func(db.Check, atc.PlanID) exec.CheckDelegate
|
||||
checkDelegateMutex sync.RWMutex
|
||||
checkDelegateArgsForCall []struct {
|
||||
arg1 db.Check
|
||||
arg2 atc.PlanID
|
||||
}
|
||||
checkDelegateReturns struct {
|
||||
result1 exec.CheckDelegate
|
||||
}
|
||||
checkDelegateReturnsOnCall map[int]struct {
|
||||
result1 exec.CheckDelegate
|
||||
}
|
||||
GetDelegateStub func(db.Build, atc.PlanID) exec.GetDelegate
|
||||
getDelegateMutex sync.RWMutex
|
||||
getDelegateArgsForCall []struct {
|
||||
|
@ -124,6 +136,67 @@ func (fake *FakeDelegateFactory) BuildStepDelegateReturnsOnCall(i int, result1 e
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeDelegateFactory) CheckDelegate(arg1 db.Check, arg2 atc.PlanID) exec.CheckDelegate {
|
||||
fake.checkDelegateMutex.Lock()
|
||||
ret, specificReturn := fake.checkDelegateReturnsOnCall[len(fake.checkDelegateArgsForCall)]
|
||||
fake.checkDelegateArgsForCall = append(fake.checkDelegateArgsForCall, struct {
|
||||
arg1 db.Check
|
||||
arg2 atc.PlanID
|
||||
}{arg1, arg2})
|
||||
fake.recordInvocation("CheckDelegate", []interface{}{arg1, arg2})
|
||||
fake.checkDelegateMutex.Unlock()
|
||||
if fake.CheckDelegateStub != nil {
|
||||
return fake.CheckDelegateStub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.checkDelegateReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeDelegateFactory) CheckDelegateCallCount() int {
|
||||
fake.checkDelegateMutex.RLock()
|
||||
defer fake.checkDelegateMutex.RUnlock()
|
||||
return len(fake.checkDelegateArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeDelegateFactory) CheckDelegateCalls(stub func(db.Check, atc.PlanID) exec.CheckDelegate) {
|
||||
fake.checkDelegateMutex.Lock()
|
||||
defer fake.checkDelegateMutex.Unlock()
|
||||
fake.CheckDelegateStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeDelegateFactory) CheckDelegateArgsForCall(i int) (db.Check, atc.PlanID) {
|
||||
fake.checkDelegateMutex.RLock()
|
||||
defer fake.checkDelegateMutex.RUnlock()
|
||||
argsForCall := fake.checkDelegateArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeDelegateFactory) CheckDelegateReturns(result1 exec.CheckDelegate) {
|
||||
fake.checkDelegateMutex.Lock()
|
||||
defer fake.checkDelegateMutex.Unlock()
|
||||
fake.CheckDelegateStub = nil
|
||||
fake.checkDelegateReturns = struct {
|
||||
result1 exec.CheckDelegate
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeDelegateFactory) CheckDelegateReturnsOnCall(i int, result1 exec.CheckDelegate) {
|
||||
fake.checkDelegateMutex.Lock()
|
||||
defer fake.checkDelegateMutex.Unlock()
|
||||
fake.CheckDelegateStub = nil
|
||||
if fake.checkDelegateReturnsOnCall == nil {
|
||||
fake.checkDelegateReturnsOnCall = make(map[int]struct {
|
||||
result1 exec.CheckDelegate
|
||||
})
|
||||
}
|
||||
fake.checkDelegateReturnsOnCall[i] = struct {
|
||||
result1 exec.CheckDelegate
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeDelegateFactory) GetDelegate(arg1 db.Build, arg2 atc.PlanID) exec.GetDelegate {
|
||||
fake.getDelegateMutex.Lock()
|
||||
ret, specificReturn := fake.getDelegateReturnsOnCall[len(fake.getDelegateArgsForCall)]
|
||||
|
@ -312,6 +385,8 @@ func (fake *FakeDelegateFactory) Invocations() map[string][][]interface{} {
|
|||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.buildStepDelegateMutex.RLock()
|
||||
defer fake.buildStepDelegateMutex.RUnlock()
|
||||
fake.checkDelegateMutex.RLock()
|
||||
defer fake.checkDelegateMutex.RUnlock()
|
||||
fake.getDelegateMutex.RLock()
|
||||
defer fake.getDelegateMutex.RUnlock()
|
||||
fake.putDelegateMutex.RLock()
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/lock"
|
||||
"github.com/concourse/concourse/atc/engine/builder"
|
||||
"github.com/concourse/concourse/atc/exec"
|
||||
)
|
||||
|
@ -38,6 +37,20 @@ type FakeStepFactory struct {
|
|||
artifactOutputStepReturnsOnCall map[int]struct {
|
||||
result1 exec.Step
|
||||
}
|
||||
CheckStepStub func(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.CheckDelegate) exec.Step
|
||||
checkStepMutex sync.RWMutex
|
||||
checkStepArgsForCall []struct {
|
||||
arg1 atc.Plan
|
||||
arg2 exec.StepMetadata
|
||||
arg3 db.ContainerMetadata
|
||||
arg4 exec.CheckDelegate
|
||||
}
|
||||
checkStepReturns struct {
|
||||
result1 exec.Step
|
||||
}
|
||||
checkStepReturnsOnCall map[int]struct {
|
||||
result1 exec.Step
|
||||
}
|
||||
GetStepStub func(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.GetDelegate) exec.Step
|
||||
getStepMutex sync.RWMutex
|
||||
getStepArgsForCall []struct {
|
||||
|
@ -66,14 +79,13 @@ type FakeStepFactory struct {
|
|||
putStepReturnsOnCall map[int]struct {
|
||||
result1 exec.Step
|
||||
}
|
||||
TaskStepStub func(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.TaskDelegate, lock.LockFactory) exec.Step
|
||||
TaskStepStub func(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.TaskDelegate) exec.Step
|
||||
taskStepMutex sync.RWMutex
|
||||
taskStepArgsForCall []struct {
|
||||
arg1 atc.Plan
|
||||
arg2 exec.StepMetadata
|
||||
arg3 db.ContainerMetadata
|
||||
arg4 exec.TaskDelegate
|
||||
arg5 lock.LockFactory
|
||||
}
|
||||
taskStepReturns struct {
|
||||
result1 exec.Step
|
||||
|
@ -209,6 +221,69 @@ func (fake *FakeStepFactory) ArtifactOutputStepReturnsOnCall(i int, result1 exec
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) CheckStep(arg1 atc.Plan, arg2 exec.StepMetadata, arg3 db.ContainerMetadata, arg4 exec.CheckDelegate) exec.Step {
|
||||
fake.checkStepMutex.Lock()
|
||||
ret, specificReturn := fake.checkStepReturnsOnCall[len(fake.checkStepArgsForCall)]
|
||||
fake.checkStepArgsForCall = append(fake.checkStepArgsForCall, struct {
|
||||
arg1 atc.Plan
|
||||
arg2 exec.StepMetadata
|
||||
arg3 db.ContainerMetadata
|
||||
arg4 exec.CheckDelegate
|
||||
}{arg1, arg2, arg3, arg4})
|
||||
fake.recordInvocation("CheckStep", []interface{}{arg1, arg2, arg3, arg4})
|
||||
fake.checkStepMutex.Unlock()
|
||||
if fake.CheckStepStub != nil {
|
||||
return fake.CheckStepStub(arg1, arg2, arg3, arg4)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.checkStepReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) CheckStepCallCount() int {
|
||||
fake.checkStepMutex.RLock()
|
||||
defer fake.checkStepMutex.RUnlock()
|
||||
return len(fake.checkStepArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) CheckStepCalls(stub func(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.CheckDelegate) exec.Step) {
|
||||
fake.checkStepMutex.Lock()
|
||||
defer fake.checkStepMutex.Unlock()
|
||||
fake.CheckStepStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) CheckStepArgsForCall(i int) (atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.CheckDelegate) {
|
||||
fake.checkStepMutex.RLock()
|
||||
defer fake.checkStepMutex.RUnlock()
|
||||
argsForCall := fake.checkStepArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) CheckStepReturns(result1 exec.Step) {
|
||||
fake.checkStepMutex.Lock()
|
||||
defer fake.checkStepMutex.Unlock()
|
||||
fake.CheckStepStub = nil
|
||||
fake.checkStepReturns = struct {
|
||||
result1 exec.Step
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) CheckStepReturnsOnCall(i int, result1 exec.Step) {
|
||||
fake.checkStepMutex.Lock()
|
||||
defer fake.checkStepMutex.Unlock()
|
||||
fake.CheckStepStub = nil
|
||||
if fake.checkStepReturnsOnCall == nil {
|
||||
fake.checkStepReturnsOnCall = make(map[int]struct {
|
||||
result1 exec.Step
|
||||
})
|
||||
}
|
||||
fake.checkStepReturnsOnCall[i] = struct {
|
||||
result1 exec.Step
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) GetStep(arg1 atc.Plan, arg2 exec.StepMetadata, arg3 db.ContainerMetadata, arg4 exec.GetDelegate) exec.Step {
|
||||
fake.getStepMutex.Lock()
|
||||
ret, specificReturn := fake.getStepReturnsOnCall[len(fake.getStepArgsForCall)]
|
||||
|
@ -335,7 +410,7 @@ func (fake *FakeStepFactory) PutStepReturnsOnCall(i int, result1 exec.Step) {
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) TaskStep(arg1 atc.Plan, arg2 exec.StepMetadata, arg3 db.ContainerMetadata, arg4 exec.TaskDelegate, arg5 lock.LockFactory) exec.Step {
|
||||
func (fake *FakeStepFactory) TaskStep(arg1 atc.Plan, arg2 exec.StepMetadata, arg3 db.ContainerMetadata, arg4 exec.TaskDelegate) exec.Step {
|
||||
fake.taskStepMutex.Lock()
|
||||
ret, specificReturn := fake.taskStepReturnsOnCall[len(fake.taskStepArgsForCall)]
|
||||
fake.taskStepArgsForCall = append(fake.taskStepArgsForCall, struct {
|
||||
|
@ -343,12 +418,11 @@ func (fake *FakeStepFactory) TaskStep(arg1 atc.Plan, arg2 exec.StepMetadata, arg
|
|||
arg2 exec.StepMetadata
|
||||
arg3 db.ContainerMetadata
|
||||
arg4 exec.TaskDelegate
|
||||
arg5 lock.LockFactory
|
||||
}{arg1, arg2, arg3, arg4, arg5})
|
||||
fake.recordInvocation("TaskStep", []interface{}{arg1, arg2, arg3, arg4, arg5})
|
||||
}{arg1, arg2, arg3, arg4})
|
||||
fake.recordInvocation("TaskStep", []interface{}{arg1, arg2, arg3, arg4})
|
||||
fake.taskStepMutex.Unlock()
|
||||
if fake.TaskStepStub != nil {
|
||||
return fake.TaskStepStub(arg1, arg2, arg3, arg4, arg5)
|
||||
return fake.TaskStepStub(arg1, arg2, arg3, arg4)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
|
@ -363,17 +437,17 @@ func (fake *FakeStepFactory) TaskStepCallCount() int {
|
|||
return len(fake.taskStepArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) TaskStepCalls(stub func(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.TaskDelegate, lock.LockFactory) exec.Step) {
|
||||
func (fake *FakeStepFactory) TaskStepCalls(stub func(atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.TaskDelegate) exec.Step) {
|
||||
fake.taskStepMutex.Lock()
|
||||
defer fake.taskStepMutex.Unlock()
|
||||
fake.TaskStepStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) TaskStepArgsForCall(i int) (atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.TaskDelegate, lock.LockFactory) {
|
||||
func (fake *FakeStepFactory) TaskStepArgsForCall(i int) (atc.Plan, exec.StepMetadata, db.ContainerMetadata, exec.TaskDelegate) {
|
||||
fake.taskStepMutex.RLock()
|
||||
defer fake.taskStepMutex.RUnlock()
|
||||
argsForCall := fake.taskStepArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5
|
||||
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
|
||||
}
|
||||
|
||||
func (fake *FakeStepFactory) TaskStepReturns(result1 exec.Step) {
|
||||
|
@ -406,6 +480,8 @@ func (fake *FakeStepFactory) Invocations() map[string][][]interface{} {
|
|||
defer fake.artifactInputStepMutex.RUnlock()
|
||||
fake.artifactOutputStepMutex.RLock()
|
||||
defer fake.artifactOutputStepMutex.RUnlock()
|
||||
fake.checkStepMutex.RLock()
|
||||
defer fake.checkStepMutex.RUnlock()
|
||||
fake.getStepMutex.RLock()
|
||||
defer fake.getStepMutex.RUnlock()
|
||||
fake.putStepMutex.RLock()
|
||||
|
|
|
@ -2,6 +2,7 @@ package builder
|
|||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
|
@ -31,6 +32,10 @@ func (delegate *delegateFactory) TaskDelegate(build db.Build, planID atc.PlanID)
|
|||
return NewTaskDelegate(build, planID, clock.NewClock())
|
||||
}
|
||||
|
||||
func (delegate *delegateFactory) CheckDelegate(check db.Check, planID atc.PlanID) exec.CheckDelegate {
|
||||
return NewCheckDelegate(check, planID, clock.NewClock())
|
||||
}
|
||||
|
||||
func (delegate *delegateFactory) BuildStepDelegate(build db.Build, planID atc.PlanID) exec.BuildStepDelegate {
|
||||
return NewBuildStepDelegate(build, planID, clock.NewClock())
|
||||
}
|
||||
|
@ -274,6 +279,29 @@ func (d *taskDelegate) Finished(logger lager.Logger, exitStatus exec.ExitStatus)
|
|||
logger.Info("finished", lager.Data{"exit-status": exitStatus})
|
||||
}
|
||||
|
||||
func NewCheckDelegate(check db.Check, planID atc.PlanID, clock clock.Clock) exec.CheckDelegate {
|
||||
return &checkDelegate{
|
||||
eventOrigin: event.Origin{ID: event.OriginID(planID)},
|
||||
check: check,
|
||||
clock: clock,
|
||||
}
|
||||
}
|
||||
|
||||
type checkDelegate struct {
|
||||
check db.Check
|
||||
eventOrigin event.Origin
|
||||
clock clock.Clock
|
||||
}
|
||||
|
||||
func (d *checkDelegate) SaveVersions(versions []atc.Version) error {
|
||||
return d.check.SaveVersions(versions)
|
||||
}
|
||||
|
||||
func (*checkDelegate) Stdout() io.Writer { return ioutil.Discard }
|
||||
func (*checkDelegate) Stderr() io.Writer { return ioutil.Discard }
|
||||
func (*checkDelegate) ImageVersionDetermined(db.UsedResourceCache) error { return nil }
|
||||
func (*checkDelegate) Errored(lager.Logger, string) { return }
|
||||
|
||||
func NewBuildStepDelegate(
|
||||
build db.Build,
|
||||
planID atc.PlanID,
|
||||
|
|
|
@ -259,6 +259,33 @@ var _ = Describe("DelegateFactory", func() {
|
|||
})
|
||||
})
|
||||
|
||||
Describe("CheckDelegate", func() {
|
||||
var (
|
||||
delegate exec.CheckDelegate
|
||||
fakeCheck *dbfakes.FakeCheck
|
||||
versions []atc.Version
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheck = new(dbfakes.FakeCheck)
|
||||
|
||||
delegate = builder.NewCheckDelegate(fakeCheck, "some-plan-id", fakeClock)
|
||||
versions = []atc.Version{{"some": "version"}}
|
||||
})
|
||||
|
||||
Describe("SaveVersions", func() {
|
||||
JustBeforeEach(func() {
|
||||
Expect(delegate.SaveVersions(versions)).To(Succeed())
|
||||
})
|
||||
|
||||
It("saves an event", func() {
|
||||
Expect(fakeCheck.SaveVersionsCallCount()).To(Equal(1))
|
||||
actualVersions := fakeCheck.SaveVersionsArgsForCall(0)
|
||||
Expect(actualVersions).To(Equal(versions))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("BuildStepDelegate", func() {
|
||||
var (
|
||||
delegate exec.BuildStepDelegate
|
||||
|
|
|
@ -25,6 +25,7 @@ type stepFactory struct {
|
|||
defaultLimits atc.ContainerLimits
|
||||
strategy worker.ContainerPlacementStrategy
|
||||
resourceFactory resource.ResourceFactory
|
||||
lockFactory lock.LockFactory
|
||||
}
|
||||
|
||||
func NewStepFactory(
|
||||
|
@ -37,6 +38,7 @@ func NewStepFactory(
|
|||
defaultLimits atc.ContainerLimits,
|
||||
strategy worker.ContainerPlacementStrategy,
|
||||
resourceFactory resource.ResourceFactory,
|
||||
lockFactory lock.LockFactory,
|
||||
) *stepFactory {
|
||||
return &stepFactory{
|
||||
pool: pool,
|
||||
|
@ -48,6 +50,7 @@ func NewStepFactory(
|
|||
defaultLimits: defaultLimits,
|
||||
strategy: strategy,
|
||||
resourceFactory: resourceFactory,
|
||||
lockFactory: lockFactory,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,12 +102,34 @@ func (factory *stepFactory) PutStep(
|
|||
return exec.LogError(putStep, delegate)
|
||||
}
|
||||
|
||||
func (factory *stepFactory) CheckStep(
|
||||
plan atc.Plan,
|
||||
stepMetadata exec.StepMetadata,
|
||||
containerMetadata db.ContainerMetadata,
|
||||
delegate exec.CheckDelegate,
|
||||
) exec.Step {
|
||||
containerMetadata.WorkingDirectory = resource.ResourcesDir("check")
|
||||
|
||||
checkStep := exec.NewCheckStep(
|
||||
plan.ID,
|
||||
*plan.Check,
|
||||
stepMetadata,
|
||||
containerMetadata,
|
||||
factory.secretManager,
|
||||
factory.resourceFactory,
|
||||
worker.NewRandomPlacementStrategy(),
|
||||
factory.pool,
|
||||
delegate,
|
||||
)
|
||||
|
||||
return checkStep
|
||||
}
|
||||
|
||||
func (factory *stepFactory) TaskStep(
|
||||
plan atc.Plan,
|
||||
stepMetadata exec.StepMetadata,
|
||||
containerMetadata db.ContainerMetadata,
|
||||
delegate exec.TaskDelegate,
|
||||
lockFactory lock.LockFactory,
|
||||
) exec.Step {
|
||||
sum := sha1.Sum([]byte(plan.Task.Name))
|
||||
containerMetadata.WorkingDirectory = filepath.Join("/tmp", "build", fmt.Sprintf("%x", sum[:4]))
|
||||
|
@ -119,7 +144,7 @@ func (factory *stepFactory) TaskStep(
|
|||
factory.strategy,
|
||||
factory.client,
|
||||
delegate,
|
||||
lockFactory,
|
||||
factory.lockFactory,
|
||||
)
|
||||
|
||||
return exec.LogError(taskStep, delegate)
|
||||
|
|
|
@ -2,6 +2,7 @@ package engine
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -17,6 +18,7 @@ import (
|
|||
|
||||
type Engine interface {
|
||||
NewBuild(db.Build) Runnable
|
||||
NewCheck(db.Check) Runnable
|
||||
ReleaseAll(lager.Logger)
|
||||
}
|
||||
|
||||
|
@ -30,6 +32,7 @@ type Runnable interface {
|
|||
|
||||
type StepBuilder interface {
|
||||
BuildStep(db.Build) (exec.Step, error)
|
||||
CheckStep(db.Check) (exec.Step, error)
|
||||
}
|
||||
|
||||
func NewEngine(builder StepBuilder) Engine {
|
||||
|
@ -77,6 +80,21 @@ func (engine *engine) NewBuild(build db.Build) Runnable {
|
|||
)
|
||||
}
|
||||
|
||||
func (engine *engine) NewCheck(check db.Check) Runnable {
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
return NewCheck(
|
||||
ctx,
|
||||
cancel,
|
||||
check,
|
||||
engine.builder,
|
||||
engine.release,
|
||||
engine.trackedStates,
|
||||
engine.waitGroup,
|
||||
)
|
||||
}
|
||||
|
||||
func NewBuild(
|
||||
ctx context.Context,
|
||||
cancel func(),
|
||||
|
@ -259,11 +277,119 @@ func (b *engineBuild) trackFinished(logger lager.Logger) {
|
|||
}
|
||||
}
|
||||
|
||||
func (build *engineBuild) runState() exec.RunState {
|
||||
existingState, _ := build.trackedStates.LoadOrStore(build.build.ID(), exec.NewRunState())
|
||||
func (b *engineBuild) runState() exec.RunState {
|
||||
id := fmt.Sprintf("build:%v", b.build.ID())
|
||||
existingState, _ := b.trackedStates.LoadOrStore(id, exec.NewRunState())
|
||||
return existingState.(exec.RunState)
|
||||
}
|
||||
|
||||
func (build *engineBuild) clearRunState() {
|
||||
build.trackedStates.Delete(build.build.ID())
|
||||
func (b *engineBuild) clearRunState() {
|
||||
id := fmt.Sprintf("build:%v", b.build.ID())
|
||||
b.trackedStates.Delete(id)
|
||||
}
|
||||
|
||||
func NewCheck(
|
||||
ctx context.Context,
|
||||
cancel func(),
|
||||
check db.Check,
|
||||
builder StepBuilder,
|
||||
release chan bool,
|
||||
trackedStates *sync.Map,
|
||||
waitGroup *sync.WaitGroup,
|
||||
) Runnable {
|
||||
return &engineCheck{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
|
||||
check: check,
|
||||
builder: builder,
|
||||
|
||||
release: release,
|
||||
trackedStates: trackedStates,
|
||||
waitGroup: waitGroup,
|
||||
}
|
||||
}
|
||||
|
||||
type engineCheck struct {
|
||||
ctx context.Context
|
||||
cancel func()
|
||||
|
||||
check db.Check
|
||||
builder StepBuilder
|
||||
|
||||
release chan bool
|
||||
trackedStates *sync.Map
|
||||
waitGroup *sync.WaitGroup
|
||||
}
|
||||
|
||||
func (c *engineCheck) Run(logger lager.Logger) {
|
||||
c.waitGroup.Add(1)
|
||||
defer c.waitGroup.Done()
|
||||
|
||||
logger = logger.WithData(lager.Data{
|
||||
"check": c.check.ID(),
|
||||
})
|
||||
|
||||
lock, acquired, err := c.check.AcquireTrackingLock(logger)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-get-lock", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !acquired {
|
||||
logger.Debug("check-already-tracked")
|
||||
return
|
||||
}
|
||||
|
||||
defer lock.Release()
|
||||
|
||||
err = c.check.Start()
|
||||
if err != nil {
|
||||
logger.Error("failed-to-start-check", err)
|
||||
return
|
||||
}
|
||||
|
||||
step, err := c.builder.CheckStep(c.check)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-create-check-step", err)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("running")
|
||||
|
||||
state := c.runState()
|
||||
defer c.clearRunState()
|
||||
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
ctx := lagerctx.NewContext(c.ctx, logger)
|
||||
done <- step.Run(ctx, state)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-c.release:
|
||||
logger.Info("releasing")
|
||||
|
||||
case err = <-done:
|
||||
if err != nil {
|
||||
logger.Info("errored", lager.Data{"error": err.Error()})
|
||||
c.check.FinishWithError(err)
|
||||
} else {
|
||||
logger.Info("succeeded")
|
||||
if err = c.check.Finish(); err != nil {
|
||||
logger.Error("failed-to-finish-check", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *engineCheck) runState() exec.RunState {
|
||||
id := fmt.Sprintf("check:%v", c.check.ID())
|
||||
existingState, _ := c.trackedStates.LoadOrStore(id, exec.NewRunState())
|
||||
return existingState.(exec.RunState)
|
||||
}
|
||||
|
||||
func (c *engineCheck) clearRunState() {
|
||||
id := fmt.Sprintf("check:%v", c.check.ID())
|
||||
c.trackedStates.Delete(id)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
var _ = Describe("Engine", func() {
|
||||
var (
|
||||
fakeBuild *dbfakes.FakeBuild
|
||||
fakeCheck *dbfakes.FakeCheck
|
||||
fakeStepBuilder *enginefakes.FakeStepBuilder
|
||||
)
|
||||
|
||||
|
@ -30,6 +31,9 @@ var _ = Describe("Engine", func() {
|
|||
fakeBuild = new(dbfakes.FakeBuild)
|
||||
fakeBuild.IDReturns(128)
|
||||
|
||||
fakeCheck = new(dbfakes.FakeCheck)
|
||||
fakeCheck.IDReturns(128)
|
||||
|
||||
fakeStepBuilder = new(enginefakes.FakeStepBuilder)
|
||||
})
|
||||
|
||||
|
@ -47,15 +51,30 @@ var _ = Describe("Engine", func() {
|
|||
build = engine.NewBuild(fakeBuild)
|
||||
})
|
||||
|
||||
// It("succeeds", func() {
|
||||
// Expect(err).NotTo(HaveOccurred())
|
||||
// })
|
||||
|
||||
It("returns a build", func() {
|
||||
Expect(build).NotTo(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("NewCheck", func() {
|
||||
var (
|
||||
check Runnable
|
||||
engine Engine
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
engine = NewEngine(fakeStepBuilder)
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
check = engine.NewCheck(fakeCheck)
|
||||
})
|
||||
|
||||
It("returns a build", func() {
|
||||
Expect(check).NotTo(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Build", func() {
|
||||
var (
|
||||
build Runnable
|
||||
|
@ -325,4 +344,164 @@ var _ = Describe("Engine", func() {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Check", func() {
|
||||
var (
|
||||
check Runnable
|
||||
release chan bool
|
||||
cancel chan bool
|
||||
waitGroup *sync.WaitGroup
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
|
||||
ctx := context.Background()
|
||||
cancel = make(chan bool)
|
||||
release = make(chan bool)
|
||||
trackedStates := new(sync.Map)
|
||||
waitGroup = new(sync.WaitGroup)
|
||||
|
||||
check = NewCheck(
|
||||
ctx,
|
||||
func() { cancel <- true },
|
||||
fakeCheck,
|
||||
fakeStepBuilder,
|
||||
release,
|
||||
trackedStates,
|
||||
waitGroup,
|
||||
)
|
||||
})
|
||||
|
||||
Describe("Run", func() {
|
||||
var logger lager.Logger
|
||||
|
||||
BeforeEach(func() {
|
||||
logger = lagertest.NewTestLogger("test")
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
check.Run(logger)
|
||||
})
|
||||
|
||||
Context("when acquiring the lock succeeds", func() {
|
||||
var fakeLock *lockfakes.FakeLock
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeLock = new(lockfakes.FakeLock)
|
||||
|
||||
fakeCheck.AcquireTrackingLockReturns(fakeLock, true, nil)
|
||||
})
|
||||
|
||||
Context("when the check is started", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheck.StartReturns(nil)
|
||||
})
|
||||
|
||||
Context("when converting the plan to a step succeeds", func() {
|
||||
var fakeStep *execfakes.FakeStep
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeStep = new(execfakes.FakeStep)
|
||||
|
||||
fakeStepBuilder.CheckStepReturns(fakeStep, nil)
|
||||
})
|
||||
|
||||
It("releases the lock", func() {
|
||||
waitGroup.Wait()
|
||||
Expect(fakeLock.ReleaseCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
Context("when the check is released", func() {
|
||||
BeforeEach(func() {
|
||||
readyToRelease := make(chan bool)
|
||||
|
||||
go func() {
|
||||
<-readyToRelease
|
||||
release <- true
|
||||
}()
|
||||
|
||||
fakeStep.RunStub = func(context.Context, exec.RunState) error {
|
||||
close(readyToRelease)
|
||||
<-time.After(time.Hour)
|
||||
return nil
|
||||
}
|
||||
})
|
||||
|
||||
It("does not finish the check", func() {
|
||||
waitGroup.Wait()
|
||||
Expect(fakeCheck.FinishCallCount()).To(Equal(0))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the check finishes without error", func() {
|
||||
BeforeEach(func() {
|
||||
fakeStep.RunReturns(nil)
|
||||
})
|
||||
|
||||
It("finishes the check", func() {
|
||||
waitGroup.Wait()
|
||||
Expect(fakeCheck.FinishCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the check finishes with error", func() {
|
||||
BeforeEach(func() {
|
||||
fakeStep.RunReturns(errors.New("nope"))
|
||||
})
|
||||
|
||||
It("finishes the check", func() {
|
||||
waitGroup.Wait()
|
||||
Expect(fakeCheck.FinishWithErrorCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the check finishes with cancelled error", func() {
|
||||
BeforeEach(func() {
|
||||
fakeStep.RunReturns(context.Canceled)
|
||||
})
|
||||
|
||||
It("finishes the check", func() {
|
||||
waitGroup.Wait()
|
||||
Expect(fakeCheck.FinishWithErrorCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when converting the plan to a step fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeStepBuilder.CheckStepReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("releases the lock", func() {
|
||||
Expect(fakeLock.ReleaseCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the check can't be started", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheck.StartReturns(errors.New("nope"))
|
||||
})
|
||||
|
||||
It("does not create the check step", func() {
|
||||
Expect(fakeStepBuilder.CheckStepCallCount()).To(BeZero())
|
||||
})
|
||||
|
||||
It("releases the lock", func() {
|
||||
Expect(fakeLock.ReleaseCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when acquiring the lock fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheck.AcquireTrackingLockReturns(nil, false, errors.New("no lock for you"))
|
||||
})
|
||||
|
||||
It("does not create the check step", func() {
|
||||
Expect(fakeStepBuilder.CheckStepCallCount()).To(BeZero())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -21,6 +21,17 @@ type FakeEngine struct {
|
|||
newBuildReturnsOnCall map[int]struct {
|
||||
result1 engine.Runnable
|
||||
}
|
||||
NewCheckStub func(db.Check) engine.Runnable
|
||||
newCheckMutex sync.RWMutex
|
||||
newCheckArgsForCall []struct {
|
||||
arg1 db.Check
|
||||
}
|
||||
newCheckReturns struct {
|
||||
result1 engine.Runnable
|
||||
}
|
||||
newCheckReturnsOnCall map[int]struct {
|
||||
result1 engine.Runnable
|
||||
}
|
||||
ReleaseAllStub func(lager.Logger)
|
||||
releaseAllMutex sync.RWMutex
|
||||
releaseAllArgsForCall []struct {
|
||||
|
@ -90,6 +101,66 @@ func (fake *FakeEngine) NewBuildReturnsOnCall(i int, result1 engine.Runnable) {
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeEngine) NewCheck(arg1 db.Check) engine.Runnable {
|
||||
fake.newCheckMutex.Lock()
|
||||
ret, specificReturn := fake.newCheckReturnsOnCall[len(fake.newCheckArgsForCall)]
|
||||
fake.newCheckArgsForCall = append(fake.newCheckArgsForCall, struct {
|
||||
arg1 db.Check
|
||||
}{arg1})
|
||||
fake.recordInvocation("NewCheck", []interface{}{arg1})
|
||||
fake.newCheckMutex.Unlock()
|
||||
if fake.NewCheckStub != nil {
|
||||
return fake.NewCheckStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.newCheckReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeEngine) NewCheckCallCount() int {
|
||||
fake.newCheckMutex.RLock()
|
||||
defer fake.newCheckMutex.RUnlock()
|
||||
return len(fake.newCheckArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeEngine) NewCheckCalls(stub func(db.Check) engine.Runnable) {
|
||||
fake.newCheckMutex.Lock()
|
||||
defer fake.newCheckMutex.Unlock()
|
||||
fake.NewCheckStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeEngine) NewCheckArgsForCall(i int) db.Check {
|
||||
fake.newCheckMutex.RLock()
|
||||
defer fake.newCheckMutex.RUnlock()
|
||||
argsForCall := fake.newCheckArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeEngine) NewCheckReturns(result1 engine.Runnable) {
|
||||
fake.newCheckMutex.Lock()
|
||||
defer fake.newCheckMutex.Unlock()
|
||||
fake.NewCheckStub = nil
|
||||
fake.newCheckReturns = struct {
|
||||
result1 engine.Runnable
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeEngine) NewCheckReturnsOnCall(i int, result1 engine.Runnable) {
|
||||
fake.newCheckMutex.Lock()
|
||||
defer fake.newCheckMutex.Unlock()
|
||||
fake.NewCheckStub = nil
|
||||
if fake.newCheckReturnsOnCall == nil {
|
||||
fake.newCheckReturnsOnCall = make(map[int]struct {
|
||||
result1 engine.Runnable
|
||||
})
|
||||
}
|
||||
fake.newCheckReturnsOnCall[i] = struct {
|
||||
result1 engine.Runnable
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeEngine) ReleaseAll(arg1 lager.Logger) {
|
||||
fake.releaseAllMutex.Lock()
|
||||
fake.releaseAllArgsForCall = append(fake.releaseAllArgsForCall, struct {
|
||||
|
@ -126,6 +197,8 @@ func (fake *FakeEngine) Invocations() map[string][][]interface{} {
|
|||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.newBuildMutex.RLock()
|
||||
defer fake.newBuildMutex.RUnlock()
|
||||
fake.newCheckMutex.RLock()
|
||||
defer fake.newCheckMutex.RUnlock()
|
||||
fake.releaseAllMutex.RLock()
|
||||
defer fake.releaseAllMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
|
|
|
@ -23,6 +23,19 @@ type FakeStepBuilder struct {
|
|||
result1 exec.Step
|
||||
result2 error
|
||||
}
|
||||
CheckStepStub func(db.Check) (exec.Step, error)
|
||||
checkStepMutex sync.RWMutex
|
||||
checkStepArgsForCall []struct {
|
||||
arg1 db.Check
|
||||
}
|
||||
checkStepReturns struct {
|
||||
result1 exec.Step
|
||||
result2 error
|
||||
}
|
||||
checkStepReturnsOnCall map[int]struct {
|
||||
result1 exec.Step
|
||||
result2 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
@ -90,11 +103,76 @@ func (fake *FakeStepBuilder) BuildStepReturnsOnCall(i int, result1 exec.Step, re
|
|||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeStepBuilder) CheckStep(arg1 db.Check) (exec.Step, error) {
|
||||
fake.checkStepMutex.Lock()
|
||||
ret, specificReturn := fake.checkStepReturnsOnCall[len(fake.checkStepArgsForCall)]
|
||||
fake.checkStepArgsForCall = append(fake.checkStepArgsForCall, struct {
|
||||
arg1 db.Check
|
||||
}{arg1})
|
||||
fake.recordInvocation("CheckStep", []interface{}{arg1})
|
||||
fake.checkStepMutex.Unlock()
|
||||
if fake.CheckStepStub != nil {
|
||||
return fake.CheckStepStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
fakeReturns := fake.checkStepReturns
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeStepBuilder) CheckStepCallCount() int {
|
||||
fake.checkStepMutex.RLock()
|
||||
defer fake.checkStepMutex.RUnlock()
|
||||
return len(fake.checkStepArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeStepBuilder) CheckStepCalls(stub func(db.Check) (exec.Step, error)) {
|
||||
fake.checkStepMutex.Lock()
|
||||
defer fake.checkStepMutex.Unlock()
|
||||
fake.CheckStepStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeStepBuilder) CheckStepArgsForCall(i int) db.Check {
|
||||
fake.checkStepMutex.RLock()
|
||||
defer fake.checkStepMutex.RUnlock()
|
||||
argsForCall := fake.checkStepArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeStepBuilder) CheckStepReturns(result1 exec.Step, result2 error) {
|
||||
fake.checkStepMutex.Lock()
|
||||
defer fake.checkStepMutex.Unlock()
|
||||
fake.CheckStepStub = nil
|
||||
fake.checkStepReturns = struct {
|
||||
result1 exec.Step
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeStepBuilder) CheckStepReturnsOnCall(i int, result1 exec.Step, result2 error) {
|
||||
fake.checkStepMutex.Lock()
|
||||
defer fake.checkStepMutex.Unlock()
|
||||
fake.CheckStepStub = nil
|
||||
if fake.checkStepReturnsOnCall == nil {
|
||||
fake.checkStepReturnsOnCall = make(map[int]struct {
|
||||
result1 exec.Step
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.checkStepReturnsOnCall[i] = struct {
|
||||
result1 exec.Step
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeStepBuilder) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.buildStepMutex.RLock()
|
||||
defer fake.buildStepMutex.RUnlock()
|
||||
fake.checkStepMutex.RLock()
|
||||
defer fake.checkStepMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
package exec
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/lager"
|
||||
"code.cloudfoundry.org/lager/lagerctx"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/creds"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/metric"
|
||||
"github.com/concourse/concourse/atc/resource"
|
||||
"github.com/concourse/concourse/atc/worker"
|
||||
)
|
||||
|
||||
type CheckStep struct {
|
||||
planID atc.PlanID
|
||||
plan atc.CheckPlan
|
||||
metadata StepMetadata
|
||||
containerMetadata db.ContainerMetadata
|
||||
secrets creds.Secrets
|
||||
resourceFactory resource.ResourceFactory
|
||||
strategy worker.ContainerPlacementStrategy
|
||||
pool worker.Pool
|
||||
delegate CheckDelegate
|
||||
succeeded bool
|
||||
}
|
||||
|
||||
type CheckDelegate interface {
|
||||
BuildStepDelegate
|
||||
|
||||
SaveVersions([]atc.Version) error
|
||||
}
|
||||
|
||||
func NewCheckStep(
|
||||
planID atc.PlanID,
|
||||
plan atc.CheckPlan,
|
||||
metadata StepMetadata,
|
||||
containerMetadata db.ContainerMetadata,
|
||||
secrets creds.Secrets,
|
||||
resourceFactory resource.ResourceFactory,
|
||||
strategy worker.ContainerPlacementStrategy,
|
||||
pool worker.Pool,
|
||||
delegate CheckDelegate,
|
||||
) *CheckStep {
|
||||
return &CheckStep{
|
||||
planID: planID,
|
||||
plan: plan,
|
||||
metadata: metadata,
|
||||
secrets: secrets,
|
||||
containerMetadata: containerMetadata,
|
||||
resourceFactory: resourceFactory,
|
||||
pool: pool,
|
||||
strategy: strategy,
|
||||
delegate: delegate,
|
||||
}
|
||||
}
|
||||
|
||||
func (step *CheckStep) Run(ctx context.Context, state RunState) error {
|
||||
logger := lagerctx.FromContext(ctx)
|
||||
logger = logger.Session("check-step", lager.Data{
|
||||
"step-name": step.plan.Name,
|
||||
})
|
||||
|
||||
resourceTypes := step.plan.VersionedResourceTypes
|
||||
|
||||
containerSpec := worker.ContainerSpec{
|
||||
ImageSpec: worker.ImageSpec{
|
||||
ResourceType: step.plan.Type,
|
||||
},
|
||||
BindMounts: []worker.BindMountSource{
|
||||
&worker.CertsVolumeMount{Logger: logger},
|
||||
},
|
||||
Tags: step.plan.Tags,
|
||||
TeamID: step.metadata.TeamID,
|
||||
Env: step.metadata.Env(),
|
||||
}
|
||||
|
||||
workerSpec := worker.WorkerSpec{
|
||||
ResourceType: step.plan.Type,
|
||||
Tags: step.plan.Tags,
|
||||
ResourceTypes: resourceTypes,
|
||||
TeamID: step.metadata.TeamID,
|
||||
}
|
||||
|
||||
expires := db.ContainerOwnerExpiries{
|
||||
Min: 5 * time.Minute,
|
||||
Max: 1 * time.Hour,
|
||||
}
|
||||
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(
|
||||
step.metadata.ResourceConfigID,
|
||||
step.metadata.BaseResourceTypeID,
|
||||
expires,
|
||||
)
|
||||
|
||||
chosenWorker, err := step.pool.FindOrChooseWorkerForContainer(
|
||||
ctx,
|
||||
logger,
|
||||
owner,
|
||||
containerSpec,
|
||||
workerSpec,
|
||||
step.strategy,
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-find-or-choose-worker", err)
|
||||
return err
|
||||
}
|
||||
|
||||
container, err := chosenWorker.FindOrCreateContainer(
|
||||
ctx,
|
||||
logger,
|
||||
step.delegate,
|
||||
owner,
|
||||
step.containerMetadata,
|
||||
containerSpec,
|
||||
resourceTypes,
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-find-or-create-container", err)
|
||||
return err
|
||||
}
|
||||
|
||||
timeout, err := time.ParseDuration(step.plan.Timeout)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-parse-timeout", err)
|
||||
return err
|
||||
}
|
||||
|
||||
deadline, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
checkable := step.resourceFactory.NewResourceForContainer(container)
|
||||
|
||||
versions, err := checkable.Check(deadline, step.plan.Source, step.plan.FromVersion)
|
||||
if err != nil {
|
||||
if err == context.DeadlineExceeded {
|
||||
return fmt.Errorf("Timed out after %v while checking for new versions", timeout)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
metric.CheckFinished{
|
||||
CheckName: step.plan.Name,
|
||||
ResourceConfigScopeID: strconv.Itoa(step.metadata.ResourceConfigScopeID),
|
||||
Success: err == nil,
|
||||
}.Emit(logger)
|
||||
|
||||
err = step.delegate.SaveVersions(versions)
|
||||
if err != nil {
|
||||
logger.Error("failed-to-save-versions", err)
|
||||
return err
|
||||
}
|
||||
|
||||
step.succeeded = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *CheckStep) Succeeded() bool {
|
||||
return step.succeeded
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
package exec_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/creds/credsfakes"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/exec"
|
||||
"github.com/concourse/concourse/atc/exec/artifact"
|
||||
"github.com/concourse/concourse/atc/exec/execfakes"
|
||||
"github.com/concourse/concourse/atc/resource/resourcefakes"
|
||||
"github.com/concourse/concourse/atc/worker"
|
||||
"github.com/concourse/concourse/atc/worker/workerfakes"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("CheckStep", func() {
|
||||
var (
|
||||
ctx context.Context
|
||||
cancel func()
|
||||
|
||||
fakeWorker *workerfakes.FakeWorker
|
||||
fakePool *workerfakes.FakePool
|
||||
fakeStrategy *workerfakes.FakeContainerPlacementStrategy
|
||||
fakeResourceFactory *resourcefakes.FakeResourceFactory
|
||||
fakeSecretManager *credsfakes.FakeSecrets
|
||||
fakeDelegate *execfakes.FakeCheckDelegate
|
||||
checkPlan *atc.CheckPlan
|
||||
|
||||
interpolatedResourceTypes atc.VersionedResourceTypes
|
||||
|
||||
containerMetadata = db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
StepName: "some-step",
|
||||
}
|
||||
|
||||
stepMetadata = exec.StepMetadata{
|
||||
ResourceConfigID: 1,
|
||||
BaseResourceTypeID: 1,
|
||||
TeamID: 123,
|
||||
}
|
||||
|
||||
owner = db.NewResourceConfigCheckSessionContainerOwner(stepMetadata.ResourceConfigID, stepMetadata.BaseResourceTypeID, db.ContainerOwnerExpiries{
|
||||
Min: 5 * time.Minute,
|
||||
Max: 1 * time.Hour,
|
||||
})
|
||||
|
||||
repo *artifact.Repository
|
||||
state *execfakes.FakeRunState
|
||||
|
||||
checkStep *exec.CheckStep
|
||||
stepErr error
|
||||
|
||||
planID atc.PlanID
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
|
||||
planID = atc.PlanID("some-plan-id")
|
||||
|
||||
fakeStrategy = new(workerfakes.FakeContainerPlacementStrategy)
|
||||
fakePool = new(workerfakes.FakePool)
|
||||
fakeWorker = new(workerfakes.FakeWorker)
|
||||
fakeResourceFactory = new(resourcefakes.FakeResourceFactory)
|
||||
|
||||
fakeSecretManager = new(credsfakes.FakeSecrets)
|
||||
fakeSecretManager.GetReturnsOnCall(0, "super-secret-source", nil, true, nil)
|
||||
fakeSecretManager.GetReturnsOnCall(1, "source", nil, true, nil)
|
||||
|
||||
fakeDelegate = new(execfakes.FakeCheckDelegate)
|
||||
|
||||
repo = artifact.NewRepository()
|
||||
state = new(execfakes.FakeRunState)
|
||||
state.ArtifactsReturns(repo)
|
||||
|
||||
interpolatedResourceTypes = atc.VersionedResourceTypes{
|
||||
{
|
||||
ResourceType: atc.ResourceType{
|
||||
Name: "custom-resource",
|
||||
Type: "custom-type",
|
||||
Source: atc.Source{"some-custom": "super-secret-source"},
|
||||
},
|
||||
Version: atc.Version{"some-custom": "version"},
|
||||
},
|
||||
}
|
||||
|
||||
checkPlan = &atc.CheckPlan{
|
||||
Name: "some-name",
|
||||
Type: "some-resource-type",
|
||||
Source: atc.Source{"some": "super-secret-source"},
|
||||
Tags: []string{"some", "tags"},
|
||||
Timeout: "10s",
|
||||
FromVersion: atc.Version{"some-custom": "version"},
|
||||
VersionedResourceTypes: interpolatedResourceTypes,
|
||||
}
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
cancel()
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
plan := atc.Plan{
|
||||
ID: atc.PlanID(planID),
|
||||
Check: checkPlan,
|
||||
}
|
||||
|
||||
checkStep = exec.NewCheckStep(
|
||||
plan.ID,
|
||||
*plan.Check,
|
||||
stepMetadata,
|
||||
containerMetadata,
|
||||
fakeSecretManager,
|
||||
fakeResourceFactory,
|
||||
fakeStrategy,
|
||||
fakePool,
|
||||
fakeDelegate,
|
||||
)
|
||||
|
||||
stepErr = checkStep.Run(ctx, state)
|
||||
})
|
||||
|
||||
Context("when find or choosing worker succeeds", func() {
|
||||
var (
|
||||
fakeResource *resourcefakes.FakeResource
|
||||
versions []atc.Version
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeWorker.NameReturns("some-worker")
|
||||
fakePool.FindOrChooseWorkerForContainerReturns(fakeWorker, nil)
|
||||
|
||||
fakeResource = new(resourcefakes.FakeResource)
|
||||
fakeResourceFactory.NewResourceForContainerReturns(fakeResource)
|
||||
})
|
||||
|
||||
It("finds or chooses a worker", func() {
|
||||
Expect(fakePool.FindOrChooseWorkerForContainerCallCount()).To(Equal(1))
|
||||
_, _, actualOwner, actualContainerSpec, actualWorkerSpec, strategy := fakePool.FindOrChooseWorkerForContainerArgsForCall(0)
|
||||
|
||||
Expect(actualOwner).To(Equal(owner))
|
||||
|
||||
Expect(actualContainerSpec.ImageSpec).To(Equal(worker.ImageSpec{
|
||||
ResourceType: "some-resource-type",
|
||||
}))
|
||||
Expect(actualContainerSpec.Tags).To(Equal([]string{"some", "tags"}))
|
||||
Expect(actualContainerSpec.TeamID).To(Equal(123))
|
||||
Expect(actualContainerSpec.Env).To(Equal(stepMetadata.Env()))
|
||||
|
||||
Expect(actualWorkerSpec).To(Equal(worker.WorkerSpec{
|
||||
ResourceType: "some-resource-type",
|
||||
Tags: atc.Tags{"some", "tags"},
|
||||
TeamID: stepMetadata.TeamID,
|
||||
ResourceTypes: interpolatedResourceTypes,
|
||||
}))
|
||||
|
||||
Expect(strategy).To(Equal(fakeStrategy))
|
||||
})
|
||||
|
||||
It("creates a container with the correct type and owner", func() {
|
||||
_, _, delegate, actualOwner, actualContainerMetadata, actualContainerSpec, actualResourceTypes := fakeWorker.FindOrCreateContainerArgsForCall(0)
|
||||
|
||||
Expect(actualOwner).To(Equal(owner))
|
||||
|
||||
Expect(actualContainerSpec.ImageSpec).To(Equal(worker.ImageSpec{
|
||||
ResourceType: "some-resource-type",
|
||||
}))
|
||||
Expect(actualContainerMetadata).To(Equal(containerMetadata))
|
||||
Expect(actualContainerSpec.Tags).To(Equal([]string{"some", "tags"}))
|
||||
Expect(actualContainerSpec.TeamID).To(Equal(123))
|
||||
Expect(actualContainerSpec.Env).To(Equal(stepMetadata.Env()))
|
||||
|
||||
Expect(actualResourceTypes).To(Equal(interpolatedResourceTypes))
|
||||
Expect(delegate).To(Equal(fakeDelegate))
|
||||
})
|
||||
|
||||
Context("when the timeout cannot be parsed", func() {
|
||||
BeforeEach(func() {
|
||||
checkPlan.Timeout = "bad-value"
|
||||
})
|
||||
|
||||
It("fails to parse the timeout and returns the error", func() {
|
||||
Expect(stepErr).To(HaveOccurred())
|
||||
Expect(stepErr).To(MatchError("time: invalid duration bad-value"))
|
||||
})
|
||||
})
|
||||
|
||||
It("times out after the specified timeout", func() {
|
||||
now := time.Now()
|
||||
ctx, _, _ := fakeResource.CheckArgsForCall(0)
|
||||
deadline, _ := ctx.Deadline()
|
||||
Expect(deadline).Should(BeTemporally("~", now.Add(10*time.Second), time.Second))
|
||||
})
|
||||
|
||||
It("runs the check resource action", func() {
|
||||
Expect(fakeResource.CheckCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
Context("when resource check succeeds", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.CheckReturns(versions, nil)
|
||||
})
|
||||
|
||||
It("saves the versions", func() {
|
||||
Expect(fakeDelegate.SaveVersionsCallCount()).To(Equal(1))
|
||||
|
||||
actualVersions := fakeDelegate.SaveVersionsArgsForCall(0)
|
||||
Expect(actualVersions).To(Equal(versions))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when performing the check fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.CheckReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("returns error", func() {
|
||||
Expect(stepErr).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("is not successful", func() {
|
||||
Expect(checkStep.Succeeded()).To(BeFalse())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when find or choosing a worker fails", func() {
|
||||
disaster := errors.New("nope")
|
||||
|
||||
BeforeEach(func() {
|
||||
fakePool.FindOrChooseWorkerForContainerReturns(nil, disaster)
|
||||
})
|
||||
|
||||
It("returns the failure", func() {
|
||||
Expect(stepErr).To(Equal(disaster))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when find or creating a container fails", func() {
|
||||
disaster := errors.New("nope")
|
||||
|
||||
BeforeEach(func() {
|
||||
fakePool.FindOrChooseWorkerForContainerReturns(fakeWorker, nil)
|
||||
fakeWorker.FindOrCreateContainerReturns(nil, disaster)
|
||||
})
|
||||
|
||||
It("returns the failure", func() {
|
||||
Expect(stepErr).To(Equal(disaster))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,360 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package execfakes
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/exec"
|
||||
)
|
||||
|
||||
type FakeCheckDelegate struct {
|
||||
ErroredStub func(lager.Logger, string)
|
||||
erroredMutex sync.RWMutex
|
||||
erroredArgsForCall []struct {
|
||||
arg1 lager.Logger
|
||||
arg2 string
|
||||
}
|
||||
ImageVersionDeterminedStub func(db.UsedResourceCache) error
|
||||
imageVersionDeterminedMutex sync.RWMutex
|
||||
imageVersionDeterminedArgsForCall []struct {
|
||||
arg1 db.UsedResourceCache
|
||||
}
|
||||
imageVersionDeterminedReturns struct {
|
||||
result1 error
|
||||
}
|
||||
imageVersionDeterminedReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
SaveVersionsStub func([]atc.Version) error
|
||||
saveVersionsMutex sync.RWMutex
|
||||
saveVersionsArgsForCall []struct {
|
||||
arg1 []atc.Version
|
||||
}
|
||||
saveVersionsReturns struct {
|
||||
result1 error
|
||||
}
|
||||
saveVersionsReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
StderrStub func() io.Writer
|
||||
stderrMutex sync.RWMutex
|
||||
stderrArgsForCall []struct {
|
||||
}
|
||||
stderrReturns struct {
|
||||
result1 io.Writer
|
||||
}
|
||||
stderrReturnsOnCall map[int]struct {
|
||||
result1 io.Writer
|
||||
}
|
||||
StdoutStub func() io.Writer
|
||||
stdoutMutex sync.RWMutex
|
||||
stdoutArgsForCall []struct {
|
||||
}
|
||||
stdoutReturns struct {
|
||||
result1 io.Writer
|
||||
}
|
||||
stdoutReturnsOnCall map[int]struct {
|
||||
result1 io.Writer
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) Errored(arg1 lager.Logger, arg2 string) {
|
||||
fake.erroredMutex.Lock()
|
||||
fake.erroredArgsForCall = append(fake.erroredArgsForCall, struct {
|
||||
arg1 lager.Logger
|
||||
arg2 string
|
||||
}{arg1, arg2})
|
||||
fake.recordInvocation("Errored", []interface{}{arg1, arg2})
|
||||
fake.erroredMutex.Unlock()
|
||||
if fake.ErroredStub != nil {
|
||||
fake.ErroredStub(arg1, arg2)
|
||||
}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ErroredCallCount() int {
|
||||
fake.erroredMutex.RLock()
|
||||
defer fake.erroredMutex.RUnlock()
|
||||
return len(fake.erroredArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ErroredCalls(stub func(lager.Logger, string)) {
|
||||
fake.erroredMutex.Lock()
|
||||
defer fake.erroredMutex.Unlock()
|
||||
fake.ErroredStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ErroredArgsForCall(i int) (lager.Logger, string) {
|
||||
fake.erroredMutex.RLock()
|
||||
defer fake.erroredMutex.RUnlock()
|
||||
argsForCall := fake.erroredArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ImageVersionDetermined(arg1 db.UsedResourceCache) error {
|
||||
fake.imageVersionDeterminedMutex.Lock()
|
||||
ret, specificReturn := fake.imageVersionDeterminedReturnsOnCall[len(fake.imageVersionDeterminedArgsForCall)]
|
||||
fake.imageVersionDeterminedArgsForCall = append(fake.imageVersionDeterminedArgsForCall, struct {
|
||||
arg1 db.UsedResourceCache
|
||||
}{arg1})
|
||||
fake.recordInvocation("ImageVersionDetermined", []interface{}{arg1})
|
||||
fake.imageVersionDeterminedMutex.Unlock()
|
||||
if fake.ImageVersionDeterminedStub != nil {
|
||||
return fake.ImageVersionDeterminedStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.imageVersionDeterminedReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ImageVersionDeterminedCallCount() int {
|
||||
fake.imageVersionDeterminedMutex.RLock()
|
||||
defer fake.imageVersionDeterminedMutex.RUnlock()
|
||||
return len(fake.imageVersionDeterminedArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ImageVersionDeterminedCalls(stub func(db.UsedResourceCache) error) {
|
||||
fake.imageVersionDeterminedMutex.Lock()
|
||||
defer fake.imageVersionDeterminedMutex.Unlock()
|
||||
fake.ImageVersionDeterminedStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ImageVersionDeterminedArgsForCall(i int) db.UsedResourceCache {
|
||||
fake.imageVersionDeterminedMutex.RLock()
|
||||
defer fake.imageVersionDeterminedMutex.RUnlock()
|
||||
argsForCall := fake.imageVersionDeterminedArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ImageVersionDeterminedReturns(result1 error) {
|
||||
fake.imageVersionDeterminedMutex.Lock()
|
||||
defer fake.imageVersionDeterminedMutex.Unlock()
|
||||
fake.ImageVersionDeterminedStub = nil
|
||||
fake.imageVersionDeterminedReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) ImageVersionDeterminedReturnsOnCall(i int, result1 error) {
|
||||
fake.imageVersionDeterminedMutex.Lock()
|
||||
defer fake.imageVersionDeterminedMutex.Unlock()
|
||||
fake.ImageVersionDeterminedStub = nil
|
||||
if fake.imageVersionDeterminedReturnsOnCall == nil {
|
||||
fake.imageVersionDeterminedReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.imageVersionDeterminedReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) SaveVersions(arg1 []atc.Version) error {
|
||||
var arg1Copy []atc.Version
|
||||
if arg1 != nil {
|
||||
arg1Copy = make([]atc.Version, len(arg1))
|
||||
copy(arg1Copy, arg1)
|
||||
}
|
||||
fake.saveVersionsMutex.Lock()
|
||||
ret, specificReturn := fake.saveVersionsReturnsOnCall[len(fake.saveVersionsArgsForCall)]
|
||||
fake.saveVersionsArgsForCall = append(fake.saveVersionsArgsForCall, struct {
|
||||
arg1 []atc.Version
|
||||
}{arg1Copy})
|
||||
fake.recordInvocation("SaveVersions", []interface{}{arg1Copy})
|
||||
fake.saveVersionsMutex.Unlock()
|
||||
if fake.SaveVersionsStub != nil {
|
||||
return fake.SaveVersionsStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.saveVersionsReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) SaveVersionsCallCount() int {
|
||||
fake.saveVersionsMutex.RLock()
|
||||
defer fake.saveVersionsMutex.RUnlock()
|
||||
return len(fake.saveVersionsArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) SaveVersionsCalls(stub func([]atc.Version) error) {
|
||||
fake.saveVersionsMutex.Lock()
|
||||
defer fake.saveVersionsMutex.Unlock()
|
||||
fake.SaveVersionsStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) SaveVersionsArgsForCall(i int) []atc.Version {
|
||||
fake.saveVersionsMutex.RLock()
|
||||
defer fake.saveVersionsMutex.RUnlock()
|
||||
argsForCall := fake.saveVersionsArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) SaveVersionsReturns(result1 error) {
|
||||
fake.saveVersionsMutex.Lock()
|
||||
defer fake.saveVersionsMutex.Unlock()
|
||||
fake.SaveVersionsStub = nil
|
||||
fake.saveVersionsReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) SaveVersionsReturnsOnCall(i int, result1 error) {
|
||||
fake.saveVersionsMutex.Lock()
|
||||
defer fake.saveVersionsMutex.Unlock()
|
||||
fake.SaveVersionsStub = nil
|
||||
if fake.saveVersionsReturnsOnCall == nil {
|
||||
fake.saveVersionsReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.saveVersionsReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) Stderr() io.Writer {
|
||||
fake.stderrMutex.Lock()
|
||||
ret, specificReturn := fake.stderrReturnsOnCall[len(fake.stderrArgsForCall)]
|
||||
fake.stderrArgsForCall = append(fake.stderrArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("Stderr", []interface{}{})
|
||||
fake.stderrMutex.Unlock()
|
||||
if fake.StderrStub != nil {
|
||||
return fake.StderrStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.stderrReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) StderrCallCount() int {
|
||||
fake.stderrMutex.RLock()
|
||||
defer fake.stderrMutex.RUnlock()
|
||||
return len(fake.stderrArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) StderrCalls(stub func() io.Writer) {
|
||||
fake.stderrMutex.Lock()
|
||||
defer fake.stderrMutex.Unlock()
|
||||
fake.StderrStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) StderrReturns(result1 io.Writer) {
|
||||
fake.stderrMutex.Lock()
|
||||
defer fake.stderrMutex.Unlock()
|
||||
fake.StderrStub = nil
|
||||
fake.stderrReturns = struct {
|
||||
result1 io.Writer
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) StderrReturnsOnCall(i int, result1 io.Writer) {
|
||||
fake.stderrMutex.Lock()
|
||||
defer fake.stderrMutex.Unlock()
|
||||
fake.StderrStub = nil
|
||||
if fake.stderrReturnsOnCall == nil {
|
||||
fake.stderrReturnsOnCall = make(map[int]struct {
|
||||
result1 io.Writer
|
||||
})
|
||||
}
|
||||
fake.stderrReturnsOnCall[i] = struct {
|
||||
result1 io.Writer
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) Stdout() io.Writer {
|
||||
fake.stdoutMutex.Lock()
|
||||
ret, specificReturn := fake.stdoutReturnsOnCall[len(fake.stdoutArgsForCall)]
|
||||
fake.stdoutArgsForCall = append(fake.stdoutArgsForCall, struct {
|
||||
}{})
|
||||
fake.recordInvocation("Stdout", []interface{}{})
|
||||
fake.stdoutMutex.Unlock()
|
||||
if fake.StdoutStub != nil {
|
||||
return fake.StdoutStub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.stdoutReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) StdoutCallCount() int {
|
||||
fake.stdoutMutex.RLock()
|
||||
defer fake.stdoutMutex.RUnlock()
|
||||
return len(fake.stdoutArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) StdoutCalls(stub func() io.Writer) {
|
||||
fake.stdoutMutex.Lock()
|
||||
defer fake.stdoutMutex.Unlock()
|
||||
fake.StdoutStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) StdoutReturns(result1 io.Writer) {
|
||||
fake.stdoutMutex.Lock()
|
||||
defer fake.stdoutMutex.Unlock()
|
||||
fake.StdoutStub = nil
|
||||
fake.stdoutReturns = struct {
|
||||
result1 io.Writer
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) StdoutReturnsOnCall(i int, result1 io.Writer) {
|
||||
fake.stdoutMutex.Lock()
|
||||
defer fake.stdoutMutex.Unlock()
|
||||
fake.StdoutStub = nil
|
||||
if fake.stdoutReturnsOnCall == nil {
|
||||
fake.stdoutReturnsOnCall = make(map[int]struct {
|
||||
result1 io.Writer
|
||||
})
|
||||
}
|
||||
fake.stdoutReturnsOnCall[i] = struct {
|
||||
result1 io.Writer
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.erroredMutex.RLock()
|
||||
defer fake.erroredMutex.RUnlock()
|
||||
fake.imageVersionDeterminedMutex.RLock()
|
||||
defer fake.imageVersionDeterminedMutex.RUnlock()
|
||||
fake.saveVersionsMutex.RLock()
|
||||
defer fake.saveVersionsMutex.RUnlock()
|
||||
fake.stderrMutex.RLock()
|
||||
defer fake.stderrMutex.RUnlock()
|
||||
fake.stdoutMutex.RLock()
|
||||
defer fake.stdoutMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakeCheckDelegate) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ exec.CheckDelegate = new(FakeCheckDelegate)
|
|
@ -5,19 +5,26 @@ import (
|
|||
)
|
||||
|
||||
type StepMetadata struct {
|
||||
BuildID int
|
||||
BuildName string
|
||||
TeamID int
|
||||
TeamName string
|
||||
JobID int
|
||||
JobName string
|
||||
PipelineID int
|
||||
PipelineName string
|
||||
ExternalURL string
|
||||
BuildID int
|
||||
BuildName string
|
||||
TeamID int
|
||||
TeamName string
|
||||
JobID int
|
||||
JobName string
|
||||
PipelineID int
|
||||
PipelineName string
|
||||
ResourceConfigScopeID int
|
||||
ResourceConfigID int
|
||||
BaseResourceTypeID int
|
||||
ExternalURL string
|
||||
}
|
||||
|
||||
func (metadata StepMetadata) Env() []string {
|
||||
env := []string{fmt.Sprintf("BUILD_ID=%d", metadata.BuildID)}
|
||||
env := []string{}
|
||||
|
||||
if metadata.BuildID != 0 {
|
||||
env = append(env, fmt.Sprintf("BUILD_ID=%d", metadata.BuildID))
|
||||
}
|
||||
|
||||
if metadata.BuildName != "" {
|
||||
env = append(env, "BUILD_NAME="+metadata.BuildName)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package gc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/lager/lagerctx"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
)
|
||||
|
||||
type checkCollector struct {
|
||||
checkLifecycle db.CheckLifecycle
|
||||
recyclePeriod time.Duration
|
||||
}
|
||||
|
||||
func NewCheckCollector(checkLifecycle db.CheckLifecycle, recyclePeriod time.Duration) *checkCollector {
|
||||
return &checkCollector{
|
||||
checkLifecycle: checkLifecycle,
|
||||
recyclePeriod: recyclePeriod,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *checkCollector) Run(ctx context.Context) error {
|
||||
logger := lagerctx.FromContext(ctx).Session("check-collector")
|
||||
|
||||
logger.Debug("start")
|
||||
defer logger.Debug("done")
|
||||
|
||||
return c.checkLifecycle.RemoveExpiredChecks(c.recyclePeriod)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package gc_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/atc/db/dbfakes"
|
||||
"github.com/concourse/concourse/atc/gc"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("CheckCollector", func() {
|
||||
var collector gc.Collector
|
||||
var fakeCheckLifecycle *dbfakes.FakeCheckLifecycle
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheckLifecycle = new(dbfakes.FakeCheckLifecycle)
|
||||
|
||||
collector = gc.NewCheckCollector(fakeCheckLifecycle, time.Hour*24)
|
||||
})
|
||||
|
||||
Describe("Run", func() {
|
||||
It("tells the check lifecycle to remove expired checks", func() {
|
||||
err := collector.Run(context.TODO())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(fakeCheckLifecycle.RemoveExpiredChecksCallCount()).To(Equal(1))
|
||||
recyclePeriod := fakeCheckLifecycle.RemoveExpiredChecksArgsForCall(0)
|
||||
Expect(recyclePeriod).To(Equal(time.Hour * 24))
|
||||
})
|
||||
})
|
||||
})
|
|
@ -22,6 +22,7 @@ type aggregateCollector struct {
|
|||
containerCollector Collector
|
||||
resourceConfigCheckSessionCollector Collector
|
||||
artifactCollector Collector
|
||||
checkCollector Collector
|
||||
}
|
||||
|
||||
func NewCollector(
|
||||
|
@ -31,6 +32,7 @@ func NewCollector(
|
|||
resourceConfigs Collector,
|
||||
resourceCaches Collector,
|
||||
artifactCollector Collector,
|
||||
checkCollector Collector,
|
||||
volumes Collector,
|
||||
containers Collector,
|
||||
resourceConfigCheckSessionCollector Collector,
|
||||
|
@ -42,6 +44,7 @@ func NewCollector(
|
|||
resourceConfigCollector: resourceConfigs,
|
||||
resourceCacheCollector: resourceCaches,
|
||||
artifactCollector: artifactCollector,
|
||||
checkCollector: checkCollector,
|
||||
volumeCollector: volumes,
|
||||
containerCollector: containers,
|
||||
resourceConfigCheckSessionCollector: resourceConfigCheckSessionCollector,
|
||||
|
@ -88,6 +91,11 @@ func (c *aggregateCollector) Run(ctx context.Context) error {
|
|||
logger.Error("artifact-collector", err)
|
||||
}
|
||||
|
||||
err = c.checkCollector.Run(ctx)
|
||||
if err != nil {
|
||||
logger.Error("check-collector", err)
|
||||
}
|
||||
|
||||
err = c.containerCollector.Run(ctx)
|
||||
if err != nil {
|
||||
logger.Error("container-collector", err)
|
||||
|
|
|
@ -20,6 +20,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
fakeResourceConfigCollector *gcfakes.FakeCollector
|
||||
fakeResourceCacheCollector *gcfakes.FakeCollector
|
||||
fakeArtifactCollector *gcfakes.FakeCollector
|
||||
fakeCheckCollector *gcfakes.FakeCollector
|
||||
fakeVolumeCollector *gcfakes.FakeCollector
|
||||
fakeContainerCollector *gcfakes.FakeCollector
|
||||
fakeResourceConfigCheckSessionCollector *gcfakes.FakeCollector
|
||||
|
@ -35,6 +36,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
fakeResourceConfigCollector = new(gcfakes.FakeCollector)
|
||||
fakeResourceCacheCollector = new(gcfakes.FakeCollector)
|
||||
fakeArtifactCollector = new(gcfakes.FakeCollector)
|
||||
fakeCheckCollector = new(gcfakes.FakeCollector)
|
||||
fakeVolumeCollector = new(gcfakes.FakeCollector)
|
||||
fakeContainerCollector = new(gcfakes.FakeCollector)
|
||||
fakeResourceConfigCheckSessionCollector = new(gcfakes.FakeCollector)
|
||||
|
@ -46,6 +48,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
fakeResourceConfigCollector,
|
||||
fakeResourceCacheCollector,
|
||||
fakeArtifactCollector,
|
||||
fakeCheckCollector,
|
||||
fakeVolumeCollector,
|
||||
fakeContainerCollector,
|
||||
fakeResourceConfigCheckSessionCollector,
|
||||
|
@ -78,6 +81,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeContainerCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
|
@ -103,6 +107,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeContainerCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
|
@ -128,6 +133,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeContainerCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
|
@ -153,6 +159,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeResourceCacheUseCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeContainerCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
|
@ -178,6 +185,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeResourceCacheUseCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeContainerCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
|
@ -204,6 +212,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeContainerCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
})
|
||||
|
@ -228,6 +237,7 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeResourceCacheUseCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
|
@ -252,10 +262,12 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeResourceCacheUseCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the artifact collector succeeds", func() {
|
||||
It("attempts to collect", func() {
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
|
@ -274,6 +286,33 @@ var _ = Describe("Aggregate Collector", func() {
|
|||
Expect(fakeWorkerCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheUseCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the check collector succeeds", func() {
|
||||
It("attempts to collect", func() {
|
||||
Expect(fakeCheckCollector.RunCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
Context("when the collector errors", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheckCollector.RunReturns(disaster)
|
||||
})
|
||||
|
||||
It("does not return an error", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("runs the rest of collectors", func() {
|
||||
Expect(fakeWorkerCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheUseCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeArtifactCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceCacheCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeResourceConfigCheckSessionCollector.RunCallCount()).To(Equal(1))
|
||||
Expect(fakeVolumeCollector.RunCallCount()).To(Equal(1))
|
||||
|
|
|
@ -51,7 +51,8 @@ var _ = Describe("ResourceConfigCheckSessionCollector", func() {
|
|||
atc.VersionedResourceTypes{})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
owner = db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), ownerExpiries)
|
||||
resourceConfig := resourceConfigScope.ResourceConfig()
|
||||
owner = db.NewResourceConfigCheckSessionContainerOwner(resourceConfig.ID(), resourceConfig.OriginBaseResourceType().ID, ownerExpiries)
|
||||
|
||||
workerFactory := db.NewWorkerFactory(dbConn)
|
||||
defaultWorkerPayload := atc.Worker{
|
||||
|
|
|
@ -69,7 +69,7 @@ var _ = Describe("ResourceConfigCollector", func() {
|
|||
worker, err := workerFactory.SaveWorker(defaultWorkerPayload, 0)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
_, err = worker.CreateContainer(db.NewResourceConfigCheckSessionContainerOwner(resourceConfig, ownerExpiries), db.ContainerMetadata{})
|
||||
_, err = worker.CreateContainer(db.NewResourceConfigCheckSessionContainerOwner(resourceConfig.ID(), resourceConfig.OriginBaseResourceType().ID, ownerExpiries), db.ContainerMetadata{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
|
@ -112,7 +112,7 @@ var _ = Describe("ResourceConfigCollector", func() {
|
|||
worker, err := workerFactory.SaveWorker(defaultWorkerPayload, 0)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
_, err = worker.CreateContainer(db.NewResourceConfigCheckSessionContainerOwner(resourceConfig, ownerExpiries), db.ContainerMetadata{})
|
||||
_, err = worker.CreateContainer(db.NewResourceConfigCheckSessionContainerOwner(resourceConfig.ID(), resourceConfig.OriginBaseResourceType().ID, ownerExpiries), db.ContainerMetadata{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
tx, err := dbConn.Begin()
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package lidar
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/engine"
|
||||
)
|
||||
|
||||
func NewChecker(
|
||||
logger lager.Logger,
|
||||
checkFactory db.CheckFactory,
|
||||
engine engine.Engine,
|
||||
) *checker {
|
||||
return &checker{
|
||||
logger: logger,
|
||||
checkFactory: checkFactory,
|
||||
engine: engine,
|
||||
}
|
||||
}
|
||||
|
||||
type checker struct {
|
||||
logger lager.Logger
|
||||
|
||||
checkFactory db.CheckFactory
|
||||
engine engine.Engine
|
||||
}
|
||||
|
||||
func (c *checker) Run(ctx context.Context) error {
|
||||
cLog := c.logger.Session("check")
|
||||
|
||||
cLog.Debug("start")
|
||||
defer cLog.Debug("done")
|
||||
|
||||
checks, err := c.checkFactory.StartedChecks()
|
||||
if err != nil {
|
||||
c.logger.Error("failed-to-fetch-resource-checks", err)
|
||||
return err
|
||||
}
|
||||
|
||||
for _, check := range checks {
|
||||
btLog := cLog.WithData(lager.Data{
|
||||
"check": check.ID(),
|
||||
})
|
||||
|
||||
engineCheck := c.engine.NewCheck(check)
|
||||
go engineCheck.Run(btLog)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package lidar_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"code.cloudfoundry.org/lager/lagertest"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/dbfakes"
|
||||
"github.com/concourse/concourse/atc/engine"
|
||||
"github.com/concourse/concourse/atc/engine/enginefakes"
|
||||
"github.com/concourse/concourse/atc/lidar"
|
||||
)
|
||||
|
||||
type Checker interface {
|
||||
Run(context.Context) error
|
||||
}
|
||||
|
||||
var _ = Describe("Checker", func() {
|
||||
var (
|
||||
err error
|
||||
|
||||
fakeCheckFactory *dbfakes.FakeCheckFactory
|
||||
fakeEngine *enginefakes.FakeEngine
|
||||
|
||||
checker Checker
|
||||
logger *lagertest.TestLogger
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheckFactory = new(dbfakes.FakeCheckFactory)
|
||||
fakeEngine = new(enginefakes.FakeEngine)
|
||||
|
||||
logger = lagertest.NewTestLogger("test")
|
||||
checker = lidar.NewChecker(
|
||||
logger,
|
||||
fakeCheckFactory,
|
||||
fakeEngine,
|
||||
)
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = checker.Run(context.TODO())
|
||||
})
|
||||
|
||||
Describe("Run", func() {
|
||||
|
||||
Context("when retrieving checks fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheckFactory.StartedChecksReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when retrieving checks succeeds", func() {
|
||||
var engineChecks []*enginefakes.FakeRunnable
|
||||
|
||||
BeforeEach(func() {
|
||||
|
||||
fakeCheckFactory.StartedChecksReturns([]db.Check{
|
||||
new(dbfakes.FakeCheck),
|
||||
new(dbfakes.FakeCheck),
|
||||
new(dbfakes.FakeCheck),
|
||||
}, nil)
|
||||
|
||||
engineChecks = []*enginefakes.FakeRunnable{}
|
||||
fakeEngine.NewCheckStub = func(build db.Check) engine.Runnable {
|
||||
engineCheck := new(enginefakes.FakeRunnable)
|
||||
engineChecks = append(engineChecks, engineCheck)
|
||||
return engineCheck
|
||||
}
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("runs all pendingg checks", func() {
|
||||
Eventually(engineChecks[0].RunCallCount).Should(Equal(1))
|
||||
Eventually(engineChecks[1].RunCallCount).Should(Equal(1))
|
||||
Eventually(engineChecks[2].RunCallCount).Should(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,88 @@
|
|||
package lidar
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/clock"
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/tedsuo/ifrit"
|
||||
)
|
||||
|
||||
//go:generate counterfeiter . Runner
|
||||
|
||||
type Runner interface {
|
||||
Run(context.Context) error
|
||||
}
|
||||
|
||||
//go:generate counterfeiter . Notifications
|
||||
|
||||
type Notifications interface {
|
||||
Listen(string) (chan bool, error)
|
||||
Unlisten(string, chan bool) error
|
||||
}
|
||||
|
||||
func NewIntervalRunner(
|
||||
logger lager.Logger,
|
||||
clock clock.Clock,
|
||||
runner Runner,
|
||||
interval time.Duration,
|
||||
notifications Notifications,
|
||||
channel string,
|
||||
) ifrit.Runner {
|
||||
return &intervalRunner{
|
||||
logger: logger,
|
||||
clock: clock,
|
||||
runner: runner,
|
||||
interval: interval,
|
||||
notifications: notifications,
|
||||
channel: channel,
|
||||
}
|
||||
}
|
||||
|
||||
type intervalRunner struct {
|
||||
logger lager.Logger
|
||||
clock clock.Clock
|
||||
runner Runner
|
||||
interval time.Duration
|
||||
notifications Notifications
|
||||
channel string
|
||||
}
|
||||
|
||||
func (r *intervalRunner) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
|
||||
r.logger.Info("start")
|
||||
defer r.logger.Info("done")
|
||||
|
||||
close(ready)
|
||||
|
||||
notifier, err := r.notifications.Listen(r.channel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer r.notifications.Unlisten(r.channel, notifier)
|
||||
|
||||
ticker := r.clock.NewTicker(r.interval)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
if err := r.runner.Run(ctx); err != nil {
|
||||
r.logger.Error("failed-to-run", err)
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C():
|
||||
if err := r.runner.Run(ctx); err != nil {
|
||||
r.logger.Error("failed-to-run", err)
|
||||
}
|
||||
case <-notifier:
|
||||
if err := r.runner.Run(ctx); err != nil {
|
||||
r.logger.Error("failed-to-run", err)
|
||||
}
|
||||
case <-signals:
|
||||
cancel()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package lidar_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"code.cloudfoundry.org/clock/fakeclock"
|
||||
"code.cloudfoundry.org/lager/lagertest"
|
||||
"github.com/concourse/concourse/atc/lidar"
|
||||
"github.com/concourse/concourse/atc/lidar/lidarfakes"
|
||||
"github.com/tedsuo/ifrit"
|
||||
)
|
||||
|
||||
var _ = Describe("IntervalRunner", func() {
|
||||
var (
|
||||
intervalRunner ifrit.Runner
|
||||
process ifrit.Process
|
||||
|
||||
logger *lagertest.TestLogger
|
||||
interval time.Duration
|
||||
notifier chan bool
|
||||
fakeRunner *lidarfakes.FakeRunner
|
||||
fakeNotifications *lidarfakes.FakeNotifications
|
||||
|
||||
runAt time.Time
|
||||
runTimes chan time.Time
|
||||
fakeClock *fakeclock.FakeClock
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
logger = lagertest.NewTestLogger("test")
|
||||
interval = time.Minute
|
||||
notifier = make(chan bool)
|
||||
fakeRunner = new(lidarfakes.FakeRunner)
|
||||
fakeNotifications = new(lidarfakes.FakeNotifications)
|
||||
fakeNotifications.ListenReturns(notifier, nil)
|
||||
|
||||
runAt = time.Unix(111, 111).UTC()
|
||||
runTimes = make(chan time.Time, 100)
|
||||
fakeClock = fakeclock.NewFakeClock(runAt)
|
||||
|
||||
fakeRunner.RunStub = func(ctx context.Context) error {
|
||||
runTimes <- fakeClock.Now()
|
||||
return nil
|
||||
}
|
||||
|
||||
intervalRunner = lidar.NewIntervalRunner(
|
||||
logger,
|
||||
fakeClock,
|
||||
fakeRunner,
|
||||
interval,
|
||||
fakeNotifications,
|
||||
"some-channel",
|
||||
)
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
process = ifrit.Invoke(intervalRunner)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
process.Signal(os.Interrupt)
|
||||
Eventually(process.Wait()).Should(Receive())
|
||||
})
|
||||
|
||||
Context("when created", func() {
|
||||
It("runs", func() {
|
||||
Expect(<-runTimes).To(Equal(runAt))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the interval elapses", func() {
|
||||
It("runs again", func() {
|
||||
Expect(<-runTimes).To(Equal(runAt))
|
||||
|
||||
fakeClock.WaitForWatcherAndIncrement(interval)
|
||||
Expect(<-runTimes).To(Equal(runAt.Add(interval)))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when it receives a notification", func() {
|
||||
It("runs again", func() {
|
||||
Expect(<-runTimes).To(Equal(runAt))
|
||||
|
||||
notifier <- true
|
||||
Expect(<-runTimes).To(Equal(runAt))
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,53 @@
|
|||
package lidar
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/clock"
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/tedsuo/ifrit"
|
||||
"github.com/tedsuo/ifrit/grouper"
|
||||
)
|
||||
|
||||
func NewRunner(
|
||||
logger lager.Logger,
|
||||
clock clock.Clock,
|
||||
scanRunner Runner,
|
||||
scanInterval time.Duration,
|
||||
checkRunner Runner,
|
||||
checkInterval time.Duration,
|
||||
notifications Notifications,
|
||||
) ifrit.Runner {
|
||||
return grouper.NewParallel(
|
||||
os.Interrupt,
|
||||
[]grouper.Member{
|
||||
{
|
||||
Name: "scanner",
|
||||
Runner: NewIntervalRunner(logger, clock, scanRunner, scanInterval, notifications, "scanner"),
|
||||
},
|
||||
{
|
||||
Name: "checker",
|
||||
Runner: NewIntervalRunner(logger, clock, checkRunner, checkInterval, notifications, "checker"),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func NewCheckerRunner(
|
||||
logger lager.Logger,
|
||||
clock clock.Clock,
|
||||
checkRunner Runner,
|
||||
checkInterval time.Duration,
|
||||
notifications Notifications,
|
||||
) ifrit.Runner {
|
||||
return grouper.NewParallel(
|
||||
os.Interrupt,
|
||||
[]grouper.Member{
|
||||
{
|
||||
Name: "checker",
|
||||
Runner: NewIntervalRunner(logger, clock, checkRunner, checkInterval, notifications, "checker"),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package lidar_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLidar(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Lidar Suite")
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package lidar_test
|
|
@ -0,0 +1,190 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package lidarfakes
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/concourse/concourse/atc/lidar"
|
||||
)
|
||||
|
||||
type FakeNotifications struct {
|
||||
ListenStub func(string) (chan bool, error)
|
||||
listenMutex sync.RWMutex
|
||||
listenArgsForCall []struct {
|
||||
arg1 string
|
||||
}
|
||||
listenReturns struct {
|
||||
result1 chan bool
|
||||
result2 error
|
||||
}
|
||||
listenReturnsOnCall map[int]struct {
|
||||
result1 chan bool
|
||||
result2 error
|
||||
}
|
||||
UnlistenStub func(string, chan bool) error
|
||||
unlistenMutex sync.RWMutex
|
||||
unlistenArgsForCall []struct {
|
||||
arg1 string
|
||||
arg2 chan bool
|
||||
}
|
||||
unlistenReturns struct {
|
||||
result1 error
|
||||
}
|
||||
unlistenReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) Listen(arg1 string) (chan bool, error) {
|
||||
fake.listenMutex.Lock()
|
||||
ret, specificReturn := fake.listenReturnsOnCall[len(fake.listenArgsForCall)]
|
||||
fake.listenArgsForCall = append(fake.listenArgsForCall, struct {
|
||||
arg1 string
|
||||
}{arg1})
|
||||
fake.recordInvocation("Listen", []interface{}{arg1})
|
||||
fake.listenMutex.Unlock()
|
||||
if fake.ListenStub != nil {
|
||||
return fake.ListenStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
fakeReturns := fake.listenReturns
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) ListenCallCount() int {
|
||||
fake.listenMutex.RLock()
|
||||
defer fake.listenMutex.RUnlock()
|
||||
return len(fake.listenArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) ListenCalls(stub func(string) (chan bool, error)) {
|
||||
fake.listenMutex.Lock()
|
||||
defer fake.listenMutex.Unlock()
|
||||
fake.ListenStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) ListenArgsForCall(i int) string {
|
||||
fake.listenMutex.RLock()
|
||||
defer fake.listenMutex.RUnlock()
|
||||
argsForCall := fake.listenArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) ListenReturns(result1 chan bool, result2 error) {
|
||||
fake.listenMutex.Lock()
|
||||
defer fake.listenMutex.Unlock()
|
||||
fake.ListenStub = nil
|
||||
fake.listenReturns = struct {
|
||||
result1 chan bool
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) ListenReturnsOnCall(i int, result1 chan bool, result2 error) {
|
||||
fake.listenMutex.Lock()
|
||||
defer fake.listenMutex.Unlock()
|
||||
fake.ListenStub = nil
|
||||
if fake.listenReturnsOnCall == nil {
|
||||
fake.listenReturnsOnCall = make(map[int]struct {
|
||||
result1 chan bool
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.listenReturnsOnCall[i] = struct {
|
||||
result1 chan bool
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) Unlisten(arg1 string, arg2 chan bool) error {
|
||||
fake.unlistenMutex.Lock()
|
||||
ret, specificReturn := fake.unlistenReturnsOnCall[len(fake.unlistenArgsForCall)]
|
||||
fake.unlistenArgsForCall = append(fake.unlistenArgsForCall, struct {
|
||||
arg1 string
|
||||
arg2 chan bool
|
||||
}{arg1, arg2})
|
||||
fake.recordInvocation("Unlisten", []interface{}{arg1, arg2})
|
||||
fake.unlistenMutex.Unlock()
|
||||
if fake.UnlistenStub != nil {
|
||||
return fake.UnlistenStub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.unlistenReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) UnlistenCallCount() int {
|
||||
fake.unlistenMutex.RLock()
|
||||
defer fake.unlistenMutex.RUnlock()
|
||||
return len(fake.unlistenArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) UnlistenCalls(stub func(string, chan bool) error) {
|
||||
fake.unlistenMutex.Lock()
|
||||
defer fake.unlistenMutex.Unlock()
|
||||
fake.UnlistenStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) UnlistenArgsForCall(i int) (string, chan bool) {
|
||||
fake.unlistenMutex.RLock()
|
||||
defer fake.unlistenMutex.RUnlock()
|
||||
argsForCall := fake.unlistenArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) UnlistenReturns(result1 error) {
|
||||
fake.unlistenMutex.Lock()
|
||||
defer fake.unlistenMutex.Unlock()
|
||||
fake.UnlistenStub = nil
|
||||
fake.unlistenReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) UnlistenReturnsOnCall(i int, result1 error) {
|
||||
fake.unlistenMutex.Lock()
|
||||
defer fake.unlistenMutex.Unlock()
|
||||
fake.UnlistenStub = nil
|
||||
if fake.unlistenReturnsOnCall == nil {
|
||||
fake.unlistenReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.unlistenReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.listenMutex.RLock()
|
||||
defer fake.listenMutex.RUnlock()
|
||||
fake.unlistenMutex.RLock()
|
||||
defer fake.unlistenMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakeNotifications) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ lidar.Notifications = new(FakeNotifications)
|
|
@ -0,0 +1,111 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package lidarfakes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/concourse/concourse/atc/lidar"
|
||||
)
|
||||
|
||||
type FakeRunner struct {
|
||||
RunStub func(context.Context) error
|
||||
runMutex sync.RWMutex
|
||||
runArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
}
|
||||
runReturns struct {
|
||||
result1 error
|
||||
}
|
||||
runReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeRunner) Run(arg1 context.Context) error {
|
||||
fake.runMutex.Lock()
|
||||
ret, specificReturn := fake.runReturnsOnCall[len(fake.runArgsForCall)]
|
||||
fake.runArgsForCall = append(fake.runArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
}{arg1})
|
||||
fake.recordInvocation("Run", []interface{}{arg1})
|
||||
fake.runMutex.Unlock()
|
||||
if fake.RunStub != nil {
|
||||
return fake.RunStub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
fakeReturns := fake.runReturns
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeRunner) RunCallCount() int {
|
||||
fake.runMutex.RLock()
|
||||
defer fake.runMutex.RUnlock()
|
||||
return len(fake.runArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeRunner) RunCalls(stub func(context.Context) error) {
|
||||
fake.runMutex.Lock()
|
||||
defer fake.runMutex.Unlock()
|
||||
fake.RunStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeRunner) RunArgsForCall(i int) context.Context {
|
||||
fake.runMutex.RLock()
|
||||
defer fake.runMutex.RUnlock()
|
||||
argsForCall := fake.runArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeRunner) RunReturns(result1 error) {
|
||||
fake.runMutex.Lock()
|
||||
defer fake.runMutex.Unlock()
|
||||
fake.RunStub = nil
|
||||
fake.runReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeRunner) RunReturnsOnCall(i int, result1 error) {
|
||||
fake.runMutex.Lock()
|
||||
defer fake.runMutex.Unlock()
|
||||
fake.RunStub = nil
|
||||
if fake.runReturnsOnCall == nil {
|
||||
fake.runReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.runReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeRunner) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.runMutex.RLock()
|
||||
defer fake.runMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakeRunner) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ lidar.Runner = new(FakeRunner)
|
|
@ -0,0 +1,134 @@
|
|||
package lidar
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/lager"
|
||||
"github.com/concourse/concourse/atc/creds"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func NewScanner(
|
||||
logger lager.Logger,
|
||||
checkFactory db.CheckFactory,
|
||||
secrets creds.Secrets,
|
||||
defaultCheckTimeout time.Duration,
|
||||
defaultCheckInterval time.Duration,
|
||||
) *scanner {
|
||||
return &scanner{
|
||||
logger: logger,
|
||||
checkFactory: checkFactory,
|
||||
secrets: secrets,
|
||||
defaultCheckTimeout: defaultCheckTimeout,
|
||||
defaultCheckInterval: defaultCheckInterval,
|
||||
}
|
||||
}
|
||||
|
||||
type scanner struct {
|
||||
logger lager.Logger
|
||||
|
||||
checkFactory db.CheckFactory
|
||||
secrets creds.Secrets
|
||||
defaultCheckTimeout time.Duration
|
||||
defaultCheckInterval time.Duration
|
||||
}
|
||||
|
||||
func (s *scanner) Run(ctx context.Context) error {
|
||||
|
||||
lock, acquired, err := s.checkFactory.AcquireScanningLock(s.logger)
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-get-scanning-lock", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !acquired {
|
||||
s.logger.Debug("scanning-already-in-progress")
|
||||
return nil
|
||||
}
|
||||
|
||||
defer lock.Release()
|
||||
|
||||
resources, err := s.checkFactory.Resources()
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-get-resources", err)
|
||||
return err
|
||||
}
|
||||
|
||||
resourceTypes, err := s.checkFactory.ResourceTypes()
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-get-resources", err)
|
||||
return err
|
||||
}
|
||||
|
||||
waitGroup := new(sync.WaitGroup)
|
||||
|
||||
for _, resource := range resources {
|
||||
waitGroup.Add(1)
|
||||
|
||||
go func(resource db.Resource, resourceTypes db.ResourceTypes) {
|
||||
defer waitGroup.Done()
|
||||
|
||||
err = s.check(resource, resourceTypes)
|
||||
s.setCheckError(s.logger, resource, err)
|
||||
|
||||
}(resource, resourceTypes)
|
||||
}
|
||||
|
||||
waitGroup.Wait()
|
||||
|
||||
return s.checkFactory.NotifyChecker()
|
||||
}
|
||||
|
||||
func (s *scanner) check(checkable db.Checkable, resourceTypes db.ResourceTypes) error {
|
||||
|
||||
var err error
|
||||
|
||||
parentType, found := resourceTypes.Parent(checkable)
|
||||
if found {
|
||||
err = s.check(parentType, resourceTypes)
|
||||
s.setCheckError(s.logger, parentType, err)
|
||||
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-create-type-check", err)
|
||||
return errors.Wrapf(err, "parent type '%v' error", parentType.Name())
|
||||
}
|
||||
}
|
||||
|
||||
interval := s.defaultCheckInterval
|
||||
if every := checkable.CheckEvery(); every != "" {
|
||||
interval, err = time.ParseDuration(every)
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-parse-check-every", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if time.Now().Before(checkable.LastCheckEndTime().Add(interval)) {
|
||||
s.logger.Debug("interval-not-reached", lager.Data{"interval": interval})
|
||||
return nil
|
||||
}
|
||||
|
||||
version := checkable.CurrentPinnedVersion()
|
||||
|
||||
_, created, err := s.checkFactory.TryCreateCheck(checkable, resourceTypes, version, false)
|
||||
if err != nil {
|
||||
s.logger.Error("failed-to-create-check", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !created {
|
||||
s.logger.Info("check-already-exists")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scanner) setCheckError(logger lager.Logger, checkable db.Checkable, err error) {
|
||||
setErr := checkable.SetCheckSetupError(err)
|
||||
if setErr != nil {
|
||||
logger.Error("failed-to-set-check-error", setErr)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
package lidar_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"code.cloudfoundry.org/lager/lagertest"
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/creds/credsfakes"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/atc/db/dbfakes"
|
||||
"github.com/concourse/concourse/atc/db/lock/lockfakes"
|
||||
"github.com/concourse/concourse/atc/lidar"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
type Scanner interface {
|
||||
Run(ctx context.Context) error
|
||||
}
|
||||
|
||||
var _ = Describe("Scanner", func() {
|
||||
var (
|
||||
err error
|
||||
|
||||
fakeCheckFactory *dbfakes.FakeCheckFactory
|
||||
fakeSecrets *credsfakes.FakeSecrets
|
||||
|
||||
logger *lagertest.TestLogger
|
||||
scanner Scanner
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeCheckFactory = new(dbfakes.FakeCheckFactory)
|
||||
fakeSecrets = new(credsfakes.FakeSecrets)
|
||||
|
||||
logger = lagertest.NewTestLogger("test")
|
||||
scanner = lidar.NewScanner(
|
||||
logger,
|
||||
fakeCheckFactory,
|
||||
fakeSecrets,
|
||||
time.Minute*1,
|
||||
time.Minute*1,
|
||||
)
|
||||
})
|
||||
|
||||
JustBeforeEach(func() {
|
||||
err = scanner.Run(context.TODO())
|
||||
})
|
||||
|
||||
Describe("Run", func() {
|
||||
Context("when acquiring scanning lock fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheckFactory.AcquireScanningLockReturns(nil, false, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when scanning lock is already held", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheckFactory.AcquireScanningLockReturns(nil, false, nil)
|
||||
})
|
||||
|
||||
It("does not error", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("does not continue", func() {
|
||||
Expect(fakeCheckFactory.ResourcesCallCount()).To(Equal(0))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when acquiring the lock succeeds", func() {
|
||||
var fakeLock *lockfakes.FakeLock
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeLock = new(lockfakes.FakeLock)
|
||||
fakeCheckFactory.AcquireScanningLockReturns(fakeLock, true, nil)
|
||||
})
|
||||
|
||||
It("releases the lock", func() {
|
||||
Expect(fakeLock.ReleaseCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
Context("when fetching resources fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheckFactory.ResourcesReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when fetching resources succeeds", func() {
|
||||
var fakeResource *dbfakes.FakeResource
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeResource = new(dbfakes.FakeResource)
|
||||
fakeResource.NameReturns("some-name")
|
||||
fakeResource.TagsReturns([]string{"tag-a", "tag-b"})
|
||||
fakeResource.SourceReturns(atc.Source{"some": "source"})
|
||||
|
||||
fakeCheckFactory.ResourcesReturns([]db.Resource{fakeResource}, nil)
|
||||
})
|
||||
|
||||
Context("when fetching resource types fails", func() {
|
||||
BeforeEach(func() {
|
||||
fakeCheckFactory.ResourceTypesReturns(nil, errors.New("nope"))
|
||||
})
|
||||
|
||||
It("errors", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when fetching resources types succeeds", func() {
|
||||
var fakeResourceType *dbfakes.FakeResourceType
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeResourceType = new(dbfakes.FakeResourceType)
|
||||
fakeResourceType.NameReturns("some-type")
|
||||
fakeResourceType.TypeReturns("some-base-type")
|
||||
fakeResourceType.TagsReturns([]string{"some-tag"})
|
||||
fakeResourceType.SourceReturns(atc.Source{"some": "type-source"})
|
||||
|
||||
fakeCheckFactory.ResourceTypesReturns([]db.ResourceType{fakeResourceType}, nil)
|
||||
})
|
||||
|
||||
Context("when the resource parent type is a base type", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.TypeReturns("base-type")
|
||||
})
|
||||
|
||||
Context("when the check interval is parseable", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.CheckEveryReturns("10s")
|
||||
})
|
||||
|
||||
Context("when the last check end time is within our interval", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.LastCheckEndTimeReturns(time.Now())
|
||||
})
|
||||
|
||||
It("does not check", func() {
|
||||
Expect(fakeCheckFactory.CreateCheckCallCount()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("clears the check error", func() {
|
||||
Expect(fakeResource.SetCheckSetupErrorCallCount()).To(Equal(1))
|
||||
Expect(fakeResource.SetCheckSetupErrorArgsForCall(0)).To(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the last check end time is past our interval", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.LastCheckEndTimeReturns(time.Now().Add(-time.Hour))
|
||||
})
|
||||
|
||||
It("creates a check", func() {
|
||||
Expect(fakeCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
})
|
||||
|
||||
It("clears the check error", func() {
|
||||
Expect(fakeResource.SetCheckSetupErrorCallCount()).To(Equal(1))
|
||||
Expect(fakeResource.SetCheckSetupErrorArgsForCall(0)).To(BeNil())
|
||||
})
|
||||
|
||||
It("sends a notification for the checker to run", func() {
|
||||
Expect(fakeCheckFactory.NotifyCheckerCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the checkable has a pinned version", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.CurrentPinnedVersionReturns(atc.Version{"some": "version"})
|
||||
})
|
||||
|
||||
It("creates a check", func() {
|
||||
Expect(fakeCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
_, _, fromVersion, _ := fakeCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(fromVersion).To(Equal(atc.Version{"some": "version"}))
|
||||
})
|
||||
|
||||
It("clears the check error", func() {
|
||||
Expect(fakeResource.SetCheckSetupErrorCallCount()).To(Equal(1))
|
||||
Expect(fakeResource.SetCheckSetupErrorArgsForCall(0)).To(BeNil())
|
||||
})
|
||||
|
||||
It("sends a notification for the checker to run", func() {
|
||||
Expect(fakeCheckFactory.NotifyCheckerCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the checkable does not have a pinned version", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.CurrentPinnedVersionReturns(nil)
|
||||
})
|
||||
|
||||
It("creates a check", func() {
|
||||
Expect(fakeCheckFactory.TryCreateCheckCallCount()).To(Equal(1))
|
||||
_, _, fromVersion, _ := fakeCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(fromVersion).To(BeNil())
|
||||
})
|
||||
|
||||
It("clears the check error", func() {
|
||||
Expect(fakeResource.SetCheckSetupErrorCallCount()).To(Equal(1))
|
||||
Expect(fakeResource.SetCheckSetupErrorArgsForCall(0)).To(BeNil())
|
||||
})
|
||||
|
||||
It("sends a notification for the checker to run", func() {
|
||||
Expect(fakeCheckFactory.NotifyCheckerCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the resource has a parent type", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResource.TypeReturns("custom-type")
|
||||
fakeResource.PipelineIDReturns(1)
|
||||
fakeResourceType.NameReturns("custom-type")
|
||||
fakeResourceType.PipelineIDReturns(1)
|
||||
})
|
||||
|
||||
Context("when it fails to create a check for parent resource", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceType.CheckEveryReturns("not-a-duration")
|
||||
})
|
||||
|
||||
It("sets the check error", func() {
|
||||
Expect(fakeResourceType.SetCheckSetupErrorCallCount()).To(Equal(1))
|
||||
Expect(fakeResource.SetCheckSetupErrorCallCount()).To(Equal(1))
|
||||
err := fakeResource.SetCheckSetupErrorArgsForCall(0)
|
||||
Expect(err.Error()).To(ContainSubstring("parent type 'custom-type' error:"))
|
||||
})
|
||||
|
||||
It("does not create a check", func() {
|
||||
Expect(fakeCheckFactory.TryCreateCheckCallCount()).To(Equal(0))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the parent type requires a check", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceType.LastCheckEndTimeReturns(time.Now().Add(-time.Hour))
|
||||
fakeResource.LastCheckEndTimeReturns(time.Now().Add(-time.Hour))
|
||||
})
|
||||
|
||||
Context("when the parent type has a version", func() {
|
||||
BeforeEach(func() {
|
||||
fakeResourceType.VersionReturns(atc.Version{"some": "version"})
|
||||
})
|
||||
|
||||
It("creates a check for both the parent and the resource", func() {
|
||||
Expect(fakeCheckFactory.TryCreateCheckCallCount()).To(Equal(2))
|
||||
|
||||
checkable, _, _, manuallyTriggered := fakeCheckFactory.TryCreateCheckArgsForCall(0)
|
||||
Expect(checkable).To(Equal(fakeResourceType))
|
||||
Expect(manuallyTriggered).To(BeFalse())
|
||||
|
||||
checkable, _, _, manuallyTriggered = fakeCheckFactory.TryCreateCheckArgsForCall(1)
|
||||
Expect(checkable).To(Equal(fakeResource))
|
||||
Expect(manuallyTriggered).To(BeFalse())
|
||||
})
|
||||
|
||||
It("sends a notification for the checker to run", func() {
|
||||
Expect(fakeCheckFactory.NotifyCheckerCallCount()).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -469,6 +469,31 @@ func (event ResourceCheck) Emit(logger lager.Logger) {
|
|||
)
|
||||
}
|
||||
|
||||
type CheckFinished struct {
|
||||
ResourceConfigScopeID string
|
||||
CheckName string
|
||||
Success bool
|
||||
}
|
||||
|
||||
func (event CheckFinished) Emit(logger lager.Logger) {
|
||||
state := EventStateOK
|
||||
if !event.Success {
|
||||
state = EventStateWarning
|
||||
}
|
||||
emit(
|
||||
logger.Session("check-finished"),
|
||||
Event{
|
||||
Name: "check finished",
|
||||
Value: 1,
|
||||
State: state,
|
||||
Attributes: map[string]string{
|
||||
"scope_id": event.ResourceConfigScopeID,
|
||||
"check_name": event.CheckName,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
var lockTypeNames = map[int]string{
|
||||
lock.LockTypeResourceConfigChecking: "ResourceConfigChecking",
|
||||
lock.LockTypeBuildTracking: "BuildTracking",
|
||||
|
|
|
@ -79,7 +79,6 @@ func (rsf *radarSchedulerFactory) BuildScheduler(pipeline db.Pipeline) scheduler
|
|||
pipeline,
|
||||
maxinflight.NewUpdater(pipeline),
|
||||
factory.NewBuildFactory(
|
||||
pipeline.ID(),
|
||||
atc.NewPlanFactory(time.Now().Unix()),
|
||||
),
|
||||
inputMapper,
|
||||
|
|
12
atc/plan.go
12
atc/plan.go
|
@ -9,6 +9,7 @@ type Plan struct {
|
|||
Do *DoPlan `json:"do,omitempty"`
|
||||
Get *GetPlan `json:"get,omitempty"`
|
||||
Put *PutPlan `json:"put,omitempty"`
|
||||
Check *CheckPlan `json:"check,omitempty"`
|
||||
Task *TaskPlan `json:"task,omitempty"`
|
||||
OnAbort *OnAbortPlan `json:"on_abort,omitempty"`
|
||||
OnError *OnErrorPlan `json:"on_error,omitempty"`
|
||||
|
@ -107,6 +108,17 @@ type PutPlan struct {
|
|||
VersionedResourceTypes VersionedResourceTypes `json:"resource_types,omitempty"`
|
||||
}
|
||||
|
||||
type CheckPlan struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Source Source `json:"source"`
|
||||
Tags Tags `json:"tags,omitempty"`
|
||||
Timeout string `json:"timeout,omitempty"`
|
||||
FromVersion Version `json:"from_version,omitempty"`
|
||||
|
||||
VersionedResourceTypes VersionedResourceTypes `json:"resource_types,omitempty"`
|
||||
}
|
||||
|
||||
type TaskPlan struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ func (factory PlanFactory) NewPlan(step Step) Plan {
|
|||
plan.Put = &t
|
||||
case TaskPlan:
|
||||
plan.Task = &t
|
||||
case CheckPlan:
|
||||
plan.Check = &t
|
||||
case OnAbortPlan:
|
||||
plan.OnAbort = &t
|
||||
case OnErrorPlan:
|
||||
|
|
|
@ -11,6 +11,7 @@ func (plan Plan) Public() *json.RawMessage {
|
|||
Do *json.RawMessage `json:"do,omitempty"`
|
||||
Get *json.RawMessage `json:"get,omitempty"`
|
||||
Put *json.RawMessage `json:"put,omitempty"`
|
||||
Check *json.RawMessage `json:"check,omitempty"`
|
||||
Task *json.RawMessage `json:"task,omitempty"`
|
||||
OnAbort *json.RawMessage `json:"on_abort,omitempty"`
|
||||
OnError *json.RawMessage `json:"on_error,omitempty"`
|
||||
|
@ -47,6 +48,10 @@ func (plan Plan) Public() *json.RawMessage {
|
|||
public.Put = plan.Put.Public()
|
||||
}
|
||||
|
||||
if plan.Check != nil {
|
||||
public.Check = plan.Check.Public()
|
||||
}
|
||||
|
||||
if plan.Task != nil {
|
||||
public.Task = plan.Task.Public()
|
||||
}
|
||||
|
@ -224,6 +229,16 @@ func (plan PutPlan) Public() *json.RawMessage {
|
|||
})
|
||||
}
|
||||
|
||||
func (plan CheckPlan) Public() *json.RawMessage {
|
||||
return enc(struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}{
|
||||
Type: plan.Type,
|
||||
Name: plan.Name,
|
||||
})
|
||||
}
|
||||
|
||||
func (plan TaskPlan) Public() *json.RawMessage {
|
||||
return enc(struct {
|
||||
Name string `json:"name"`
|
||||
|
|
|
@ -53,6 +53,16 @@ var _ = Describe("Plan", func() {
|
|||
},
|
||||
},
|
||||
|
||||
atc.Plan{
|
||||
ID: "4.2",
|
||||
Check: &atc.CheckPlan{
|
||||
Type: "type",
|
||||
Name: "name",
|
||||
Source: atc.Source{"some": "source"},
|
||||
Tags: atc.Tags{"tags"},
|
||||
},
|
||||
},
|
||||
|
||||
atc.Plan{
|
||||
ID: "5",
|
||||
Task: &atc.TaskPlan{
|
||||
|
@ -379,6 +389,13 @@ var _ = Describe("Plan", func() {
|
|||
"resource": "resource"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "4.2",
|
||||
"check": {
|
||||
"type": "type",
|
||||
"name": "name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"task": {
|
||||
|
|
|
@ -320,7 +320,11 @@ func (scanner *resourceScanner) check(
|
|||
TeamID: scanner.dbPipeline.TeamID(),
|
||||
}
|
||||
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), ContainerExpiries)
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
ContainerExpiries,
|
||||
)
|
||||
|
||||
chosenWorker, err := scanner.pool.FindOrChooseWorkerForContainer(
|
||||
context.Background(),
|
||||
|
|
|
@ -94,6 +94,7 @@ var _ = Describe("ResourceScanner", func() {
|
|||
fakeDBPipeline = new(dbfakes.FakePipeline)
|
||||
fakeResourceConfig = new(dbfakes.FakeResourceConfig)
|
||||
fakeResourceConfig.IDReturns(123)
|
||||
fakeResourceConfig.OriginBaseResourceTypeReturns(&db.UsedBaseResourceType{ID: 456})
|
||||
fakeResourceConfigScope = new(dbfakes.FakeResourceConfigScope)
|
||||
fakeResourceConfigScope.IDReturns(456)
|
||||
fakeResourceConfigScope.ResourceConfigReturns(fakeResourceConfig)
|
||||
|
@ -238,7 +239,7 @@ var _ = Describe("ResourceScanner", func() {
|
|||
Expect(err).To(BeNil())
|
||||
|
||||
_, _, owner, containerSpec, workerSpec, _ := fakePool.FindOrChooseWorkerForContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, radar.ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, radar.ContainerExpiries)))
|
||||
Expect(containerSpec.ImageSpec).To(Equal(worker.ImageSpec{
|
||||
ResourceType: "git",
|
||||
}))
|
||||
|
@ -259,7 +260,7 @@ var _ = Describe("ResourceScanner", func() {
|
|||
var metadata db.ContainerMetadata
|
||||
Expect(fakeWorker.FindOrCreateContainerCallCount()).To(Equal(1))
|
||||
_, _, _, owner, metadata, containerSpec, resourceTypes = fakeWorker.FindOrCreateContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, radar.ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, radar.ContainerExpiries)))
|
||||
Expect(metadata).To(Equal(db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
}))
|
||||
|
@ -661,7 +662,7 @@ var _ = Describe("ResourceScanner", func() {
|
|||
Expect(err).To(BeNil())
|
||||
|
||||
_, _, owner, containerSpec, workerSpec, _ := fakePool.FindOrChooseWorkerForContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, radar.ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, radar.ContainerExpiries)))
|
||||
Expect(containerSpec.ImageSpec).To(Equal(worker.ImageSpec{
|
||||
ResourceType: "git",
|
||||
}))
|
||||
|
@ -681,7 +682,7 @@ var _ = Describe("ResourceScanner", func() {
|
|||
|
||||
var metadata db.ContainerMetadata
|
||||
_, _, _, owner, metadata, containerSpec, resourceTypes = fakeWorker.FindOrCreateContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, radar.ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, radar.ContainerExpiries)))
|
||||
Expect(metadata).To(Equal(db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
}))
|
||||
|
|
|
@ -255,7 +255,11 @@ func (scanner *resourceTypeScanner) check(
|
|||
TeamID: scanner.dbPipeline.TeamID(),
|
||||
}
|
||||
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), ContainerExpiries)
|
||||
owner := db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
ContainerExpiries,
|
||||
)
|
||||
|
||||
chosenWorker, err := scanner.pool.FindOrChooseWorkerForContainer(
|
||||
context.Background(),
|
||||
|
@ -278,7 +282,11 @@ func (scanner *resourceTypeScanner) check(
|
|||
context.Background(),
|
||||
logger,
|
||||
worker.NoopImageFetchingDelegate{},
|
||||
db.NewResourceConfigCheckSessionContainerOwner(resourceConfigScope.ResourceConfig(), ContainerExpiries),
|
||||
db.NewResourceConfigCheckSessionContainerOwner(
|
||||
resourceConfigScope.ResourceConfig().ID(),
|
||||
resourceConfigScope.ResourceConfig().OriginBaseResourceType().ID,
|
||||
ContainerExpiries,
|
||||
),
|
||||
db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
},
|
||||
|
|
|
@ -82,6 +82,7 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
fakeDBPipeline = new(dbfakes.FakePipeline)
|
||||
fakeResourceConfig = new(dbfakes.FakeResourceConfig)
|
||||
fakeResourceConfig.IDReturns(123)
|
||||
fakeResourceConfig.OriginBaseResourceTypeReturns(&db.UsedBaseResourceType{ID: 456})
|
||||
fakeResourceConfigScope = new(dbfakes.FakeResourceConfigScope)
|
||||
fakeResourceConfigScope.IDReturns(123)
|
||||
fakeResourceConfigScope.ResourceConfigReturns(fakeResourceConfig)
|
||||
|
@ -187,7 +188,7 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
Expect(resourceTypes).To(Equal(atc.VersionedResourceTypes{}))
|
||||
|
||||
_, _, owner, containerSpec, workerSpec, _ := fakePool.FindOrChooseWorkerForContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, ContainerExpiries)))
|
||||
Expect(containerSpec.ImageSpec).To(Equal(worker.ImageSpec{
|
||||
ResourceType: "registry-image",
|
||||
}))
|
||||
|
@ -201,8 +202,9 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
}))
|
||||
|
||||
Expect(fakeWorker.FindOrCreateContainerCallCount()).To(Equal(1))
|
||||
|
||||
_, _, _, owner, metadata, containerSpec, resourceTypes = fakeWorker.FindOrCreateContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, ContainerExpiries)))
|
||||
Expect(metadata).To(Equal(db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
}))
|
||||
|
@ -244,7 +246,7 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
Expect(err).To(BeNil())
|
||||
|
||||
_, _, owner, containerSpec, workerSpec, _ := fakePool.FindOrChooseWorkerForContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, ContainerExpiries)))
|
||||
Expect(containerSpec.ImageSpec).To(Equal(worker.ImageSpec{
|
||||
ResourceType: "registry-image",
|
||||
}))
|
||||
|
@ -257,7 +259,7 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
|
||||
Expect(fakeWorker.FindOrCreateContainerCallCount()).To(Equal(1))
|
||||
_, _, _, owner, metadata, containerSpec, resourceTypes = fakeWorker.FindOrCreateContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, ContainerExpiries)))
|
||||
Expect(metadata).To(Equal(db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
}))
|
||||
|
@ -470,7 +472,7 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
Expect(err).To(BeNil())
|
||||
|
||||
_, _, owner, containerSpec, workerSpec, _ := fakePool.FindOrChooseWorkerForContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, ContainerExpiries)))
|
||||
Expect(containerSpec.ImageSpec).To(Equal(worker.ImageSpec{
|
||||
ResourceType: "registry-image",
|
||||
}))
|
||||
|
@ -485,7 +487,7 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
|
||||
Expect(fakeWorker.FindOrCreateContainerCallCount()).To(Equal(1))
|
||||
_, _, _, owner, metadata, containerSpec, resourceTypes = fakeWorker.FindOrCreateContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, ContainerExpiries)))
|
||||
Expect(metadata).To(Equal(db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
}))
|
||||
|
@ -594,7 +596,7 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
Expect(resourceTypes).To(Equal(interpolatedResourceTypes))
|
||||
|
||||
_, _, owner, containerSpec, workerSpec, _ := fakePool.FindOrChooseWorkerForContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, ContainerExpiries)))
|
||||
Expect(containerSpec.ImageSpec).To(Equal(worker.ImageSpec{
|
||||
ResourceType: "registry-image",
|
||||
}))
|
||||
|
@ -607,7 +609,7 @@ var _ = Describe("ResourceTypeScanner", func() {
|
|||
|
||||
Expect(fakeWorker.FindOrCreateContainerCallCount()).To(Equal(1))
|
||||
_, _, _, owner, metadata, containerSpec, resourceTypes = fakeWorker.FindOrCreateContainerArgsForCall(0)
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(fakeResourceConfig, ContainerExpiries)))
|
||||
Expect(owner).To(Equal(db.NewResourceConfigCheckSessionContainerOwner(123, 456, ContainerExpiries)))
|
||||
Expect(metadata).To(Equal(db.ContainerMetadata{
|
||||
Type: db.ContainerTypeCheck,
|
||||
}))
|
||||
|
|
|
@ -9,6 +9,12 @@ import (
|
|||
"github.com/concourse/concourse/atc/worker"
|
||||
)
|
||||
|
||||
//go:generate counterfeiter . ResourceFactory
|
||||
|
||||
type ResourceFactory interface {
|
||||
NewResourceForContainer(container worker.Container) Resource
|
||||
}
|
||||
|
||||
//go:generate counterfeiter . Resource
|
||||
|
||||
type Resource interface {
|
||||
|
@ -33,28 +39,24 @@ func ResourcesDir(suffix string) string {
|
|||
return filepath.Join("/tmp", "build", suffix)
|
||||
}
|
||||
|
||||
func NewResource(container worker.Container) *resource {
|
||||
return &resource{
|
||||
container: container,
|
||||
}
|
||||
}
|
||||
|
||||
type resource struct {
|
||||
container worker.Container
|
||||
|
||||
ScriptFailure bool
|
||||
}
|
||||
|
||||
//go:generate counterfeiter . ResourceFactory
|
||||
|
||||
type ResourceFactory interface {
|
||||
NewResourceForContainer(worker.Container) Resource
|
||||
}
|
||||
|
||||
func NewResourceFactory() ResourceFactory {
|
||||
func NewResourceFactory() *resourceFactory {
|
||||
return &resourceFactory{}
|
||||
}
|
||||
|
||||
// TODO: This factory is purely used for testing and faking out the Resource
|
||||
// object. Please remove asap if possible.
|
||||
type resourceFactory struct{}
|
||||
|
||||
func (rf *resourceFactory) NewResourceForContainer(container worker.Container) Resource {
|
||||
return &resource{
|
||||
container: container,
|
||||
}
|
||||
return NewResource(container)
|
||||
}
|
||||
|
|
|
@ -19,8 +19,7 @@ var (
|
|||
var _ = BeforeEach(func() {
|
||||
fakeContainer = new(workerfakes.FakeContainer)
|
||||
|
||||
resourceFactory := resource.NewResourceFactory()
|
||||
resourceForContainer = resourceFactory.NewResourceForContainer(fakeContainer)
|
||||
resourceForContainer = resource.NewResource(fakeContainer)
|
||||
})
|
||||
|
||||
func TestResource(t *testing.T) {
|
||||
|
|
|
@ -3,8 +3,3 @@ package atc
|
|||
type CheckRequestBody struct {
|
||||
From Version `json:"from"`
|
||||
}
|
||||
|
||||
type CheckResponseBody struct {
|
||||
ExitStatus int `json:"exit_status"`
|
||||
Stderr string `json:"stderr"`
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ const (
|
|||
AbortBuild = "AbortBuild"
|
||||
GetBuildPreparation = "GetBuildPreparation"
|
||||
|
||||
GetCheck = "GetCheck"
|
||||
|
||||
GetJob = "GetJob"
|
||||
CreateJobBuild = "CreateJobBuild"
|
||||
ListAllJobs = "ListAllJobs"
|
||||
|
@ -124,6 +126,8 @@ var Routes = rata.Routes([]rata.Route{
|
|||
{Path: "/api/v1/builds/:build_id/preparation", Method: "GET", Name: GetBuildPreparation},
|
||||
{Path: "/api/v1/builds/:build_id/artifacts", Method: "GET", Name: ListBuildArtifacts},
|
||||
|
||||
{Path: "/api/v1/checks/:check_id", Method: "GET", Name: GetCheck},
|
||||
|
||||
{Path: "/api/v1/jobs", Method: "GET", Name: ListAllJobs},
|
||||
{Path: "/api/v1/teams/:team_name/pipelines/:pipeline_name/jobs", Method: "GET", Name: ListJobs},
|
||||
{Path: "/api/v1/teams/:team_name/pipelines/:pipeline_name/jobs/:job_name", Method: "GET", Name: GetJob},
|
||||
|
|
|
@ -16,13 +16,11 @@ type BuildFactory interface {
|
|||
}
|
||||
|
||||
type buildFactory struct {
|
||||
PipelineID int
|
||||
planFactory atc.PlanFactory
|
||||
}
|
||||
|
||||
func NewBuildFactory(pipelineID int, planFactory atc.PlanFactory) BuildFactory {
|
||||
func NewBuildFactory(planFactory atc.PlanFactory) BuildFactory {
|
||||
return &buildFactory{
|
||||
PipelineID: pipelineID,
|
||||
planFactory: planFactory,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ var _ = Describe("Factory Aggregate", func() {
|
|||
actualPlanFactory = atc.NewPlanFactory(123)
|
||||
expectedPlanFactory = atc.NewPlanFactory(123)
|
||||
|
||||
buildFactory = factory.NewBuildFactory(42, actualPlanFactory)
|
||||
buildFactory = factory.NewBuildFactory(actualPlanFactory)
|
||||
|
||||
resources = atc.ResourceConfigs{
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue