Skip to content

Commit

Permalink
Merge pull request #53 from jensoncs/master
Browse files Browse the repository at this point in the history
[Jenson|Roy] Enforce Proctor Client upgrade
  • Loading branch information
roy peter authored Nov 21, 2018
2 parents 2b654dd + 69645ab commit 3dd1e03
Show file tree
Hide file tree
Showing 17 changed files with 279 additions and 60 deletions.
5 changes: 4 additions & 1 deletion cmd/version/version.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package version

import (
"fmt"
"github.com/fatih/color"
"github.com/gojektech/proctor/io"
"github.com/spf13/cobra"
)

const ClientVersion = "v0.2.0"

func NewCmd(printer io.Printer) *cobra.Command {
return &cobra.Command{
Use: "version",
Short: "Print version of Proctor command-line tool",
Long: `Example: proctor version`,
Run: func(cmd *cobra.Command, args []string) {
printer.Println("😊 Proctor: A Developer Friendly Automation Orchestrator v0.2.0", color.Reset)
printer.Println(fmt.Sprintf("Proctor: A Developer Friendly Automation Orchestrator %v",ClientVersion), color.Reset)
},
}
}
2 changes: 1 addition & 1 deletion cmd/version/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestVersionCmd(t *testing.T) {
mockPrinter := &io.MockPrinter{}
versionCmd := NewCmd(mockPrinter)

mockPrinter.On("Println", "😊 Proctor: A Developer Friendly Automation Orchestrator v0.2.0", color.Reset).Once()
mockPrinter.On("Println", "Proctor: A Developer Friendly Automation Orchestrator v0.2.0", color.Reset).Once()

versionCmd.Run(&cobra.Command{}, []string{})

Expand Down
14 changes: 13 additions & 1 deletion daemon/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/gojektech/proctor/cmd/version"
"io/ioutil"
"net"
"net/http"
"net/url"
Expand All @@ -29,6 +31,7 @@ type client struct {
proctordHost string
emailId string
accessToken string
clientVersion string
connectionTimeoutSecs time.Duration
}

Expand All @@ -43,6 +46,7 @@ func NewClient(proctorConfig config.ProctorConfig) Client {
emailId: proctorConfig.Email,
accessToken: proctorConfig.AccessToken,
connectionTimeoutSecs: proctorConfig.ConnectionTimeoutSecs,
clientVersion: version.ClientVersion,
}
}

