refactor(10.2-01): nest framework packages under modules
- Move remaining beach packages and embedded admin assets\n- Rewrite framework, example, build, and gate paths
This commit is contained in:
104
modules/tide/replay.go
Normal file
104
modules/tide/replay.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package tide
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ReplayFlow executes each recorded step against target and diffs responses.
|
||||
func ReplayFlow(ctx context.Context, flow Flow, cfg ReplayConfig) (Result, error) {
|
||||
if err := validateFlow(flow); err != nil {
|
||||
return Result{}, err
|
||||
}
|
||||
if strings.TrimSpace(cfg.Target) == "" {
|
||||
return Result{}, fmt.Errorf("tide: replay target is required")
|
||||
}
|
||||
client := cfg.Client
|
||||
if client == nil {
|
||||
client = defaultClient()
|
||||
}
|
||||
limit := maxBody(cfg.MaxBody)
|
||||
store := cfg.Store
|
||||
if store == nil {
|
||||
store = mustMemoryStore()
|
||||
}
|
||||
result := Result{OK: true, Steps: make([]StepResult, 0, len(flow.Steps))}
|
||||
skipRest := false
|
||||
for _, step := range flow.Steps {
|
||||
if skipRest {
|
||||
result.Steps = append(result.Steps, StepResult{ID: step.ID, Skipped: true})
|
||||
continue
|
||||
}
|
||||
sr := StepResult{ID: step.ID, OK: true}
|
||||
want := step
|
||||
if err := materializeSidecar(cfg.BaseDir, &want.Response); err != nil {
|
||||
return result, fmt.Errorf("tide: replay step %s: %w", step.ID, err)
|
||||
}
|
||||
req, err := expandRequest(step.Request, store)
|
||||
if err != nil {
|
||||
sr.OK = false
|
||||
result.OK = false
|
||||
sr.Diffs = append(sr.Diffs, Diff{Path: "request", Expected: "resolved placeholders", Actual: err.Error()})
|
||||
result.Steps = append(result.Steps, sr)
|
||||
skipRest = true
|
||||
continue
|
||||
}
|
||||
got, err := doStep(ctx, client, cfg.Target, req, limit)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("tide: replay step %s: %w", step.ID, err)
|
||||
}
|
||||
live := step
|
||||
live.Request = req
|
||||
live.Response = got
|
||||
if err := CaptureStep(store, &live); err != nil {
|
||||
sr.OK = false
|
||||
result.OK = false
|
||||
sr.Diffs = append(sr.Diffs, Diff{Path: "capture", Expected: "captured value", Actual: err.Error()})
|
||||
result.Steps = append(result.Steps, sr)
|
||||
skipRest = true
|
||||
continue
|
||||
}
|
||||
if err := store.Save(); err != nil {
|
||||
return result, fmt.Errorf("tide: replay step %s: %w", step.ID, err)
|
||||
}
|
||||
want.Response, err = expandResponse(want.Response, store)
|
||||
if err != nil {
|
||||
sr.OK = false
|
||||
result.OK = false
|
||||
sr.Diffs = append(sr.Diffs, Diff{Path: "expected", Expected: "resolved placeholders", Actual: err.Error()})
|
||||
result.Steps = append(result.Steps, sr)
|
||||
skipRest = true
|
||||
continue
|
||||
}
|
||||
sr.Diffs = append(sr.Diffs, compareStep(want, live.Response)...)
|
||||
if len(sr.Diffs) > 0 {
|
||||
sr.OK = false
|
||||
result.OK = false
|
||||
}
|
||||
result.Steps = append(result.Steps, sr)
|
||||
}
|
||||
if !result.OK {
|
||||
return result, &MismatchError{Result: result}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func mustMemoryStore() *Store {
|
||||
s, _ := OpenStore("")
|
||||
return s
|
||||
}
|
||||
|
||||
func compareStep(want Step, got Response) []Diff {
|
||||
var diffs []Diff
|
||||
if want.Response.Status != 0 && got.Status != want.Response.Status {
|
||||
diffs = append(diffs, Diff{
|
||||
Path: "status",
|
||||
Expected: fmt.Sprintf("%d", want.Response.Status),
|
||||
Actual: fmt.Sprintf("%d", got.Status),
|
||||
})
|
||||
}
|
||||
diffs = append(diffs, compareHeaders(want.Response.Headers, got.Headers, want.Headers)...)
|
||||
diffs = append(diffs, compareBodies(want.Response, got, want)...)
|
||||
return diffs
|
||||
}
|
||||
Reference in New Issue
Block a user