VMware vSphere Integrated Containers provider (#206)

* Add Virtual Kubelet provider for VIC

Initial virtual kubelet provider for VMware VIC.  This provider currently
handles creating and starting of a pod VM via the VIC portlayer and persona
server.  Image store handling via the VIC persona server.  This provider
currently requires the feature/wolfpack branch of VIC.

* Added pod stop and delete.  Also added node capacity.

Added the ability to stop and delete pod VMs via VIC.  Also retrieve
node capacity information from the VCH.

* Cleanup and readme file

Some file clean up and added a Readme.md markdown file for the VIC
provider.

* Cleaned up errors, added function comments, moved operation code

1. Cleaned up error handling.  Set standard for creating errors.
2. Added method prototype comments for all interface functions.
3. Moved PodCreator, PodStarter, PodStopper, and PodDeleter to a new folder.

* Add mocking code and unit tests for podcache, podcreator, and podstarter

Used the unit test framework used in VIC to handle assertions in the provider's
unit test.  Mocking code generated using OSS project mockery, which is compatible
with the testify assertion framework.

* Vendored packages for the VIC provider

Requires feature/wolfpack branch of VIC and a few specific commit sha of
projects used within VIC.

* Implementation of POD Stopper and Deleter unit tests (#4)

* Updated files for initial PR
This commit is contained in:
Loc Nguyen
2018-06-04 15:41:32 -07:00
committed by Ria Bhatia
parent 98a111e8b7
commit 513cebe7b7
6296 changed files with 1123685 additions and 8 deletions

View File

@@ -0,0 +1,64 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"encoding/base64"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// PassThroughAuth never manipulates the request
var PassThroughAuth runtime.ClientAuthInfoWriter
func init() {
PassThroughAuth = runtime.ClientAuthInfoWriterFunc(func(_ runtime.ClientRequest, _ strfmt.Registry) error { return nil })
}
// BasicAuth provides a basic auth info writer
func BasicAuth(username, password string) runtime.ClientAuthInfoWriter {
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
encoded := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
r.SetHeaderParam("Authorization", "Basic "+encoded)
return nil
})
}
// APIKeyAuth provides an API key auth info writer
func APIKeyAuth(name, in, value string) runtime.ClientAuthInfoWriter {
if in == "query" {
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
r.SetQueryParam(name, value)
return nil
})
}
if in == "header" {
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
r.SetHeaderParam(name, value)
return nil
})
}
return nil
}
// BearerToken provides a header based oauth2 bearer access token auth info writer
func BearerToken(token string) runtime.ClientAuthInfoWriter {
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
r.SetHeaderParam("Authorization", "Bearer "+token)
return nil
})
}

View File

@@ -0,0 +1,65 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
func TestBasicAuth(t *testing.T) {
r, _ := newRequest("GET", "/", nil)
writer := BasicAuth("someone", "with a password")
writer.AuthenticateRequest(r, nil)
req := new(http.Request)
req.Header = make(http.Header)
req.Header.Set("Authorization", r.header.Get("Authorization"))
usr, pw, ok := req.BasicAuth()
if assert.True(t, ok) {
assert.Equal(t, "someone", usr)
assert.Equal(t, "with a password", pw)
}
}
func TestAPIKeyAuth_Query(t *testing.T) {
r, _ := newRequest("GET", "/", nil)
writer := APIKeyAuth("api_key", "query", "the-shared-key")
writer.AuthenticateRequest(r, nil)
assert.Equal(t, "the-shared-key", r.query.Get("api_key"))
}
func TestAPIKeyAuth_Header(t *testing.T) {
r, _ := newRequest("GET", "/", nil)
writer := APIKeyAuth("x-api-token", "header", "the-shared-key")
writer.AuthenticateRequest(r, nil)
assert.Equal(t, "the-shared-key", r.header.Get("x-api-token"))
}
func TestBearerTokenAuth(t *testing.T) {
r, _ := newRequest("GET", "/", nil)
writer := BearerToken("the-shared-token")
writer.AuthenticateRequest(r, nil)
assert.Equal(t, "Bearer the-shared-token", r.header.Get("Authorization"))
}

272
vendor/github.com/go-openapi/runtime/client/request.go generated vendored Normal file
View File