Expand All @@ -53,8 +57,9 @@ func (c *client) ListProcs() ([]proc.Metadata, error) {
req, err := http.NewRequest("GET", "http://"+c.proctordHost+"/jobs/metadata", nil)
req.Header.Add(utility.UserEmailHeaderKey, c.emailId)
req.Header.Add(utility.AccessTokenHeaderKey, c.accessToken)
resp, err := client.Do(req)
req.Header.Add(utility.ClientVersionHeaderKey, c.clientVersion)

resp, err := client.Do(req)
if err != nil {
return []proc.Metadata{}, buildNetworkError(err)
}
Expand Down Expand Up @@ -85,6 +90,7 @@ func (c *client) ExecuteProc(name string, args map[string]string) (string, error
req.Header.Add("Content-Type", "application/json")
req.Header.Add(utility.UserEmailHeaderKey, c.emailId)
req.Header.Add(utility.AccessTokenHeaderKey, c.accessToken)
req.Header.Add(utility.ClientVersionHeaderKey, c.clientVersion)
resp, err := client.Do(req)

if err != nil {
Expand Down Expand Up @@ -116,8 +122,10 @@ func (c *client) StreamProcLogs(name string) error {
headers := make(map[string][]string)
token := []string{c.accessToken}
emailId := []string{c.emailId}
clientVersion := []string{c.clientVersion}
headers[utility.AccessTokenHeaderKey] = token
headers[utility.UserEmailHeaderKey] = emailId
headers[utility.ClientVersionHeaderKey] = clientVersion

wsConn, response, err := websocket.DefaultDialer.Dial(proctodWebsocketURLWithProcName, headers)
if err != nil {
Expand Down Expand Up @@ -171,6 +179,10 @@ func buildHTTPError(c *client, resp *http.Response) error {
return fmt.Errorf("%s\n%s", utility.UnauthorizedErrorHeader, utility.UnauthorizedErrorMissingConfig)
}
return fmt.Errorf("%s\n%s", utility.UnauthorizedErrorHeader, utility.UnauthorizedErrorInvalidConfig)
} else if resp.StatusCode == http.StatusBadRequest {
body, _ := ioutil.ReadAll(resp.Body)
bodyString := string(body)
return fmt.Errorf(bodyString)
} else {
return fmt.Errorf("%s\nStatus Code: %d, %s", utility.GenericResponseErrorHeader, resp.StatusCode, http.StatusText(resp.StatusCode))
}
Expand Down
125 changes: 101 additions & 24 deletions daemon/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package daemon

import (
"errors"
"fmt"
"github.com/gojektech/proctor/cmd/version"
"net/http"
"net/http/httptest"
"strings"
Expand Down Expand Up @@ -29,7 +31,7 @@ func TestListProcsReturnsListOfProcsWithDetails(t *testing.T) {
var args = []env.VarMetadata{env.VarMetadata{Name: "ARG1", Description: "Argument name"}}
var secrets = []env.VarMetadata{env.VarMetadata{Name: "SECRET1", Description: "Base64 encoded secret for authentication."}}
envVars := env.Vars{Secrets: secrets, Args: args}
var procListExpected = []proc.Metadata{proc.Metadata{Name: "job-1", Description: "job description", EnvVars: envVars}}
var expectedProcList = []proc.Metadata{proc.Metadata{Name: "job-1", Description: "job description", EnvVars: envVars}}

httpmock.RegisterStubRequest(
httpmock.NewStubRequest(
Expand All @@ -40,16 +42,17 @@ func TestListProcsReturnsListOfProcsWithDetails(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)

procList, err := proctorClient.ListProcs()

assert.NoError(t, err)
assert.Equal(t, procListExpected, procList)
assert.Equal(t, expectedProcList, procList)
}

func TestListProcsReturnErrorFromResponseBody(t *testing.T) {
Expand All @@ -68,8 +71,9 @@ func TestListProcsReturnErrorFromResponseBody(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand Down Expand Up @@ -97,8 +101,9 @@ func TestListProcsReturnClientSideTimeoutError(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand All @@ -125,8 +130,9 @@ func TestListProcsReturnClientSideConnectionError(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand All @@ -152,8 +158,9 @@ func TestListProcsForUnauthorizedUser(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand All @@ -164,6 +171,36 @@ func TestListProcsForUnauthorizedUser(t *testing.T) {
assert.Equal(t, "Unauthorized Access!!!\nPlease check the EMAIL_ID and ACCESS_TOKEN validity in proctor config file.", err.Error())
}

func TestListProcsReturnProcListBadRequestError(t *testing.T) {
proctorConfig := config.ProctorConfig{Host: "proctor.example.com", Email: "proctor@example.com", AccessToken: "access-token"}
proctorClient := NewClient(proctorConfig)
var expectedProcList = []proc.Metadata{}
expectedBody := fmt.Sprintf("Your Proctor client is using an outdated version: %s . To continue using proctor, please upgrade to latest version.", "0.1.0")

httpmock.Activate()
defer httpmock.DeactivateAndReset()

httpmock.RegisterStubRequest(
httpmock.NewStubRequest(
"GET",
"http://"+proctorConfig.Host+"/jobs/metadata",
func(req *http.Request) (*http.Response, error) {
return httpmock.NewStringResponse(400,expectedBody), nil
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)

listProcResponse, err := proctorClient.ListProcs()
assert.Equal(t,expectedBody,err.Error())
assert.Equal(t, expectedProcList, listProcResponse)
}

func TestListProcsForUnauthorizedErrorWithConfigMissing(t *testing.T) {
proctorConfig := config.ProctorConfig{Host: "proctor.example.com", Email: "proctor@example.com", AccessToken: ""}
proctorClient := NewClient(proctorConfig)
Expand All @@ -179,8 +216,9 @@ func TestListProcsForUnauthorizedErrorWithConfigMissing(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{""},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{""},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand Down Expand Up @@ -211,8 +249,9 @@ func TestExecuteProc(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand Down Expand Up @@ -242,8 +281,9 @@ func TestExecuteProcInternalServerError(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand All @@ -254,6 +294,39 @@ func TestExecuteProcInternalServerError(t *testing.T) {
assert.Equal(t, expectedProcResponse, executeProcResponse)
}

func TestExecuteProcBadRequest(t *testing.T) {
proctorConfig := config.ProctorConfig{Host: "proctor.example.com", Email: "proctor@example.com", AccessToken: "access-token"}
proctorClient := NewClient(proctorConfig)
expectedProcResponse := ""
procName := "run-sample"
procArgs := map[string]string{"SAMPLE_ARG1": "sample-value"}
expectedBody := fmt.Sprintf("Your Proctor client is using an outdated version: %s . To continue using proctor, please upgrade to latest version.", "0.1.0")

httpmock.Activate()
defer httpmock.DeactivateAndReset()

httpmock.RegisterStubRequest(
httpmock.NewStubRequest(
"POST",
"http://"+proctorConfig.Host+"/jobs/execute",
func(req *http.Request) (*http.Response, error) {
return httpmock.NewStringResponse(400, expectedBody), nil
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)

executeProcResponse, err := proctorClient.ExecuteProc(procName, procArgs)

assert.Equal(t, expectedBody, err.Error())
assert.Equal(t, expectedProcResponse, executeProcResponse)
}

func TestExecuteProcUnAuthorized(t *testing.T) {
proctorConfig := config.ProctorConfig{Host: "proctor.example.com", Email: "proctor@example.com", AccessToken: "access-token"}
proctorClient := NewClient(proctorConfig)
Expand All @@ -270,8 +343,9 @@ func TestExecuteProcUnAuthorized(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand All @@ -298,8 +372,9 @@ func TestExecuteProcUnAuthorizedWhenEmailAndAccessTokenNotSet(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{""},
utility.AccessTokenHeaderKey: []string{""},
utility.UserEmailHeaderKey: []string{""},
utility.AccessTokenHeaderKey: []string{""},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand All @@ -326,8 +401,9 @@ func TestExecuteProcsReturnClientSideConnectionError(t *testing.T) {
},
).WithHeader(
&http.Header{
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.UserEmailHeaderKey: []string{"proctor@example.com"},
utility.AccessTokenHeaderKey: []string{"access-token"},
utility.ClientVersionHeaderKey: []string{version.ClientVersion},
},
),
)
Expand All @@ -344,6 +420,7 @@ func TestLogStreamForAuthorizedUser(t *testing.T) {
upgrader := websocket.Upgrader{}
assert.Equal(t, "proctor@example.com", r.Header.Get(utility.UserEmailHeaderKey))
assert.Equal(t, "access-token", r.Header.Get(utility.AccessTokenHeaderKey))
assert.Equal(t, version.ClientVersion, r.Header.Get(utility.ClientVersionHeaderKey))
conn, _ := upgrader.Upgrade(w, r, nil)
defer conn.Close()
}
Expand Down
Loading

0 comments on commit 3dd1e03

Please sign in to comment.