mirror of
https://github.com/aykhans/sarin.git
synced 2026-02-28 14:59:14 +00:00
Add e2e tests
This commit is contained in:
401
e2e/config_file_test.go
Normal file
401
e2e/config_file_test.go
Normal file
@@ -0,0 +1,401 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfigFileBasic(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
out := res.jsonOutput(t)
|
||||
assertHasResponseKey(t, out, "200")
|
||||
assertResponseCount(t, out, 1)
|
||||
}
|
||||
|
||||
func TestConfigFileWithMethod(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
method: POST
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if req.Method != http.MethodPost {
|
||||
t.Errorf("expected method POST from config, got %s", req.Method)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileWithHeaders(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
headers:
|
||||
- X-Config: config-value
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Headers["X-Config"]; len(v) == 0 || v[0] != "config-value" {
|
||||
t.Errorf("expected X-Config: config-value, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileWithParams(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
params:
|
||||
- key1: value1
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Query["key1"]; len(v) == 0 || v[0] != "value1" {
|
||||
t.Errorf("expected key1=value1, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileWithCookies(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
cookies:
|
||||
- session: abc123
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v, ok := req.Cookies["session"]; !ok || v != "abc123" {
|
||||
t.Errorf("expected cookie session=abc123, got %v", req.Cookies)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileWithBody(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
method: POST
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
body: "hello from config"
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if req.Body != "hello from config" {
|
||||
t.Errorf("expected body 'hello from config', got %q", req.Body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileCLIOverridesScalars(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "http://should-be-overridden.invalid"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
// CLI -U should override the config file URL (scalar override)
|
||||
res := run("-f", configPath, "-U", cs.URL)
|
||||
assertExitCode(t, res, 0)
|
||||
assertResponseCount(t, res.jsonOutput(t), 1)
|
||||
|
||||
// Verify it actually hit our server
|
||||
if cs.requestCount() != 1 {
|
||||
t.Errorf("expected 1 request to capture server, got %d", cs.requestCount())
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileCLIOverridesMethods(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
method: GET
|
||||
requests: 4
|
||||
quiet: true
|
||||
output: json
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
// CLI -M POST overrides config file's method: GET
|
||||
res := run("-f", configPath, "-M", "POST")
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
for _, r := range cs.allRequests() {
|
||||
if r.Method != http.MethodPost {
|
||||
t.Errorf("expected all requests to be POST (CLI overrides config), got %s", r.Method)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileInvalidYAML(t *testing.T) {
|
||||
t.Parallel()
|
||||
configPath := writeTemp(t, "bad.yaml", `{{{not valid yaml`)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 1)
|
||||
}
|
||||
|
||||
func TestConfigFileNotFound(t *testing.T) {
|
||||
t.Parallel()
|
||||
res := run("-f", "/nonexistent/path/config.yaml")
|
||||
assertExitCode(t, res, 1)
|
||||
}
|
||||
|
||||
func TestConfigFileWithDryRun(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
config := `
|
||||
url: "http://example.com"
|
||||
requests: 3
|
||||
quiet: true
|
||||
output: json
|
||||
dryRun: true
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
out := res.jsonOutput(t)
|
||||
assertHasResponseKey(t, out, "dry-run")
|
||||
assertResponseCount(t, out, 3)
|
||||
}
|
||||
|
||||
func TestConfigFileWithConcurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 6
|
||||
concurrency: 3
|
||||
quiet: true
|
||||
output: json
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
out := res.jsonOutput(t)
|
||||
assertResponseCount(t, out, 6)
|
||||
}
|
||||
|
||||
func TestConfigFileNestedIncludes(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
// Create inner config
|
||||
innerConfig := `
|
||||
headers:
|
||||
- X-Inner: from-inner
|
||||
`
|
||||
innerPath := writeTemp(t, "inner.yaml", innerConfig)
|
||||
|
||||
// Create outer config that includes inner
|
||||
outerConfig := `
|
||||
configFile: "` + innerPath + `"
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
`
|
||||
outerPath := writeTemp(t, "outer.yaml", outerConfig)
|
||||
|
||||
res := run("-f", outerPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Headers["X-Inner"]; len(v) == 0 || v[0] != "from-inner" {
|
||||
t.Errorf("expected X-Inner: from-inner from nested config, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileFromHTTPURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
headers:
|
||||
- X-Remote-Config: yes
|
||||
`
|
||||
// Serve config via HTTP
|
||||
configServer := statusServerWithBody(config)
|
||||
defer configServer.Close()
|
||||
|
||||
res := run("-f", configServer.URL)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Headers["X-Remote-Config"]; len(v) == 0 || v[0] != "yes" {
|
||||
t.Errorf("expected X-Remote-Config: yes from HTTP config, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileMultiValueHeaders(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
headers:
|
||||
- X-Multi:
|
||||
- val1
|
||||
- val2
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
// With multiple values, sarin cycles through them (random start).
|
||||
// With -r 1, we should see exactly one of them.
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
v, ok := req.Headers["X-Multi"]
|
||||
if !ok || len(v) == 0 {
|
||||
t.Fatalf("expected X-Multi header, got headers: %v", req.Headers)
|
||||
}
|
||||
if v[0] != "val1" && v[0] != "val2" {
|
||||
t.Errorf("expected X-Multi to be val1 or val2, got %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileWithTimeout(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
timeout: 5s
|
||||
quiet: true
|
||||
output: json
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
assertResponseCount(t, res.jsonOutput(t), 1)
|
||||
}
|
||||
|
||||
func TestConfigFileWithInsecure(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
config := `
|
||||
url: "http://example.com"
|
||||
requests: 1
|
||||
insecure: true
|
||||
quiet: true
|
||||
output: json
|
||||
dryRun: true
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
}
|
||||
|
||||
func TestConfigFileWithLuaScript(t *testing.T) {
|
||||
t.Parallel()
|
||||
cs := newCaptureServer()
|
||||
defer cs.Close()
|
||||
|
||||
scriptContent := `function transform(req) req.headers["X-Config-Lua"] = {"yes"} return req end`
|
||||
scriptPath := writeTemp(t, "script.lua", scriptContent)
|
||||
|
||||
config := `
|
||||
url: "` + cs.URL + `"
|
||||
requests: 1
|
||||
quiet: true
|
||||
output: json
|
||||
lua: "@` + scriptPath + `"
|
||||
`
|
||||
configPath := writeTemp(t, "config.yaml", config)
|
||||
|
||||
res := run("-f", configPath)
|
||||
assertExitCode(t, res, 0)
|
||||
|
||||
req := cs.lastRequest()
|
||||
if v := req.Headers["X-Config-Lua"]; len(v) == 0 || v[0] != "yes" {
|
||||
t.Errorf("expected X-Config-Lua: yes, got %v", v)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user