mirror of
https://github.com/aykhans/sarin.git
synced 2026-02-28 06:49:13 +00:00
199 lines
4.8 KiB
Go
199 lines
4.8 KiB
Go
package e2e
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
"go.yaml.in/yaml/v4"
|
|
)
|
|
|
|
// --- JSON output structure verification ---
|
|
|
|
func TestJSONOutputHasStatFields(t *testing.T) {
|
|
t.Parallel()
|
|
cs := newCaptureServer()
|
|
defer cs.Close()
|
|
|
|
res := run("-U", cs.URL, "-r", "3", "-q", "-o", "json")
|
|
assertExitCode(t, res, 0)
|
|
|
|
out := res.jsonOutput(t)
|
|
|
|
// Verify total has all stat fields
|
|
if out.Total.Count.String() != "3" {
|
|
t.Errorf("expected count 3, got %s", out.Total.Count.String())
|
|
}
|
|
if out.Total.Min == "" {
|
|
t.Error("expected min to be non-empty")
|
|
}
|
|
if out.Total.Max == "" {
|
|
t.Error("expected max to be non-empty")
|
|
}
|
|
if out.Total.Average == "" {
|
|
t.Error("expected average to be non-empty")
|
|
}
|
|
if out.Total.P90 == "" {
|
|
t.Error("expected p90 to be non-empty")
|
|
}
|
|
if out.Total.P95 == "" {
|
|
t.Error("expected p95 to be non-empty")
|
|
}
|
|
if out.Total.P99 == "" {
|
|
t.Error("expected p99 to be non-empty")
|
|
}
|
|
}
|
|
|
|
func TestJSONOutputResponseStatFields(t *testing.T) {
|
|
t.Parallel()
|
|
cs := newCaptureServer()
|
|
defer cs.Close()
|
|
|
|
res := run("-U", cs.URL, "-r", "5", "-q", "-o", "json")
|
|
assertExitCode(t, res, 0)
|
|
|
|
out := res.jsonOutput(t)
|
|
stat, ok := out.Responses["200"]
|
|
if !ok {
|
|
t.Fatal("expected 200 in responses")
|
|
}
|
|
|
|
if stat.Count.String() != "5" {
|
|
t.Errorf("expected response count 5, got %s", stat.Count.String())
|
|
}
|
|
if stat.Min == "" || stat.Max == "" || stat.Average == "" {
|
|
t.Error("expected min/max/average to be non-empty")
|
|
}
|
|
}
|
|
|
|
func TestJSONOutputMultipleStatusCodes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Create servers with different status codes
|
|
srv200 := statusServer(200)
|
|
defer srv200.Close()
|
|
srv404 := statusServer(404)
|
|
defer srv404.Close()
|
|
|
|
// We can only target one URL, so use a single server
|
|
// Instead, test that dry-run produces the expected structure
|
|
res := run("-U", "http://example.com", "-r", "3", "-z", "-q", "-o", "json")
|
|
assertExitCode(t, res, 0)
|
|
|
|
out := res.jsonOutput(t)
|
|
// dry-run should have "dry-run" key
|
|
stat := out.Responses["dry-run"]
|
|
if stat.Count.String() != "3" {
|
|
t.Errorf("expected dry-run count 3, got %s", stat.Count.String())
|
|
}
|
|
}
|
|
|
|
func TestJSONOutputIsValidJSON(t *testing.T) {
|
|
t.Parallel()
|
|
cs := newCaptureServer()
|
|
defer cs.Close()
|
|
|
|
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "json")
|
|
assertExitCode(t, res, 0)
|
|
|
|
// Verify it's valid JSON
|
|
var raw map[string]any
|
|
if err := json.Unmarshal([]byte(res.Stdout), &raw); err != nil {
|
|
t.Fatalf("stdout is not valid JSON: %v", err)
|
|
}
|
|
|
|
// Verify top-level structure
|
|
if _, ok := raw["responses"]; !ok {
|
|
t.Error("expected 'responses' key in JSON output")
|
|
}
|
|
if _, ok := raw["total"]; !ok {
|
|
t.Error("expected 'total' key in JSON output")
|
|
}
|
|
}
|
|
|
|
// --- YAML output structure verification ---
|
|
|
|
func TestYAMLOutputIsValidYAML(t *testing.T) {
|
|
t.Parallel()
|
|
cs := newCaptureServer()
|
|
defer cs.Close()
|
|
|
|
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "yaml")
|
|
assertExitCode(t, res, 0)
|
|
|
|
var raw map[string]any
|
|
if err := yaml.Unmarshal([]byte(res.Stdout), &raw); err != nil {
|
|
t.Fatalf("stdout is not valid YAML: %v", err)
|
|
}
|
|
|
|
if _, ok := raw["responses"]; !ok {
|
|
t.Error("expected 'responses' key in YAML output")
|
|
}
|
|
if _, ok := raw["total"]; !ok {
|
|
t.Error("expected 'total' key in YAML output")
|
|
}
|
|
}
|
|
|
|
func TestYAMLOutputHasStatFields(t *testing.T) {
|
|
t.Parallel()
|
|
cs := newCaptureServer()
|
|
defer cs.Close()
|
|
|
|
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "yaml")
|
|
assertExitCode(t, res, 0)
|
|
|
|
assertContains(t, res.Stdout, "count:")
|
|
assertContains(t, res.Stdout, "min:")
|
|
assertContains(t, res.Stdout, "max:")
|
|
assertContains(t, res.Stdout, "average:")
|
|
assertContains(t, res.Stdout, "p90:")
|
|
assertContains(t, res.Stdout, "p95:")
|
|
assertContains(t, res.Stdout, "p99:")
|
|
}
|
|
|
|
// --- Table output content verification ---
|
|
|
|
func TestTableOutputContainsHeaders(t *testing.T) {
|
|
t.Parallel()
|
|
cs := newCaptureServer()
|
|
defer cs.Close()
|
|
|
|
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "table")
|
|
assertExitCode(t, res, 0)
|
|
|
|
// Table should contain column headers
|
|
assertContains(t, res.Stdout, "Response")
|
|
assertContains(t, res.Stdout, "Count")
|
|
assertContains(t, res.Stdout, "Min")
|
|
assertContains(t, res.Stdout, "Max")
|
|
}
|
|
|
|
func TestTableOutputContainsStatusCode(t *testing.T) {
|
|
t.Parallel()
|
|
cs := newCaptureServer()
|
|
defer cs.Close()
|
|
|
|
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "table")
|
|
assertExitCode(t, res, 0)
|
|
|
|
assertContains(t, res.Stdout, "200")
|
|
}
|
|
|
|
// --- Version output format ---
|
|
|
|
func TestVersionOutputFormat(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
res := run("-v")
|
|
assertExitCode(t, res, 0)
|
|
|
|
lines := strings.Split(strings.TrimSpace(res.Stdout), "\n")
|
|
if len(lines) < 4 {
|
|
t.Fatalf("expected at least 4 lines in version output, got %d: %s", len(lines), res.Stdout)
|
|
}
|
|
assertContains(t, lines[0], "Version:")
|
|
assertContains(t, lines[1], "Git Commit:")
|
|
assertContains(t, lines[2], "Build Date:")
|
|
assertContains(t, lines[3], "Go Version:")
|
|
}
|