@@ -0,0 +1,272 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
"time"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// NewRequest creates a new swagger http client request
func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter) (*request, error) {
return &request{
pathPattern: pathPattern,
method: method,
writer: writer,
header: make(http.Header),
query: make(url.Values),
timeout: DefaultTimeout,
}, nil
}
// Request represents a swagger client request.
//
// This Request struct converts to a HTTP request.
// There might be others that convert to other transports.
// There is no error checking here, it is assumed to be used after a spec has been validated.
// so impossible combinations should not arise (hopefully).
//
// The main purpose of this struct is to hide the machinery of adding params to a transport request.
// The generated code only implements what is necessary to turn a param into a valid value for these methods.
type request struct {
pathPattern string
method string
writer runtime.ClientRequestWriter
pathParams map[string]string
header http.Header
query url.Values
formFields url.Values
fileFields map[string]runtime.NamedReadCloser
payload interface{}
timeout time.Duration
}
var (
// ensure interface compliance
_ runtime.ClientRequest = new(request)
)
// BuildHTTP creates a new http request based on the data from the params
func (r *request) BuildHTTP(mediaType string, producers map[string]runtime.Producer, registry strfmt.Registry) (*http.Request, error) {
// build the data
if err := r.writer.WriteToRequest(r, registry); err != nil {
return nil, err
}
// create http request
path := r.pathPattern
for k, v := range r.pathParams {
path = strings.Replace(path, "{"+k+"}", v, -1)
}
var body io.ReadCloser
var pr *io.PipeReader
var pw *io.PipeWriter
buf := bytes.NewBuffer(nil)
body = ioutil.NopCloser(buf)
if r.fileFields != nil {
pr, pw = io.Pipe()
body = pr
}
req, err := http.NewRequest(r.method, path, body)
if err != nil {
return nil, err
}
req.URL.RawQuery = r.query.Encode()
req.Header = r.header
// check if this is a form type request
if len(r.formFields) > 0 || len(r.fileFields) > 0 {
// check if this is multipart
if len(r.fileFields) > 0 {
mp := multipart.NewWriter(pw)
req.Header.Set(runtime.HeaderContentType, mp.FormDataContentType())
go func() {
defer func() {
mp.Close()
pw.Close()
}()
for fn, v := range r.formFields {
if len(v) > 0 {
if err := mp.WriteField(fn, v[0]); err != nil {
pw.CloseWithError(err)
log.Println(err)
}
}
}
for fn, f := range r.fileFields {
wrtr, err := mp.CreateFormFile(fn, filepath.Base(f.Name()))
if err != nil {
pw.CloseWithError(err)
log.Println(err)
}
defer func() {
for _, ff := range r.fileFields {
ff.Close()
}
}()
if _, err := io.Copy(wrtr, f); err != nil {
pw.CloseWithError(err)
log.Println(err)
}
}
}()
return req, nil
}
req.Header.Set(runtime.HeaderContentType, mediaType)
// write the form values as the body
buf.WriteString(r.formFields.Encode())
return req, nil
}
// if there is payload, use the producer to write the payload, and then
// set the header to the content-type appropriate for the payload produced
if r.payload != nil {
// TODO: infer most appropriate content type based on the producer used,
// and the `consumers` section of the spec/operation
req.Header.Set(runtime.HeaderContentType, mediaType)
if rdr, ok := r.payload.(io.ReadCloser); ok {
req.Body = rdr
return req, nil
}
if rdr, ok := r.payload.(io.Reader); ok {
req.Body = ioutil.NopCloser(rdr)
return req, nil
}
// set the content length of the request or else a chunked transfer is
// declared, and this corrupts outgoing JSON payloads. the content's
// length must be set prior to the body being written per the spec at
// https://golang.org/pkg/net/http
//
// If Body is present, Content-Length is <= 0 and TransferEncoding
// hasn't been set to "identity", Write adds
// "Transfer-Encoding: chunked" to the header. Body is closed
// after it is sent.
//
// to that end a temporary buffer, b, is created to produce the payload
// body, and then its size is used to set the request's content length
var b bytes.Buffer
producer := producers[mediaType]
if err := producer.Produce(&b, r.payload); err != nil {
return nil, err
}
req.ContentLength = int64(b.Len())
if _, err := buf.Write(b.Bytes()); err != nil {
return nil, err
}
}
return req, nil
}
// SetHeaderParam adds a header param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetHeaderParam(name string, values ...string) error {
if r.header == nil {
r.header = make(http.Header)
}
r.header[http.CanonicalHeaderKey(name)] = values
return nil
}
// SetQueryParam adds a query param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetQueryParam(name string, values ...string) error {
if r.query == nil {
r.query = make(url.Values)
}
r.query[name] = values
return nil
}
// SetFormParam adds a forn param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetFormParam(name string, values ...string) error {
if r.formFields == nil {
r.formFields = make(url.Values)
}
r.formFields[name] = values
return nil
}
// SetPathParam adds a path param to the request
func (r *request) SetPathParam(name string, value string) error {
if r.pathParams == nil {
r.pathParams = make(map[string]string)
}
r.pathParams[name] = value
return nil
}
// SetFileParam adds a file param to the request
func (r *request) SetFileParam(name string, file runtime.NamedReadCloser) error {
if actualFile, ok := file.(*os.File); ok {
fi, err := os.Stat(actualFile.Name())
if err != nil {
return err
}
if fi.IsDir() {
return fmt.Errorf("%q is a directory, only files are supported", file.Name())
}
}
if r.fileFields == nil {
r.fileFields = make(map[string]runtime.NamedReadCloser)
}
if r.formFields == nil {
r.formFields = make(url.Values)
}
r.fileFields[name] = file
return nil
}
// SetBodyParam sets a body parameter on the request.
// This does not yet serialze the object, this happens as late as possible.
func (r *request) SetBodyParam(payload interface{}) error {
r.payload = payload
return nil
}
// SetTimeout sets the timeout for a request
func (r *request) SetTimeout(timeout time.Duration) error {
r.timeout = timeout
return nil
}

