ajhahn.de
← eeco
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)
	}
}