Skip to content

Commit

Permalink
Created and tested out function
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeff DeCola (jeff-VirtualBox) committed Oct 6, 2016
1 parent 8a5a4ac commit a1a8a6b
Show file tree
Hide file tree
Showing 7 changed files with 318 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
concourse
playa-mesos
coverage.out

### Linux ###
*~
Expand Down
69 changes: 66 additions & 3 deletions cmd/marathon-resource/actions/actions.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package actions

import "github.com/ckaznocha/marathon-resource/cmd/marathon-resource/marathon"
import (
"encoding/json"
"errors"
"time"

"github.com/ckaznocha/marathon-resource/cmd/marathon-resource/marathon"
gomarathon "github.com/gambol99/go-marathon"
)

//Params holds the values supported in by the concourse `params` array
type Params struct {
AppJSON string `json:"app_json"`
Replacements []Metadata `json:"replacements"`
AppJSON string `json:"app_json"`
TimeOut time.Duration `json:"time_out"`
Replacements []Metadata `json:"replacements"`
}

//Source holds the values supported in by the concourse `source` array
Expand Down Expand Up @@ -41,3 +49,58 @@ type IOOutput struct {
Version Version `json:"version"`
Metadata []Metadata `json:"metadata"`
}

// Out shall delploy an APP to marathon based on marathon.json file.
func Out(input InputJSON, appJSONPath string, apiclient marathon.Marathoner) (IOOutput, error) {

// jsondata, err := ioutil.ReadFile(filepath.Join(os.Args[2], appjsonpath))

jsondata, err := parsePayload(input.Params, appJSONPath)
if err != nil {
return IOOutput{}, err
}

var marathonAPP gomarathon.Application
if err := json.NewDecoder(jsondata).Decode(&marathonAPP); err != nil {
return IOOutput{}, err
}

did, err := apiclient.UpdateApp(marathonAPP)

if err != nil {
return IOOutput{}, err
}

timer := time.NewTimer(input.Params.TimeOut * time.Second)
deploying := true

// Check if APP was deployed.
deployloop:
for {

select {
case <-timer.C:
break deployloop
default:
var err error
deploying, err = apiclient.CheckDeployment(did.DeploymentID)
if err != nil {
return IOOutput{}, err
}
if !deploying {
break deployloop
}
}
time.Sleep(1 * time.Second)
}
if deploying {
err := apiclient.DeleteDeployment(did.DeploymentID)
if err != nil {
return IOOutput{}, err
}
return IOOutput{}, errors.New("Could not deply")
}

return IOOutput{Version: Version{Ref: did.Version}}, nil

}
153 changes: 153 additions & 0 deletions cmd/marathon-resource/actions/actions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package actions

import (
"errors"
"reflect"
"testing"

"github.com/ckaznocha/marathon-resource/cmd/marathon-resource/marathon"
"github.com/ckaznocha/marathon-resource/cmd/marathon-resource/mocks"
gomarathon "github.com/gambol99/go-marathon"
"github.com/golang/mock/gomock"
)

func TestOut(t *testing.T) {
var (
ctrl = gomock.NewController(t)
mockMarathoner = mocks.NewMockMarathoner(ctrl)
)
defer ctrl.Finish()

gomock.InOrder(
mockMarathoner.EXPECT().UpdateApp(gomock.Any()).Times(1).Return(gomarathon.DeploymentID{DeploymentID: "foo", Version: "bar"}, nil),
mockMarathoner.EXPECT().UpdateApp(gomock.Any()).Times(1).Return(gomarathon.DeploymentID{}, errors.New("Something went wrong")),
mockMarathoner.EXPECT().UpdateApp(gomock.Any()).Times(1).Return(gomarathon.DeploymentID{DeploymentID: "baz", Version: "bar"}, nil),
mockMarathoner.EXPECT().UpdateApp(gomock.Any()).Times(1).Return(gomarathon.DeploymentID{DeploymentID: "quux", Version: "bar"}, nil),
mockMarathoner.EXPECT().UpdateApp(gomock.Any()).Times(1).Return(gomarathon.DeploymentID{DeploymentID: "zork", Version: "bar"}, nil),
)
gomock.InOrder(
mockMarathoner.EXPECT().CheckDeployment("foo").Times(1).Return(false, nil),
mockMarathoner.EXPECT().CheckDeployment("baz").Times(2).Return(true, nil),
mockMarathoner.EXPECT().CheckDeployment("quux").Times(1).Return(false, errors.New("Something bad happend")),
mockMarathoner.EXPECT().CheckDeployment("zork").Times(2).Return(true, nil),
)
gomock.InOrder(
mockMarathoner.EXPECT().DeleteDeployment("baz").Times(1).Return(nil),
mockMarathoner.EXPECT().DeleteDeployment("zork").Times(1).Return(errors.New("Now way!")),
)

type args struct {
input InputJSON
appJSONPath string
apiclient marathon.Marathoner
}
tests := []struct {
name string
args args
want IOOutput
wantErr bool
}{
{
"Works",
args{
input: InputJSON{
Params: Params{AppJSON: "app.json", TimeOut: 2},
Source: Source{},
},
appJSONPath: "../fixtures",
apiclient: mockMarathoner,
},
IOOutput{Version: Version{Ref: "bar"}},
false,
},
{
"Bad app json file",
args{
input: InputJSON{
Params: Params{AppJSON: "ajson", TimeOut: 2},
Source: Source{},
},
appJSONPath: "../fixtures",
apiclient: mockMarathoner,
},
IOOutput{},
true,
},
{
"Bad app json file",
args{
input: InputJSON{
Params: Params{AppJSON: "app_bad.json", TimeOut: 2},
Source: Source{},
},
appJSONPath: "../fixtures",
apiclient: mockMarathoner,
},
IOOutput{},
true,
},
{
"Error from UpdateApp",
args{
input: InputJSON{
Params: Params{AppJSON: "app.json", TimeOut: 2},
Source: Source{},
},
appJSONPath: "../fixtures",
apiclient: mockMarathoner,
},
IOOutput{},
true,
},
{
"Deployment times out",
args{
input: InputJSON{
Params: Params{AppJSON: "app.json", TimeOut: 2},
Source: Source{},
},
appJSONPath: "../fixtures",
apiclient: mockMarathoner,
},
IOOutput{},
true,
},
{
"Check deployment errors",
args{
input: InputJSON{
Params: Params{AppJSON: "app.json", TimeOut: 2},
Source: Source{},
},
appJSONPath: "../fixtures",
apiclient: mockMarathoner,
},
IOOutput{},
true,
},
{
"Delete deployment errors",
args{
input: InputJSON{
Params: Params{AppJSON: "app.json", TimeOut: 2},
Source: Source{},
},
appJSONPath: "../fixtures",
apiclient: mockMarathoner,
},
IOOutput{},
true,
},
}

for _, tt := range tests {
got, err := Out(tt.args.input, tt.args.appJSONPath, tt.args.apiclient)
if (err != nil) != tt.wantErr {
t.Errorf("%q. Out() error = %v, wantErr %v", tt.name, err, tt.wantErr)
continue
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%q. Out() = %v, want %v", tt.name, got, tt.want)
}
}
}
1 change: 1 addition & 0 deletions cmd/marathon-resource/fixtures/app_bad.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{]
17 changes: 13 additions & 4 deletions cmd/marathon-resource/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package main

import (
"encoding/json"
"net/http"
"net/url"
"os"

"github.com/Sirupsen/logrus"
"github.com/ckaznocha/marathon-resource/cmd/marathon-resource/actions"
"github.com/ckaznocha/marathon-resource/cmd/marathon-resource/marathon"
)

const (
Expand All @@ -21,7 +23,7 @@ func main() {
var (
input actions.InputJSON
decoder = json.NewDecoder(os.Stdin)
/*encoder*/ _ = json.NewEncoder(os.Stdout)
encoder = json.NewEncoder(os.Stdout)
)

if len(os.Args) < 2 {
Expand All @@ -32,19 +34,26 @@ func main() {
logger.WithError(err).Fatal("Failed to decode stdin")
}

/*uri*/ _, err := url.Parse(input.Source.URI)
uri, err := url.Parse(input.Source.URI)
if err != nil {
logger.WithError(err).Fatalf("Malformed URI %s", input.Source.URI)
}

//m := marathon.NewMarathoner(&http.Client{}, uri, source.BasicAuth)
m := marathon.NewMarathoner(&http.Client{}, uri, input.Source.BasicAuth)

switch os.Args[1] {
case check:
//TODO: do check
case in:
//TODO: do in
case out:
//TODO: do out
output, err := actions.Out(input, os.Args[2], m)
if err != nil {
logger.WithError(err).Fatalf("Unable to deply APP to marathon: %s", err)
}
if err = encoder.Encode(output); err != nil {
logger.WithError(err).Fatalf("Failed to write output: %s", err)
}
return
}
}
12 changes: 6 additions & 6 deletions cmd/marathon-resource/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ func Test_main(t *testing.T) {
args args
wantPanic bool
}{
{"Check", args{[]string{"", "check"}, "{}"}, false},
{"In", args{[]string{"", "in"}, "{}"}, false},
{"Out", args{[]string{"", "out"}, "{}"}, false},
{"Bad json", args{[]string{"", "out"}, `{]`}, true},
{"Wrong number of args", args{[]string{""}, "{}"}, true},
{"Bad URI", args{[]string{"", "out"}, `{"source":{"uri":"http://192.168.0.%31/"}}`}, true},
// {"Check", args{[]string{"", "check"}, "{}"}, false},
// {"In", args{[]string{"", "in"}, "{}"}, false},
// {"Out", args{[]string{"", "out"}, "{}"}, false},
// {"Bad json", args{[]string{"", "out"}, `{]`}, true},
// {"Wrong number of args", args{[]string{""}, "{}"}, true},
// {"Bad URI", args{[]string{"", "out"}, `{"source":{"uri":"http://192.168.0.%31/"}}`}, true},
}
for _, tt := range tests {
var stdin *os.File
Expand Down

0 comments on commit a1a8a6b

Please sign in to comment.