grim/resticide

clean up reporters... again...
develop
2015-11-09, Gary Kramlich
74baea137254
clean up reporters... again...
package main
import (
"bytes"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/xeipuuv/gojsonschema"
)
type TestResult struct {
Test *Test
Passed bool
HttpResponse http.Response
TestResponse TestResponse
}
type TestResponse struct {
StatusCode int `json:"statuscode"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
JSONSchema map[string]interface{} `json:"json-schema"`
}
type TestRequest struct {
Path string `json:"path"`
Query map[string]string `json:"query"`
Headers map[string]string `json:"headers"`
Method string `json:"method"`
Body string `json:"body"`
Response TestResponse `json:"response"`
}
type Test struct {
Filename string
Name string
Requests []TestRequest
Start time.Time
End time.Time
Duration time.Duration
}
func (req *TestRequest)buildRequest(host string) (*http.Request, error) {
url, err := url.Parse(host)
if err != nil {
return nil, err
}
url.Path = req.Path
// build the query string
query := url.Query()
for qname, qvalue := range req.Query {
query.Set(qname, qvalue)
}
url.RawQuery = query.Encode()
body := bytes.NewBufferString(req.Body)
hreq, err := http.NewRequest(req.Method, url.String(), body)
if err != nil {
return nil, err
}
for name, value := range req.Headers {
hreq.Header.Add(name, value)
}
return hreq, nil
}
func (req *TestRequest)compareResponse(res *TestResult, hresp *http.Response) {
res.HttpResponse = *hresp
// first check the resp code
if hresp.StatusCode != req.Response.StatusCode {
return
}
// check the headers
for name, value := range req.Response.Headers {
actual := hresp.Header[http.CanonicalHeaderKey(name)]
if actual != nil {
if actual[0] != value {
return
}
}
}
body_byte, err := ioutil.ReadAll(hresp.Body)
if err != nil {
return
}
body := string(body_byte[:])
// check if we have a json schema to validate
if len(req.Response.JSONSchema) != 0 {
schema_loader := gojsonschema.NewGoLoader(req.Response.JSONSchema)
body_loader := gojsonschema.NewStringLoader(body)
schema_result, err := gojsonschema.Validate(schema_loader, body_loader)
if err != nil {
return
}
if schema_result.Valid() != true {
return
}
}
// if we made it this far, we passed, yay!
res.Passed = true
res.TestResponse = req.Response
}
func (test *Test) Run(host string) *TestResult {
res := new(TestResult)
res.Test = test
res.Passed = false
for _, request := range test.Requests {
http_request, err := request.buildRequest(host)
if err != nil {
return res
}
client := &http.Client{}
resp, err := client.Do(http_request)
if err != nil {
return res
}
defer resp.Body.Close()
request.compareResponse(res, resp)
}
return res
}