View File

@@ -0,0 +1,244 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"encoding/json"
"encoding/xml"
"io/ioutil"
"mime"
"mime/multipart"
"os"
"path/filepath"
"testing"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"github.com/stretchr/testify/assert"
)
var testProducers = map[string]runtime.Producer{
runtime.JSONMime: runtime.JSONProducer(),
runtime.XMLMime: runtime.XMLProducer(),
runtime.TextMime: runtime.TextProducer(),
}
func TestBuildRequest_SetHeaders(t *testing.T) {
r, _ := newRequest("GET", "/flats/{id}/", nil)
// single value
r.SetHeaderParam("X-Rate-Limit", "500")
assert.Equal(t, "500", r.header.Get("X-Rate-Limit"))
r.SetHeaderParam("X-Rate-Limit", "400")
assert.Equal(t, "400", r.header.Get("X-Rate-Limit"))
// multi value
r.SetHeaderParam("X-Accepts", "json", "xml", "yaml")
assert.EqualValues(t, []string{"json", "xml", "yaml"}, r.header["X-Accepts"])
}
func TestBuildRequest_SetPath(t *testing.T) {
r, _ := newRequest("GET", "/flats/{id}/?hello=world", nil)
r.SetPathParam("id", "1345")
assert.Equal(t, "1345", r.pathParams["id"])
}
func TestBuildRequest_SetQuery(t *testing.T) {
r, _ := newRequest("GET", "/flats/{id}/", nil)
// single value
r.SetQueryParam("hello", "there")
assert.Equal(t, "there", r.query.Get("hello"))
// multi value
r.SetQueryParam("goodbye", "cruel", "world")
assert.Equal(t, []string{"cruel", "world"}, r.query["goodbye"])
}
func TestBuildRequest_SetForm(t *testing.T) {
// non-multipart
r, _ := newRequest("POST", "/flats", nil)
r.SetFormParam("hello", "world")
assert.Equal(t, "world", r.formFields.Get("hello"))
r.SetFormParam("goodbye", "cruel", "world")
assert.Equal(t, []string{"cruel", "world"}, r.formFields["goodbye"])
}
func TestBuildRequest_SetFile(t *testing.T) {
// needs to convert form to multipart
r, _ := newRequest("POST", "/flats/{id}/image", nil)
// error if it isn't there
err := r.SetFileParam("not there", os.NewFile(0, "./i-dont-exist"))
assert.Error(t, err)
// error if it isn't a file
err = r.SetFileParam("directory", os.NewFile(0, "../client"))
assert.Error(t, err)
// success adds it to the map
err = r.SetFileParam("file", mustGetFile("./runtime.go"))
if assert.NoError(t, err) {
fl, ok := r.fileFields["file"]
if assert.True(t, ok) {
assert.Equal(t, "runtime.go", filepath.Base(fl.Name()))
}
}
}
func mustGetFile(path string) *os.File {
f, err := os.Open(path)
if err != nil {
panic(err)
}
return f
}
func TestBuildRequest_SetBody(t *testing.T) {
r, _ := newRequest("GET", "/flats/{id}/?hello=world", nil)
bd := []struct{ Name, Hobby string }{{"Tom", "Organ trail"}, {"John", "Bird watching"}}
r.SetBodyParam(bd)
assert.Equal(t, bd, r.payload)
}
func TestBuildRequest_BuildHTTP_Payload(t *testing.T) {
bd := []struct{ Name, Hobby string }{{"Tom", "Organ trail"}, {"John", "Bird watching"}}
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
req.SetBodyParam(bd)
req.SetQueryParam("hello", "world")
req.SetPathParam("id", "1234")
req.SetHeaderParam("X-Rate-Limit", "200")
return nil
})
r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
r.SetHeaderParam(runtime.HeaderContentType, runtime.JSONMime)
req, err := r.BuildHTTP(runtime.JSONMime, testProducers, nil)
if assert.NoError(t, err) && assert.NotNil(t, req) {
assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
assert.Equal(t, "world", req.URL.Query().Get("hello"))
assert.Equal(t, "/flats/1234/", req.URL.Path)
expectedBody, _ := json.Marshal(bd)
actualBody, _ := ioutil.ReadAll(req.Body)
assert.Equal(t, append(expectedBody, '\n'), actualBody)
}
}
func TestBuildRequest_BuildHTTP_XMLPayload(t *testing.T) {
bd := []struct {
XMLName xml.Name `xml:"person"`
Name string `xml:"name"`
Hobby string `xml:"hobby"`
}{{xml.Name{}, "Tom", "Organ trail"}, {xml.Name{}, "John", "Bird watching"}}
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
req.SetBodyParam(bd)
req.SetQueryParam("hello", "world")
req.SetPathParam("id", "1234")
req.SetHeaderParam("X-Rate-Limit", "200")
return nil
})
r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
r.SetHeaderParam(runtime.HeaderContentType, runtime.XMLMime)
req, err := r.BuildHTTP(runtime.XMLMime, testProducers, nil)
if assert.NoError(t, err) && assert.NotNil(t, req) {
assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
assert.Equal(t, "world", req.URL.Query().Get("hello"))
assert.Equal(t, "/flats/1234/", req.URL.Path)
expectedBody, _ := xml.Marshal(bd)
actualBody, _ := ioutil.ReadAll(req.Body)
assert.Equal(t, expectedBody, actualBody)
}
}
func TestBuildRequest_BuildHTTP_TextPayload(t *testing.T) {
bd := "Tom: Organ trail; John: Bird watching"
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
req.SetBodyParam(bd)
req.SetQueryParam("hello", "world")
req.SetPathParam("id", "1234")
req.SetHeaderParam("X-Rate-Limit", "200")
return nil
})
r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
r.SetHeaderParam(runtime.HeaderContentType, runtime.TextMime)
req, err := r.BuildHTTP(runtime.TextMime, testProducers, nil)
if assert.NoError(t, err) && assert.NotNil(t, req) {
assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
assert.Equal(t, "world", req.URL.Query().Get("hello"))
assert.Equal(t, "/flats/1234/", req.URL.Path)
expectedBody := []byte(bd)
actualBody, _ := ioutil.ReadAll(req.Body)
assert.Equal(t, expectedBody, actualBody)
}
}
func TestBuildRequest_BuildHTTP_Form(t *testing.T) {
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
req.SetFormParam("something", "some value")
req.SetQueryParam("hello", "world")
req.SetPathParam("id", "1234")
req.SetHeaderParam("X-Rate-Limit", "200")
return nil
})
r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
r.SetHeaderParam(runtime.HeaderContentType, runtime.JSONMime)
req, err := r.BuildHTTP(runtime.JSONMime, testProducers, nil)
if assert.NoError(t, err) && assert.NotNil(t, req) {
assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
assert.Equal(t, "world", req.URL.Query().Get("hello"))
assert.Equal(t, "/flats/1234/", req.URL.Path)
expected := []byte("something=some+value")
actual, _ := ioutil.ReadAll(req.Body)
assert.Equal(t, expected, actual)
}
}
func TestBuildRequest_BuildHTTP_Files(t *testing.T) {
cont, _ := ioutil.ReadFile("./runtime.go")
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
req.SetFormParam("something", "some value")
req.SetFileParam("file", mustGetFile("./runtime.go"))
req.SetQueryParam("hello", "world")
req.SetPathParam("id", "1234")
req.SetHeaderParam("X-Rate-Limit", "200")
return nil
})
r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
r.SetHeaderParam(runtime.HeaderContentType, runtime.JSONMime)
req, err := r.BuildHTTP(runtime.JSONMime, testProducers, nil)
if assert.NoError(t, err) && assert.NotNil(t, req) {
assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
assert.Equal(t, "world", req.URL.Query().Get("hello"))
assert.Equal(t, "/flats/1234/", req.URL.Path)
mediaType, params, err := mime.ParseMediaType(req.Header.Get(runtime.HeaderContentType))
if assert.NoError(t, err) {
assert.Equal(t, runtime.MultipartFormMime, mediaType)
boundary := params["boundary"]
mr := multipart.NewReader(req.Body, boundary)
defer req.Body.Close()
frm, err := mr.ReadForm(1 << 20)
if assert.NoError(t, err) {
assert.Equal(t, "some value", frm.Value["something"][0])
mpff := frm.File["file"][0]
mpf, _ := mpff.Open()
defer mpf.Close()
assert.Equal(t, "runtime.go", mpff.Filename)
actual, _ := ioutil.ReadAll(mpf)
assert.Equal(t, cont, actual)
}
}
}
}

