Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pkg/behaviourtest/steps/branch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ func TestThenBranchUnchanged_NoRepo(t *testing.T) {

func TestParseDummyAgentTable_ExpandsIssueInCheckoutBranchOnly(t *testing.T) {
w := &world.World{
Org: "org",
RepoName: "repo",
SCM: &fakeCleanupSCM{},
Install: &fakeInstallState{},
FixturesRoot: "e2e/behaviour",
Expand Down
10 changes: 7 additions & 3 deletions pkg/behaviourtest/steps/cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,13 @@ func CleanupScenario(w *world.World) {

// --- Dummy script cleanup ---
if len(w.DummyOps) > 0 {
empty := []byte("ops: []\n")
if err := w.SCM.CommitFile(ctx, w.Install.ConfigOwner(), w.Install.ConfigRepo(), w.BehaviourScriptPath(), "behaviour: clear dummy agent script", empty); err != nil {
worldLogf(w, "behaviour cleanup: clear dummy script: %v", err)
if w.Org == "" || w.RepoName == "" {
worldLogf(w, "behaviour cleanup: clear dummy script: no repo configured; call 'Given the enrolled test repository' first")
} else {
empty := []byte("ops: []\n")
if err := w.SCM.CommitFile(ctx, w.Org, w.RepoName, w.BehaviourScriptPath(), "behaviour: clear dummy agent script", empty); err != nil {
worldLogf(w, "behaviour cleanup: clear dummy script: %v", err)
}
}
}
}
Expand Down
48 changes: 25 additions & 23 deletions pkg/behaviourtest/steps/cleanup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,12 +614,11 @@ func TestCleanupScenario_ClearsDummyOps(t *testing.T) {
t.Parallel()

scmDriver := &fakeCleanupSCM{}
installDriver := &fakeCleanupInstall{owner: "org", repo: "repo"}
w := &world.World{
Org: "org",
RepoOwner: "org",
RepoName: "repo",
DummyOps: []runtime.BehaviourOperation{{Op: "echo", Args: "hello"}},
Install: installDriver,
SCM: scmDriver,
}
CleanupScenario(w)
Expand All @@ -631,12 +630,11 @@ func TestCleanupScenario_ClearsDummyOps_Error(t *testing.T) {

var logged []string
scmDriver := &fakeCleanupSCM{commitFileErr: fmt.Errorf("commit failed")}
installDriver := &fakeCleanupInstall{owner: "org", repo: "repo"}
w := &world.World{
Org: "org",
RepoOwner: "org",
RepoName: "repo",
DummyOps: []runtime.BehaviourOperation{{Op: "echo", Args: "hello"}},
Install: installDriver,
SCM: scmDriver,
Logf: func(format string, args ...any) { logged = append(logged, fmt.Sprintf(format, args...)) },
}
Expand All @@ -645,6 +643,27 @@ func TestCleanupScenario_ClearsDummyOps_Error(t *testing.T) {
assert.Contains(t, logged[0], "clear dummy script")
}

// --- Empty identity guard tests ---

func TestCleanupScenario_ClearsDummyOps_EmptyIdentity(t *testing.T) {
t.Parallel()

var logged []string
scmDriver := &fakeCleanupSCM{}
w := &world.World{
RepoOwner: "org",
RepoName: "repo",
// Org deliberately not set — should log instead of calling SCM.
DummyOps: []runtime.BehaviourOperation{{Op: "echo", Args: "hello"}},
SCM: scmDriver,
Logf: func(format string, args ...any) { logged = append(logged, fmt.Sprintf(format, args...)) },
}
CleanupScenario(w)
assert.False(t, scmDriver.commitFileCalled, "should not call CommitFile with empty Org")
require.Len(t, logged, 1)
assert.Contains(t, logged[0], "no repo configured")
}

// --- Kill switch cleanup tests ---

func TestCleanupScenario_DeactivatesKillSwitch(t *testing.T) {
Expand All @@ -653,12 +672,11 @@ func TestCleanupScenario_DeactivatesKillSwitch(t *testing.T) {
scmDriver := &fakeCleanupSCM{
fileContent: []byte("version: \"1\"\nkill_switch: true\nroles:\n - triage\n"),
}
installDriver := &fakeCleanupInstall{owner: "org", repo: "repo"}
w := &world.World{
Org: "org",
RepoOwner: "org",
RepoName: "repo",
KillSwitchActivated: true,
Install: installDriver,
SCM: scmDriver,
}
CleanupScenario(w)
Expand Down Expand Up @@ -687,12 +705,11 @@ func TestCleanupScenario_DeactivateKillSwitch_Error(t *testing.T) {
fileContent: []byte("version: \"1\"\nkill_switch: true\nroles:\n - triage\n"),
commitFileErr: fmt.Errorf("commit failed"),
}
installDriver := &fakeCleanupInstall{owner: "org", repo: "repo"}
w := &world.World{
Org: "org",
RepoOwner: "org",
RepoName: "repo",
KillSwitchActivated: true,
Install: installDriver,
SCM: scmDriver,
Logf: func(format string, args ...any) { logged = append(logged, fmt.Sprintf(format, args...)) },
}
Expand All @@ -701,21 +718,6 @@ func TestCleanupScenario_DeactivateKillSwitch_Error(t *testing.T) {
assert.Contains(t, logged[0], "deactivate kill switch")
}

// fakeCleanupInstall satisfies the Install interface for cleanup tests.
type fakeCleanupInstall struct {
owner string
repo string
}

func (f *fakeCleanupInstall) Mode() string { return "per-repo" }
func (f *fakeCleanupInstall) ConfigOwner() string { return f.owner }
func (f *fakeCleanupInstall) ConfigRepo() string { return f.repo }
func (f *fakeCleanupInstall) ConfigPathPrefix() string { return ".fullsend" }
func (f *fakeCleanupInstall) TriageWorkflowRepo() string { return f.repo }
func (f *fakeCleanupInstall) TriageWorkflowFile() string { return "fullsend.yaml" }
func (f *fakeCleanupInstall) AgentWorkflowFile() string { return "reusable-triage.yml" }
func (f *fakeCleanupInstall) AgentArtifactName() string { return "fullsend-triage" }

func TestCleanupScenario_BranchScenarioSweep(t *testing.T) {
t.Parallel()

Expand Down
39 changes: 27 additions & 12 deletions pkg/behaviourtest/steps/dispatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ func registerDispatchSteps(sc *godog.ScenarioContext) {
// It also marks w.KillSwitchActivated so CleanupScenario deactivates the
// switch before the slot is reused by another scenario.
func givenKillSwitchActive(w *world.World) error {
if w.Org == "" || w.RepoName == "" {
return fmt.Errorf("no repo configured; call 'Given the enrolled test repository' before kill-switch operations")
}
cfgPath := filepath.Join(".fullsend", "config.yaml")
cfgData, err := w.SCM.GetFileContent(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), cfgPath)
cfgData, err := w.SCM.GetFileContent(context.Background(), w.Org, w.RepoName, cfgPath)
if err != nil {
return fmt.Errorf("reading config: %w", err)
}
Expand All @@ -61,7 +64,7 @@ func givenKillSwitchActive(w *world.World) error {
if err != nil {
return err
}
if err := w.SCM.CommitFile(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), cfgPath, "behaviour: activate kill switch", merged); err != nil {
if err := w.SCM.CommitFile(context.Background(), w.Org, w.RepoName, cfgPath, "behaviour: activate kill switch", merged); err != nil {
return fmt.Errorf("updating config: %w", err)
}
w.KillSwitchActivated = true
Expand All @@ -72,8 +75,11 @@ func givenKillSwitchActive(w *world.World) error {
// config.yaml. Exported so CleanupScenario (in package steps) can call
// it during scenario teardown.
func DeactivateKillSwitch(w *world.World) error {
if w.Org == "" || w.RepoName == "" {
return fmt.Errorf("no repo configured; call 'Given the enrolled test repository' before kill-switch operations")
}
cfgPath := filepath.Join(".fullsend", "config.yaml")
cfgData, err := w.SCM.GetFileContent(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), cfgPath)
cfgData, err := w.SCM.GetFileContent(context.Background(), w.Org, w.RepoName, cfgPath)
if err != nil {
return fmt.Errorf("reading config: %w", err)
}
Expand All @@ -86,21 +92,24 @@ func DeactivateKillSwitch(w *world.World) error {
if err != nil {
return err
}
if err := w.SCM.CommitFile(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), cfgPath, "behaviour: deactivate kill switch", merged); err != nil {
if err := w.SCM.CommitFile(context.Background(), w.Org, w.RepoName, cfgPath, "behaviour: deactivate kill switch", merged); err != nil {
return fmt.Errorf("updating config: %w", err)
}
return nil
}

func givenDisabledCustomHarness(w *world.World, name, doc string) error {
if w.Org == "" || w.RepoName == "" {
return fmt.Errorf("no repo configured; call 'Given the enrolled test repository' before harness operations")
}
name = strings.TrimSpace(name)
doc = strings.TrimSpace(doc)
if name == "" || doc == "" {
return fmt.Errorf("harness name and contents are required")
}

harnessPath := filepath.Join(".fullsend", "harness", name+".yaml")
if err := w.SCM.CommitFile(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), harnessPath, fmt.Sprintf("behaviour: add harness %s", name), []byte(doc)); err != nil {
if err := w.SCM.CommitFile(context.Background(), w.Org, w.RepoName, harnessPath, fmt.Sprintf("behaviour: add harness %s", name), []byte(doc)); err != nil {
return fmt.Errorf("committing harness: %w", err)
}

Expand All @@ -109,7 +118,7 @@ func givenDisabledCustomHarness(w *world.World, name, doc string) error {
}

cfgPath := filepath.Join(".fullsend", "config.yaml")
cfgData, err := w.SCM.GetFileContent(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), cfgPath)
cfgData, err := w.SCM.GetFileContent(context.Background(), w.Org, w.RepoName, cfgPath)
if err != nil {
return fmt.Errorf("reading config: %w", err)
}
Expand All @@ -136,13 +145,16 @@ func givenDisabledCustomHarness(w *world.World, name, doc string) error {
if err != nil {
return err
}
if err := w.SCM.CommitFile(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), cfgPath, fmt.Sprintf("behaviour: register disabled harness %s", name), merged); err != nil {
if err := w.SCM.CommitFile(context.Background(), w.Org, w.RepoName, cfgPath, fmt.Sprintf("behaviour: register disabled harness %s", name), merged); err != nil {
return fmt.Errorf("updating config: %w", err)
}
return nil
}

func givenCustomHarness(w *world.World, name, doc string) error {
if w.Org == "" || w.RepoName == "" {
return fmt.Errorf("no repo configured; call 'Given the enrolled test repository' before harness operations")
}
name = strings.TrimSpace(name)
doc = strings.TrimSpace(doc)
if name == "" || doc == "" {
Expand All @@ -151,7 +163,7 @@ func givenCustomHarness(w *world.World, name, doc string) error {
w.DispatchAgent = name

harnessPath := filepath.Join(".fullsend", "harness", name+".yaml")
if err := w.SCM.CommitFile(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), harnessPath, fmt.Sprintf("behaviour: add harness %s", name), []byte(doc)); err != nil {
if err := w.SCM.CommitFile(context.Background(), w.Org, w.RepoName, harnessPath, fmt.Sprintf("behaviour: add harness %s", name), []byte(doc)); err != nil {
return fmt.Errorf("committing harness: %w", err)
}

Expand All @@ -160,7 +172,7 @@ func givenCustomHarness(w *world.World, name, doc string) error {
}

cfgPath := filepath.Join(".fullsend", "config.yaml")
cfgData, err := w.SCM.GetFileContent(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), cfgPath)
cfgData, err := w.SCM.GetFileContent(context.Background(), w.Org, w.RepoName, cfgPath)
if err != nil {
return fmt.Errorf("reading config: %w", err)
}
Expand All @@ -186,7 +198,7 @@ func givenCustomHarness(w *world.World, name, doc string) error {
if err != nil {
return err
}
if err := w.SCM.CommitFile(context.Background(), w.Install.ConfigOwner(), w.Install.ConfigRepo(), cfgPath, fmt.Sprintf("behaviour: register harness %s", name), merged); err != nil {
if err := w.SCM.CommitFile(context.Background(), w.Org, w.RepoName, cfgPath, fmt.Sprintf("behaviour: register harness %s", name), merged); err != nil {
return fmt.Errorf("updating config: %w", err)
}
return nil
Expand All @@ -201,6 +213,9 @@ func givenCustomHarness(w *world.World, name, doc string) error {
// to the config repo with the .fullsend/ prefix instead of to a hosting
// repo at the repo root.
func commitLocalHarnessResources(ctx context.Context, w *world.World, harnessName, doc string) error {
if w.Org == "" || w.RepoName == "" {
return fmt.Errorf("no repo configured; call 'Given the enrolled test repository' before harness operations")
}
var h struct {
Agent string `yaml:"agent"`
Policy string `yaml:"policy"`
Expand All @@ -209,8 +224,8 @@ func commitLocalHarnessResources(ctx context.Context, w *world.World, harnessNam
return fmt.Errorf("parsing harness YAML for resource paths: %w", err)
}

owner := w.Install.ConfigOwner()
repo := w.Install.ConfigRepo()
owner := w.Org
repo := w.RepoName

if h.Agent != "" && !strings.HasPrefix(h.Agent, "/") && !strings.HasPrefix(h.Agent, "https://") {
agentPath := filepath.Join(".fullsend", h.Agent)
Expand Down
Loading
Loading