Files
sultan/pkg/cli/cli_test.go
T
2026-10-01 23:52:15 +02:00

140 lines
4.2 KiB
Go

package cli
import (
"bytes"
"context"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func run(ctx context.Context, args ...string) (code int, stdout, stderr string) {
var out, errb bytes.Buffer
code = Run(ctx, args, &out, &errb)
return code, out.String(), errb.String()
}
func TestRun_Usage(t *testing.T) {
code, _, stderr := run(context.Background())
if code != 2 || !strings.Contains(stderr, "sultan server") {
t.Errorf("ohne Befehl: code=%d stderr=%q", code, stderr)
}
code, stdout, _ := run(context.Background(), "help")
if code != 0 || !strings.Contains(stdout, "sultan server") || !strings.Contains(stdout, "sultan agent") {
t.Errorf("help: code=%d stdout=%q", code, stdout)
}
code, _, stderr = run(context.Background(), "zaubern")
if code != 2 || !strings.Contains(stderr, "zaubern") {
t.Errorf("unbekannter Befehl: code=%d stderr=%q", code, stderr)
}
}
func TestRun_Version(t *testing.T) {
code, stdout, _ := run(context.Background(), "version")
if code != 0 || strings.TrimSpace(stdout) != "sultan "+Version {
t.Errorf("version: code=%d stdout=%q", code, stdout)
}
}
func TestRun_NotYetImplemented(t *testing.T) {
for _, cmd := range []string{"agent", "token"} {
code, _, stderr := run(context.Background(), cmd)
if code != 1 || !strings.Contains(stderr, "noch nicht implementiert") {
t.Errorf("%s: code=%d stderr=%q", cmd, code, stderr)
}
}
}
func TestServerFlags(t *testing.T) {
cfg, err := parseServerFlags(nil, &bytes.Buffer{})
if err != nil {
t.Fatal(err)
}
if cfg.DataDir != "./suldata" || cfg.AgentAddr != ":8443" || cfg.ProviderAddr != "127.0.0.1:8080" ||
cfg.InterceptorURL != "http://127.0.0.1:8081" || cfg.RefreshInterval != time.Minute {
t.Errorf("Defaults: %+v", cfg)
}
cfg, err = parseServerFlags([]string{
"--data-dir=/srv/sul", "--agent-addr", ":9443", "--provider-addr=:8080",
"--interceptor-url=http://lander:8081", "--refresh=30s",
}, &bytes.Buffer{})
if err != nil {
t.Fatal(err)
}
if cfg.DataDir != "/srv/sul" || cfg.AgentAddr != ":9443" || cfg.ProviderAddr != ":8080" ||
cfg.InterceptorURL != "http://lander:8081" || cfg.RefreshInterval != 30*time.Second {
t.Errorf("Overrides: %+v", cfg)
}
if _, err := parseServerFlags([]string{"--gibts-nicht"}, &bytes.Buffer{}); err == nil {
t.Error("unbekanntes Flag akzeptiert")
}
if _, err := parseServerFlags([]string{"überzählig"}, &bytes.Buffer{}); err == nil {
t.Error("überzähliges Argument akzeptiert")
}
}
func TestRun_ServerHelpAndBadFlags(t *testing.T) {
code, stdout, stderr := run(context.Background(), "server", "--help")
if code != 0 || !strings.Contains(stdout+stderr, "data-dir") {
t.Errorf("server --help: code=%d out=%q err=%q", code, stdout, stderr)
}
code, _, _ = run(context.Background(), "server", "--bogus")
if code != 2 {
t.Errorf("server --bogus: code=%d", code)
}
}
// Startet den echten Server über die CLI und beendet ihn per Kontext
// (wie SIGTERM in main).
func TestRun_ServerStartsAndStops(t *testing.T) {
dir := filepath.Join(t.TempDir(), "suldata")
ctx, cancel := context.WithCancel(context.Background())
type result struct {
code int
stderr string
}
done := make(chan result, 1)
go func() {
code, _, stderr := run(ctx, "server", "--data-dir="+dir, "--agent-addr=127.0.0.1:0", "--provider-addr=127.0.0.1:0")
done <- result{code, stderr}
}()
deadline := time.Now().Add(5 * time.Second)
for {
if _, err := os.Stat(filepath.Join(dir, "server.crt")); err == nil {
break
}
if time.Now().After(deadline) {
t.Fatal("Server hat das Datenverzeichnis nicht angelegt")
}
time.Sleep(10 * time.Millisecond)
}
time.Sleep(100 * time.Millisecond)
cancel()
select {
case r := <-done:
if r.code != 0 {
t.Errorf("Exit-Code %d, stderr:\n%s", r.code, r.stderr)
}
if !strings.Contains(r.stderr, "Fingerprint") {
t.Errorf("Start-Log ohne Fingerprint:\n%s", r.stderr)
}
case <-time.After(10 * time.Second):
t.Fatal("Server endet nicht")
}
}
func TestRun_ServerStartError(t *testing.T) {
file := filepath.Join(t.TempDir(), "datei")
os.WriteFile(file, nil, 0o600)
code, _, stderr := run(context.Background(), "server", "--data-dir="+filepath.Join(file, "sub"))
if code != 1 || stderr == "" {
t.Errorf("unbrauchbares Datenverzeichnis: code=%d stderr=%q", code, stderr)
}
}