test: fix TestRunExecListUsesJobEventAndAllPlans hang on macOS (#1378)

`TestRunExecListUsesJobEventAndAllPlans` hangs until the test timeout on macOS.

Regression from https://gitea.com/gitea/runner/pulls/1338, which added a fifth `runExecList` call to the test to cover `exec --list --detect-event` without events. That took the captured output from 498 to 560 bytes. `captureStdout` swapped `os.Stdout` for a pipe it only read after the callback returned, and on macOS 27.2 an unread pipe holds 512 bytes, so the write blocked forever. Linux pipes hold 64 KiB, so was unaffected.

`printList` and `runExecList` now write to a passed writer, `exec --list` hands them `cmd.OutOrStdout()`, and the tests pass a buffer, so no test swaps `os.Stdout` anymore.

---------

Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1378
Reviewed-by: Lunny Xiao <[email protected]>
This commit is contained in:
silverwindandLunny Xiao committed 2026-11-05 04:22:01 +00:00
1 parent 319567213d
commit 7d6e1ff021
2 files changed
+25 -47

No files matched your search

+17 -40
View File
@@ -5,7 +5,6 @@ package cmd
import (
"bytes"
"io"
"os"
"path/filepath"
"strings"
@@ -182,19 +181,18 @@ func TestRunExecListUsesJobEventAndAllPlans(t *testing.T) {
},
}
out := captureStdout(t, func() {
require.NoError(t, runExecList(planner, &executeArgs{job: "build"}))
require.NoError(t, runExecList(planner, &executeArgs{event: "push"}))
require.NoError(t, runExecList(planner, &executeArgs{autodetectEvent: true}))
require.NoError(t, runExecList(planner, &executeArgs{}))
emptyPlanner, err := model.NewWorkflowPlanner(t.TempDir(), false)
require.NoError(t, err)
require.NoError(t, runExecList(emptyPlanner, &executeArgs{autodetectEvent: true}))
})
var out bytes.Buffer
require.NoError(t, runExecList(&out, planner, &executeArgs{job: "build"}))
require.NoError(t, runExecList(&out, planner, &executeArgs{event: "push"}))
require.NoError(t, runExecList(&out, planner, &executeArgs{autodetectEvent: true}))
require.NoError(t, runExecList(&out, planner, &executeArgs{}))
emptyPlanner, err := model.NewWorkflowPlanner(t.TempDir(), false)
require.NoError(t, err)
require.NoError(t, runExecList(&out, emptyPlanner, &executeArgs{autodetectEvent: true}))
require.Contains(t, out, "Build")
require.Contains(t, out, "Test")
require.Contains(t, out, "Lint")
require.Contains(t, out.String(), "Build")
require.Contains(t, out.String(), "Test")
require.Contains(t, out.String(), "Lint")
require.Equal(t, []string{"job:build", "event:push", "event:push", "all"}, planner.calls)
}
@@ -208,14 +206,13 @@ func TestPrintListReportsDuplicateJobIDs(t *testing.T) {
},
}}}
out := captureStdout(t, func() {
printList(plan)
})
var out bytes.Buffer
printList(&out, plan)
require.Contains(t, out, "Workflow file")
require.Contains(t, out, "Build A")
require.Contains(t, out, "Build B")
require.Contains(t, out, "Detected multiple jobs with the same job name")
require.Contains(t, out.String(), "Workflow file")
require.Contains(t, out.String(), "Build A")
require.Contains(t, out.String(), "Build B")
require.Contains(t, out.String(), "Detected multiple jobs with the same job name")
}
func TestLoadExecCmdDefinesExpectedFlags(t *testing.T) {
@@ -293,26 +290,6 @@ func rawOnNode(event string) yaml.Node {
return *node.Content[0]
}
func captureStdout(t *testing.T, fn func()) string {
t.Helper()
old := os.Stdout
r, w, err := os.Pipe()
require.NoError(t, err)
os.Stdout = w
fn()
require.NoError(t, w.Close())
os.Stdout = old
var buf bytes.Buffer
_, err = io.Copy(&buf, r)
require.NoError(t, err)
require.NoError(t, r.Close())
return buf.String()
}
func TestExecuteArgsLoadEnvsResultsOrigin(t *testing.T) {
t.Setenv("ACTIONS_RESULTS_URL", "") // the default is only supplied when nothing else does
handler, err := artifactcache.StartHandler(artifactcache.Options{Dir: t.TempDir(), OutboundIP: "127.0.0.1"})