fix(cli): Test las die Konfiguration des Hosts statt einer Attrappe
TestRunNoArgsDefaultsToServe rief run(nil) auf und griff damit auf den Default-Pfad /etc/vpnportal/config.yaml zu. Auf einem Entwicklungsrechner existiert der nicht, der Test war dort gruen. Auf einem Zielhost mit installierter Konfiguration las er dagegen die Produktivkonfiguration und loeste echte Verbindungsversuche zu Firewall und Domain Controllern aus. Die Kommandoauswahl ist jetzt als reine Funktion commandFor testbar. Kein Test ruft serve oder check mehr ohne expliziten --config-Pfad auf. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBHF4R9EAejDJUMdwr6C68
This commit is contained in:
parent
0fc2d8808b
commit
7237aee744
2 changed files with 61 additions and 12 deletions
|
|
@ -21,12 +21,17 @@ func main() {
|
||||||
os.Exit(run(os.Args[1:], os.Stdout, os.Stderr))
|
os.Exit(run(os.Args[1:], os.Stdout, os.Stderr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(args []string, stdout, stderr io.Writer) int {
|
// commandFor waehlt das Unterkommando. Fehlt es oder beginnt das erste
|
||||||
cmd := "serve"
|
// Argument mit '-', gilt serve als Vorgabe.
|
||||||
rest := args
|
func commandFor(args []string) (cmd string, rest []string) {
|
||||||
if len(args) > 0 && len(args[0]) > 0 && args[0][0] != '-' {
|
if len(args) > 0 && len(args[0]) > 0 && args[0][0] != '-' {
|
||||||
cmd, rest = args[0], args[1:]
|
return args[0], args[1:]
|
||||||
}
|
}
|
||||||
|
return "serve", args
|
||||||
|
}
|
||||||
|
|
||||||
|
func run(args []string, stdout, stderr io.Writer) int {
|
||||||
|
cmd, rest := commandFor(args)
|
||||||
|
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case "version":
|
case "version":
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
@ -30,14 +31,57 @@ func TestRunUnknownCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunNoArgsDefaultsToServe(t *testing.T) {
|
// commandFor wird bewusst ohne Seiteneffekte getestet. Ein Test, der run(nil)
|
||||||
|
// aufruft, wuerde den Default-Konfigpfad /etc/vpnportal/config.yaml lesen —
|
||||||
|
// auf einem Zielhost also die Produktivkonfiguration, samt Verbindungsversuch
|
||||||
|
// zu Firewall und Domain Controllern.
|
||||||
|
func TestCommandForDispatch(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
wantCmd string
|
||||||
|
wantRest []string
|
||||||
|
}{
|
||||||
|
{"ohne Argumente", nil, "serve", nil},
|
||||||
|
{"leere Liste", []string{}, "serve", []string{}},
|
||||||
|
{"nur Flag", []string{"--config", "/x.yaml"}, "serve", []string{"--config", "/x.yaml"}},
|
||||||
|
{"kurzes Flag", []string{"-h"}, "serve", []string{"-h"}},
|
||||||
|
{"version", []string{"version"}, "version", []string{}},
|
||||||
|
{"serve mit Flag", []string{"serve", "--config", "/x"}, "serve", []string{"--config", "/x"}},
|
||||||
|
{"check mit Flag", []string{"check", "--test-auth", "u"}, "check", []string{"--test-auth", "u"}},
|
||||||
|
{"unbekannt", []string{"frobnicate"}, "frobnicate", []string{}},
|
||||||
|
{"leeres Argument", []string{""}, "serve", []string{""}},
|
||||||
|
}
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
cmd, rest := commandFor(tc.args)
|
||||||
|
if cmd != tc.wantCmd {
|
||||||
|
t.Errorf("cmd = %q, want %q", cmd, tc.wantCmd)
|
||||||
|
}
|
||||||
|
if len(rest) != len(tc.wantRest) {
|
||||||
|
t.Fatalf("rest = %q, want %q", rest, tc.wantRest)
|
||||||
|
}
|
||||||
|
for i := range rest {
|
||||||
|
if rest[i] != tc.wantRest[i] {
|
||||||
|
t.Errorf("rest[%d] = %q, want %q", i, rest[i], tc.wantRest[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunServeReportsMissingConfigPath(t *testing.T) {
|
||||||
|
// Expliziter Pfad: der Test darf niemals die Konfiguration des Hosts lesen.
|
||||||
|
missing := filepath.Join(t.TempDir(), "gibtsnicht.yaml")
|
||||||
var out, errOut bytes.Buffer
|
var out, errOut bytes.Buffer
|
||||||
// serve ohne --config muss mit Fehler abbrechen, nicht mit "unknown command"
|
code := run([]string{"--config", missing}, &out, &errOut)
|
||||||
code := run(nil, &out, &errOut)
|
|
||||||
if code == 2 {
|
if code == 2 {
|
||||||
t.Fatalf("no args must default to serve, not unknown-command")
|
t.Fatal("ein fuehrendes Flag muss auf serve abgebildet werden, nicht auf unknown-command")
|
||||||
}
|
}
|
||||||
if !strings.Contains(errOut.String(), "config") {
|
if code == 0 {
|
||||||
t.Errorf("stderr should complain about missing config, got %q", errOut.String())
|
t.Fatal("fehlende Konfiguration muss zum Abbruch fuehren")
|
||||||
|
}
|
||||||
|
if !strings.Contains(errOut.String(), missing) {
|
||||||
|
t.Errorf("stderr muss den Pfad nennen, got %q", errOut.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue