Skip to content

Commit

Permalink
work on "hof test": add api tests, refactor some, improve print
Browse files Browse the repository at this point in the history
  • Loading branch information
verdverm committed Oct 16, 2020
1 parent bfee91f commit 6d00945
Show file tree
Hide file tree
Showing 9 changed files with 391 additions and 95 deletions.
175 changes: 175 additions & 0 deletions lib/test/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package test

import (
"fmt"
"strings"

"cuelang.org/go/cue"
"github.com/parnurzeal/gorequest"

"github.com/hofstadter-io/hof/lib/cuetils"
)

const HTTP2_GOAWAY_CHECK = "http2: server sent GOAWAY and closed the connection"

func RunAPI(T *Tester, verbose int) (err error) {
fmt.Println("api:", T.Name)

// make sure we resolve references and unifications
val := T.Value.Eval()

vSyn, vErr := cuetils.ValueToSyntaxString(val)
if vErr != nil {
fmt.Println(vSyn)
return vErr
}
if verbose > 0 {
fmt.Println(vSyn)
}

return runCase(T, verbose, val)
}

func runCase(T *Tester, verbose int, val cue.Value) (err error) {

req := val.Lookup("req")
expected := val.Lookup("resp")

R, err := buildRequest(T, verbose, req)
if err != nil {
return err
}

actual, err := makeRequest(T, verbose, R)
if err != nil {
return err
}

err = checkResponse(T, verbose, actual, expected)

return err
}


func buildRequest(T *Tester, verbose int, val cue.Value) (R *gorequest.SuperAgent, err error) {
req := val.Eval()
R = gorequest.New()

method := req.Lookup("method")
R.Method, err = method.String()
if err != nil {
return
}

host := req.Lookup("host")
path := req.Lookup("path")
hostStr, err := host.String()
if err != nil {
return
}
pathStr, err := path.String()
if err != nil {
return
}
R.Url = hostStr + pathStr

headers := req.Lookup("headers")
if headers.Exists() {
H, err := headers.Struct()
if err != nil {
return R, err
}
hIter := H.Fields()
for hIter.Next() {
label := hIter.Label()
value, err := hIter.Value().String()
if err != nil {
return R, err
}
R.Header.Add(label, value)
}
}

query := req.Lookup("query")
if query.Exists() {
Q, err := query.Struct()
if err != nil {
return R, err
}
qIter := Q.Fields()
for qIter.Next() {
label := qIter.Label()
value, err := qIter.Value().String()
if err != nil {
return R, err
}
R.QueryData.Add(label, value)
}
}

data := req.Lookup("data")
if data.Exists() {
err := data.Decode(&R.Data)
if err != nil {
return R, err
}
}

return
}

func makeRequest(T *Tester, verbose int, R *gorequest.SuperAgent) (gorequest.Response, error) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in HTTP: %v %v\n", R, r)
}
}()

resp, body, errs := R.End()

if len(errs) != 0 && resp == nil {
return resp, fmt.Errorf("%v", errs)
}

if len(errs) != 0 && !strings.Contains(errs[0].Error(), HTTP2_GOAWAY_CHECK) {
return resp, fmt.Errorf("Internal Weirdr Error:\b%v\n%s\n", errs, body)
}
if len(errs) != 0 {
return resp, fmt.Errorf("Internal Error:\n%v\n%s\n", errs, body)
}

if verbose > 0 {
fmt.Println(body)
}
fmt.Println(body)

return resp, nil
}

func checkResponse(T *Tester, verbose int, actual gorequest.Response, expect cue.Value) (err error) {
expect = expect.Eval()

S, err := expect.Struct()
if err != nil {
return err
}
iter := S.Fields()
for iter.Next() {
label := iter.Label()
value := iter.Value()

switch label {
case "status":
status, err := value.Int64()
if err != nil {
return err
}
if int64(actual.StatusCode) != status {
return fmt.Errorf("status code mismatch %v != %v", actual.StatusCode, status)
}
}
}


return nil
}
89 changes: 89 additions & 0 deletions lib/test/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package test

import (
"fmt"
"os/exec"
"strings"
)

type BaseTester struct {
Dir string
Env map[string]string
Sysenv bool
}

type BashTester struct {
BaseTester

Script string
}

func RunBash(T *Tester, verbose int) (err error) {
// Decode our BT
var BT BashTester
err = T.Value.Decode(&BT)

// Check for errors and validate
if err != nil {
return err
}
if BT.Script == "" {
return fmt.Errorf("Bash tester %q has empty script field", T.Name)
}

// Prep our command
cmd := exec.Command("bash", "-p", "-c", BT.Script)
cmd.Dir = BT.Dir

// add env vars if needed
if len(BT.Env) > 0 {
for k,v := range BT.Env {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
}
}

// Run and save output
out, err := cmd.CombinedOutput()
T.Output = string(out)

return err
}

type ExecTester struct {
BaseTester

Command string
}

func RunExec(T *Tester, verbose int) (err error) {
// Decode our ET
var ET ExecTester
err = T.Value.Decode(&ET)

// Check for errors and validate
if err != nil {
return err
}
if ET.Command == "" {
return fmt.Errorf("Bash tester %q has empty script field", T.Name)
}

args := strings.Fields(ET.Command)

// Prep our command
cmd := exec.Command(args[0], args[1:]...)
cmd.Dir = ET.Dir

// add env vars if needed
if len(ET.Env) > 0 {
for k,v := range ET.Env {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
}
}

// Run and save output
out, err := cmd.CombinedOutput()
T.Output = string(out)

return err
}
7 changes: 7 additions & 0 deletions lib/test/hls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package test

func RunHLS(T *Tester, verbose int) (err error) {
// fmt.Println("hls:", T.Name)

return nil
}
17 changes: 17 additions & 0 deletions lib/test/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package test

import (
"fmt"
"sort"
"strings"
)

Expand Down Expand Up @@ -43,12 +44,28 @@ func printTests(suites []Suite, stats bool) {
A := t.Value.Attribute("test")
as := []string{}
for k, v := range A.Map() {

// if key is a knownTester, put it first
known := false
for _, kT := range knownTesters {
if k == kT {
as = append([]string{"["+k+"]"}, as...)
known = true
break
}
}
if known {
continue
}

// otherwise just add
if v != "" {
as = append(as, fmt.Sprintf("%s=%s", k, v))
} else {
as = append(as, fmt.Sprintf("%s", k))
}
}
sort.Strings(as[1:])
a := strings.Join(as, " ")
st := ""
if stats {
Expand Down

0 comments on commit 6d00945

Please sign in to comment.