grim/resticide

940c4cf5c4fb
Lots of other goodies trying to get schema validation going
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"time"
"github.com/xeipuuv/gojsonschema"
)
type TestResult struct {
Passed bool
HttpResponse http.Response
TestResponse TestResponse
}
type TestResponse struct {
StatusCode int
Headers map[string]string
Body string
}
type TestRequest struct {
Path string
Method string
Headers map[string]string
Body string
Response TestResponse
}
type TestData struct {
Name string
Request TestRequest
Requests []TestRequest
}
type Test struct {
Filename string
Name string
Requests []TestRequest
Start time.Time
End time.Time
Duration time.Duration
}
func load_schema() (*gojsonschema.Schema, error) {
schema_bytes, err := Asset("assets/schema.json")
if err != nil {
return nil, err
}
schema_string := string(schema_bytes[:])
schema_loader = gojsonschema.NewStringLoader(schema_string)
schema = gojsonschema.NewSchema(schema_loader)
return schema, nil
}
func find_tests(path string) ([]Test, error) {
schema, err := load_schema()
if err != nil {
return nil, err
}
tests := []Test{}
err = filepath.Walk(path, func(path string, _ os.FileInfo, _ error) error {
stat, err := os.Stat(path)
if os.IsNotExist(err) {
return nil
}
if !stat.Mode().IsRegular() {
return nil
}
ext := filepath.Ext(path)
if ext != ".json" {
return nil
}
fp, err := ioutil.ReadFile(path)
if err != nil {
return nil
}
var test Test
err = json.Unmarshal(fp, &test)
if err != nil {
return nil
}
tests = append(tests, test)
return nil
})
return tests, err
}
func (req *TestRequest)buildRequest() (*http.Request, error) {
body := bytes.NewBufferString(req.Body)
hreq, err := http.NewRequest(req.Method, req.Path, 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(hresp *http.Response) TestResult {
var res TestResult
res.Passed = false
res.HttpResponse = *hresp
// first check the resp code
if hresp.StatusCode != req.Response.StatusCode {
return res
}
// check the headers
for name, value := range req.Response.Headers {
actual := hresp.Header[http.CanonicalHeaderKey(name)]
if actual != nil {
if actual[0] != value {
return res
}
}
}
// if we made it this far, we passed, yay!
res.Passed = true
res.TestResponse = req.Response
return res
}
func (test *Test) Run() TestResult {
request, _ := test.Requests[0].buildRequest()
client := &http.Client{}
resp, _ := client.Do(request)
defer resp.Body.Close()
return test.Requests[0].compareResponse(resp)
}
func run_tests(tests []Test, reporters []Reporter) error {
n_tests := len(tests)
passed := 0
failed := 0
for _, reporter := range reporters {
reporter.Start(n_tests)
}
for _, test := range tests {
for _, reporter := range reporters {
reporter.TestStart(test)
}
test.Start = time.Now()
res := test.Run()
test.End = time.Now()
test.Duration = test.End.Sub(test.Start)
if res.Passed {
passed++
} else {
failed++
}
for _, reporter := range reporters {
reporter.TestFinish(test, res)
}
}
for _, reporter := range reporters {
reporter.Finish(n_tests, passed, failed)
}
return nil
}