Go 130 lines
package workflow
import (
"os"
"path/filepath"
"strconv"
"strings"
"testing"
)
type fakeWF struct {
code int
err error
}
func (fakeWF) Name() string { return "fake" }
func (fakeWF) Summary() string { return "fake" }
func (f fakeWF) Run(Env) (Result, error) { return Result{Code: f.code}, f.err }
func TestRun_NormalizesOutOfContractCode(t *testing.T) {
cfg := newCfg(t)
res, err := Run(fakeWF{code: 99}, Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeFinding {
t.Errorf("out-of-contract 99 -> %d, want %d", res.Code, CodeFinding)
}
}
func TestRun_NilConfig(t *testing.T) {
if _, err := Run(fakeWF{}, Env{}); err == nil {
t.Error("nil config must error")
}
}
func TestScriptRun_MissingEntryIsBlocked(t *testing.T) {
cfg := newCfg(t)
res, err := ScriptRun("ghost", Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeBlocked {
t.Errorf("missing entry -> %d, want %d (blocked)", res.Code, CodeBlocked)
}
}
func TestScriptRun_HonoursExitContract(t *testing.T) {
if _, err := os.Stat("/bin/sh"); err != nil {
t.Skip("no /bin/sh")
}
cfg := newCfg(t)
for _, code := range []int{0, 1, 2, 3} {
name := "wf"
dir := filepath.Join(cfg.Workspace, "workflows", name)
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
script := "#!/bin/sh\nexit " + strconv.Itoa(code) + "\n"
if err := os.WriteFile(filepath.Join(dir, EntryName), []byte(script), 0o755); err != nil {
t.Fatal(err)
}
res, err := ScriptRun(name, Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != code {
t.Errorf("script exit %d -> Result.Code %d", code, res.Code)
}
_ = os.RemoveAll(dir)
}
}
func TestScriptRun_DisabledMarkerIsBlocked(t *testing.T) {
if _, err := os.Stat("/bin/sh"); err != nil {
t.Skip("no /bin/sh")
}
cfg := newCfg(t)
name := "wf"
dir := filepath.Join(cfg.Workspace, "workflows", name)
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
script := "#!/bin/sh\nexit 0\n"
if err := os.WriteFile(filepath.Join(dir, EntryName), []byte(script), 0o755); err != nil {
t.Fatal(err)
}
// Enabled: runs clean.
res, err := ScriptRun(name, Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeClean {
t.Fatalf("enabled workflow -> %d, want %d", res.Code, CodeClean)
}
// Plant the disabled marker and re-run.
if err := os.WriteFile(filepath.Join(dir, DisabledMarker), nil, 0o644); err != nil {
t.Fatal(err)
}
res, err = ScriptRun(name, Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeBlocked {
t.Fatalf("disabled workflow -> %d, want %d (blocked)", res.Code, CodeBlocked)
}
if !strings.Contains(res.Summary, "disabled") {
t.Errorf("summary should mention 'disabled', got %q", res.Summary)
}
}
func TestScriptRun_NonExecutableIsBlocked(t *testing.T) {
cfg := newCfg(t)
dir := filepath.Join(cfg.Workspace, "workflows", "nox")
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
// Not executable and no interpreter: cannot be run -> blocked.
if err := os.WriteFile(filepath.Join(dir, EntryName), []byte("nonsense"), 0o644); err != nil {
t.Fatal(err)
}
res, err := ScriptRun("nox", Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeBlocked {
t.Errorf("non-executable entry -> %d, want %d (blocked)", res.Code, CodeBlocked)
}
}