diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..3924603 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,55 @@ +name: build +on: + push: + branches: + - '*' + pull_request: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: 'go.mod' + - run: "go vet ./..." + - name: Lint + uses: dominikh/staticcheck-action@v1.2.0 + with: + version: "2022.1.1" + unit-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: 'go.mod' + - name: Unit Tests + run: | + make test-unit + integration-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: 'go.mod' + - name: Integration Tests + run: | + make test-integration + snapshot-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-go@v3 + with: + go-version-file: 'go.mod' + - name: Snapshot Build + uses: goreleaser/goreleaser-action@v3 + with: + distribution: goreleaser + version: latest + args: release --debug --snapshot --skip-publish --rm-dist \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..33bc8cb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,28 @@ +name: release +on: + workflow_run: + workflows: [build] + types: + - completed + push: + tags: + - 'v*' + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-go@v3 + with: + go-version-file: 'go.mod' + - name: Tagged Release + uses: goreleaser/goreleaser-action@v3 + with: + distribution: goreleaser + version: latest + args: release --debug --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.jenkins b/.jenkins deleted file mode 100644 index 1dd410e..0000000 --- a/.jenkins +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env groovy - -pipeline { - - agent { - label 'golang-alpha' - } - - stages { - stage('Checkout') { - steps { - checkout scm - } - } - - stage('Checks') { - parallel { - - stage('Lint') { - steps { - container('golang'){ - sh 'golint -set_exit_status ./...' - } - } - } - - stage('Test') { - environment { - CGO_ENABLED = 0 - } - steps { - container('golang'){ - sh 'go test -short -covermode=atomic ./...' - } - } - } - - stage('Snapshot Build') { - steps { - container('golang'){ - sh 'goreleaser release --debug --snapshot --skip-publish --rm-dist' - } - } - } - } - } - - stage('Tagged Release') { - when { - buildingTag() - } - environment { - GITHUB_TOKEN = credentials('vio-bot-gh-token') - } - steps { - container('golang'){ - withDockerRegistry(registry: [credentialsId: 'vio-docker-hub']) { - sh 'goreleaser release --debug --rm-dist' - } - } - } - } - } -} diff --git a/Makefile b/Makefile index 601aaa0..b88cb42 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # synse-client-go # -PKG_VERSION := 1.0.0 +PKG_VERSION := v1.1.0 .PHONY: build @@ -36,7 +36,6 @@ test: test-unit test-integration ## Run all tests (unit, integration) .PHONY: test-unit test-unit: ## Run unit tests - @ # Note: this requires go1.10+ in order to do multi-package coverage reports go test -short -race -coverprofile=coverage.out -covermode=atomic ./... .PHONY: test-integration diff --git a/README.md b/README.md index 659a528..2dc15af 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://build.vio.sh/buildStatus/icon?job=vapor-ware/synse-client-go/master)](https://build.vio.sh/blue/organizations/jenkins/vapor-ware%2Fsynse-client-go/activity) +[![Build Status](https://github.com/vapor-ware/synse-client-go/workflows/build/badge.svg)](https://github.com/vapor-ware/synse-client-go/actions) [![Godoc](https://godoc.org/github.com/vapor-ware/synse-client-go/synse?status.svg)](https://godoc.org/github.com/vapor-ware/synse-client-go/synse) [![Go Report Card](https://goreportcard.com/badge/github.com/vapor-ware/synse-client-go)](https://goreportcard.com/report/github.com/vapor-ware/synse-client-go) diff --git a/go.mod b/go.mod index 87f34e7..f57714d 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,21 @@ module github.com/vapor-ware/synse-client-go -go 1.12 +go 1.19 + +require ( + github.com/creasty/defaults v1.6.0 + github.com/go-resty/resty/v2 v2.7.0 + github.com/gorilla/websocket v1.5.0 + github.com/mitchellh/mapstructure v1.5.0 + github.com/pkg/errors v0.9.1 + github.com/stretchr/testify v1.7.0 +) require ( - github.com/creasty/defaults v1.3.0 github.com/davecgh/go-spew v1.1.1 // indirect - github.com/gorilla/websocket v1.4.2 github.com/kr/pretty v0.1.0 // indirect - github.com/mitchellh/mapstructure v1.2.2 - github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.4.0 - golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect - gopkg.in/resty.v1 v1.12.0 + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/go.sum b/go.sum index 04954ad..da1b7b1 100644 --- a/go.sum +++ b/go.sum @@ -1,35 +1,35 @@ -github.com/creasty/defaults v1.3.0 h1:uG+RAxYbJgOPCOdKEcec9ZJXeva7Y6mj/8egdzwmLtw= -github.com/creasty/defaults v1.3.0/go.mod h1:CIEEvs7oIVZm30R8VxtFJs+4k201gReYyuYHJxZc68I= +github.com/creasty/defaults v1.6.0 h1:ltuE9cfphUtlrBeomuu8PEyISTXnxqkBIoQfXgv7BSc= +github.com/creasty/defaults v1.6.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4= -github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/test/http.go b/internal/test/http.go index 452971c..c1b3ee0 100644 --- a/internal/test/http.go +++ b/internal/test/http.go @@ -32,11 +32,11 @@ type HTTPServer struct { } // NewHTTPServerV3 returns an instance of a mock http server for v3 API. -func NewHTTPServerV3() HTTPServer { +func NewHTTPServerV3() *HTTPServer { m := http.NewServeMux() s := httptest.NewServer(m) - return HTTPServer{ + return &HTTPServer{ URL: s.URL[7:], // remove `http://` prefix server: s, mux: m, @@ -45,11 +45,11 @@ func NewHTTPServerV3() HTTPServer { } // NewHTTPSServerV3 returns an instance of a mock https server for v3 API. -func NewHTTPSServerV3() HTTPServer { +func NewHTTPSServerV3() *HTTPServer { m := http.NewServeMux() s := httptest.NewTLSServer(m) - return HTTPServer{ + return &HTTPServer{ URL: s.URL[8:], // remove `https://` server: s, mux: m, @@ -58,27 +58,27 @@ func NewHTTPSServerV3() HTTPServer { } // ServeUnversioned serves an unversioned endpoint. -func (s HTTPServer) ServeUnversioned(t *testing.T, uri string, statusCode int, response interface{}) { +func (s *HTTPServer) ServeUnversioned(t *testing.T, uri string, statusCode int, response interface{}) { serve(s.mux, t, uri, statusCode, response) } // ServeVersioned serves a versioned endpoint. -func (s HTTPServer) ServeVersioned(t *testing.T, uri string, statusCode int, response interface{}) { +func (s *HTTPServer) ServeVersioned(t *testing.T, uri string, statusCode int, response interface{}) { serve(s.mux, t, fmt.Sprintf("/%v%v", s.version, uri), statusCode, response) } // SetTLS starts TLS using the configured options. -func (s HTTPServer) SetTLS(cfg *tls.Config) { +func (s *HTTPServer) SetTLS(cfg *tls.Config) { s.tls = cfg } // GetCertificates returns the certificate used by the server. -func (s HTTPServer) GetCertificates() *x509.Certificate { +func (s *HTTPServer) GetCertificates() *x509.Certificate { return s.server.Certificate() } // Close closes the unversioned server connection. -func (s HTTPServer) Close() { +func (s *HTTPServer) Close() { s.server.Close() } diff --git a/internal/test/websocket.go b/internal/test/websocket.go index 395721d..432af96 100644 --- a/internal/test/websocket.go +++ b/internal/test/websocket.go @@ -39,11 +39,11 @@ type WebSocketServer struct { } // NewWebSocketServerV3 returns an instance of a mock websocket server for v3 API. -func NewWebSocketServerV3() WebSocketServer { +func NewWebSocketServerV3() *WebSocketServer { m := http.NewServeMux() s := httptest.NewServer(m) - return WebSocketServer{ + return &WebSocketServer{ URL: s.URL[7:], // remove `http://` prefix server: s, mux: m, @@ -53,11 +53,11 @@ func NewWebSocketServerV3() WebSocketServer { } // NewWebSocketTLSServerV3 returns an instance of a mock websocket tls server for v3 API. -func NewWebSocketTLSServerV3() WebSocketServer { +func NewWebSocketTLSServerV3() *WebSocketServer { m := http.NewServeMux() s := httptest.NewTLSServer(m) - return WebSocketServer{ + return &WebSocketServer{ URL: s.URL[8:], // remove `https://` prefix server: s, mux: m, @@ -67,7 +67,7 @@ func NewWebSocketTLSServerV3() WebSocketServer { } // Serve reads a request event and writes back a given response. -func (s WebSocketServer) Serve(resp string) { +func (s *WebSocketServer) Serve(resp string) { s.mux.HandleFunc( fmt.Sprintf("/%s/%s", s.version, s.entryRoute), func(w http.ResponseWriter, r *http.Request) { @@ -99,7 +99,7 @@ func (s WebSocketServer) Serve(resp string) { } // Stream issues a requests and writes back a stream of response data. -func (s WebSocketServer) Stream(responses []string) { +func (s *WebSocketServer) Stream(responses []string) { s.mux.HandleFunc( fmt.Sprintf("/%s/%s", s.version, s.entryRoute), func(w http.ResponseWriter, r *http.Request) { @@ -136,16 +136,16 @@ func (s WebSocketServer) Stream(responses []string) { } // SetTLS starts TLS using the configured options. -func (s WebSocketServer) SetTLS(cfg *tls.Config) { +func (s *WebSocketServer) SetTLS(cfg *tls.Config) { s.tls = cfg } // GetCertificates returns the certificate used by the server. -func (s WebSocketServer) GetCertificates() *x509.Certificate { +func (s *WebSocketServer) GetCertificates() *x509.Certificate { return s.server.Certificate() } // Close closes the connection. -func (s WebSocketServer) Close() { +func (s *WebSocketServer) Close() { s.server.Close() } diff --git a/synse/http.go b/synse/http.go index 7127e4a..1eb2200 100644 --- a/synse/http.go +++ b/synse/http.go @@ -6,9 +6,9 @@ import ( "crypto/tls" "encoding/json" + "github.com/go-resty/resty/v2" "github.com/pkg/errors" "github.com/vapor-ware/synse-client-go/synse/scheme" - "gopkg.in/resty.v1" ) // httpClient implements a http client. @@ -218,7 +218,7 @@ func (c *httpClient) ReadCache(opts scheme.ReadCacheOptions, out chan<- *scheme. defer close(out) errScheme := new(scheme.Error) - resp, err := c.setVersioned().R().SetDoNotParseResponse(true).SetMultiValueQueryParams(structToURLValues(opts)).SetError(errScheme).Get(readcacheURI) + resp, err := c.setVersioned().R().SetDoNotParseResponse(true).SetQueryParamsFromValues(structToURLValues(opts)).SetError(errScheme).Get(readcacheURI) if err = check(err, errScheme); err != nil { return err } @@ -288,7 +288,7 @@ func (c *httpClient) GetOptions() *Options { // against the Synse Server versioned API. func (c *httpClient) getVersionedQueryParams(uri string, params interface{}, okScheme interface{}) error { errScheme := new(scheme.Error) - _, err := c.setVersioned().R().SetMultiValueQueryParams(structToURLValues(params)).SetResult(okScheme).SetError(errScheme).Get(uri) + _, err := c.setVersioned().R().SetQueryParamsFromValues(structToURLValues(params)).SetResult(okScheme).SetError(errScheme).Get(uri) return check(err, errScheme) } @@ -315,12 +315,12 @@ func (c *httpClient) postVersioned(uri string, body interface{}, okScheme interf // setUnversioned returns a client that uses unversioned host URL. func (c *httpClient) setUnversioned() *resty.Client { - return c.client.SetHostURL(buildURL(c.scheme, c.options.Address)) + return c.client.SetBaseURL(buildURL(c.scheme, c.options.Address)) } // setVersioned returns a client that uses versioned host URL. func (c *httpClient) setVersioned() *resty.Client { - return c.client.SetHostURL(buildURL(c.scheme, c.options.Address, c.apiVersion)) + return c.client.SetBaseURL(buildURL(c.scheme, c.options.Address, c.apiVersion)) } // check validates returned response from the Synse Server. diff --git a/synse/websocket_test.go b/synse/websocket_test.go index c71b1e4..093d088 100644 --- a/synse/websocket_test.go +++ b/synse/websocket_test.go @@ -1663,6 +1663,14 @@ func TestWebSocketClientV3_ReadStream_500(t *testing.T) { assert.NotNil(t, client) assert.NoError(t, err) + var results []*scheme.Read + + defer func() { + err := client.Close() + assert.NoError(t, err) + assert.Empty(t, results) + }() + err = client.Open() assert.NoError(t, err) @@ -1672,18 +1680,13 @@ func TestWebSocketClientV3_ReadStream_500(t *testing.T) { defer close(readings) - go func() { - err := client.ReadStream(opts, readings, stop) - assert.Error(t, err) - }() - - var results []*scheme.Read + err = client.ReadStream(opts, readings, stop) + assert.Error(t, err) timeout := time.After(2 * time.Second) closer := time.After(1 * time.Second) var once sync.Once -readLoop: for { select { case r := <-readings: @@ -1693,18 +1696,13 @@ readLoop: once.Do(func() { close(stop) }) - break readLoop + return case <-timeout: // If the test does not complete after 2s, error. t.Fatal("timeout: failed getting read stream data from channel") } } - - assert.Empty(t, results) - - err = client.Close() - assert.NoError(t, err) } func TestWebSocketClientV3_WriteAsync_200(t *testing.T) {