Skip to content
This repository has been archived by the owner on Mar 24, 2022. It is now read-only.

Commit

Permalink
add methods for build plan i/o
Browse files Browse the repository at this point in the history
  • Loading branch information
vito committed Mar 14, 2018
1 parent 76d8e63 commit 8a2c45e
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 4 deletions.
49 changes: 49 additions & 0 deletions concourse/build_plan.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package concourse

import (
"io"
"net/http"
"strconv"

"github.com/concourse/atc"
Expand Down Expand Up @@ -30,3 +32,50 @@ func (client *client) BuildPlan(buildID int) (atc.PublicBuildPlan, bool, error)
return buildPlan, false, err
}
}

func (client *client) SendInputToBuildPlan(buildID int, planID atc.PlanID, src io.Reader) (bool, error) {
params := rata.Params{
"build_id": strconv.Itoa(buildID),
"plan_id": string(planID),
}

response := internal.Response{}
err := client.connection.Send(internal.Request{
Header: http.Header{"Content-Type": {"application/octet-stream"}},
RequestName: atc.SendInputToBuildPlan,
Params: params,
Body: src,
}, &response)

switch err.(type) {
case nil:
return true, nil
case internal.ResourceNotFoundError:
return false, nil
default:
return false, err
}
}

func (client *client) ReadOutputFromBuildPlan(buildID int, planID atc.PlanID) (io.ReadCloser, bool, error) {
params := rata.Params{
"build_id": strconv.Itoa(buildID),
"plan_id": string(planID),
}

response := internal.Response{}
err := client.connection.Send(internal.Request{
RequestName: atc.ReadOutputFromBuildPlan,
Params: params,
ReturnResponseBody: true,
}, &response)

switch err.(type) {
case nil:
return response.Result.(io.ReadCloser), true, nil
case internal.ResourceNotFoundError:
return nil, false, nil
default:
return nil, false, err
}
}
80 changes: 80 additions & 0 deletions concourse/build_plan_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package concourse_test

import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"

"github.com/concourse/atc"
Expand Down Expand Up @@ -58,4 +60,82 @@ var _ = Describe("ATC Handler Build Plans", func() {
})
})
})

Describe("SendInputToBuildPlan", func() {
expectedURL := "/api/v1/builds/1234/plan/some-id/input"

Context("when build exists and has a plan", func() {
BeforeEach(func() {
atcServer.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", expectedURL),
ghttp.VerifyBody([]byte("some-body-once-told-me")),
ghttp.RespondWith(http.StatusNoContent, nil),
),
)
})

It("returns true and no error", func() {
found, err := client.SendInputToBuildPlan(1234, "some-id", bytes.NewBufferString("some-body-once-told-me"))
Expect(err).NotTo(HaveOccurred())
Expect(found).To(BeTrue())
})
})

Context("when build does not exist or has no plan", func() {
BeforeEach(func() {
atcServer.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", expectedURL),
ghttp.RespondWithJSONEncoded(http.StatusNotFound, nil),
),
)
})

It("returns false and no error", func() {
found, err := client.SendInputToBuildPlan(1234, "some-id", bytes.NewBufferString("some-body-once-told-me"))
Expect(err).ToNot(HaveOccurred())
Expect(found).To(BeFalse())
})
})
})

Describe("ReadOutputFromBuildPlan", func() {
expectedURL := "/api/v1/builds/1234/plan/some-id/output"

Context("when build exists and has a plan", func() {
BeforeEach(func() {
atcServer.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", expectedURL),
ghttp.RespondWith(http.StatusOK, "the-world-is-gonna-roll-me"),
),
)
})

It("returns true and no error", func() {
out, found, err := client.ReadOutputFromBuildPlan(1234, "some-id")
Expect(err).NotTo(HaveOccurred())
Expect(found).To(BeTrue())
Expect(ioutil.ReadAll(out)).To(Equal([]byte("the-world-is-gonna-roll-me")))
})
})

Context("when build does not exist or has no plan", func() {
BeforeEach(func() {
atcServer.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", expectedURL),
ghttp.RespondWithJSONEncoded(http.StatusNotFound, nil),
),
)
})

It("returns false and no error", func() {
_, found, err := client.ReadOutputFromBuildPlan(1234, "some-id")
Expect(err).ToNot(HaveOccurred())
Expect(found).To(BeFalse())
})
})
})
})
2 changes: 2 additions & 0 deletions concourse/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type Client interface {
AbortBuild(buildID string) error
CreateBuild(plan atc.Plan) (atc.Build, error)
BuildPlan(buildID int) (atc.PublicBuildPlan, bool, error)
SendInputToBuildPlan(buildID int, planID atc.PlanID, src io.Reader) (bool, error)
ReadOutputFromBuildPlan(buildID int, planID atc.PlanID) (io.ReadCloser, bool, error)
ListContainers(queryList map[string]string) ([]atc.Container, error)
ListVolumes() ([]atc.Volume, error)
SaveWorker(atc.Worker, *time.Duration) (*atc.Worker, error)
Expand Down
143 changes: 143 additions & 0 deletions concourse/concoursefakes/fake_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions concourse/internal/connection.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package internal

import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"net/http/httputil"
Expand Down Expand Up @@ -32,7 +32,7 @@ type Request struct {
Params rata.Params
Query url.Values
Header http.Header
Body *bytes.Buffer
Body io.Reader
ReturnResponseBody bool
}

Expand Down Expand Up @@ -167,15 +167,15 @@ func (connection *connection) createHTTPRequest(passedRequest Request) (*http.Re
return req, nil
}

func (connection *connection) getBody(passedRequest Request) *bytes.Buffer {
func (connection *connection) getBody(passedRequest Request) io.Reader {
if passedRequest.Header != nil && passedRequest.Body != nil {
if _, ok := passedRequest.Header["Content-Type"]; !ok {
panic("You must pass a 'Content-Type' Header with a body")
}
return passedRequest.Body
}

return &bytes.Buffer{}
return nil
}

func (connection *connection) populateResponse(response *http.Response, returnResponseBody bool, passedResponse *Response) error {
Expand Down

0 comments on commit 8a2c45e

Please sign in to comment.