Phase 5: scaffold Crucible (sow-tools) — dispatcher + builder shims, container, PR-first CI, fail-closed (D11, D19).
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package dispatch
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
var out, errw bytes.Buffer
|
||||
for _, arg := range []string{"version", "-V", "--version"} {
|
||||
out.Reset()
|
||||
errw.Reset()
|
||||
if code := run([]string{arg}, &out, &errw); code != exitOK {
|
||||
t.Fatalf("%s: exit=%d want %d", arg, code, exitOK)
|
||||
}
|
||||
if !strings.HasPrefix(out.String(), "crucible ") {
|
||||
t.Fatalf("%s: version line %q missing prefix", arg, out.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelpAndNoArgs(t *testing.T) {
|
||||
var out, errw bytes.Buffer
|
||||
if code := run([]string{"help"}, &out, &errw); code != exitOK {
|
||||
t.Fatalf("help exit=%d want %d", code, exitOK)
|
||||
}
|
||||
if !strings.Contains(out.String(), "builders:") {
|
||||
t.Fatalf("help output missing builders section:\n%s", out.String())
|
||||
}
|
||||
// No args is a usage error (exit 64) but still prints help.
|
||||
out.Reset()
|
||||
if code := run(nil, &out, &errw); code != exitUsage {
|
||||
t.Fatalf("no-args exit=%d want %d", code, exitUsage)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListCoversRegistry(t *testing.T) {
|
||||
var out bytes.Buffer
|
||||
list(&out)
|
||||
for _, b := range Registry {
|
||||
if !strings.Contains(out.String(), b.Name) || !strings.Contains(out.String(), b.Bin) {
|
||||
t.Fatalf("list missing %s/%s:\n%s", b.Name, b.Bin, out.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownBuilderFailsUsage(t *testing.T) {
|
||||
var out, errw bytes.Buffer
|
||||
if code := run([]string{"frobnicate"}, &out, &errw); code != exitUsage {
|
||||
t.Fatalf("unknown builder exit=%d want %d", code, exitUsage)
|
||||
}
|
||||
if !strings.Contains(errw.String(), "unknown builder") {
|
||||
t.Fatalf("unknown builder stderr=%q", errw.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestEveryBuilderFailsClosed(t *testing.T) {
|
||||
for _, b := range Registry {
|
||||
var out, errw bytes.Buffer
|
||||
// Via dispatcher.
|
||||
if code := run([]string{b.Name}, &out, &errw); code != exitUnwired {
|
||||
t.Errorf("crucible %s: exit=%d want %d (must fail closed)", b.Name, code, exitUnwired)
|
||||
}
|
||||
if !strings.Contains(errw.String(), "not wired") {
|
||||
t.Errorf("crucible %s: stderr missing fail-closed message: %q", b.Name, errw.String())
|
||||
}
|
||||
// Via standalone shim path.
|
||||
out.Reset()
|
||||
errw.Reset()
|
||||
if code := runBuilder(b.Name, nil, &out, &errw); code != exitUnwired {
|
||||
t.Errorf("%s: exit=%d want %d (must fail closed)", b.Bin, code, exitUnwired)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderHelpIsOK(t *testing.T) {
|
||||
for _, b := range Registry {
|
||||
var out, errw bytes.Buffer
|
||||
if code := runBuilder(b.Name, []string{"--help"}, &out, &errw); code != exitOK {
|
||||
t.Errorf("%s --help: exit=%d want %d", b.Name, code, exitOK)
|
||||
}
|
||||
if !strings.Contains(out.String(), b.Summary) {
|
||||
t.Errorf("%s --help: missing summary", b.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user