View File

@@ -0,0 +1,44 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"io"
"net/http"
"github.com/go-openapi/runtime"
)
var _ runtime.ClientResponse = response{}
type response struct {
resp *http.Response
}
func (r response) Code() int {
return r.resp.StatusCode
}
func (r response) Message() string {
return r.resp.Status
}
func (r response) GetHeader(name string) string {
return r.resp.Header.Get(name)
}
func (r response) Body() io.ReadCloser {
return r.resp.Body
}

View File

@@ -0,0 +1,40 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"bytes"
"io/ioutil"
"net/http"
"testing"
"github.com/go-openapi/runtime"
"github.com/stretchr/testify/assert"
)
func TestResponse(t *testing.T) {
under := new(http.Response)
under.Status = "the status message"
under.StatusCode = 392
under.Header = make(http.Header)
under.Header.Set("Blah", "blah blah")
under.Body = ioutil.NopCloser(bytes.NewBufferString("some content"))
var resp runtime.ClientResponse = response{under}
assert.EqualValues(t, under.StatusCode, resp.Code())
assert.Equal(t, under.Status, resp.Message())
assert.Equal(t, "blah blah", resp.GetHeader("blah"))
assert.Equal(t, under.Body, resp.Body())
}

323
vendor/github.com/go-openapi/runtime/client/runtime.go generated vendored Normal file
View File

@@ -0,0 +1,323 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"mime"
"net/http"
"net/http/httputil"
"os"
"path"
"strings"
"sync"
"time"
"golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// TLSClientOptions to configure client authentication with mutual TLS
type TLSClientOptions struct {
Certificate string
Key string
CA string
ServerName string
InsecureSkipVerify bool
_ struct{}
}
// TLSClientAuth creates a tls.Config for mutual auth
func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
// load client cert
cert, err := tls.LoadX509KeyPair(opts.Certificate, opts.Key)
if err != nil {
return nil, fmt.Errorf("tls client cert: %v", err)
}
// create client tls config
cfg := &tls.Config{}
cfg.Certificates = []tls.Certificate{cert}
cfg.InsecureSkipVerify = opts.InsecureSkipVerify
// When no CA certificate is provided, default to the system cert pool
// that way when a request is made to a server known by the system trust store,
// the name is still verified
if opts.CA != "" {
// load ca cert
caCert, err := ioutil.ReadFile(opts.CA)
if err != nil {
return nil, fmt.Errorf("tls client ca: %v", err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
cfg.RootCAs = caCertPool
}
// apply servername overrride
if opts.ServerName != "" {
cfg.InsecureSkipVerify = false
cfg.ServerName = opts.ServerName
}
cfg.BuildNameToCertificate()
return cfg, nil
}
// TLSTransport creates a http client transport suitable for mutual tls auth
func TLSTransport(opts TLSClientOptions) (http.RoundTripper, error) {
cfg, err := TLSClientAuth(opts)
if err != nil {
return nil, err
}
return &http.Transport{TLSClientConfig: cfg}, nil
}
// TLSClient creates a http.Client for mutual auth
func TLSClient(opts TLSClientOptions) (*http.Client, error) {
transport, err := TLSTransport(opts)
if err != nil {
return nil, err
}
return &http.Client{Transport: transport}, nil
}
// DefaultTimeout the default request timeout
var DefaultTimeout = 30 * time.Second
// Runtime represents an API client that uses the transport
// to make http requests based on a swagger specification.
type Runtime struct {
DefaultMediaType string
DefaultAuthentication runtime.ClientAuthInfoWriter
Consumers map[string]runtime.Consumer
Producers map[string]runtime.Producer
Transport http.RoundTripper
Jar http.CookieJar
//Spec *spec.Document
Host string
BasePath string
Formats strfmt.Registry
Debug bool
Context context.Context
clientOnce *sync.Once
client *http.Client
schemes []string
do func(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error)
}
// New creates a new default runtime for a swagger api runtime.Client
func New(host, basePath string, schemes []string) *Runtime {
var rt Runtime
rt.DefaultMediaType = runtime.JSONMime
// TODO: actually infer this stuff from the spec
rt.Consumers = map[string]runtime.Consumer{
runtime.JSONMime: runtime.JSONConsumer(),
runtime.XMLMime: runtime.XMLConsumer(),
runtime.TextMime: runtime.TextConsumer(),
runtime.DefaultMime: runtime.ByteStreamConsumer(),
}
rt.Producers = map[string]runtime.Producer{
runtime.JSONMime: runtime.JSONProducer(),
runtime.XMLMime: runtime.XMLProducer(),
runtime.TextMime: runtime.TextProducer(),
runtime.DefaultMime: runtime.ByteStreamProducer(),
}
rt.Transport = http.DefaultTransport
rt.Jar = nil
rt.Host = host
rt.BasePath = basePath
rt.Context = context.Background()
rt.clientOnce = new(sync.Once)
if !strings.HasPrefix(rt.BasePath, "/") {
rt.BasePath = "/" + rt.BasePath
}
rt.Debug = len(os.Getenv("DEBUG")) > 0
if len(schemes) > 0 {
rt.schemes = schemes
}
rt.do = ctxhttp.Do
return &rt
}
// NewWithClient allows you to create a new transport with a configured http.Client
func NewWithClient(host, basePath string, schemes []string, client *http.Client) *Runtime {
rt := New(host, basePath, schemes)
if client != nil {
rt.clientOnce.Do(func() {
rt.client = client
})
}
return rt
}
func (r *Runtime) pickScheme(schemes []string) string {
if v := r.selectScheme(r.schemes); v != "" {
return v
}
if v := r.selectScheme(schemes); v != "" {
return v
}
return "http"
}
func (r *Runtime) selectScheme(schemes []string) string {
schLen := len(schemes)
if schLen == 0 {
return ""
}
scheme := schemes[0]
// prefer https, but skip when not possible
if scheme != "https" && schLen > 1 {
for _, sch := range schemes {
if sch == "https" {
scheme = sch
break
}
}
}
return scheme
}
// Submit a request and when there is a body on success it will turn that into the result
// all other things are turned into an api error for swagger which retains the status code
func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
params, readResponse, auth := operation.Params, operation.Reader, operation.AuthInfo
request, err := newRequest(operation.Method, operation.PathPattern, params)
if err != nil {
return nil, err
}
var accept []string
for _, mimeType := range operation.ProducesMediaTypes {
accept = append(accept, mimeType)
}
request.SetHeaderParam(runtime.HeaderAccept, accept...)
if auth == nil && r.DefaultAuthentication != nil {
auth = r.DefaultAuthentication
}
if auth != nil {
if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
return nil, err
}
}
// TODO: pick appropriate media type
cmt := r.DefaultMediaType
if len(operation.ConsumesMediaTypes) > 0 {
cmt = operation.ConsumesMediaTypes[0]
}
req, err := request.BuildHTTP(cmt, r.Producers, r.Formats)
if err != nil {
return nil, err
}
req.URL.Scheme = r.pickScheme(operation.Schemes)
req.URL.Host = r.Host
var reinstateSlash bool
if req.URL.Path != "" && req.URL.Path != "/" && req.URL.Path[len(req.URL.Path)-1] == '/' {
reinstateSlash = true
}
req.URL.Path = path.Join(r.BasePath, req.URL.Path)
if reinstateSlash {
req.URL.Path = req.URL.Path + "/"
}
r.clientOnce.Do(func() {
r.client = &http.Client{
Transport: r.Transport,
Jar: r.Jar,
}
})
if r.Debug {
b, err2 := httputil.DumpRequestOut(req, true)
if err2 != nil {
return nil, err2
}
fmt.Fprintln(os.Stderr, string(b))
}
var hasTimeout bool
pctx := operation.Context
if pctx == nil {
pctx = r.Context
} else {
hasTimeout = true
}
if pctx == nil {
pctx = context.Background()
}
var ctx context.Context
var cancel context.CancelFunc
if hasTimeout {
ctx, cancel = context.WithCancel(pctx)
} else {
ctx, cancel = context.WithTimeout(pctx, request.timeout)
}
defer cancel()
client := operation.Client
if client == nil {
client = r.client
}
if r.do == nil {
r.do = ctxhttp.Do
}
res, err := r.do(ctx, client, req) // make requests, by default follows 10 redirects before failing
if err != nil {
return nil, err
}
defer res.Body.Close()
if r.Debug {
b, err2 := httputil.DumpResponse(res, true)
if err2 != nil {
return nil, err2
}
fmt.Fprintln(os.Stderr, string(b))
}
ct := res.Header.Get(runtime.HeaderContentType)
if ct == "" { // this should really really never occur
ct = r.DefaultMediaType
}
mt, _, err := mime.ParseMediaType(ct)
if err != nil {
return nil, fmt.Errorf("parse content type: %s", err)
}
cons, ok := r.Consumers[mt]
if !ok {
// scream about not knowing what to do
return nil, fmt.Errorf("no consumer: %q", ct)
}
return readResponse.ReadResponse(response{res}, cons)
}

View File

@@ -0,0 +1,722 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"bytes"
"encoding/json"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/http/httptest"
"net/url"
"os"
"testing"
"time"
"golang.org/x/net/context"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"github.com/stretchr/testify/assert"
)
// task This describes a task. Tasks require a content property to be set.
type task struct {
// Completed
Completed bool `json:"completed" xml:"completed"`
// Content Task content can contain [GFM](https://help.github.com/articles/github-flavored-markdown/).
Content string `json:"content" xml:"content"`
// ID This id property is autogenerated when a task is created.
ID int64 `json:"id" xml:"id"`
}
func TestRuntime_TLSAuthConfig(t *testing.T) {
var opts TLSClientOptions
opts.CA = "../fixtures/certs/myCA.crt"
opts.Key = "../fixtures/certs/myclient.key"
opts.Certificate = "../fixtures/certs/myclient.crt"
opts.ServerName = "somewhere"
cfg, err := TLSClientAuth(opts)
if assert.NoError(t, err) {
if assert.NotNil(t, cfg) {
assert.Len(t, cfg.Certificates, 1)
assert.NotNil(t, cfg.RootCAs)
assert.Equal(t, "somewhere", cfg.ServerName)
}
}
}
func TestRuntime_Concurrent(t *testing.T) {
// test that it can make a simple request
// and get the response for it.
// defaults all the way down
result := []task{
{false, "task 1 content", 1},
{false, "task 2 content", 2},
}
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime)
rw.WriteHeader(http.StatusOK)
jsongen := json.NewEncoder(rw)
jsongen.Encode(result)
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
resCC := make(chan interface{})
errCC := make(chan error)
var res interface{}
var err error
for j := 0; j < 6; j++ {
go func() {
resC := make(chan interface{})
errC := make(chan error)
go func() {
var resp interface{}
var errp error
for i := 0; i < 3; i++ {
resp, errp = rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/",
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result []task
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
})
<-time.After(100 * time.Millisecond)
}
resC <- resp
errC <- errp
}()
resCC <- <-resC
errCC <- <-errC
}()
}
c := 6
for c > 0 {
res = <-resCC
err = <-errCC
c--
}
if assert.NoError(t, err) {
assert.IsType(t, []task{}, res)
actual := res.([]task)
assert.EqualValues(t, result, actual)
}
}
func TestRuntime_Canary(t *testing.T) {
// test that it can make a simple request
// and get the response for it.
// defaults all the way down
result := []task{
{false, "task 1 content", 1},
{false, "task 2 content", 2},
}
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime)
rw.WriteHeader(http.StatusOK)
jsongen := json.NewEncoder(rw)
jsongen.Encode(result)
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
res, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/",
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result []task
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
})
if assert.NoError(t, err) {
assert.IsType(t, []task{}, res)
actual := res.([]task)
assert.EqualValues(t, result, actual)
}
}
type tasks struct {
Tasks []task `xml:"task"`
}
func TestRuntime_XMLCanary(t *testing.T) {
// test that it can make a simple XML request
// and get the response for it.
result := tasks{
Tasks: []task{
{false, "task 1 content", 1},
{false, "task 2 content", 2},
},
}
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add(runtime.HeaderContentType, runtime.XMLMime)
rw.WriteHeader(http.StatusOK)
xmlgen := xml.NewEncoder(rw)
xmlgen.Encode(result)
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
res, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/",
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result tasks
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
})
if assert.NoError(t, err) {
assert.IsType(t, tasks{}, res)
actual := res.(tasks)
assert.EqualValues(t, result, actual)
}
}
func TestRuntime_TextCanary(t *testing.T) {
// test that it can make a simple text request
// and get the response for it.
result := "1: task 1 content; 2: task 2 content"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add(runtime.HeaderContentType, runtime.TextMime)
rw.WriteHeader(http.StatusOK)
rw.Write([]byte(result))
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
res, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/",
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result string
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
})
if assert.NoError(t, err) {
assert.IsType(t, "", res)
actual := res.(string)
assert.EqualValues(t, result, actual)
}
}
type roundTripperFunc func(*http.Request) (*http.Response, error)
func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return fn(req)
}
func TestRuntime_CustomTransport(t *testing.T) {
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
result := []task{
{false, "task 1 content", 1},
{false, "task 2 content", 2},
}
rt := New("localhost:3245", "/", []string{"ws", "wss", "https"})
rt.Transport = roundTripperFunc(func(req *http.Request) (*http.Response, error) {
if req.URL.Scheme != "https" {
return nil, errors.New("this was not a https request")
}
var resp http.Response
resp.StatusCode = 200
resp.Header = make(http.Header)
resp.Header.Set("content-type", "application/json")
buf := bytes.NewBuffer(nil)
enc := json.NewEncoder(buf)
enc.Encode(result)
resp.Body = ioutil.NopCloser(buf)
return &resp, nil
})
res, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/",
Schemes: []string{"ws", "wss", "https"},
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result []task
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
})
if assert.NoError(t, err) {
assert.IsType(t, []task{}, res)
actual := res.([]task)
assert.EqualValues(t, result, actual)
}
}
func TestRuntime_CustomCookieJar(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
authenticated := false
for _, cookie := range req.Cookies() {
if cookie.Name == "sessionid" && cookie.Value == "abc" {
authenticated = true
}
}
if !authenticated {
username, password, ok := req.BasicAuth()
if ok && username == "username" && password == "password" {
authenticated = true
http.SetCookie(rw, &http.Cookie{Name: "sessionid", Value: "abc"})
}
}
if authenticated {
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime)
rw.WriteHeader(http.StatusOK)
jsongen := json.NewEncoder(rw)
jsongen.Encode([]task{})
} else {
rw.WriteHeader(http.StatusUnauthorized)
}
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
rt.Jar, _ = cookiejar.New(nil)
submit := func(authInfo runtime.ClientAuthInfoWriter) {
_, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/",
Params: rwrtr,
AuthInfo: authInfo,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
return nil, nil
}
return nil, errors.New("Generic error")
}),
})
assert.NoError(t, err)
}
submit(BasicAuth("username", "password"))
submit(nil)
}
func TestRuntime_AuthCanary(t *testing.T) {
// test that it can make a simple request
// and get the response for it.
// defaults all the way down
result := []task{
{false, "task 1 content", 1},
{false, "task 2 content", 2},
}
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.Header.Get("Authorization") != "Bearer the-super-secret-token" {
rw.WriteHeader(400)
return
}
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime)
rw.WriteHeader(http.StatusOK)
jsongen := json.NewEncoder(rw)
jsongen.Encode(result)
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
res, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result []task
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
AuthInfo: BearerToken("the-super-secret-token"),
})
if assert.NoError(t, err) {
assert.IsType(t, []task{}, res)
actual := res.([]task)
assert.EqualValues(t, result, actual)
}
}
func TestRuntime_PickConsumer(t *testing.T) {
result := []task{
{false, "task 1 content", 1},
{false, "task 2 content", 2},
}
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.Header.Get("Content-Type") != "application/octet-stream" {
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
rw.WriteHeader(400)
return
}
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
rw.WriteHeader(http.StatusOK)
jsongen := json.NewEncoder(rw)
jsongen.Encode(result)
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
req.SetBodyParam(bytes.NewBufferString("hello"))
return nil
})
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
res, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "POST",
PathPattern: "/",
Schemes: []string{"http"},
ConsumesMediaTypes: []string{"application/octet-stream"},
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result []task
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
AuthInfo: BearerToken("the-super-secret-token"),
})
if assert.NoError(t, err) {
assert.IsType(t, []task{}, res)
actual := res.([]task)
assert.EqualValues(t, result, actual)
}
}
func TestRuntime_ContentTypeCanary(t *testing.T) {
// test that it can make a simple request
// and get the response for it.
// defaults all the way down
result := []task{
{false, "task 1 content", 1},
{false, "task 2 content", 2},
}
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.Header.Get("Authorization") != "Bearer the-super-secret-token" {
rw.WriteHeader(400)
return
}
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
rw.WriteHeader(http.StatusOK)
jsongen := json.NewEncoder(rw)
jsongen.Encode(result)
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
rt.do = nil
res, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/",
Schemes: []string{"http"},
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result []task
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
AuthInfo: BearerToken("the-super-secret-token"),
})
if assert.NoError(t, err) {
assert.IsType(t, []task{}, res)
actual := res.([]task)
assert.EqualValues(t, result, actual)
}
}
func TestRuntime_ChunkedResponse(t *testing.T) {
// test that it can make a simple request
// and get the response for it.
// defaults all the way down
result := []task{
{false, "task 1 content", 1},
{false, "task 2 content", 2},
}
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.Header.Get("Authorization") != "Bearer the-super-secret-token" {
rw.WriteHeader(400)
return
}
rw.Header().Add(runtime.HeaderTransferEncoding, "chunked")
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
rw.WriteHeader(http.StatusOK)
jsongen := json.NewEncoder(rw)
jsongen.Encode(result)
}))
defer server.Close()
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
//specDoc, err := spec.Load("../../fixtures/codegen/todolist.simple.yml")
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
res, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/",
Schemes: []string{"http"},
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if response.Code() == 200 {
var result []task
if err := consumer.Consume(response.Body(), &result); err != nil {
return nil, err
}
return result, nil
}
return nil, errors.New("Generic error")
}),
AuthInfo: BearerToken("the-super-secret-token"),
})
if assert.NoError(t, err) {
assert.IsType(t, []task{}, res)
actual := res.([]task)
assert.EqualValues(t, result, actual)
}
}
func TestRuntime_DebugValue(t *testing.T) {
original := os.Getenv("DEBUG")
// Emtpy DEBUG means Debug is False
os.Setenv("DEBUG", "")
runtime := New("", "/", []string{"https"})
assert.False(t, runtime.Debug)
// Non-Empty Debug means Debug is True
os.Setenv("DEBUG", "1")
runtime = New("", "/", []string{"https"})
assert.True(t, runtime.Debug)
os.Setenv("DEBUG", "true")
runtime = New("", "/", []string{"https"})
assert.True(t, runtime.Debug)
os.Setenv("DEBUG", "foo")
runtime = New("", "/", []string{"https"})
assert.True(t, runtime.Debug)
// Make sure DEBUG is initial value once again
os.Setenv("DEBUG", original)
}
func TestRuntime_OverrideScheme(t *testing.T) {
runtime := New("", "/", []string{"https"})
sch := runtime.pickScheme([]string{"http"})
assert.Equal(t, "https", sch)
}
func TestRuntime_OverrideClient(t *testing.T) {
client := &http.Client{}
runtime := NewWithClient("", "/", []string{"https"}, client)
var i int
runtime.clientOnce.Do(func() { i++ })
assert.Equal(t, client, runtime.client)
assert.Equal(t, 0, i)
}
func TestRuntime_OverrideClientOperation(t *testing.T) {
client := &http.Client{}
rt := NewWithClient("", "/", []string{"https"}, client)
var i int
rt.clientOnce.Do(func() { i++ })
assert.Equal(t, client, rt.client)
assert.Equal(t, 0, i)
var seen *http.Client
rt.do = func(_ context.Context, cl *http.Client, _ *http.Request) (*http.Response, error) {
seen = cl
res := new(http.Response)
res.StatusCode = 200
res.Body = ioutil.NopCloser(bytes.NewBufferString("OK"))
return res, nil
}
client2 := new(http.Client)
client2.Timeout = 3 * time.Second
if assert.NotEqual(t, client, client2) {
_, err := rt.Submit(&runtime.ClientOperation{
Client: client2,
Params: runtime.ClientRequestWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
return nil
}),
Reader: runtime.ClientResponseReaderFunc(func(_ runtime.ClientResponse, _ runtime.Consumer) (interface{}, error) {
return nil, nil
}),
})
if assert.NoError(t, err) {
assert.Equal(t, client2, seen)
}
}
}
func TestRuntime_PreserveTrailingSlash(t *testing.T) {
var redirected bool
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
if req.URL.Path == "/api/tasks" {
redirected = true
return
}
if req.URL.Path == "/api/tasks/" {
rw.WriteHeader(http.StatusOK)
}
}))
defer server.Close()
hu, _ := url.Parse(server.URL)
rt := New(hu.Host, "/", []string{"http"})
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
return nil
})
_, err := rt.Submit(&runtime.ClientOperation{
ID: "getTasks",
Method: "GET",
PathPattern: "/api/tasks/",
Params: rwrtr,
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if redirected {
return nil, errors.New("expected Submit to preserve trailing slashes - this caused a redirect")
}
if response.Code() == http.StatusOK {
return nil, nil
}
return nil, errors.New("Generic error")
}),
})
assert.NoError(t, err)
}