test: use t.Context() instead of context.Background() (#1306)

The test context is cancelled when the test ends, so anything still holding it stops instead of leaking into the next test. Uses inside `t.Cleanup`, `defer` and `go func` blocks are left alone, as the context is already cancelled there.

Stacked on https://gitea.com/gitea/runner/pulls/1305.

Assisted-by: Codet
Co-authored-by: bircni <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1306
Reviewed-by: bircni <[email protected]>
This commit is contained in:
Lunny Xiaoandbircni committed 2026-10-12 21:11:17 +00:00
1 parent 160e18e705
commit c3c647ef83
38 files changed
+288 -301

No files matched your search

+3 -4
View File
@@ -4,7 +4,6 @@
package common package common
import ( import (
"context"
"errors" "errors"
"testing" "testing"
@@ -13,7 +12,7 @@ import (
) )
func TestDryrunContext(t *testing.T) { func TestDryrunContext(t *testing.T) {
ctx := context.Background() ctx := t.Context()
if Dryrun(ctx) { if Dryrun(ctx) {
t.Fatal("plain context should not be dryrun") t.Fatal("plain context should not be dryrun")
} }
@@ -26,7 +25,7 @@ func TestDryrunContext(t *testing.T) {
} }
func TestJobErrorContainer(t *testing.T) { func TestJobErrorContainer(t *testing.T) {
ctx := context.Background() ctx := t.Context()
err := errors.New("job failed") err := errors.New("job failed")
SetJobError(ctx, err) SetJobError(ctx, err)
@@ -42,7 +41,7 @@ func TestJobErrorContainer(t *testing.T) {
} }
func TestLoggerAndHandlerContext(t *testing.T) { func TestLoggerAndHandlerContext(t *testing.T) {
ctx := context.Background() ctx := t.Context()
if Logger(ctx) != logging.Default() { if Logger(ctx) != logging.Default() {
t.Fatal("plain context should use the default logger") t.Fatal("plain context should use the default logger")
} }
+9 -9
View File
@@ -20,7 +20,7 @@ import (
func TestNewWorkflow(t *testing.T) { func TestNewWorkflow(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ctx := context.Background() ctx := t.Context()
// empty // empty
emptyWorkflow := NewPipelineExecutor() emptyWorkflow := NewPipelineExecutor()
@@ -72,7 +72,7 @@ func concurrencyProbe(wantActive int32) (exec Executor, count, maxActive *atomic
} }
func TestNewParallelExecutor(t *testing.T) { func TestNewParallelExecutor(t *testing.T) {
ctx := context.Background() ctx := t.Context()
exec, count, maxActive := concurrencyProbe(2) exec, count, maxActive := concurrencyProbe(2)
require.NoError(t, NewParallelExecutor(2, exec, exec, exec)(ctx)) require.NoError(t, NewParallelExecutor(2, exec, exec, exec)(ctx))
@@ -89,10 +89,10 @@ func TestNewParallelExecutor(t *testing.T) {
func TestNewParallelExecutorEmpty(t *testing.T) { func TestNewParallelExecutorEmpty(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ctx := context.Background() ctx := t.Context()
require.NoError(t, NewParallelExecutor(2)(ctx)) require.NoError(t, NewParallelExecutor(2)(ctx))
canceledCtx, cancel := context.WithCancel(context.Background()) canceledCtx, cancel := context.WithCancel(t.Context())
cancel() cancel()
err := NewParallelExecutor(2)(canceledCtx) err := NewParallelExecutor(2)(canceledCtx)
@@ -102,7 +102,7 @@ func TestNewParallelExecutorEmpty(t *testing.T) {
func TestNewParallelExecutorFailed(t *testing.T) { func TestNewParallelExecutorFailed(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
cancel() cancel()
count := 0 count := 0
@@ -118,7 +118,7 @@ func TestNewParallelExecutorFailed(t *testing.T) {
func TestNewParallelExecutorCanceled(t *testing.T) { func TestNewParallelExecutorCanceled(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
cancel() cancel()
errExpected := errors.New("fake error") errExpected := errors.New("fake error")
@@ -150,12 +150,12 @@ func TestNewParallelExecutorRunsRemainingAfterFailure(t *testing.T) {
} }
} }
require.Error(t, NewParallelExecutor(2, executors...)(context.Background())) require.Error(t, NewParallelExecutor(2, executors...)(t.Context()))
assert.Equal(t, int32(4), successCount.Load(), "a failing executor must not stop the others") assert.Equal(t, int32(4), successCount.Load(), "a failing executor must not stop the others")
} }
func TestExecutorConditionalsAndFinally(t *testing.T) { func TestExecutorConditionalsAndFinally(t *testing.T) {
ctx := context.Background() ctx := t.Context()
var calls []string var calls []string
record := func(name string) Executor { record := func(name string) Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
@@ -180,7 +180,7 @@ func TestExecutorFinallyReturnsFinallyErrorWithOriginal(t *testing.T) {
mainErr := errors.New("main failed") mainErr := errors.New("main failed")
finalErr := errors.New("cleanup failed") finalErr := errors.New("cleanup failed")
err := NewErrorExecutor(mainErr).Finally(NewErrorExecutor(finalErr))(context.Background()) err := NewErrorExecutor(mainErr).Finally(NewErrorExecutor(finalErr))(t.Context())
require.Error(t, err) require.Error(t, err)
if !strings.Contains(err.Error(), "cleanup failed") || !strings.Contains(err.Error(), "main failed") { if !strings.Contains(err.Error(), "cleanup failed") || !strings.Contains(err.Error(), "main failed") {
t.Fatalf("finally error = %q, want both cleanup and original error", err) t.Fatalf("finally error = %q, want both cleanup and original error", err)
+16 -16
View File
@@ -99,21 +99,21 @@ func TestFindGitMetadataOfSHA256RepositoryUsesOrigin(t *testing.T) {
require.NoError(t, gitCmd("-C", basedir, "remote", "add", "origin", remoteURL)) require.NoError(t, gitCmd("-C", basedir, "remote", "add", "origin", remoteURL))
require.NoError(t, gitCmd("-C", basedir, "config", "--add", "remote.origin.url", "https://github.com/other/repo.git")) require.NoError(t, gitCmd("-C", basedir, "config", "--add", "remote.origin.url", "https://github.com/other/repo.git"))
shortSHA, sha, err := FindGitRevision(context.Background(), basedir) shortSHA, sha, err := FindGitRevision(t.Context(), basedir)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, gitRevParse(t, basedir, "HEAD"), sha) require.Equal(t, gitRevParse(t, basedir, "HEAD"), sha)
require.Len(t, sha, 64) require.Len(t, sha, 64)
require.Equal(t, sha[:7], shortSHA) require.Equal(t, sha[:7], shortSHA)
ref, err := FindGitRef(context.Background(), basedir) ref, err := FindGitRef(t.Context(), basedir)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "refs/heads/main", ref) require.Equal(t, "refs/heads/main", ref)
url, err := findGitRemoteURL(context.Background(), basedir) url, err := findGitRemoteURL(t.Context(), basedir)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, remoteURL, url) require.Equal(t, remoteURL, url)
slug, err := FindGithubRepo(context.Background(), basedir) slug, err := FindGithubRepo(t.Context(), basedir)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "owner/repo", slug) require.Equal(t, "owner/repo", slug)
} }
@@ -190,7 +190,7 @@ func TestGitFindRef(t *testing.T) {
require.NoError(t, gitCmd("-C", dir, "init", "--initial-branch=master")) require.NoError(t, gitCmd("-C", dir, "init", "--initial-branch=master"))
require.NoError(t, cleanGitHooks(dir)) require.NoError(t, cleanGitHooks(dir))
tt.Prepare(t, dir) tt.Prepare(t, dir)
ref, err := FindGitRef(context.Background(), dir) ref, err := FindGitRef(t.Context(), dir)
tt.Assert(t, ref, err) tt.Assert(t, ref, err)
}) })
} }
@@ -264,17 +264,17 @@ func TestGitCloneExecutor(t *testing.T) {
Dir: dir, Dir: dir,
}) })
err := clone(context.Background()) err := clone(t.Context())
if tt.Err != nil { if tt.Err != nil {
assert.Error(t, err) //nolint:testifylint // pre-existing issue from nektos/act assert.Error(t, err) //nolint:testifylint // pre-existing issue from nektos/act
assert.Equal(t, tt.Err, err) assert.Equal(t, tt.Err, err)
assert.Equal(t, tt.Err, clone(context.Background()), "a retry on the cache keeps the error") assert.Equal(t, tt.Err, clone(t.Context()), "a retry on the cache keeps the error")
return return
} }
assert.Empty(t, err) //nolint:testifylint // pre-existing issue from nektos/act assert.Empty(t, err) //nolint:testifylint // pre-existing issue from nektos/act
marker := filepath.Join(dir, "marker") marker := filepath.Join(dir, "marker")
require.NoError(t, os.WriteFile(marker, nil, 0o644)) require.NoError(t, os.WriteFile(marker, nil, 0o644))
require.NoError(t, clone(context.Background())) require.NoError(t, clone(t.Context()))
assert.FileExists(t, marker, "an insteadOf rewrite must not evict the cache") assert.FileExists(t, marker, "an insteadOf rewrite must not evict the cache")
script, err := os.ReadFile(filepath.Join(dir, "action.sh")) script, err := os.ReadFile(filepath.Join(dir, "action.sh"))
require.NoError(t, err) require.NoError(t, err)
@@ -353,19 +353,19 @@ func TestGitCloneExecutorFollowsRemoteRefChanges(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
clone := NewGitCloneExecutor(NewGitCloneExecutorInput{URL: remoteDir, Ref: "main", Dir: dir}) clone := NewGitCloneExecutor(NewGitCloneExecutorInput{URL: remoteDir, Ref: "main", Dir: dir})
require.NoError(t, clone(context.Background())) require.NoError(t, clone(t.Context()))
require.NoError(t, gitCmd("-C", workDir, "reset", "--hard", "HEAD~1")) require.NoError(t, gitCmd("-C", workDir, "reset", "--hard", "HEAD~1"))
require.NoError(t, gitCmd("-C", workDir, "commit", "--allow-empty", "-m", "feature-rewritten")) require.NoError(t, gitCmd("-C", workDir, "commit", "--allow-empty", "-m", "feature-rewritten"))
require.NoError(t, gitCmd("-C", workDir, "push", "--force", "origin", "main")) require.NoError(t, gitCmd("-C", workDir, "push", "--force", "origin", "main"))
require.NoError(t, clone(context.Background()), "a non-fast-forward ref must update") require.NoError(t, clone(t.Context()), "a non-fast-forward ref must update")
assert.Equal(t, "feature-rewritten", gitHeadSubject(t, dir)) assert.Equal(t, "feature-rewritten", gitHeadSubject(t, dir))
tagClone := NewGitCloneExecutor(NewGitCloneExecutorInput{URL: remoteDir, Ref: "v9", Dir: t.TempDir()}) tagClone := NewGitCloneExecutor(NewGitCloneExecutorInput{URL: remoteDir, Ref: "v9", Dir: t.TempDir()})
require.Error(t, tagClone(context.Background())) require.Error(t, tagClone(t.Context()))
require.NoError(t, gitCmd("-C", workDir, "tag", "v9")) require.NoError(t, gitCmd("-C", workDir, "tag", "v9"))
require.NoError(t, gitCmd("-C", workDir, "push", "origin", "v9")) require.NoError(t, gitCmd("-C", workDir, "push", "origin", "v9"))
require.NoError(t, tagClone(context.Background()), "a tag published after a failed lookup must be fetched") require.NoError(t, tagClone(t.Context()), "a tag published after a failed lookup must be fetched")
} }
func TestGitCloneExecutorOfflineMode(t *testing.T) { func TestGitCloneExecutorOfflineMode(t *testing.T) {
@@ -385,7 +385,7 @@ func TestGitCloneExecutorOfflineMode(t *testing.T) {
URL: remoteDir, URL: remoteDir,
Ref: "main", Ref: "main",
Dir: cacheDir, Dir: cacheDir,
})(context.Background())) })(t.Context()))
t.Run("cached branch resolves without fetching", func(t *testing.T) { t.Run("cached branch resolves without fetching", func(t *testing.T) {
// Offline reuse of a cached branch must succeed even though ResolveRevision(input.Ref) // Offline reuse of a cached branch must succeed even though ResolveRevision(input.Ref)
@@ -395,7 +395,7 @@ func TestGitCloneExecutorOfflineMode(t *testing.T) {
Ref: "main", Ref: "main",
Dir: cacheDir, Dir: cacheDir,
OfflineMode: true, OfflineMode: true,
})(context.Background()) })(t.Context())
require.NoError(t, err) require.NoError(t, err)
out, err := exec.Command("git", "-C", cacheDir, "log", "--oneline", "-1", "--format=%s").Output() out, err := exec.Command("git", "-C", cacheDir, "log", "--oneline", "-1", "--format=%s").Output()
@@ -410,7 +410,7 @@ func TestGitCloneExecutorOfflineMode(t *testing.T) {
Ref: "never-fetched", Ref: "never-fetched",
Dir: cacheDir, Dir: cacheDir,
OfflineMode: true, OfflineMode: true,
})(context.Background()) })(t.Context())
require.Error(t, err) require.Error(t, err)
}) })
} }
@@ -430,7 +430,7 @@ func TestGitCloneExecutorQuietDemotesCloneLine(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
hook := logtest.New() hook := logtest.New()
logger := logging.New(logging.NewLevelHandler(hook, logging.LevelInfo)) logger := logging.New(logging.NewLevelHandler(hook, logging.LevelInfo))
ctx := common.WithLogger(context.Background(), logger.With("job", "j1")) ctx := common.WithLogger(t.Context(), logger.With("job", "j1"))
require.NoError(t, NewGitCloneExecutor(NewGitCloneExecutorInput{ require.NoError(t, NewGitCloneExecutor(NewGitCloneExecutorInput{
URL: remoteDir, URL: remoteDir,
+1 -2
View File
@@ -5,7 +5,6 @@
package container package container
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
@@ -42,7 +41,7 @@ func buildScratchImage(t *testing.T, platform string) string {
func TestImageExistsLocally(t *testing.T) { func TestImageExistsLocally(t *testing.T) {
requireDocker(t) requireDocker(t)
ctx := context.Background() ctx := t.Context()
// a non-existent image is reported absent // a non-existent image is reported absent
missing, err := ImageExistsLocally(ctx, "library/alpine:this-random-tag-will-never-exist", "linux/amd64") missing, err := ImageExistsLocally(ctx, "library/alpine:this-random-tag-will-never-exist", "linux/amd64")
+4 -4
View File
@@ -19,7 +19,7 @@ import (
) )
func TestIsolatedCacheContainer(t *testing.T) { func TestIsolatedCacheContainer(t *testing.T) {
ctx := context.Background() ctx := t.Context()
cache, lan := netip.MustParseAddr("172.18.0.3"), netip.MustParseAddr("192.168.1.20") cache, lan := netip.MustParseAddr("172.18.0.3"), netip.MustParseAddr("192.168.1.20")
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("ContainerList", ctx, mobyclient.ContainerListOptions{}).Return(mobyclient.ContainerListResult{Items: []container.Summary{{}, { client.On("ContainerList", ctx, mobyclient.ContainerListOptions{}).Return(mobyclient.ContainerListResult{Items: []container.Summary{{}, {
@@ -58,7 +58,7 @@ func TestIsAddressPoolExhausted(t *testing.T) {
} }
func TestCreateDockerNetworkInheritsDaemonMTU(t *testing.T) { func TestCreateDockerNetworkInheritsDaemonMTU(t *testing.T) {
ctx := context.Background() ctx := t.Context()
for _, tc := range []struct { for _, tc := range []struct {
bridgeOptions, want map[string]string bridgeOptions, want map[string]string
}{ }{
@@ -87,7 +87,7 @@ func (m *mockDockerClient) NetworkDisconnect(ctx context.Context, id string, opt
} }
func TestConnectAndDisconnectNetwork(t *testing.T) { func TestConnectAndDisconnectNetwork(t *testing.T) {
ctx := context.Background() ctx := t.Context()
connect := func(answer error) error { connect := func(answer error) error {
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("NetworkConnect", ctx, "jobs", mobyclient.NetworkConnectOptions{ client.On("NetworkConnect", ctx, "jobs", mobyclient.NetworkConnectOptions{
@@ -117,7 +117,7 @@ func TestConnectAndDisconnectNetwork(t *testing.T) {
// and old enough to predate any job now starting are the runner's to reclaim. An unexpected // and old enough to predate any job now starting are the runner's to reclaim. An unexpected
// NetworkRemove fails the test on its own, since testify has no expectation to match it against. // NetworkRemove fails the test on its own, since testify has no expectation to match it against.
func TestRemoveOrphanNetworks(t *testing.T) { func TestRemoveOrphanNetworks(t *testing.T) {
ctx := context.Background() ctx := t.Context()
cutoff := time.Date(2026, time.April, 29, 20, 0, 0, 0, time.UTC) cutoff := time.Date(2026, time.April, 29, 20, 0, 0, 0, time.UTC)
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("NetworkList", ctx, mobyclient.NetworkListOptions{ client.On("NetworkList", ctx, mobyclient.NetworkListOptions{
+2 -2
View File
@@ -285,7 +285,7 @@ func TestRemoveLabelledRemovesContainersNetworksAndVolumes(t *testing.T) {
containerFailure := errors.New("container removal failed") containerFailure := errors.New("container removal failed")
listFailure := errors.New("listing failed") listFailure := errors.New("listing failed")
volumeFailure := errors.New("volume removal failed") volumeFailure := errors.New("volume removal failed")
ctx := context.Background() ctx := t.Context()
filters := make(mobyclient.Filters).Add("label", jobLabel+"=job-1") filters := make(mobyclient.Filters).Add("label", jobLabel+"=job-1")
cli := &mockDockerClient{} cli := &mockDockerClient{}
cli.On("ContainerList", ctx, mobyclient.ContainerListOptions{All: true, Filters: filters}). cli.On("ContainerList", ctx, mobyclient.ContainerListOptions{All: true, Filters: filters}).
@@ -312,7 +312,7 @@ func TestRemoveLabelledRemovesContainersNetworksAndVolumes(t *testing.T) {
func TestDockerProxyWithDaemon(t *testing.T) { func TestDockerProxyWithDaemon(t *testing.T) {
requireDocker(t) requireDocker(t)
ctx := context.Background() ctx := t.Context()
require.NoError(t, NewDockerPullExecutor(NewDockerPullExecutorInput{Image: "alpine"})(ctx)) require.NoError(t, NewDockerPullExecutor(NewDockerPullExecutorInput{Image: "alpine"})(ctx))
direct, err := GetDockerClient(ctx) direct, err := GetDockerClient(ctx)
require.NoError(t, err) require.NoError(t, err)
+2 -3
View File
@@ -5,7 +5,6 @@
package container package container
import ( import (
"context"
"io" "io"
"strings" "strings"
"testing" "testing"
@@ -37,13 +36,13 @@ func TestCleanImage(t *testing.T) {
} }
for _, table := range tables { for _, table := range tables {
imageOut := cleanImage(context.Background(), table.imageIn) imageOut := cleanImage(t.Context(), table.imageIn)
assert.Equal(t, table.imageOut, imageOut) assert.Equal(t, table.imageOut, imageOut)
} }
} }
func TestGetImagePullOptions(t *testing.T) { func TestGetImagePullOptions(t *testing.T) {
ctx := context.Background() ctx := t.Context()
orig := config.Dir() orig := config.Dir()
t.Cleanup(func() { config.SetDir(orig) }) t.Cleanup(func() { config.SetDir(orig) })
+16 -16
View File
@@ -166,7 +166,7 @@ func (m *mockConn) Close() (err error) {
} }
func TestDockerExecAbort(t *testing.T) { func TestDockerExecAbort(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
reader := &interruptReader{started: make(chan struct{}), interrupted: make(chan struct{}), stopped: make(chan struct{})} reader := &interruptReader{started: make(chan struct{}), interrupted: make(chan struct{}), stopped: make(chan struct{})}
conn := &mockConn{} conn := &mockConn{}
@@ -207,7 +207,7 @@ func TestDockerExecAbort(t *testing.T) {
} }
func TestDockerExecFailure(t *testing.T) { func TestDockerExecFailure(t *testing.T) {
ctx := context.Background() ctx := t.Context()
conn := &mockConn{} conn := &mockConn{}
@@ -254,7 +254,7 @@ func stdcopyFrame(stream stdcopy.StdType, payload string) []byte {
// attach() streaming goroutine has drained and flushed the container's output, // attach() streaming goroutine has drained and flushed the container's output,
// so a final line without a trailing newline is not lost. // so a final line without a trailing newline is not lost.
func TestDockerAttachFlushesTrailingLine(t *testing.T) { func TestDockerAttachFlushesTrailingLine(t *testing.T) {
ctx := context.Background() ctx := t.Context()
framed := bytes.NewBuffer(stdcopyFrame(stdcopy.Stdout, "line one\nlast line without newline")) framed := bytes.NewBuffer(stdcopyFrame(stdcopy.Stdout, "line one\nlast line without newline"))
@@ -303,7 +303,7 @@ func TestDockerAttachFlushesTrailingLine(t *testing.T) {
} }
func TestDockerWaitFailure(t *testing.T) { func TestDockerWaitFailure(t *testing.T) {
ctx := context.Background() ctx := t.Context()
statusCh := make(chan container.WaitResponse, 1) statusCh := make(chan container.WaitResponse, 1)
statusCh <- container.WaitResponse{StatusCode: 2} statusCh <- container.WaitResponse{StatusCode: 2}
@@ -355,7 +355,7 @@ func TestRemoveIgnoresAutoRemoveRace(t *testing.T) {
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
ctx := common.WithLogger(context.Background(), logger) ctx := common.WithLogger(t.Context(), logger)
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("ContainerKill", ctx, "abc", killOpts).Return(mobyclient.ContainerKillResult{}, nil) client.On("ContainerKill", ctx, "abc", killOpts).Return(mobyclient.ContainerKillResult{}, nil)
client.On("ContainerRemove", ctx, "abc", removeOpts).Return(mobyclient.ContainerRemoveResult{}, tc.err) client.On("ContainerRemove", ctx, "abc", removeOpts).Return(mobyclient.ContainerRemoveResult{}, tc.err)
@@ -388,7 +388,7 @@ func TestRemoveIgnoresAutoRemoveRace(t *testing.T) {
// create() lost its reply, must still be removed rather than leaking with its network. It // create() lost its reply, must still be removed rather than leaking with its network. It
// was never started here, so it is not worth a kill of its own. // was never started here, so it is not worth a kill of its own.
func TestRemoveWithoutIDUsesName(t *testing.T) { func TestRemoveWithoutIDUsesName(t *testing.T) {
ctx := context.Background() ctx := t.Context()
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("ContainerRemove", ctx, "job-1", mobyclient.ContainerRemoveOptions{RemoveVolumes: true, Force: true}). client.On("ContainerRemove", ctx, "job-1", mobyclient.ContainerRemoveOptions{RemoveVolumes: true, Force: true}).
Return(mobyclient.ContainerRemoveResult{}, nil) Return(mobyclient.ContainerRemoveResult{}, nil)
@@ -401,7 +401,7 @@ func TestRemoveWithoutIDUsesName(t *testing.T) {
// find() must drop a stale cached id so later Copy/Exec don't hit the // find() must drop a stale cached id so later Copy/Exec don't hit the
// daemon with a torn-down container. // daemon with a torn-down container.
func TestFindRevalidatesStaleID(t *testing.T) { func TestFindRevalidatesStaleID(t *testing.T) {
ctx := context.Background() ctx := t.Context()
notFound := cerrdefs.ErrNotFound.WithMessage("No such container") notFound := cerrdefs.ErrNotFound.WithMessage("No such container")
boom := errors.New("daemon unreachable") boom := errors.New("daemon unreachable")
newCR := func(id string) (*containerReference, *mockDockerClient) { newCR := func(id string) (*containerReference, *mockDockerClient) {
@@ -459,7 +459,7 @@ func TestFindRevalidatesStaleID(t *testing.T) {
// Every daemon entry point fails fast with a clear, container-named // Every daemon entry point fails fast with a clear, container-named
// error when no live cr.id is known. // error when no live cr.id is known.
func TestRejectsMissingContainer(t *testing.T) { func TestRejectsMissingContainer(t *testing.T) {
ctx := context.Background() ctx := t.Context()
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("ContainerList", ctx, mobyclient.ContainerListOptions{All: true}).Return(mobyclient.ContainerListResult{}, nil) client.On("ContainerList", ctx, mobyclient.ContainerListOptions{All: true}).Return(mobyclient.ContainerListResult{}, nil)
cr := &containerReference{cli: client, input: &NewContainerInput{Name: "job-1"}} cr := &containerReference{cli: client, input: &NewContainerInput{Name: "job-1"}}
@@ -616,7 +616,7 @@ func TestCheckVolumes(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) { t.Run(tc.desc, func(t *testing.T) {
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
ctx := common.WithLogger(context.Background(), logger) ctx := common.WithLogger(t.Context(), logger)
cr := &containerReference{ cr := &containerReference{
input: &NewContainerInput{ input: &NewContainerInput{
ValidVolumes: tc.validVolumes, ValidVolumes: tc.validVolumes,
@@ -656,12 +656,12 @@ func TestMergeContainerConfigsKeepsTheRunnersFilesAndEnvToItself(t *testing.T) {
logger := logging.New(logtest.New()) logger := logging.New(logtest.New())
cr := &containerReference{input: &NewContainerInput{NetworkMode: "bridge", WorkflowOptions: option}} cr := &containerReference{input: &NewContainerInput{NetworkMode: "bridge", WorkflowOptions: option}}
_, _, err := cr.mergeContainerConfigs(common.WithLogger(context.Background(), logger), &container.Config{}, &container.HostConfig{}) _, _, err := cr.mergeContainerConfigs(common.WithLogger(t.Context(), logger), &container.Config{}, &container.HostConfig{})
require.ErrorContains(t, err, "not allowed in a workflow") require.ErrorContains(t, err, "not allowed in a workflow")
// the runner reading its own files is what those options are for // the runner reading its own files is what those options are for
cr = &containerReference{input: &NewContainerInput{NetworkMode: "bridge", RunnerOptions: option}} cr = &containerReference{input: &NewContainerInput{NetworkMode: "bridge", RunnerOptions: option}}
_, _, err = cr.mergeContainerConfigs(common.WithLogger(context.Background(), logger), &container.Config{}, &container.HostConfig{}) _, _, err = cr.mergeContainerConfigs(common.WithLogger(t.Context(), logger), &container.Config{}, &container.HostConfig{})
require.NoError(t, err) require.NoError(t, err)
} }
@@ -673,7 +673,7 @@ func TestMergeContainerConfigsKeepsTheRunnersFilesAndEnvToItself(t *testing.T) {
WorkflowOptions: "--env RUNNER_SECRET --env GIVEN=value", WorkflowOptions: "--env RUNNER_SECRET --env GIVEN=value",
}} }}
config, _, err := cr.mergeContainerConfigs(common.WithLogger(context.Background(), logger), &container.Config{}, &container.HostConfig{}) config, _, err := cr.mergeContainerConfigs(common.WithLogger(t.Context(), logger), &container.Config{}, &container.HostConfig{})
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, []string{"RUNNER_SECRET", "RUNNER_SECRET", "GIVEN=value"}, config.Env) assert.Equal(t, []string{"RUNNER_SECRET", "RUNNER_SECRET", "GIVEN=value"}, config.Env)
} }
@@ -723,7 +723,7 @@ func mergeOptions(t *testing.T, runnerOptions, workflowOptions string, privilege
ValidVolumes: []string{"**"}, ValidVolumes: []string{"**"},
}} }}
_, hostConfig, err := cr.mergeContainerConfigs(common.WithLogger(context.Background(), logger), &container.Config{}, &container.HostConfig{ _, hostConfig, err := cr.mergeContainerConfigs(common.WithLogger(t.Context(), logger), &container.Config{}, &container.HostConfig{
Privileged: privileged, Privileged: privileged,
UsernsMode: container.UsernsMode("private"), UsernsMode: container.UsernsMode("private"),
NetworkMode: container.NetworkMode("bridge"), NetworkMode: container.NetworkMode("bridge"),
@@ -767,7 +767,7 @@ func TestMergeContainerConfigsStripsDangerousOptionsWhenUnprivileged(t *testing.
func TestCheckVolumesRejectsEscapingHostPaths(t *testing.T) { func TestCheckVolumesRejectsEscapingHostPaths(t *testing.T) {
logger := logging.New(logtest.New()) logger := logging.New(logtest.New())
ctx := common.WithLogger(context.Background(), logger) ctx := common.WithLogger(t.Context(), logger)
base := t.TempDir() base := t.TempDir()
allowed := filepath.Join(base, "allowed") allowed := filepath.Join(base, "allowed")
@@ -808,7 +808,7 @@ func TestSanitizeConfigKeepsTmpfsMounts(t *testing.T) {
for _, validVolumes := range [][]string{nil, {"data"}, {"**:ro"}} { for _, validVolumes := range [][]string{nil, {"data"}, {"**:ro"}} {
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
_, sanitized := (&containerReference{input: &NewContainerInput{ValidVolumes: validVolumes}}).sanitizeConfig(common.WithLogger(context.Background(), logger), &container.Config{}, &container.HostConfig{Mounts: []mount.Mount{ _, sanitized := (&containerReference{input: &NewContainerInput{ValidVolumes: validVolumes}}).sanitizeConfig(common.WithLogger(t.Context(), logger), &container.Config{}, &container.HostConfig{Mounts: []mount.Mount{
hostConfig.Mounts[0], hostConfig.Mounts[0],
{Type: mount.TypeVolume, Target: "/anonymous"}, {Type: mount.TypeVolume, Target: "/anonymous"},
{Type: mount.TypeTmpfs, Source: "/etc", Target: "/etc-copy"}, {Type: mount.TypeTmpfs, Source: "/etc", Target: "/etc-copy"},
@@ -898,7 +898,7 @@ func TestContainerInfoFromInspect(t *testing.T) {
func TestMergeContainerConfigsVolumesReplaceRunnerMounts(t *testing.T) { func TestMergeContainerConfigsVolumesReplaceRunnerMounts(t *testing.T) {
logger := logging.New(logtest.New()) logger := logging.New(logtest.New())
ctx := common.WithLogger(context.Background(), logger) ctx := common.WithLogger(t.Context(), logger)
cr := &containerReference{ cr := &containerReference{
input: &NewContainerInput{ input: &NewContainerInput{
NetworkMode: "bridge", NetworkMode: "bridge",
+1 -2
View File
@@ -4,7 +4,6 @@
package container package container
import ( import (
"context"
"testing" "testing"
mobyclient "github.com/moby/moby/client" mobyclient "github.com/moby/moby/client"
@@ -15,7 +14,7 @@ import (
// so the daemon has to be pinged explicitly here to decide whether to skip. // so the daemon has to be pinged explicitly here to decide whether to skip.
func requireDocker(t *testing.T) { func requireDocker(t *testing.T) {
t.Helper() t.Helper()
ctx := context.Background() ctx := t.Context()
cli, err := GetDockerClient(ctx) cli, err := GetDockerClient(ctx)
if err != nil { if err != nil {
t.Skipf("skipping: docker client unavailable: %v", err) t.Skipf("skipping: docker client unavailable: %v", err)
+8 -8
View File
@@ -62,7 +62,7 @@ func TestCopyDir(t *testing.T) {
func TestGetContainerArchive(t *testing.T) { func TestGetContainerArchive(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
ctx := context.Background() ctx := t.Context()
e := &HostEnvironment{ e := &HostEnvironment{
Path: filepath.Join(dir, "path"), Path: filepath.Join(dir, "path"),
TmpDir: filepath.Join(dir, "tmp"), TmpDir: filepath.Join(dir, "tmp"),
@@ -97,7 +97,7 @@ func TestHostEnvironmentExecExitCode(t *testing.T) {
t.Skip("uses POSIX shell") t.Skip("uses POSIX shell")
} }
dir := t.TempDir() dir := t.TempDir()
ctx := context.Background() ctx := t.Context()
e := &HostEnvironment{ e := &HostEnvironment{
Path: filepath.Join(dir, "path"), Path: filepath.Join(dir, "path"),
TmpDir: filepath.Join(dir, "tmp"), TmpDir: filepath.Join(dir, "tmp"),
@@ -148,7 +148,7 @@ func TestHostEnvironmentAllocatePTY(t *testing.T) {
err := e.Exec( err := e.Exec(
[]string{"sh", "-c", "[ -t 1 ] && printf TTY || printf NOTTY"}, []string{"sh", "-c", "[ -t 1 ] && printf TTY || printf NOTTY"},
map[string]string{"PATH": os.Getenv("PATH")}, "", "", map[string]string{"PATH": os.Getenv("PATH")}, "", "",
)(context.Background()) )(t.Context())
require.NoError(t, err) require.NoError(t, err)
got := strings.TrimSpace(strings.ReplaceAll(buf.String(), "\r", "")) got := strings.TrimSpace(strings.ReplaceAll(buf.String(), "\r", ""))
assert.Equal(t, tc.expect, got) assert.Equal(t, tc.expect, got)
@@ -157,7 +157,7 @@ func TestHostEnvironmentAllocatePTY(t *testing.T) {
} }
func TestHostEnvironmentRemovePreservesWorkdirByDefault(t *testing.T) { func TestHostEnvironmentRemovePreservesWorkdirByDefault(t *testing.T) {
ctx := common.WithLogger(context.Background(), logging.Default()) ctx := common.WithLogger(t.Context(), logging.Default())
base := t.TempDir() base := t.TempDir()
miscRoot := filepath.Join(base, "misc") miscRoot := filepath.Join(base, "misc")
path := filepath.Join(miscRoot, "hostexecutor") path := filepath.Join(miscRoot, "hostexecutor")
@@ -179,7 +179,7 @@ func TestHostEnvironmentRemovePreservesWorkdirByDefault(t *testing.T) {
} }
func TestHostEnvironmentRemoveCleansWorkdirWhenOwned(t *testing.T) { func TestHostEnvironmentRemoveCleansWorkdirWhenOwned(t *testing.T) {
ctx := common.WithLogger(context.Background(), logging.Default()) ctx := common.WithLogger(t.Context(), logging.Default())
base := t.TempDir() base := t.TempDir()
miscRoot := filepath.Join(base, "misc") miscRoot := filepath.Join(base, "misc")
path := filepath.Join(miscRoot, "hostexecutor") path := filepath.Join(miscRoot, "hostexecutor")
@@ -220,7 +220,7 @@ func TestRemoveAllWithContextDoesNotHangOnStuckDelete(t *testing.T) {
removeAll = orig removeAll = orig
}) })
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) ctx, cancel := context.WithTimeout(t.Context(), 100*time.Millisecond)
defer cancel() defer cancel()
err := removeAllWithContext(ctx, t.TempDir()) err := removeAllWithContext(ctx, t.TempDir())
@@ -237,7 +237,7 @@ func TestHostEnvironmentRemoveDoesNotHangOnStuckCleanUp(t *testing.T) {
hostCleanupTimeout = 100 * time.Millisecond hostCleanupTimeout = 100 * time.Millisecond
t.Cleanup(func() { hostCleanupTimeout = orig }) t.Cleanup(func() { hostCleanupTimeout = orig })
ctx := common.WithLogger(context.Background(), logging.Default()) ctx := common.WithLogger(t.Context(), logging.Default())
base := t.TempDir() base := t.TempDir()
path := filepath.Join(base, "misc", "hostexecutor") path := filepath.Join(base, "misc", "hostexecutor")
require.NoError(t, os.MkdirAll(path, 0o700)) require.NoError(t, os.MkdirAll(path, 0o700))
@@ -290,7 +290,7 @@ func TestHostEnvironmentRemoveDoesNotHangOnStuckPathRemoval(t *testing.T) {
removeAll = origRemoveAll removeAll = origRemoveAll
}) })
ctx := common.WithLogger(context.Background(), logging.Default()) ctx := common.WithLogger(t.Context(), logging.Default())
base := t.TempDir() base := t.TempDir()
path := filepath.Join(base, "misc", "hostexecutor") path := filepath.Join(base, "misc", "hostexecutor")
require.NoError(t, os.MkdirAll(path, 0o700)) require.NoError(t, os.MkdirAll(path, 0o700))
+10 -11
View File
@@ -5,7 +5,6 @@ package container
import ( import (
"bufio" "bufio"
"context"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -28,7 +27,7 @@ func TestParseEnvFileSingleLine(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, []byte("FOO=bar\nBAZ=qux\n"), 0o600)) require.NoError(t, os.WriteFile(envPath, []byte("FOO=bar\nBAZ=qux\n"), 0o600))
env := map[string]string{} env := map[string]string{}
require.NoError(t, parseEnvFile(e, envPath, &env)(context.Background())) require.NoError(t, parseEnvFile(e, envPath, &env)(t.Context()))
assert.Equal(t, "bar", env["FOO"]) assert.Equal(t, "bar", env["FOO"])
assert.Equal(t, "qux", env["BAZ"]) assert.Equal(t, "qux", env["BAZ"])
} }
@@ -39,7 +38,7 @@ func TestParseEnvFileMultiLine(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, []byte(content), 0o600)) require.NoError(t, os.WriteFile(envPath, []byte(content), 0o600))
env := map[string]string{} env := map[string]string{}
require.NoError(t, parseEnvFile(e, envPath, &env)(context.Background())) require.NoError(t, parseEnvFile(e, envPath, &env)(t.Context()))
assert.Equal(t, "line1\nline2", env["FOO"]) assert.Equal(t, "line1\nline2", env["FOO"])
} }
@@ -50,7 +49,7 @@ func TestParseEnvFileLargeValueWithinLimit(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, []byte(content), 0o600)) require.NoError(t, os.WriteFile(envPath, []byte(content), 0o600))
env := map[string]string{} env := map[string]string{}
require.NoError(t, parseEnvFile(e, envPath, &env)(context.Background())) require.NoError(t, parseEnvFile(e, envPath, &env)(t.Context()))
assert.Equal(t, big, env["FOO"]) assert.Equal(t, big, env["FOO"])
} }
@@ -61,7 +60,7 @@ func TestParseEnvFileLineExceedsBufferReportsScannerError(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, []byte(content), 0o600)) require.NoError(t, os.WriteFile(envPath, []byte(content), 0o600))
env := map[string]string{} env := map[string]string{}
err := parseEnvFile(e, envPath, &env)(context.Background()) err := parseEnvFile(e, envPath, &env)(t.Context())
require.ErrorIs(t, err, bufio.ErrTooLong) require.ErrorIs(t, err, bufio.ErrTooLong)
assert.Contains(t, err.Error(), "reading env file") assert.Contains(t, err.Error(), "reading env file")
} }
@@ -73,7 +72,7 @@ func TestParseEnvFileBlankLines(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, []byte("\nFOO=bar\n\n \nBAZ=qux\n\n"), 0o600)) require.NoError(t, os.WriteFile(envPath, []byte("\nFOO=bar\n\n \nBAZ=qux\n\n"), 0o600))
env := map[string]string{} env := map[string]string{}
require.NoError(t, parseEnvFile(e, envPath, &env)(context.Background())) require.NoError(t, parseEnvFile(e, envPath, &env)(t.Context()))
assert.Equal(t, "bar", env["FOO"]) assert.Equal(t, "bar", env["FOO"])
assert.Equal(t, "qux", env["BAZ"]) assert.Equal(t, "qux", env["BAZ"])
} }
@@ -84,12 +83,12 @@ func TestParseEnvFileMultiLineKeepsBlankLines(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, []byte("FOO<<EOF\nline1\n\nline2\nEOF\n"), 0o600)) require.NoError(t, os.WriteFile(envPath, []byte("FOO<<EOF\nline1\n\nline2\nEOF\n"), 0o600))
env := map[string]string{} env := map[string]string{}
require.NoError(t, parseEnvFile(e, envPath, &env)(context.Background())) require.NoError(t, parseEnvFile(e, envPath, &env)(t.Context()))
assert.Equal(t, "line1\n\nline2", env["FOO"]) assert.Equal(t, "line1\n\nline2", env["FOO"])
require.NoError(t, os.WriteFile(envPath, []byte("FOO<<EOF\n\nline2\nEOF\n"), 0o600)) require.NoError(t, os.WriteFile(envPath, []byte("FOO<<EOF\n\nline2\nEOF\n"), 0o600))
env = map[string]string{} env = map[string]string{}
require.NoError(t, parseEnvFile(e, envPath, &env)(context.Background())) require.NoError(t, parseEnvFile(e, envPath, &env)(t.Context()))
assert.Equal(t, "\nline2", env["FOO"]) assert.Equal(t, "\nline2", env["FOO"])
} }
@@ -99,7 +98,7 @@ func TestParseEnvFileUTF8BOM(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, content, 0o600)) require.NoError(t, os.WriteFile(envPath, content, 0o600))
env := map[string]string{} env := map[string]string{}
require.NoError(t, parseEnvFile(e, envPath, &env)(context.Background())) require.NoError(t, parseEnvFile(e, envPath, &env)(t.Context()))
assert.Equal(t, "bar", env["FOO"]) assert.Equal(t, "bar", env["FOO"])
} }
@@ -121,7 +120,7 @@ func TestParseEnvFileUTF16(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, content, 0o600)) require.NoError(t, os.WriteFile(envPath, content, 0o600))
env := map[string]string{} env := map[string]string{}
require.NoError(t, parseEnvFile(e, envPath, &env)(context.Background())) require.NoError(t, parseEnvFile(e, envPath, &env)(t.Context()))
assert.Equal(t, "bar", env["FOO"]) assert.Equal(t, "bar", env["FOO"])
assert.Equal(t, "line1", env["MULTI"]) assert.Equal(t, "line1", env["MULTI"])
}) })
@@ -133,7 +132,7 @@ func TestParseEnvFileMissingDelimiter(t *testing.T) {
require.NoError(t, os.WriteFile(envPath, []byte("FOO<<EOF\nline1\nline2\n"), 0o600)) require.NoError(t, os.WriteFile(envPath, []byte("FOO<<EOF\nline1\nline2\n"), 0o600))
env := map[string]string{} env := map[string]string{}
err := parseEnvFile(e, envPath, &env)(context.Background()) err := parseEnvFile(e, envPath, &env)(t.Context())
require.Error(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), "delimiter") assert.Contains(t, err.Error(), "delimiter")
} }
+4 -4
View File
@@ -105,7 +105,7 @@ func TestSetRef(t *testing.T) {
Event: table.event, Event: table.event,
} }
SetRef(context.Background(), ghc, "/some/dir") SetRef(t.Context(), ghc, "/some/dir")
ghc.SetRefTypeAndName() ghc.SetRefTypeAndName()
assert.Equal(t, table.ref, ghc.Ref) assert.Equal(t, table.ref, ghc.Ref)
@@ -123,7 +123,7 @@ func TestSetRef(t *testing.T) {
Event: map[string]any{}, Event: map[string]any{},
} }
SetRef(context.Background(), ghc, "/some/dir") SetRef(t.Context(), ghc, "/some/dir")
assert.Equal(t, "refs/heads/master", ghc.Ref) assert.Equal(t, "refs/heads/master", ghc.Ref)
}) })
@@ -210,14 +210,14 @@ func TestSetSha(t *testing.T) {
Event: table.event, Event: table.event,
} }
SetSha(context.Background(), ghc, "/some/dir") SetSha(t.Context(), ghc, "/some/dir")
assert.Equal(t, table.sha, ghc.Sha) assert.Equal(t, table.sha, ghc.Sha)
}) })
} }
t.Run("pinned checkout keeps the first sha and ref", func(t *testing.T) { t.Run("pinned checkout keeps the first sha and ref", func(t *testing.T) {
ctx := WithPinnedCheckout(context.Background()) ctx := WithPinnedCheckout(t.Context())
for _, head := range []string{"first", "moved"} { for _, head := range []string{"first", "moved"} {
findGitRevision = func(context.Context, string) (string, string, error) { return "", head, nil } findGitRevision = func(context.Context, string) (string, string, error) { return "", head, nil }
findGitRef = func(context.Context, string) (string, error) { return "refs/heads/" + head, nil } findGitRef = func(context.Context, string) (string, error) { return "refs/heads/" + head, nil }
+7 -7
View File
@@ -132,7 +132,7 @@ runs:
return nil return nil
} }
action, err := readActionImpl(context.Background(), tt.step, "actionDir", "actionPath", readFile, writeFile) action, err := readActionImpl(t.Context(), tt.step, "actionDir", "actionPath", readFile, writeFile)
assert.NoError(t, err) //nolint:testifylint // pre-existing issue from nektos/act assert.NoError(t, err) //nolint:testifylint // pre-existing issue from nektos/act
assert.Equal(t, tt.expected, action) assert.Equal(t, tt.expected, action)
@@ -225,7 +225,7 @@ func TestActionRunner(t *testing.T) {
for _, tt := range table { for _, tt := range table {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
cm.On("CopyDir", "/var/run/act/actions/dir/", "dir/", false, true).Return(func(ctx context.Context) error { return nil }) cm.On("CopyDir", "/var/run/act/actions/dir/", "dir/", false, true).Return(func(ctx context.Context) error { return nil })
@@ -290,7 +290,7 @@ func TestNewStepContainerDoesNotUseDockerSecrets(t *testing.T) {
ContainerNewContainer = origContainerNewContainer ContainerNewContainer = origContainerNewContainer
}() }()
ctx := context.Background() ctx := t.Context()
rc := &RunContext{ rc := &RunContext{
Name: "job", Name: "job",
Config: &Config{ Config: &Config{
@@ -327,7 +327,7 @@ func TestNewStepContainerDoesNotUseDockerSecrets(t *testing.T) {
} }
func TestMaybeCopyToActionDirHoldsCloneLock(t *testing.T) { func TestMaybeCopyToActionDirHoldsCloneLock(t *testing.T) {
ctx := context.Background() ctx := t.Context()
actionDir := t.TempDir() actionDir := t.TempDir()
@@ -447,7 +447,7 @@ func TestExecAsDockerHoldsCloneLockForRemoteUncached(t *testing.T) {
env: map[string]string{}, env: map[string]string{},
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
done := make(chan error, 1) done := make(chan error, 1)
@@ -619,7 +619,7 @@ func TestExecAsDockerStageEntrypoint(t *testing.T) {
cm.On("Start", true).Return(func(context.Context) error { return nil }) cm.On("Start", true).Return(func(context.Context) error { return nil })
cm.On("Close").Return(func(context.Context) error { return nil }) cm.On("Close").Return(func(context.Context) error { return nil })
require.NoError(t, execAsDocker(context.Background(), step, "action", t.TempDir(), t.TempDir(), false, tc.stage)) require.NoError(t, execAsDocker(t.Context(), step, "action", t.TempDir(), t.TempDir(), false, tc.stage))
require.NotNil(t, input) require.NotNil(t, input)
assert.Equal(t, tc.wantCmd, input.Cmd) assert.Equal(t, tc.wantCmd, input.Cmd)
assert.Equal(t, tc.wantEntrypoint, input.Entrypoint) assert.Equal(t, tc.wantEntrypoint, input.Entrypoint)
@@ -634,7 +634,7 @@ func TestDockerActionHasPreAndPostStep(t *testing.T) {
newStep := func(runs model.ActionRuns) actionStep { newStep := func(runs model.ActionRuns) actionStep {
return &stepActionRemote{action: &model.Action{Runs: runs}} return &stepActionRemote{action: &model.Action{Runs: runs}}
} }
ctx := context.Background() ctx := t.Context()
assert.False(t, hasPreStep(newStep(model.ActionRuns{Using: "docker", Image: "Dockerfile"}))(ctx)) assert.False(t, hasPreStep(newStep(model.ActionRuns{Using: "docker", Image: "Dockerfile"}))(ctx))
assert.False(t, hasPostStep(newStep(model.ActionRuns{Using: "docker", Image: "Dockerfile"}))(ctx)) assert.False(t, hasPostStep(newStep(model.ActionRuns{Using: "docker", Image: "Dockerfile"}))(ctx))
+11 -11
View File
@@ -62,7 +62,7 @@ func TestCancelledJobStatusEnablesAlwaysAndCancelledSteps(t *testing.T) {
enabled, err := interp.Evaluate("always()", exprparser.DefaultStatusCheckSuccess) enabled, err := interp.Evaluate("always()", exprparser.DefaultStatusCheckSuccess)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, true, enabled, "`if: always()` step must run on a cancelled job") assert.Equal(t, true, enabled, "`if: always()` step must run on a cancelled job")
setJobResult(context.Background(), rc, rc, true) setJobResult(t.Context(), rc, rc, true)
assert.Equal(t, "cancelled", rc.Run.Job().Result) assert.Equal(t, "cancelled", rc.Run.Job().Result)
} }
@@ -76,7 +76,7 @@ func TestMainStepsExecutorRunsAlwaysStepsAfterCancel(t *testing.T) {
"job1": createJob(t, `runs-on: ubuntu-latest`, ""), "job1": createJob(t, `runs-on: ubuntu-latest`, ""),
}) })
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
var ran []string var ran []string
@@ -110,7 +110,7 @@ func TestMainStepsExecutorMarksFailedOnTimeoutBetweenSteps(t *testing.T) {
"job1": createJob(t, `runs-on: ubuntu-latest`, ""), "job1": createJob(t, `runs-on: ubuntu-latest`, ""),
}) })
ctx := newControllableDeadlineContext(context.Background()) ctx := newControllableDeadlineContext(t.Context())
var ran []string var ran []string
var laterStepCtxErr error var laterStepCtxErr error
@@ -149,7 +149,7 @@ func TestStepsExecutorRunsMainStepsAfterPreCancel(t *testing.T) {
"job1": createJob(t, `runs-on: ubuntu-latest`, ""), "job1": createJob(t, `runs-on: ubuntu-latest`, ""),
}) })
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
var ran []string var ran []string
@@ -200,7 +200,7 @@ func TestStepsExecutorRunsMainStepsAfterPreFailure(t *testing.T) {
}, },
} }
err := newStepsExecutor(rc, preSteps, steps)(context.Background()) err := newStepsExecutor(rc, preSteps, steps)(t.Context())
require.ErrorIs(t, err, assert.AnError, "the pre-step error is propagated") require.ErrorIs(t, err, assert.AnError, "the pre-step error is propagated")
assert.Equal(t, []string{"pre1", "always-step"}, ran, "the main always() step runs after a pre-step failure") assert.Equal(t, []string{"pre1", "always-step"}, ran, "the main always() step runs after a pre-step failure")
@@ -215,7 +215,7 @@ func TestPreStepFailureAffectsMainStepIfStatus(t *testing.T) {
rc := createIfTestRunContext(map[string]*model.Job{ rc := createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, ""), "job1": createJob(t, `runs-on: ubuntu-latest`, ""),
}) })
ctx := common.WithJobErrorContainer(context.Background()) ctx := common.WithJobErrorContainer(t.Context())
reportStepError(ctx, rc, assert.AnError) reportStepError(ctx, rc, assert.AnError)
@@ -251,7 +251,7 @@ func TestPreStepFailureAffectsMainStepIfStatus(t *testing.T) {
// from cancellation (so the steps run) yet still carry a usable error container. // from cancellation (so the steps run) yet still carry a usable error container.
func TestPostStepsContextCancelledIsUsableForFailingStep(t *testing.T) { func TestPostStepsContextCancelledIsUsableForFailingStep(t *testing.T) {
jobSpan := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID{1}, SpanID: trace.SpanID{1}}) jobSpan := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID{1}, SpanID: trace.SpanID{1}})
cancelled, cancel := context.WithCancel(trace.ContextWithSpanContext(common.WithJobErrorContainer(context.Background()), jobSpan)) cancelled, cancel := context.WithCancel(trace.ContextWithSpanContext(common.WithJobErrorContainer(t.Context()), jobSpan))
cancel() cancel()
require.ErrorIs(t, cancelled.Err(), context.Canceled) require.ErrorIs(t, cancelled.Err(), context.Canceled)
@@ -273,7 +273,7 @@ func TestPostStepsContextCancelledIsUsableForFailingStep(t *testing.T) {
// job-error container (via context.WithoutCancel), so the timeout failure and any post-step error // job-error container (via context.WithoutCancel), so the timeout failure and any post-step error
// survive into the post phase and the job is still reported as failed. // survive into the post phase and the job is still reported as failed.
func TestPostStepsContextDeadlinePreservesJobError(t *testing.T) { func TestPostStepsContextDeadlinePreservesJobError(t *testing.T) {
base := common.WithJobErrorContainer(context.Background()) base := common.WithJobErrorContainer(t.Context())
common.SetJobError(base, assert.AnError) common.SetJobError(base, assert.AnError)
expired, cancel := context.WithDeadline(base, time.Now().Add(-time.Hour)) expired, cancel := context.WithDeadline(base, time.Now().Add(-time.Hour))
defer cancel() defer cancel()
@@ -292,14 +292,14 @@ func TestReportStepErrorTreatsCancelAsInterruption(t *testing.T) {
rc := &RunContext{} rc := &RunContext{}
// stray read cancellation while the job context is live: ignored, not a failure // stray read cancellation while the job context is live: ignored, not a failure
live := common.WithJobErrorContainer(context.Background()) live := common.WithJobErrorContainer(t.Context())
reportStepError(live, rc, context.Canceled) reportStepError(live, rc, context.Canceled)
require.NoError(t, common.JobError(live)) require.NoError(t, common.JobError(live))
assert.False(t, rc.jobFailed) assert.False(t, rc.jobFailed)
assert.False(t, rc.jobCancelled) assert.False(t, rc.jobCancelled)
// genuine job cancellation: recorded as cancelled, still not a failure // genuine job cancellation: recorded as cancelled, still not a failure
cancelled, cancel := context.WithCancel(common.WithJobErrorContainer(context.Background())) cancelled, cancel := context.WithCancel(common.WithJobErrorContainer(t.Context()))
cancel() cancel()
reportStepError(cancelled, rc, context.Canceled) reportStepError(cancelled, rc, context.Canceled)
require.NoError(t, common.JobError(cancelled)) require.NoError(t, common.JobError(cancelled))
@@ -307,7 +307,7 @@ func TestReportStepErrorTreatsCancelAsInterruption(t *testing.T) {
assert.True(t, rc.jobCancelled) assert.True(t, rc.jobCancelled)
// a real error still fails the job // a real error still fails the job
failed := common.WithJobErrorContainer(context.Background()) failed := common.WithJobErrorContainer(t.Context())
reportStepError(failed, rc, assert.AnError) reportStepError(failed, rc, assert.AnError)
require.ErrorIs(t, common.JobError(failed), assert.AnError) require.ErrorIs(t, common.JobError(failed), assert.AnError)
assert.True(t, rc.jobFailed) assert.True(t, rc.jobFailed)
+11 -12
View File
@@ -6,7 +6,6 @@ package runner
import ( import (
"bytes" "bytes"
"context"
"io" "io"
"os" "os"
"testing" "testing"
@@ -27,7 +26,7 @@ func unsecureRC() *RunContext {
func TestSetEnv(t *testing.T) { func TestSetEnv(t *testing.T) {
a := assert.New(t) a := assert.New(t)
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
ctx := common.WithLogger(context.Background(), logger) ctx := common.WithLogger(t.Context(), logger)
rc := unsecureRC() rc := unsecureRC()
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
@@ -45,7 +44,7 @@ func TestSetEnv(t *testing.T) {
func TestStopCommandsKeepsSuppressedLinesInLog(t *testing.T) { func TestStopCommandsKeepsSuppressedLinesInLog(t *testing.T) {
a := assert.New(t) a := assert.New(t)
ctx := context.Background() ctx := t.Context()
rc := unsecureRC() rc := unsecureRC()
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
@@ -68,7 +67,7 @@ func TestStopCommandsKeepsSuppressedLinesInLog(t *testing.T) {
func TestSetOutput(t *testing.T) { func TestSetOutput(t *testing.T) {
a := assert.New(t) a := assert.New(t)
ctx := context.Background() ctx := t.Context()
rc := new(RunContext) rc := new(RunContext)
rc.StepResults = make(map[string]*model.StepResult) rc.StepResults = make(map[string]*model.StepResult)
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
@@ -108,7 +107,7 @@ func TestSetOutput(t *testing.T) {
func TestAddpath(t *testing.T) { func TestAddpath(t *testing.T) {
a := assert.New(t) a := assert.New(t)
ctx := context.Background() ctx := t.Context()
rc := unsecureRC() rc := unsecureRC()
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
@@ -123,7 +122,7 @@ func TestStopCommands(t *testing.T) {
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
a := assert.New(t) a := assert.New(t)
ctx := common.WithLogger(context.Background(), logger) ctx := common.WithLogger(t.Context(), logger)
rc := unsecureRC() rc := unsecureRC()
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
@@ -149,7 +148,7 @@ func TestStopCommands(t *testing.T) {
func TestStopCommandsResumesOnCommandNamedToken(t *testing.T) { func TestStopCommandsResumesOnCommandNamedToken(t *testing.T) {
a := assert.New(t) a := assert.New(t)
rc := unsecureRC() rc := unsecureRC()
handler := rc.commandHandler(context.Background()) handler := rc.commandHandler(t.Context())
handler("::stop-commands::add-mask\n") handler("::stop-commands::add-mask\n")
handler("::set-env name=x::suppressed\n") handler("::set-env name=x::suppressed\n")
@@ -162,7 +161,7 @@ func TestStopCommandsResumesOnCommandNamedToken(t *testing.T) {
func TestAddpathADO(t *testing.T) { func TestAddpathADO(t *testing.T) {
a := assert.New(t) a := assert.New(t)
ctx := context.Background() ctx := t.Context()
rc := unsecureRC() rc := unsecureRC()
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
@@ -177,7 +176,7 @@ func TestAddmask(t *testing.T) {
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
a := assert.New(t) a := assert.New(t)
ctx := context.Background() ctx := t.Context()
loggerCtx := common.WithLogger(ctx, logger) loggerCtx := common.WithLogger(ctx, logger)
rc := new(RunContext) rc := new(RunContext)
@@ -231,7 +230,7 @@ func TestAddmaskUsemask(t *testing.T) {
} }
re := captureOutput(t, func() { re := captureOutput(t, func() {
ctx := context.Background() ctx := t.Context()
ctx = WithJobLogger(ctx, "0", "testjob", config, &rc.Masks, map[string]any{}) ctx = WithJobLogger(ctx, "0", "testjob", config, &rc.Masks, map[string]any{})
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
@@ -248,7 +247,7 @@ func TestSaveState(t *testing.T) {
StepResults: map[string]*model.StepResult{}, StepResults: map[string]*model.StepResult{},
} }
ctx := context.Background() ctx := t.Context()
handler := rc.commandHandler(ctx) handler := rc.commandHandler(ctx)
handler("::save-state name=state-name::state-value\n") handler("::save-state name=state-name::state-value\n")
@@ -281,7 +280,7 @@ func TestUnsecureCommands(t *testing.T) {
a := assert.New(t) a := assert.New(t)
rc := &RunContext{Env: tt.jobEnv} rc := &RunContext{Env: tt.jobEnv}
rc.setCurrentStepEnv(tt.stepEnv) rc.setCurrentStepEnv(tt.stepEnv)
handler := rc.commandHandler(context.Background()) handler := rc.commandHandler(t.Context())
handler("::set-env name=x::valz\n") handler("::set-env name=x::valz\n")
handler("::add-path::/opt/bin\n") handler("::add-path::/opt/bin\n")
+7 -8
View File
@@ -5,7 +5,6 @@
package runner package runner
import ( import (
"context"
"strings" "strings"
"testing" "testing"
@@ -82,7 +81,7 @@ func createRunContext(t *testing.T) *RunContext {
func TestEvaluateRunContext(t *testing.T) { func TestEvaluateRunContext(t *testing.T) {
rc := createRunContext(t) rc := createRunContext(t)
ee := rc.NewExpressionEvaluator(context.Background()) ee := rc.NewExpressionEvaluator(t.Context())
tables := []struct { tables := []struct {
in string in string
@@ -142,7 +141,7 @@ func TestEvaluateRunContext(t *testing.T) {
for _, table := range tables { for _, table := range tables {
t.Run(table.in, func(t *testing.T) { t.Run(table.in, func(t *testing.T) {
assertObject := assert.New(t) assertObject := assert.New(t)
out, err := ee.evaluate(context.Background(), table.in, exprparser.DefaultStatusCheckNone) out, err := ee.evaluate(t.Context(), table.in, exprparser.DefaultStatusCheckNone)
if table.errMesg == "" { if table.errMesg == "" {
assertObject.NoError(err, table.in) //nolint:testifylint // pre-existing issue from nektos/act assertObject.NoError(err, table.in) //nolint:testifylint // pre-existing issue from nektos/act
assertObject.Equal(table.out, out, table.in) assertObject.Equal(table.out, out, table.in)
@@ -162,7 +161,7 @@ func TestEvaluateStep(t *testing.T) {
env: map[string]string{"INPUT_FORGED": "leaked"}, env: map[string]string{"INPUT_FORGED": "leaked"},
} }
ee := rc.NewStepExpressionEvaluator(context.Background(), step) ee := rc.NewStepExpressionEvaluator(t.Context(), step)
tables := []struct { tables := []struct {
in string in string
@@ -184,7 +183,7 @@ func TestEvaluateStep(t *testing.T) {
for _, table := range tables { for _, table := range tables {
t.Run(table.in, func(t *testing.T) { t.Run(table.in, func(t *testing.T) {
assertObject := assert.New(t) assertObject := assert.New(t)
out, err := ee.evaluate(context.Background(), table.in, exprparser.DefaultStatusCheckNone) out, err := ee.evaluate(t.Context(), table.in, exprparser.DefaultStatusCheckNone)
if table.errMesg == "" { if table.errMesg == "" {
assertObject.NoError(err, table.in) //nolint:testifylint // pre-existing issue from nektos/act assertObject.NoError(err, table.in) //nolint:testifylint // pre-existing issue from nektos/act
assertObject.Equal(table.out, out, table.in) assertObject.Equal(table.out, out, table.in)
@@ -224,7 +223,7 @@ func TestInterpolate(t *testing.T) {
}, },
}, },
} }
ee := rc.NewExpressionEvaluator(context.Background()) ee := rc.NewExpressionEvaluator(t.Context())
tables := []struct { tables := []struct {
in string in string
out string out string
@@ -270,14 +269,14 @@ func TestInterpolate(t *testing.T) {
for _, table := range tables { for _, table := range tables {
t.Run("interpolate", func(t *testing.T) { t.Run("interpolate", func(t *testing.T) {
out, err := ee.Interpolate(context.Background(), table.in) out, err := ee.Interpolate(t.Context(), table.in)
require.NoError(t, err, table.in) require.NoError(t, err, table.in)
assert.Equal(t, table.out, out, table.in) assert.Equal(t, table.out, out, table.in)
}) })
} }
for _, in := range []string{"${{ 1) && (2 }}", "run ${{ 1) && (2 }} now", "${{ 1"} { for _, in := range []string{"${{ 1) && (2 }}", "run ${{ 1) && (2 }} now", "${{ 1"} {
_, err := ee.Interpolate(context.Background(), in) _, err := ee.Interpolate(t.Context(), in)
assert.Error(t, err, in) assert.Error(t, err, in)
} }
} }
+1 -2
View File
@@ -4,7 +4,6 @@
package runner package runner
import ( import (
"context"
"os" "os"
"os/exec" "os/exec"
"runtime" "runtime"
@@ -30,7 +29,7 @@ func requireLinuxDocker(t *testing.T) {
// so the daemon has to be pinged explicitly here to decide whether to skip. // so the daemon has to be pinged explicitly here to decide whether to skip.
func requireDocker(t *testing.T) { func requireDocker(t *testing.T) {
t.Helper() t.Helper()
ctx := context.Background() ctx := t.Context()
cli, err := container.GetDockerClient(ctx) cli, err := container.GetDockerClient(ctx)
if err != nil { if err != nil {
t.Skipf("skipping: docker client unavailable: %v", err) t.Skipf("skipping: docker client unavailable: %v", err)
+21 -21
View File
@@ -44,7 +44,7 @@ func TestJobExecutor(t *testing.T) {
{workdir, "job-nil-step", "push", "invalid Step 0: missing run or uses key", platforms, secrets}, {workdir, "job-nil-step", "push", "invalid Step 0: missing run or uses key", platforms, secrets},
} }
// These tests are sufficient to only check syntax. // These tests are sufficient to only check syntax.
ctx := common.WithDryrun(context.Background(), true) ctx := common.WithDryrun(t.Context(), true)
for _, table := range tables { for _, table := range tables {
t.Run(table.workflowPath, func(t *testing.T) { t.Run(table.workflowPath, func(t *testing.T) {
t.Parallel() t.Parallel()
@@ -137,7 +137,7 @@ func (apm *actionPreparerMock) actionDownloadInfo() (string, string, bool) {
func TestPrintPrepareActionsGolden(t *testing.T) { func TestPrintPrepareActionsGolden(t *testing.T) {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo)) logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo))
ctx := common.WithLogger(context.Background(), logger.With("job", "j1")) ctx := common.WithLogger(t.Context(), logger.With("job", "j1"))
preparers := []actionPreparer{ preparers := []actionPreparer{
&actionPreparerMock{reference: "actions/checkout@v7", sha: "9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0", ok: true}, &actionPreparerMock{reference: "actions/checkout@v7", sha: "9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0", ok: true},
@@ -160,7 +160,7 @@ func TestPrintPrepareActionsGolden(t *testing.T) {
func TestPrintPrepareActionsSkipsWithoutActions(t *testing.T) { func TestPrintPrepareActionsSkipsWithoutActions(t *testing.T) {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo)) logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo))
ctx := common.WithLogger(context.Background(), logger.With("job", "j1")) ctx := common.WithLogger(t.Context(), logger.With("job", "j1"))
require.NoError(t, printPrepareActions(&RunContext{}, nil)(ctx)) require.NoError(t, printPrepareActions(&RunContext{}, nil)(ctx))
@@ -169,7 +169,7 @@ func TestPrintPrepareActionsSkipsWithoutActions(t *testing.T) {
func TestPrintPrepareActionsFailsJobOnDownloadError(t *testing.T) { func TestPrintPrepareActionsFailsJobOnDownloadError(t *testing.T) {
logger := logging.New(logtest.New()) logger := logging.New(logtest.New())
ctx := common.WithJobErrorContainer(common.WithLogger(context.Background(), logger.With("job", "j1"))) ctx := common.WithJobErrorContainer(common.WithLogger(t.Context(), logger.With("job", "j1")))
downloadErr := errors.New("failed to fetch \"actions/checkout\"") downloadErr := errors.New("failed to fetch \"actions/checkout\"")
rc := &RunContext{} rc := &RunContext{}
@@ -220,7 +220,7 @@ func TestPrintCompleteJobName(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo)) logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo))
ctx := common.WithLogger(context.Background(), logger.With("job", "j1")) ctx := common.WithLogger(t.Context(), logger.With("job", "j1"))
require.NoError(t, printCompleteJobName(tt.rc)(ctx)) require.NoError(t, printCompleteJobName(tt.rc)(ctx))
@@ -239,7 +239,7 @@ type actionStepMock struct {
// every action is downloaded before any step runs, and the job name closes the section. A pre // every action is downloaded before any step runs, and the job name closes the section. A pre
// step that downloaded its own action would leave the log interleaved with the downloads. // step that downloaded its own action would leave the log interleaved with the downloads.
func TestNewJobExecutorDownloadsAllActionsBeforeTheFirstStep(t *testing.T) { func TestNewJobExecutorDownloadsAllActionsBeforeTheFirstStep(t *testing.T) {
ctx := common.WithJobErrorContainer(context.Background()) ctx := common.WithJobErrorContainer(t.Context())
jim := &jobInfoMock{} jim := &jobInfoMock{}
sfm := &stepFactoryMock{} sfm := &stepFactoryMock{}
rc := &RunContext{ rc := &RunContext{
@@ -484,7 +484,7 @@ func TestNewJobExecutor(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
fmt.Printf("::group::%s\n", tt.name) //nolint:forbidigo // pre-existing issue from nektos/act fmt.Printf("::group::%s\n", tt.name) //nolint:forbidigo // pre-existing issue from nektos/act
ctx, cancel := context.WithCancel(common.WithJobErrorContainer(context.Background())) ctx, cancel := context.WithCancel(common.WithJobErrorContainer(t.Context()))
defer cancel() defer cancel()
jim := &jobInfoMock{} jim := &jobInfoMock{}
sfm := &stepFactoryMock{} sfm := &stepFactoryMock{}
@@ -632,7 +632,7 @@ func (ctx *controllableDeadlineContext) expire() {
// still run against a fresh, non-expired context, and the job must still be // still run against a fresh, non-expired context, and the job must still be
// reported as failed. // reported as failed.
func TestNewJobExecutorRunsPostStepsAfterTimeout(t *testing.T) { func TestNewJobExecutorRunsPostStepsAfterTimeout(t *testing.T) {
ctx := newControllableDeadlineContext(common.WithJobErrorContainer(context.Background())) ctx := newControllableDeadlineContext(common.WithJobErrorContainer(t.Context()))
jim := &jobInfoMock{} jim := &jobInfoMock{}
sfm := &stepFactoryMock{} sfm := &stepFactoryMock{}
@@ -713,7 +713,7 @@ func TestSetJobResultMatrixContinueOnError(t *testing.T) {
return &model.Plan{Stages: []*model.Stage{{Runs: []*model.Run{{Workflow: wf, JobID: "job1"}}}}} return &model.Plan{Stages: []*model.Stage{{Runs: []*model.Run{{Workflow: wf, JobID: "job1"}}}}}
} }
ctx := context.Background() ctx := t.Context()
// fail drives a single matrix combination through the failure path; each // fail drives a single matrix combination through the failure path; each
// RunContext is its own jobInfo (rc implements jobInfo) and shares the job. // RunContext is its own jobInfo (rc implements jobInfo) and shares the job.
@@ -808,7 +808,7 @@ func TestTryUploadJobSummaryRetriesTransientFailure(t *testing.T) {
})) }))
defer server.Close() defer server.Close()
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
cm.On("GetContainerArchive", mock.Anything, "/var/run/act/workflow/step-summary-0.md").Return( cm.On("GetContainerArchive", mock.Anything, "/var/run/act/workflow/step-summary-0.md").Return(
io.NopCloser(bytes.NewReader(tarArchive(t, tarEntry{name: "step-summary-0.md", body: "# summary"}))), io.NopCloser(bytes.NewReader(tarArchive(t, tarEntry{name: "step-summary-0.md", body: "# summary"}))),
@@ -852,7 +852,7 @@ func TestTryUploadJobSummaryStopsAtPhaseTimeout(t *testing.T) {
defer server.Close() defer server.Close()
defer close(release) defer close(release)
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
cm.On("GetContainerArchive", mock.Anything, "/var/run/act/workflow/step-summary-0.md").Return( cm.On("GetContainerArchive", mock.Anything, "/var/run/act/workflow/step-summary-0.md").Return(
io.NopCloser(bytes.NewReader(tarArchive(t, tarEntry{name: "step-summary-0.md", body: "# summary"}))), io.NopCloser(bytes.NewReader(tarArchive(t, tarEntry{name: "step-summary-0.md", body: "# summary"}))),
@@ -896,7 +896,7 @@ func TestTryUploadJobSummaryUploadsEachStepIndependentlyWithInstanceTransport(t
})) }))
defer server.Close() defer server.Close()
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
// Three steps: 0 has content, 1 has empty content (skipped), 2 has content. // Three steps: 0 has content, 1 has empty content (skipped), 2 has content.
cm.On("GetContainerArchive", mock.Anything, "/var/run/act/workflow/step-summary-0.md").Return( cm.On("GetContainerArchive", mock.Anything, "/var/run/act/workflow/step-summary-0.md").Return(
@@ -944,7 +944,7 @@ func TestTryUploadJobSummaryRequiresExactCapability(t *testing.T) {
"GITEA_RUN_ID": "12", "GITEA_RUN_ID": "12",
}, &containerMock{}, 1) }, &containerMock{}, 1)
tryUploadJobSummary(context.Background(), rc) tryUploadJobSummary(t.Context(), rc)
assert.Equal(t, 0, requests) assert.Equal(t, 0, requests)
} }
@@ -964,7 +964,7 @@ func TestTryUploadJobSummarySkipsWhenJobIDMissingFromToken(t *testing.T) {
"GITEA_RUN_ID": "12", "GITEA_RUN_ID": "12",
}, &containerMock{}, 1) }, &containerMock{}, 1)
tryUploadJobSummary(context.Background(), rc) tryUploadJobSummary(t.Context(), rc)
assert.Equal(t, 0, requests) assert.Equal(t, 0, requests)
} }
@@ -977,7 +977,7 @@ func TestExtractJobIDFromRuntimeToken(t *testing.T) {
} }
func TestReadSingleFileFromContainerArchiveFindsMatchingRegularFile(t *testing.T) { func TestReadSingleFileFromContainerArchiveFindsMatchingRegularFile(t *testing.T) {
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
cm.On("GetContainerArchive", ctx, "/var/run/act/workflow/SUMMARY.md").Return( cm.On("GetContainerArchive", ctx, "/var/run/act/workflow/SUMMARY.md").Return(
io.NopCloser(bytes.NewReader(tarArchive(t, io.NopCloser(bytes.NewReader(tarArchive(t,
@@ -997,7 +997,7 @@ func TestReadSingleFileFromContainerArchiveFindsMatchingRegularFile(t *testing.T
func TestReadSingleFileFromContainerArchiveTruncatesWhenTooLarge(t *testing.T) { func TestReadSingleFileFromContainerArchiveTruncatesWhenTooLarge(t *testing.T) {
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
ctx := common.WithLogger(context.Background(), logger) ctx := common.WithLogger(t.Context(), logger)
cm := &containerMock{} cm := &containerMock{}
content := strings.Repeat("a", 300) content := strings.Repeat("a", 300)
cm.On("GetContainerArchive", ctx, "/var/run/act/workflow/SUMMARY.md").Return( cm.On("GetContainerArchive", ctx, "/var/run/act/workflow/SUMMARY.md").Return(
@@ -1022,7 +1022,7 @@ func TestReadSingleFileFromContainerArchiveTruncatesWhenTooLarge(t *testing.T) {
func TestReadSingleFileFromContainerArchiveKeepsExactLimitWithoutWarning(t *testing.T) { func TestReadSingleFileFromContainerArchiveKeepsExactLimitWithoutWarning(t *testing.T) {
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
ctx := common.WithLogger(context.Background(), logger) ctx := common.WithLogger(t.Context(), logger)
cm := &containerMock{} cm := &containerMock{}
cm.On("GetContainerArchive", ctx, "/var/run/act/workflow/SUMMARY.md").Return( cm.On("GetContainerArchive", ctx, "/var/run/act/workflow/SUMMARY.md").Return(
io.NopCloser(bytes.NewReader(tarArchive(t, tarEntry{name: "SUMMARY.md", body: "abc"}))), io.NopCloser(bytes.NewReader(tarArchive(t, tarEntry{name: "SUMMARY.md", body: "abc"}))),
@@ -1092,7 +1092,7 @@ func makeTestRC(t *testing.T, jobYAML string) *RunContext {
Name: "workflow1", Name: "workflow1",
Jobs: map[string]*model.Job{"job1": job}, Jobs: map[string]*model.Job{"job1": job},
}, nil) }, nil)
rc.ExprEval = rc.NewExpressionEvaluator(context.Background()) rc.ExprEval = rc.NewExpressionEvaluator(t.Context())
return rc return rc
} }
@@ -1110,7 +1110,7 @@ func TestApplyJobTimeout(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
rc := makeTestRC(t, tc.yaml) rc := makeTestRC(t, tc.yaml)
ctx := context.Background() ctx := t.Context()
newCtx, cancel := applyJobTimeout(ctx, rc, rc.Run.Job()) newCtx, cancel := applyJobTimeout(ctx, rc, rc.Run.Job())
defer cancel() defer cancel()
_, hasDeadline := newCtx.Deadline() _, hasDeadline := newCtx.Deadline()
@@ -1134,7 +1134,7 @@ func TestEvaluateJobContinueOnError(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
rc := makeTestRC(t, tc.yaml) rc := makeTestRC(t, tc.yaml)
got := evaluateJobContinueOnError(context.Background(), rc, rc.Run.Job()) got := evaluateJobContinueOnError(t.Context(), rc, rc.Run.Job())
assert.Equal(t, tc.want, got) assert.Equal(t, tc.want, got)
}) })
} }
@@ -1199,7 +1199,7 @@ func TestTryUploadJobSummaryMasksSecrets(t *testing.T) {
rc.Config.ExtraMasks = []string{"pr0xypw"} rc.Config.ExtraMasks = []string{"pr0xypw"}
rc.Masks = []string{"runtime-added"} rc.Masks = []string{"runtime-added"}
tryUploadJobSummary(context.Background(), rc) tryUploadJobSummary(t.Context(), rc)
assert.Equal(t, "deployed true with *** and *** via ***", got) assert.Equal(t, "deployed true with *** and *** via ***", got)
cm.AssertExpectations(t) cm.AssertExpectations(t)
+2 -2
View File
@@ -63,7 +63,7 @@ func TestReusableWorkflowCachedBranchRefRefreshes(t *testing.T) {
} }
cacheDir := t.TempDir() cacheDir := t.TempDir()
require.NoError(t, cloneRemoteReusableWorkflow(rc, remoteDir, "master", cacheDir)(context.Background())) require.NoError(t, cloneRemoteReusableWorkflow(rc, remoteDir, "master", cacheDir)(t.Context()))
got, err := os.ReadFile(filepath.Join(cacheDir, workflowPath)) got, err := os.ReadFile(filepath.Join(cacheDir, workflowPath))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, tmpl("v1"), string(got)) require.Equal(t, tmpl("v1"), string(got))
@@ -73,7 +73,7 @@ func TestReusableWorkflowCachedBranchRefRefreshes(t *testing.T) {
gitMust(t, workDir, "commit", "-am", "v2") gitMust(t, workDir, "commit", "-am", "v2")
gitMust(t, workDir, "push", "origin", "master") gitMust(t, workDir, "push", "origin", "master")
require.NoError(t, cloneRemoteReusableWorkflow(rc, remoteDir, "master", cacheDir)(context.Background())) require.NoError(t, cloneRemoteReusableWorkflow(rc, remoteDir, "master", cacheDir)(t.Context()))
got, err = os.ReadFile(filepath.Join(cacheDir, workflowPath)) got, err = os.ReadFile(filepath.Join(cacheDir, workflowPath))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, tmpl("v2"), string(got), "cached workflow file must reflect the updated branch tip") require.Equal(t, tmpl("v2"), string(got), "cached workflow file must reflect the updated branch tip")
+48 -48
View File
@@ -83,7 +83,7 @@ func TestRunContext_EvalBool(t *testing.T) {
}, },
}, },
} }
rc.ExprEval = rc.NewExpressionEvaluator(context.Background()) rc.ExprEval = rc.NewExpressionEvaluator(t.Context())
tables := []struct { tables := []struct {
in string in string
@@ -176,7 +176,7 @@ func TestRunContext_EvalBool(t *testing.T) {
for _, table := range tables { for _, table := range tables {
t.Run(table.in, func(t *testing.T) { t.Run(table.in, func(t *testing.T) {
assertObject := assert.New(t) assertObject := assert.New(t)
b, err := EvalBool(context.Background(), rc.ExprEval, table.in, exprparser.DefaultStatusCheckSuccess) b, err := EvalBool(t.Context(), rc.ExprEval, table.in, exprparser.DefaultStatusCheckSuccess)
if table.wantErr { if table.wantErr {
assertObject.Error(err) //nolint:testifylint // pre-existing issue from nektos/act assertObject.Error(err) //nolint:testifylint // pre-existing issue from nektos/act
} }
@@ -563,8 +563,8 @@ func TestRunContext_GetBindsAndMounts(t *testing.T) {
} }
rc.Run.JobID = "job1" rc.Run.JobID = "job1"
rc.Run.Workflow.Jobs = map[string]*model.Job{"job1": job} rc.Run.Workflow.Jobs = map[string]*model.Job{"job1": job}
rc.ExprEval = rc.NewExpressionEvaluator(context.Background()) rc.ExprEval = rc.NewExpressionEvaluator(t.Context())
require.NoError(t, rc.resolvePlatformImage(context.Background())) require.NoError(t, rc.resolvePlatformImage(t.Context()))
gotbind, gotmount := rc.GetBindsAndMounts(t.Context()) gotbind, gotmount := rc.GetBindsAndMounts(t.Context())
assert.Contains(t, gotbind, "/host/mame/roms:/root/.mame/roms:ro") assert.Contains(t, gotbind, "/host/mame/roms:/root/.mame/roms:ro")
@@ -864,7 +864,7 @@ func TestInterpolateOutputsIsPerMatrixComboKeepingNeedsOutputs(t *testing.T) {
needed := &model.Job{Outputs: map[string]string{"o": "from-gitea"}} needed := &model.Job{Outputs: map[string]string{"o": "from-gitea"}}
run := &model.Run{JobID: "j", Workflow: &model.Workflow{Name: "w", Jobs: map[string]*model.Job{"j": job, "needed": needed}}} run := &model.Run{JobID: "j", Workflow: &model.Workflow{Name: "w", Jobs: map[string]*model.Job{"j": job, "needed": needed}}}
r := &runnerImpl{config: &Config{}} r := &runnerImpl{config: &Config{}}
ctx := context.Background() ctx := t.Context()
_, err := r.newRunContext(ctx, &model.Run{JobID: "needed", Workflow: run.Workflow}, nil) _, err := r.newRunContext(ctx, &model.Run{JobID: "needed", Workflow: run.Workflow}, nil)
require.NoError(t, err) require.NoError(t, err)
@@ -927,7 +927,7 @@ func TestGetGitHubContext(t *testing.T) {
} }
rc.Run.JobID = "job1" rc.Run.JobID = "job1"
ghc := rc.getGithubContext(context.Background()) ghc := rc.getGithubContext(t.Context())
logging.Debugf("%v", ghc) logging.Debugf("%v", ghc)
@@ -957,7 +957,7 @@ func TestGetGitHubContext(t *testing.T) {
assert.Equal(t, ghc.Job, "job1") //nolint:testifylint // pre-existing issue from nektos/act assert.Equal(t, ghc.Job, "job1") //nolint:testifylint // pre-existing issue from nektos/act
rc.Config.PresetGitHubContext = &model.GithubContext{Actor: "preset-actor", TriggeringActor: "triggerer", Job: "preset-job"} rc.Config.PresetGitHubContext = &model.GithubContext{Actor: "preset-actor", TriggeringActor: "triggerer", Job: "preset-job"}
ghc = rc.getGithubContext(context.Background()) ghc = rc.getGithubContext(t.Context())
assert.Equal(t, "preset-actor", ghc.Actor) assert.Equal(t, "preset-actor", ghc.Actor)
assert.Equal(t, "triggerer", ghc.TriggeringActor) assert.Equal(t, "triggerer", ghc.TriggeringActor)
assert.Equal(t, "job1", ghc.Job) assert.Equal(t, "job1", ghc.Job)
@@ -1027,7 +1027,7 @@ func TestGetGithubContextRef(t *testing.T) {
}, },
} }
ghc := rc.getGithubContext(context.Background()) ghc := rc.getGithubContext(t.Context())
assert.Equal(t, data.ref, ghc.Ref) assert.Equal(t, data.ref, ghc.Ref)
}) })
@@ -1066,44 +1066,44 @@ func TestRunContextRunsOnPlatformNames(t *testing.T) {
rc := createIfTestRunContext(map[string]*model.Job{ rc := createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, ""), "job1": createJob(t, `runs-on: ubuntu-latest`, ""),
}) })
assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(context.Background())) assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ${{ 'ubuntu-latest' }}`, ""), "job1": createJob(t, `runs-on: ${{ 'ubuntu-latest' }}`, ""),
}) })
assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(context.Background())) assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: [self-hosted, my-runner]`, ""), "job1": createJob(t, `runs-on: [self-hosted, my-runner]`, ""),
}) })
assertObject.Equal([]string{"self-hosted", "my-runner"}, rc.runsOnPlatformNames(context.Background())) assertObject.Equal([]string{"self-hosted", "my-runner"}, rc.runsOnPlatformNames(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: [self-hosted, "${{ 'my-runner' }}"]`, ""), "job1": createJob(t, `runs-on: [self-hosted, "${{ 'my-runner' }}"]`, ""),
}) })
assertObject.Equal([]string{"self-hosted", "my-runner"}, rc.runsOnPlatformNames(context.Background())) assertObject.Equal([]string{"self-hosted", "my-runner"}, rc.runsOnPlatformNames(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ${{ fromJSON('["ubuntu-latest"]') }}`, ""), "job1": createJob(t, `runs-on: ${{ fromJSON('["ubuntu-latest"]') }}`, ""),
}) })
assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(context.Background())) assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(t.Context()))
// test missing / invalid runs-on // test missing / invalid runs-on
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `name: something`, ""), "job1": createJob(t, `name: something`, ""),
}) })
assertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background())) assertObject.Equal([]string{}, rc.runsOnPlatformNames(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: "job1": createJob(t, `runs-on:
mapping: value`, ""), mapping: value`, ""),
}) })
assertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background())) assertObject.Equal([]string{}, rc.runsOnPlatformNames(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ${{ invalid expression }}`, ""), "job1": createJob(t, `runs-on: ${{ invalid expression }}`, ""),
}) })
assertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background())) assertObject.Equal([]string{}, rc.runsOnPlatformNames(t.Context()))
} }
func TestRunContextIsEnabled(t *testing.T) { func TestRunContextIsEnabled(t *testing.T) {
@@ -1117,8 +1117,8 @@ env:
BROKEN: ${{ fromJSON('invalid') }} BROKEN: ${{ fromJSON('invalid') }}
if: success()`, ""), if: success()`, ""),
}) })
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
require.Error(t, evaluateJobEnvAndDefaults(context.Background(), rc)) require.Error(t, evaluateJobEnvAndDefaults(t.Context(), rc))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "failure"), "job1": createJob(t, `runs-on: ubuntu-latest`, "failure"),
@@ -1127,7 +1127,7 @@ needs: [job1]
if: success()`, ""), if: success()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.False(rc.isEnabled(context.Background())) assertObject.False(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "success"), "job1": createJob(t, `runs-on: ubuntu-latest`, "success"),
@@ -1136,7 +1136,7 @@ needs: [job1]
if: success()`, ""), if: success()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "failure"), "job1": createJob(t, `runs-on: ubuntu-latest`, "failure"),
@@ -1144,14 +1144,14 @@ if: success()`, ""),
if: success()`, ""), if: success()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
// failure() // failure()
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest "job1": createJob(t, `runs-on: ubuntu-latest
if: failure()`, ""), if: failure()`, ""),
}) })
assertObject.False(rc.isEnabled(context.Background())) assertObject.False(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "failure"), "job1": createJob(t, `runs-on: ubuntu-latest`, "failure"),
@@ -1160,7 +1160,7 @@ needs: [job1]
if: failure()`, ""), if: failure()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "success"), "job1": createJob(t, `runs-on: ubuntu-latest`, "success"),
@@ -1169,7 +1169,7 @@ needs: [job1]
if: failure()`, ""), if: failure()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.False(rc.isEnabled(context.Background())) assertObject.False(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "failure"), "job1": createJob(t, `runs-on: ubuntu-latest`, "failure"),
@@ -1177,14 +1177,14 @@ if: failure()`, ""),
if: failure()`, ""), if: failure()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.False(rc.isEnabled(context.Background())) assertObject.False(rc.isEnabled(t.Context()))
// always() // always()
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest "job1": createJob(t, `runs-on: ubuntu-latest
if: always()`, ""), if: always()`, ""),
}) })
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "failure"), "job1": createJob(t, `runs-on: ubuntu-latest`, "failure"),
@@ -1193,7 +1193,7 @@ needs: [job1]
if: always()`, ""), if: always()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "success"), "job1": createJob(t, `runs-on: ubuntu-latest`, "success"),
@@ -1202,7 +1202,7 @@ needs: [job1]
if: always()`, ""), if: always()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `runs-on: ubuntu-latest`, "success"), "job1": createJob(t, `runs-on: ubuntu-latest`, "success"),
@@ -1210,23 +1210,23 @@ if: always()`, ""),
if: always()`, ""), if: always()`, ""),
}) })
rc.Run.JobID = "job2" rc.Run.JobID = "job2"
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `uses: ./.github/workflows/reusable.yml`, ""), "job1": createJob(t, `uses: ./.github/workflows/reusable.yml`, ""),
}) })
assertObject.True(rc.isEnabled(context.Background())) assertObject.True(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `uses: ./.github/workflows/reusable.yml "job1": createJob(t, `uses: ./.github/workflows/reusable.yml
if: false`, ""), if: false`, ""),
}) })
assertObject.False(rc.isEnabled(context.Background())) assertObject.False(rc.isEnabled(t.Context()))
rc = createIfTestRunContext(map[string]*model.Job{ rc = createIfTestRunContext(map[string]*model.Job{
"job1": createJob(t, `if: ${{ fromJSON('not-json') }}`, ""), "job1": createJob(t, `if: ${{ fromJSON('not-json') }}`, ""),
}) })
enabled, err := rc.isEnabled(context.Background()) enabled, err := rc.isEnabled(t.Context())
require.NoError(t, err) require.NoError(t, err)
assertObject.False(enabled) assertObject.False(enabled)
} }
@@ -1308,7 +1308,7 @@ func TestPrintStartJobContainerGroupGolden(t *testing.T) {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo)) logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo))
entry := logger.With("job", "j1") entry := logger.With("job", "j1")
ctx := common.WithLogger(context.Background(), entry) ctx := common.WithLogger(t.Context(), entry)
printStartJobContainerGroup(ctx, "node:20", "GITEA-WORKFLOW-build-JOB-test", "gitea-runner-network")() printStartJobContainerGroup(ctx, "node:20", "GITEA-WORKFLOW-build-JOB-test", "gitea-runner-network")()
@@ -1443,7 +1443,7 @@ func TestWaitForServiceContainers(t *testing.T) {
Return(&container.Info{ID: "id", State: "running", Health: container.HealthNone}, nil).Once() Return(&container.Info{ID: "id", State: "running", Health: container.HealthNone}, nil).Once()
rc := newRunContext(0, &serviceContainer{name: "redis", container: service}) rc := newRunContext(0, &serviceContainer{name: "redis", container: service})
require.NoError(t, rc.waitForServiceContainers()(context.Background())) require.NoError(t, rc.waitForServiceContainers()(t.Context()))
service.AssertExpectations(t) service.AssertExpectations(t)
}) })
@@ -1478,7 +1478,7 @@ func TestWaitForServiceContainers(t *testing.T) {
service.On("DumpLogs", mock.Anything).Return(nil).Once() service.On("DumpLogs", mock.Anything).Return(nil).Once()
rc := newRunContext(0, &serviceContainer{name: "postgres", container: service}) rc := newRunContext(0, &serviceContainer{name: "postgres", container: service})
err := rc.waitForServiceContainers()(context.Background()) err := rc.waitForServiceContainers()(t.Context())
require.Error(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), "the service 'postgres' is unhealthy: connection refused") assert.Contains(t, err.Error(), "the service 'postgres' is unhealthy: connection refused")
service.AssertExpectations(t) service.AssertExpectations(t)
@@ -1490,7 +1490,7 @@ func TestWaitForServiceContainers(t *testing.T) {
Return(&container.Info{State: "exited", ExitCode: 2, Health: container.HealthNone}, nil).Once() Return(&container.Info{State: "exited", ExitCode: 2, Health: container.HealthNone}, nil).Once()
rc := newRunContext(0, &serviceContainer{name: "postgres", container: service}) rc := newRunContext(0, &serviceContainer{name: "postgres", container: service})
require.NoError(t, rc.waitForServiceContainers()(context.Background())) require.NoError(t, rc.waitForServiceContainers()(t.Context()))
}) })
t.Run("proceeds when the container is gone", func(t *testing.T) { t.Run("proceeds when the container is gone", func(t *testing.T) {
@@ -1499,7 +1499,7 @@ func TestWaitForServiceContainers(t *testing.T) {
Return((*container.Info)(nil), container.ErrContainerNotFound).Once() Return((*container.Info)(nil), container.ErrContainerNotFound).Once()
rc := newRunContext(0, &serviceContainer{name: "postgres", container: service}) rc := newRunContext(0, &serviceContainer{name: "postgres", container: service})
require.NoError(t, rc.waitForServiceContainers()(context.Background())) require.NoError(t, rc.waitForServiceContainers()(t.Context()))
}) })
t.Run("fails right away when one service fails while another is still starting", func(t *testing.T) { t.Run("fails right away when one service fails while another is still starting", func(t *testing.T) {
@@ -1533,7 +1533,7 @@ func TestWaitForServiceContainers(t *testing.T) {
Return(&container.Info{State: "running", Health: container.HealthStarting}, nil) Return(&container.Info{State: "running", Health: container.HealthStarting}, nil)
rc := newRunContext(20*time.Millisecond, &serviceContainer{name: "postgres", container: service}) rc := newRunContext(20*time.Millisecond, &serviceContainer{name: "postgres", container: service})
err := rc.waitForServiceContainers()(context.Background()) err := rc.waitForServiceContainers()(t.Context())
require.Error(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), "did not become healthy within") assert.Contains(t, err.Error(), "did not become healthy within")
}) })
@@ -1545,7 +1545,7 @@ func TestWaitForServiceContainers(t *testing.T) {
Return((*container.Info)(nil), errors.New("inspect aborted")) Return((*container.Info)(nil), errors.New("inspect aborted"))
rc := newRunContext(20*time.Millisecond, &serviceContainer{name: "postgres", container: service}) rc := newRunContext(20*time.Millisecond, &serviceContainer{name: "postgres", container: service})
err := rc.waitForServiceContainers()(context.Background()) err := rc.waitForServiceContainers()(t.Context())
require.Error(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), "did not become healthy within") assert.Contains(t, err.Error(), "did not become healthy within")
}) })
@@ -1558,7 +1558,7 @@ func TestWaitForServiceContainers(t *testing.T) {
svc := &serviceContainer{name: "postgres", container: service} svc := &serviceContainer{name: "postgres", container: service}
rc := newRunContext(-1, svc) rc := newRunContext(-1, svc)
require.NoError(t, rc.waitForServiceContainers()(context.Background())) require.NoError(t, rc.waitForServiceContainers()(t.Context()))
service.AssertExpectations(t) service.AssertExpectations(t)
assert.Equal(t, "id", svc.info.ID) assert.Equal(t, "id", svc.info.ID)
}) })
@@ -1568,13 +1568,13 @@ func TestWaitForServiceContainers(t *testing.T) {
service.On("Inspect", mock.Anything).Return((*container.Info)(nil), errors.New("daemon is gone")).Once() service.On("Inspect", mock.Anything).Return((*container.Info)(nil), errors.New("daemon is gone")).Once()
rc := newRunContext(-1, &serviceContainer{name: "postgres", container: service}) rc := newRunContext(-1, &serviceContainer{name: "postgres", container: service})
err := rc.waitForServiceContainers()(context.Background()) err := rc.waitForServiceContainers()(t.Context())
require.Error(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), "failed to inspect service 'postgres'") assert.Contains(t, err.Error(), "failed to inspect service 'postgres'")
}) })
t.Run("is a no-op without services", func(t *testing.T) { t.Run("is a no-op without services", func(t *testing.T) {
require.NoError(t, newRunContext(0).waitForServiceContainers()(context.Background())) require.NoError(t, newRunContext(0).waitForServiceContainers()(t.Context()))
}) })
} }
@@ -1590,7 +1590,7 @@ func TestReportUnstartedServices(t *testing.T) {
{name: "redis", container: running}, {name: "redis", container: running},
}} }}
require.NoError(t, rc.reportUnstartedServices()(context.Background())) require.NoError(t, rc.reportUnstartedServices()(t.Context()))
dead.AssertExpectations(t) dead.AssertExpectations(t)
running.AssertExpectations(t) running.AssertExpectations(t)
} }
@@ -1630,14 +1630,14 @@ func TestCaptureJobContainerInfoExportsDockerWorkspace(t *testing.T) {
JobContainer: job, JobContainer: job,
} }
require.NoError(t, rc.captureJobContainerInfo()(context.Background())) require.NoError(t, rc.captureJobContainerInfo()(t.Context()))
assert.Equal(t, "job-container-id", rc.jobContainerID) assert.Equal(t, "job-container-id", rc.jobContainerID)
assert.Equal(t, "/var/lib/docker/volumes/job/_data/owner/repo", rc.Env["GITEA_DOCKER_WORKSPACE"]) assert.Equal(t, "/var/lib/docker/volumes/job/_data/owner/repo", rc.Env["GITEA_DOCKER_WORKSPACE"])
rc.Config.Workdir = "/elsewhere" rc.Config.Workdir = "/elsewhere"
rc.Env = map[string]string{} rc.Env = map[string]string{}
require.NoError(t, rc.captureJobContainerInfo()(context.Background())) require.NoError(t, rc.captureJobContainerInfo()(t.Context()))
assert.NotContains(t, rc.Env, "GITEA_DOCKER_WORKSPACE") assert.NotContains(t, rc.Env, "GITEA_DOCKER_WORKSPACE")
} }
@@ -1714,7 +1714,7 @@ func TestRunContextContainerImageCannotSelectBackend(t *testing.T) {
} }
func TestRunContextImageOS(t *testing.T) { func TestRunContextImageOS(t *testing.T) {
ctx := context.Background() ctx := t.Context()
t.Run("prefers the release in the resolved image tag", func(t *testing.T) { t.Run("prefers the release in the resolved image tag", func(t *testing.T) {
rc := createRunsOnRunContext(t, "ubuntu-latest") rc := createRunsOnRunContext(t, "ubuntu-latest")
@@ -1741,7 +1741,7 @@ func TestRunContextImageOS(t *testing.T) {
} }
func TestRunContextGetRunnerContext(t *testing.T) { func TestRunContextGetRunnerContext(t *testing.T) {
ctx := context.Background() ctx := t.Context()
t.Run("adds the runner values the container cannot know", func(t *testing.T) { t.Run("adds the runner values the container cannot know", func(t *testing.T) {
rc := createRunsOnRunContext(t, "ubuntu-latest") rc := createRunsOnRunContext(t, "ubuntu-latest")
@@ -1821,7 +1821,7 @@ func TestParentDir(t *testing.T) {
} }
func TestRunContextWithGithubEnvRunnerValues(t *testing.T) { func TestRunContextWithGithubEnvRunnerValues(t *testing.T) {
ctx := context.Background() ctx := t.Context()
rc := createRunsOnRunContext(t, "ubuntu-latest") rc := createRunsOnRunContext(t, "ubuntu-latest")
rc.Config.RunnerName = "runner-1" rc.Config.RunnerName = "runner-1"
rc.Config.Secrets = map[string]string{"ACTIONS_STEP_DEBUG": "true"} rc.Config.Secrets = map[string]string{"ACTIONS_STEP_DEBUG": "true"}
+6 -6
View File
@@ -281,7 +281,7 @@ func TestRunEvent(t *testing.T) {
requireDocker(t) requireDocker(t)
t.Parallel() t.Parallel()
ctx := context.Background() ctx := t.Context()
tables := []TestJobFileInfo{ tables := []TestJobFileInfo{
// Shells // Shells
@@ -384,7 +384,7 @@ func TestRunEventHostEnvironment(t *testing.T) {
// nix-specific cases gate on their own tool below so a missing pwsh/nix skips just those. // nix-specific cases gate on their own tool below so a missing pwsh/nix skips just those.
requireHostTools(t, "bash", "node") requireHostTools(t, "bash", "node")
ctx := context.Background() ctx := t.Context()
tables := []TestJobFileInfo{} tables := []TestJobFileInfo{}
@@ -482,7 +482,7 @@ func TestRunEventHostEnvironment(t *testing.T) {
func TestDryrunEvent(t *testing.T) { func TestDryrunEvent(t *testing.T) {
t.Parallel() t.Parallel()
// Dryrun plans without containers or network (shells and local actions only). // Dryrun plans without containers or network (shells and local actions only).
ctx := common.WithDryrun(context.Background(), true) ctx := common.WithDryrun(t.Context(), true)
tables := []TestJobFileInfo{ tables := []TestJobFileInfo{
// Shells // Shells
@@ -513,7 +513,7 @@ func TestReusableWorkflowCaller(t *testing.T) {
requireDocker(t) requireDocker(t)
t.Parallel() t.Parallel()
table := TestJobFileInfo{workdir, "uses-workflow", "push", "", platforms, map[string]string{"secret": "keep_it_private"}} table := TestJobFileInfo{workdir, "uses-workflow", "push", "", platforms, map[string]string{"secret": "keep_it_private"}}
table.runTest(context.Background(), t, &Config{Secrets: table.secrets}) table.runTest(t.Context(), t, &Config{Secrets: table.secrets})
} }
func TestRunEventSecrets(t *testing.T) { func TestRunEventSecrets(t *testing.T) {
@@ -534,7 +534,7 @@ func TestRunEventSecrets(t *testing.T) {
secrets, _ := godotenv.Read(filepath.Join(workdir, workflowPath, ".secrets")) secrets, _ := godotenv.Read(filepath.Join(workdir, workflowPath, ".secrets"))
assert.NoError(t, err, "Failed to read .secrets") //nolint:testifylint // pre-existing issue from nektos/act assert.NoError(t, err, "Failed to read .secrets") //nolint:testifylint // pre-existing issue from nektos/act
tjfi.runTest(context.Background(), t, &Config{Secrets: secrets, Env: env}) tjfi.runTest(t.Context(), t, &Config{Secrets: secrets, Env: env})
} }
func TestRunEventPullRequest(t *testing.T) { func TestRunEventPullRequest(t *testing.T) {
@@ -551,5 +551,5 @@ func TestRunEventPullRequest(t *testing.T) {
platforms: platforms, platforms: platforms,
} }
tjfi.runTest(context.Background(), t, &Config{EventPath: filepath.Join(workdir, workflowPath, "event.json")}) tjfi.runTest(t.Context(), t, &Config{EventPath: filepath.Join(workdir, workflowPath, "event.json")})
} }
+2 -2
View File
@@ -35,7 +35,7 @@ func (salm *stepActionLocalMocks) readAction(_ context.Context, step *model.Step
} }
func TestStepActionLocalTest(t *testing.T) { func TestStepActionLocalTest(t *testing.T) {
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
salm := &stepActionLocalMocks{} salm := &stepActionLocalMocks{}
@@ -225,7 +225,7 @@ func TestStepActionLocalPost(t *testing.T) {
for _, tt := range table { for _, tt := range table {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
+4 -4
View File
@@ -175,7 +175,7 @@ func TestStepActionRemote(t *testing.T) {
for _, tt := range table { for _, tt := range table {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
sarm := &stepActionRemoteMocks{} sarm := &stepActionRemoteMocks{}
@@ -438,7 +438,7 @@ func TestStepActionRemotePost(t *testing.T) {
for _, tt := range table { for _, tt := range table {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ctx := context.Background() ctx := t.Context()
cm := &containerMock{} cm := &containerMock{}
@@ -772,7 +772,7 @@ func TestStepActionRemotePreResolvesDownloadedCommit(t *testing.T) {
readAction: readActionImpl, readAction: readActionImpl,
} }
require.NoError(t, sar.prepareActionExecutor()(context.Background())) require.NoError(t, sar.prepareActionExecutor()(t.Context()))
reference, sha, ok := sar.actionDownloadInfo() reference, sha, ok := sar.actionDownloadInfo()
assert.True(t, ok) assert.True(t, ok)
@@ -853,7 +853,7 @@ func TestStepActionRemoteCloneTokenSurvivesNilSecrets(t *testing.T) {
for _, tt := range table { for _, tt := range table {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ctx := context.Background() ctx := t.Context()
var capturedToken string var capturedToken string
setCloneExecutor(t, func(input git.NewGitCloneExecutorInput) common.Executor { setCloneExecutor(t, func(input git.NewGitCloneExecutorInput) common.Executor {
+3 -4
View File
@@ -6,7 +6,6 @@ package runner
import ( import (
"bytes" "bytes"
"context"
"io" "io"
"slices" "slices"
"strings" "strings"
@@ -35,7 +34,7 @@ func TestStepDockerMain(t *testing.T) {
ContainerNewContainer = origContainerNewContainer ContainerNewContainer = origContainerNewContainer
}() }()
ctx := context.Background() ctx := t.Context()
sd := &stepDocker{ sd := &stepDocker{
RunContext: &RunContext{ RunContext: &RunContext{
@@ -124,7 +123,7 @@ func TestStepDockerNewStepContainerAllocatePTY(t *testing.T) {
ContainerNewContainer = origContainerNewContainer ContainerNewContainer = origContainerNewContainer
}() }()
ctx := context.Background() ctx := t.Context()
sd := &stepDocker{ sd := &stepDocker{
RunContext: &RunContext{ RunContext: &RunContext{
StepResults: map[string]*model.StepResult{}, StepResults: map[string]*model.StepResult{},
@@ -197,7 +196,7 @@ func TestStepDockerNewStepContainerNetworkModeAndPath(t *testing.T) {
ContainerNewContainer = origContainerNewContainer ContainerNewContainer = origContainerNewContainer
}() }()
ctx := context.Background() ctx := t.Context()
platform := tc.platform platform := tc.platform
sd := &stepDocker{ sd := &stepDocker{
+2 -3
View File
@@ -6,7 +6,6 @@ package runner
import ( import (
"bytes" "bytes"
"context"
"io" "io"
"strings" "strings"
"testing" "testing"
@@ -87,7 +86,7 @@ env:
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo)) logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo))
entry := logger.With("job", "j1") entry := logger.With("job", "j1")
ctx := common.WithLogger(context.Background(), entry) ctx := common.WithLogger(t.Context(), entry)
sr := &stepRun{ sr := &stepRun{
Step: &step, Step: &step,
@@ -133,7 +132,7 @@ env:
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo)) logger := logging.New(logging.NewLevelHandler(newJobLogHandler(buf, cyan), logging.LevelInfo))
entry := logger.With("job", "j1") entry := logger.With("job", "j1")
ctx := common.WithLogger(context.Background(), entry) ctx := common.WithLogger(t.Context(), entry)
printRunActionHeader(ctx, &step, map[string]string{"CUSTOM": "value", "GITHUB_TOKEN": "tok"}, &RunContext{}) printRunActionHeader(ctx, &step, map[string]string{"CUSTOM": "value", "GITHUB_TOKEN": "tok"}, &RunContext{})
+1 -1
View File
@@ -68,7 +68,7 @@ func TestStepRun(t *testing.T) {
cm.On("UpdateFromEnv", "/var/run/act/workflow/outputcmd.txt", mock.AnythingOfType("*map[string]string")).Return(noopExecutor) cm.On("UpdateFromEnv", "/var/run/act/workflow/outputcmd.txt", mock.AnythingOfType("*map[string]string")).Return(noopExecutor)
ctx := context.Background() ctx := t.Context()
cm.On("GetContainerArchive", ctx, "/var/run/act/workflow/pathcmd.txt").Return(io.NopCloser(&bytes.Buffer{}), nil) cm.On("GetContainerArchive", ctx, "/var/run/act/workflow/pathcmd.txt").Return(io.NopCloser(&bytes.Buffer{}), nil)
+29 -29
View File
@@ -166,8 +166,8 @@ func TestSetupEnv(t *testing.T) {
sm.On("getStepModel").Return(step) sm.On("getStepModel").Return(step)
sm.On("getEnv").Return(&env) sm.On("getEnv").Return(&env)
require.NoError(t, setupEnv(context.Background(), sm)) require.NoError(t, setupEnv(t.Context(), sm))
require.NoError(t, setupInputs(context.Background(), sm)) require.NoError(t, setupInputs(t.Context(), sm))
// These are commit or system specific // These are commit or system specific
delete(env, "GITHUB_REF") delete(env, "GITHUB_REF")
@@ -304,58 +304,58 @@ func TestIsStepEnabled(t *testing.T) {
// success() // success()
step := createTestStep(t, "if: success()") step := createTestStep(t, "if: success()")
assertObject.True(isStepEnabled(context.Background(), step.getIfExpression(context.Background(), stepStageMain), step, stepStageMain)) assertObject.True(isStepEnabled(t.Context(), step.getIfExpression(t.Context(), stepStageMain), step, stepStageMain))
step = createTestStep(t, "if: success()") step = createTestStep(t, "if: success()")
step.getRunContext().StepResults["a"] = &model.StepResult{ step.getRunContext().StepResults["a"] = &model.StepResult{
Conclusion: model.StepStatusSuccess, Conclusion: model.StepStatusSuccess,
} }
assertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.True(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
step = createTestStep(t, "if: success()") step = createTestStep(t, "if: success()")
step.getRunContext().StepResults["a"] = &model.StepResult{ step.getRunContext().StepResults["a"] = &model.StepResult{
Conclusion: model.StepStatusFailure, Conclusion: model.StepStatusFailure,
} }
assertObject.False(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.False(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
// failure() // failure()
step = createTestStep(t, "if: failure()") step = createTestStep(t, "if: failure()")
assertObject.False(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.False(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
step = createTestStep(t, "if: failure()") step = createTestStep(t, "if: failure()")
step.getRunContext().StepResults["a"] = &model.StepResult{ step.getRunContext().StepResults["a"] = &model.StepResult{
Conclusion: model.StepStatusSuccess, Conclusion: model.StepStatusSuccess,
} }
assertObject.False(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.False(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
step = createTestStep(t, "if: failure()") step = createTestStep(t, "if: failure()")
step.getRunContext().StepResults["a"] = &model.StepResult{ step.getRunContext().StepResults["a"] = &model.StepResult{
Conclusion: model.StepStatusFailure, Conclusion: model.StepStatusFailure,
} }
assertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.True(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
// always() // always()
step = createTestStep(t, "if: always()") step = createTestStep(t, "if: always()")
assertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.True(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
step = createTestStep(t, "if: always()") step = createTestStep(t, "if: always()")
step.getRunContext().StepResults["a"] = &model.StepResult{ step.getRunContext().StepResults["a"] = &model.StepResult{
Conclusion: model.StepStatusSuccess, Conclusion: model.StepStatusSuccess,
} }
assertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.True(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
step = createTestStep(t, "if: always()") step = createTestStep(t, "if: always()")
step.getRunContext().StepResults["a"] = &model.StepResult{ step.getRunContext().StepResults["a"] = &model.StepResult{
Conclusion: model.StepStatusFailure, Conclusion: model.StepStatusFailure,
} }
assertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.True(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
// neither env nor the step's own with: values are inputs, at any stage // neither env nor the step's own with: values are inputs, at any stage
step = createTestStep(t, "if: inputs.forged") step = createTestStep(t, "if: inputs.forged")
step.getRunContext().Env["INPUT_FORGED"] = "leaked" step.getRunContext().Env["INPUT_FORGED"] = "leaked"
*step.getEnv() = map[string]string{"INPUT_FORGED": "leaked"} *step.getEnv() = map[string]string{"INPUT_FORGED": "leaked"}
assertObject.False(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain)) assertObject.False(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStageMain))
assertObject.False(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStagePost)) assertObject.False(isStepEnabled(t.Context(), step.getStepModel().If.Value, step, stepStagePost))
} }
func TestIsContinueOnError(t *testing.T) { func TestIsContinueOnError(t *testing.T) {
@@ -388,44 +388,44 @@ func TestIsContinueOnError(t *testing.T) {
// absent // absent
step := createTestStep(t, "name: test") step := createTestStep(t, "name: test")
continueOnError, err := isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain) continueOnError, err := isContinueOnError(t.Context(), step.getStepModel().RawContinueOnError, step, stepStageMain)
assertObject.False(continueOnError) assertObject.False(continueOnError)
assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act
// explcit true // explcit true
step = createTestStep(t, "continue-on-error: true") step = createTestStep(t, "continue-on-error: true")
continueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain) continueOnError, err = isContinueOnError(t.Context(), step.getStepModel().RawContinueOnError, step, stepStageMain)
assertObject.True(continueOnError) assertObject.True(continueOnError)
assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act
// explicit false // explicit false
step = createTestStep(t, "continue-on-error: false") step = createTestStep(t, "continue-on-error: false")
continueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain) continueOnError, err = isContinueOnError(t.Context(), step.getStepModel().RawContinueOnError, step, stepStageMain)
assertObject.False(continueOnError) assertObject.False(continueOnError)
assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act
// expression true // expression true
step = createTestStep(t, "continue-on-error: ${{ 'test' == 'test' }}") step = createTestStep(t, "continue-on-error: ${{ 'test' == 'test' }}")
continueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain) continueOnError, err = isContinueOnError(t.Context(), step.getStepModel().RawContinueOnError, step, stepStageMain)
assertObject.True(continueOnError) assertObject.True(continueOnError)
assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act
// expression false // expression false
step = createTestStep(t, "continue-on-error: ${{ 'test' != 'test' }}") step = createTestStep(t, "continue-on-error: ${{ 'test' != 'test' }}")
continueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain) continueOnError, err = isContinueOnError(t.Context(), step.getStepModel().RawContinueOnError, step, stepStageMain)
assertObject.False(continueOnError) assertObject.False(continueOnError)
assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act assertObject.NoError(err) //nolint:testifylint // pre-existing issue from nektos/act
// the step's own with: values are not inputs // the step's own with: values are not inputs
step = createTestStep(t, "continue-on-error: ${{ inputs.forged }}") step = createTestStep(t, "continue-on-error: ${{ inputs.forged }}")
*step.getEnv() = map[string]string{"INPUT_FORGED": "true"} *step.getEnv() = map[string]string{"INPUT_FORGED": "true"}
continueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain) continueOnError, err = isContinueOnError(t.Context(), step.getStepModel().RawContinueOnError, step, stepStageMain)
assertObject.False(continueOnError) assertObject.False(continueOnError)
require.NoError(t, err) require.NoError(t, err)
// expression parse error // expression parse error
step = createTestStep(t, "continue-on-error: ${{ 'test' != test }}") step = createTestStep(t, "continue-on-error: ${{ 'test' != test }}")
continueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain) continueOnError, err = isContinueOnError(t.Context(), step.getStepModel().RawContinueOnError, step, stepStageMain)
assertObject.False(continueOnError) assertObject.False(continueOnError)
assertObject.Error(err) assertObject.Error(err)
} }
@@ -449,9 +449,9 @@ func TestRunStepExecutorDoesNotLeakRefusalToNextStep(t *testing.T) {
StepResults: map[string]*model.StepResult{}, StepResults: map[string]*model.StepResult{},
JobContainer: cm, JobContainer: cm,
} }
rc.ExprEval = rc.NewExpressionEvaluator(context.Background()) rc.ExprEval = rc.NewExpressionEvaluator(t.Context())
// Dryrun skips reading the path file back from the (mocked) container. // Dryrun skips reading the path file back from the (mocked) container.
ctx := common.WithDryrun(context.Background(), true) ctx := common.WithDryrun(t.Context(), true)
// A refusal parsed out of the job container's own output belongs to no step, so the // A refusal parsed out of the job container's own output belongs to no step, so the
// first step must not be failed by it. // first step must not be failed by it.
@@ -499,7 +499,7 @@ func TestRunStepExecutorParity(t *testing.T) {
newStep := func(t *testing.T, stepModel *model.Step) *stepRun { newStep := func(t *testing.T, stepModel *model.Step) *stepRun {
rc := createRunContext(t) rc := createRunContext(t)
rc.JobContainer = &container.HostEnvironment{ActPath: t.TempDir()} rc.JobContainer = &container.HostEnvironment{ActPath: t.TempDir()}
rc.ExprEval = rc.NewExpressionEvaluator(context.Background()) rc.ExprEval = rc.NewExpressionEvaluator(t.Context())
return &stepRun{RunContext: rc, Step: stepModel, env: map[string]string{}} return &stepRun{RunContext: rc, Step: stepModel, env: map[string]string{}}
} }
badExpression := "${{ 'test' != test }}" badExpression := "${{ 'test' != test }}"
@@ -514,7 +514,7 @@ func TestRunStepExecutorParity(t *testing.T) {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
step := newStep(t, test.step) step := newStep(t, test.step)
logger, hook := logtest.NewLogger() logger, hook := logtest.NewLogger()
err := runStepExecutor(step, stepStageMain, test.executor)(common.WithLogger(context.Background(), logger)) err := runStepExecutor(step, stepStageMain, test.executor)(common.WithLogger(t.Context(), logger))
require.ErrorContains(t, err, test.wantError) require.ErrorContains(t, err, test.wantError)
assert.Equal(t, model.StepStatusFailure, step.RunContext.StepResults[test.step.ID].Conclusion) assert.Equal(t, model.StepStatusFailure, step.RunContext.StepResults[test.step.ID].Conclusion)
@@ -548,7 +548,7 @@ func TestRunStepExecutorParity(t *testing.T) {
require.NoError(t, os.WriteFile(step.env["GITHUB_OUTPUT"], []byte("kept=value\n"), 0o600)) require.NoError(t, os.WriteFile(step.env["GITHUB_OUTPUT"], []byte("kept=value\n"), 0o600))
require.NoError(t, os.WriteFile(step.env["GITHUB_STATE"], []byte("saved=value\n"), 0o600)) require.NoError(t, os.WriteFile(step.env["GITHUB_STATE"], []byte("saved=value\n"), 0o600))
return nil return nil
})(common.WithLogger(context.Background(), logger)) })(common.WithLogger(t.Context(), logger))
require.NoError(t, err) require.NoError(t, err)
result := step.RunContext.StepResults[step.Step.ID] result := step.RunContext.StepResults[step.Step.ID]
@@ -595,7 +595,7 @@ func TestRunStepExecutorParity(t *testing.T) {
Config: outer.RunContext.Config, Run: outer.RunContext.Run, Env: map[string]string{}, StepResults: map[string]*model.StepResult{}, Config: outer.RunContext.Config, Run: outer.RunContext.Run, Env: map[string]string{}, StepResults: map[string]*model.StepResult{},
JobContainer: outer.RunContext.JobContainer, Parent: outer.RunContext, JobContainer: outer.RunContext.JobContainer, Parent: outer.RunContext,
} }
childRC.ExprEval = childRC.NewExpressionEvaluator(context.Background()) childRC.ExprEval = childRC.NewExpressionEvaluator(t.Context())
child := &stepRun{RunContext: childRC, Step: &model.Step{ID: "child"}, env: map[string]string{}} child := &stepRun{RunContext: childRC, Step: &model.Step{ID: "child"}, env: map[string]string{}}
err := runStepExecutor(outer, stepStageMain, func(ctx context.Context) error { err := runStepExecutor(outer, stepStageMain, func(ctx context.Context) error {
@@ -606,7 +606,7 @@ func TestRunStepExecutorParity(t *testing.T) {
})(ctx)) })(ctx))
outer.RunContext.setOutput(ctx, map[string]string{"name": "declared"}, "outer") outer.RunContext.setOutput(ctx, map[string]string{"name": "declared"}, "outer")
return nil return nil
})(context.Background()) })(t.Context())
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, map[string]string{"declared": "outer"}, outer.RunContext.StepResults[outer.Step.ID].Outputs) assert.Equal(t, map[string]string{"declared": "outer"}, outer.RunContext.StepResults[outer.Step.ID].Outputs)
@@ -639,9 +639,9 @@ func TestRunStepExecutorParity(t *testing.T) {
}) })
t.Run("timeout must be positive", func(t *testing.T) { t.Run("timeout must be positive", func(t *testing.T) {
exprEval := createRunContext(t).NewExpressionEvaluator(context.Background()) exprEval := createRunContext(t).NewExpressionEvaluator(t.Context())
for timeout, wantDeadline := range map[string]bool{"-1": false, "0": false, "1": true} { for timeout, wantDeadline := range map[string]bool{"-1": false, "0": false, "1": true} {
ctx, cancel := evaluateStepTimeout(context.Background(), exprEval, &model.Step{TimeoutMinutes: timeout}) ctx, cancel := evaluateStepTimeout(t.Context(), exprEval, &model.Step{TimeoutMinutes: timeout})
_, hasDeadline := ctx.Deadline() _, hasDeadline := ctx.Deadline()
cancel() cancel()
assert.Equal(t, wantDeadline, hasDeadline, timeout) assert.Equal(t, wantDeadline, hasDeadline, timeout)
+1 -2
View File
@@ -5,7 +5,6 @@ package cmd
import ( import (
"bytes" "bytes"
"context"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
@@ -217,7 +216,7 @@ func TestPrintListReportsDuplicateJobIDs(t *testing.T) {
} }
func TestLoadExecCmdDefinesExpectedFlags(t *testing.T) { func TestLoadExecCmdDefinesExpectedFlags(t *testing.T) {
cmd := loadExecCmd(context.Background()) cmd := loadExecCmd(t.Context())
for _, name := range []string{ for _, name := range []string{
"list", "list",
+11 -11
View File
@@ -38,7 +38,7 @@ func TestPoller_WorkerStateCounters(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
p := &Poller{client: client, cfg: cfg} p := &Poller{client: client, cfg: cfg}
ctx := context.Background() ctx := t.Context()
s1 := &workerState{} s1 := &workerState{}
s2 := &workerState{} s2 := &workerState{}
@@ -69,7 +69,7 @@ func TestPoller_FetchErrorIncrementsErrorsOnly(t *testing.T) {
p := &Poller{client: client, cfg: cfg} p := &Poller{client: client, cfg: cfg}
s := &workerState{} s := &workerState{}
_, ok := p.fetchTask(context.Background(), s) _, ok := p.fetchTask(t.Context(), s)
require.False(t, ok) require.False(t, ok)
assert.Equal(t, int64(1), s.consecutiveErrors) assert.Equal(t, int64(1), s.consecutiveErrors)
assert.Equal(t, int64(0), s.consecutiveEmpty) assert.Equal(t, int64(0), s.consecutiveEmpty)
@@ -90,14 +90,14 @@ func TestPoller_FetchTimeoutIsNoSignal(t *testing.T) {
hook := logtest.SetDefault(t) hook := logtest.SetDefault(t)
s := &workerState{consecutiveErrors: 2} s := &workerState{consecutiveErrors: 2}
_, ok := p.fetchTask(context.Background(), s) _, ok := p.fetchTask(t.Context(), s)
require.False(t, ok) require.False(t, ok)
assert.Equal(t, int64(2), s.consecutiveErrors) assert.Equal(t, int64(2), s.consecutiveErrors)
assert.Equal(t, int64(1), s.consecutiveEmpty) assert.Equal(t, int64(1), s.consecutiveEmpty)
assert.True(t, p.lastPollFailed.Load(), "a timeout must not clear a known failure") assert.True(t, p.lastPollFailed.Load(), "a timeout must not clear a known failure")
// An idle runner against a server holding the request open must not flood. // An idle runner against a server holding the request open must not flood.
_, _ = p.fetchTask(context.Background(), s) _, _ = p.fetchTask(t.Context(), s)
assert.Len(t, hook.AllRecords(), 1) assert.Len(t, hook.AllRecords(), 1)
} }
@@ -120,7 +120,7 @@ func TestPoller_FetchUnauthenticatedStopsPolling(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
p := New(cfg, client, nil) p := New(cfg, client, nil)
s := &workerState{} s := &workerState{}
_, ok := p.fetchTask(context.Background(), s) _, ok := p.fetchTask(t.Context(), s)
require.False(t, ok) require.False(t, ok)
assert.True(t, p.Unregistered(), "runner should be marked unregistered") assert.True(t, p.Unregistered(), "runner should be marked unregistered")
@@ -261,7 +261,7 @@ func TestPollerPausesAndResumesForLocalAvailability(t *testing.T) {
return fetches.Load() > 0 return fetches.Load() > 0
}, time.Second, 10*time.Millisecond, "polling should resume after local recovery") }, time.Second, 10*time.Millisecond, "polling should resume after local recovery")
shutdownCtx, cancel := context.WithTimeout(context.Background(), time.Second) shutdownCtx, cancel := context.WithTimeout(t.Context(), time.Second)
defer cancel() defer cancel()
require.NoError(t, poller.Shutdown(shutdownCtx)) require.NoError(t, poller.Shutdown(shutdownCtx))
wg.Wait() wg.Wait()
@@ -280,7 +280,7 @@ func (m *mockRunner) Run(ctx context.Context, _ *runnerv1.Task) error {
func TestPollerRunIdleMaintenance(t *testing.T) { func TestPollerRunIdleMaintenance(t *testing.T) {
runner := &idleAwareRunner{} runner := &idleAwareRunner{}
p := &Poller{runner: runner, jobsCtx: context.Background()} p := &Poller{runner: runner, jobsCtx: t.Context()}
p.runIdleMaintenance() p.runIdleMaintenance()
@@ -315,7 +315,7 @@ func TestPollerPollCallsOnIdle(t *testing.T) {
return runner.idleCalls.Load() > 0 return runner.idleCalls.Load() > 0
}, time.Second, 10*time.Millisecond) }, time.Second, 10*time.Millisecond)
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(t.Context(), time.Second)
defer cancel() defer cancel()
require.NoError(t, poller.Shutdown(ctx)) require.NoError(t, poller.Shutdown(ctx))
wg.Wait() wg.Wait()
@@ -344,7 +344,7 @@ func TestPollerPollOnceCallsOnIdle(t *testing.T) {
return runner.idleCalls.Load() > 0 return runner.idleCalls.Load() > 0
}, time.Second, 10*time.Millisecond) }, time.Second, 10*time.Millisecond)
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(t.Context(), time.Second)
defer cancel() defer cancel()
require.NoError(t, poller.Shutdown(ctx)) require.NoError(t, poller.Shutdown(ctx))
wg.Wait() wg.Wait()
@@ -411,7 +411,7 @@ func TestPoller_ConcurrencyLimitedByCapacity(t *testing.T) {
return runner.totalCompleted.Load() >= totalTasks return runner.totalCompleted.Load() >= totalTasks
}, 2*time.Second, 10*time.Millisecond, "all tasks should complete") }, 2*time.Second, 10*time.Millisecond, "all tasks should complete")
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(t.Context(), time.Second)
defer cancel() defer cancel()
err = poller.Shutdown(ctx) err = poller.Shutdown(ctx)
require.NoError(t, err) require.NoError(t, err)
@@ -467,7 +467,7 @@ func TestPoller_ShutdownForcesJobsOnTimeout(t *testing.T) {
return runner.running.Load() == 1 return runner.running.Load() == 1
}, time.Second, 10*time.Millisecond, "task should start running") }, time.Second, 10*time.Millisecond, "task should start running")
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) ctx, cancel := context.WithTimeout(t.Context(), 50*time.Millisecond)
defer cancel() defer cancel()
start := time.Now() start := time.Now()
err = poller.Shutdown(ctx) err = poller.Shutdown(ctx)
+6 -6
View File
@@ -25,7 +25,7 @@ func TestRunPostTaskScriptSkippedWhenEmpty(t *testing.T) {
r := &Runner{ r := &Runner{
cfg: &config.Config{}, cfg: &config.Config{},
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
@@ -48,7 +48,7 @@ func TestRunPostTaskScriptNonZeroExitDoesNotPanic(t *testing.T) {
cfg.Runner.PostTaskScript = scriptPath cfg.Runner.PostTaskScript = scriptPath
r := &Runner{cfg: cfg} r := &Runner{cfg: cfg}
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
@@ -66,7 +66,7 @@ func TestPostTaskScriptContextUsesFullTimeout(t *testing.T) {
// A task context that finished close to its own deadline must not truncate the // A task context that finished close to its own deadline must not truncate the
// script's budget: the script should still get its full configured timeout. // script's budget: the script should still get its full configured timeout.
near, cancelNear := context.WithTimeout(context.Background(), time.Second) near, cancelNear := context.WithTimeout(t.Context(), time.Second)
defer cancelNear() defer cancelNear()
scriptCtx, cancel := postTaskScriptContext(near, timeout) scriptCtx, cancel := postTaskScriptContext(near, timeout)
defer cancel() defer cancel()
@@ -75,7 +75,7 @@ func TestPostTaskScriptContextUsesFullTimeout(t *testing.T) {
assert.Greater(t, time.Until(deadline), time.Minute, "script timeout truncated to task deadline") assert.Greater(t, time.Until(deadline), time.Minute, "script timeout truncated to task deadline")
// An already-cancelled task context must not cancel the script either. // An already-cancelled task context must not cancel the script either.
cancelledCtx, cancelIt := context.WithCancel(context.Background()) cancelledCtx, cancelIt := context.WithCancel(t.Context())
cancelIt() cancelIt()
scriptCtx2, cancel2 := postTaskScriptContext(cancelledCtx, timeout) scriptCtx2, cancel2 := postTaskScriptContext(cancelledCtx, timeout)
defer cancel2() defer cancel2()
@@ -91,7 +91,7 @@ func TestPostTaskScriptEnv(t *testing.T) {
envs: map[string]string{"BASE": "1"}, envs: map[string]string{"BASE": "1"},
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{ taskCtx, err := structpb.NewStruct(map[string]any{
@@ -128,7 +128,7 @@ func TestRunPostTaskScriptIntegration(t *testing.T) {
envs: map[string]string{"CUSTOM": "runner-env"}, envs: map[string]string{"CUSTOM": "runner-env"},
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
+9 -9
View File
@@ -46,7 +46,7 @@ func TestRunnerCleanupStaleTaskDirs(t *testing.T) {
now: func() time.Time { return now }, now: func() time.Time { return now },
} }
r.cleanupStaleDirs(context.Background(), workdirRoot, isTaskIDDir) r.cleanupStaleDirs(t.Context(), workdirRoot, isTaskIDDir)
assert.NoDirExists(t, oldTask) assert.NoDirExists(t, oldTask)
assert.DirExists(t, freshTask) assert.DirExists(t, freshTask)
@@ -85,7 +85,7 @@ func TestRunnerOnIdleCleansStaleHostScratchDirs(t *testing.T) {
now: func() time.Time { return now }, now: func() time.Time { return now },
} }
r.OnIdle(context.Background()) r.OnIdle(t.Context())
assert.NoDirExists(t, staleScratch) // stale scratch reclaimed assert.NoDirExists(t, staleScratch) // stale scratch reclaimed
assert.DirExists(t, freshScratch) // within cleanup age, kept assert.DirExists(t, freshScratch) // within cleanup age, kept
@@ -113,7 +113,7 @@ func TestRunnerCleanupStaleTaskDirsMissingRoot(t *testing.T) {
// Must be a silent no-op rather than a warning or panic when the root // Must be a silent no-op rather than a warning or panic when the root
// has not yet been created (e.g. the runner has never executed a task). // has not yet been created (e.g. the runner has never executed a task).
r.cleanupStaleDirs(context.Background(), filepath.Join(t.TempDir(), "missing"), isTaskIDDir) r.cleanupStaleDirs(t.Context(), filepath.Join(t.TempDir(), "missing"), isTaskIDDir)
} }
func TestRunnerCleanupStaleTaskDirsHonorsContext(t *testing.T) { func TestRunnerCleanupStaleTaskDirsHonorsContext(t *testing.T) {
@@ -127,7 +127,7 @@ func TestRunnerCleanupStaleTaskDirsHonorsContext(t *testing.T) {
require.NoError(t, os.Chtimes(dir, now.Add(-3*time.Hour), now.Add(-3*time.Hour))) require.NoError(t, os.Chtimes(dir, now.Add(-3*time.Hour), now.Add(-3*time.Hour)))
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
cancel() cancel()
r := &Runner{ r := &Runner{
@@ -265,7 +265,7 @@ func TestRunnerOnIdleIntegratesCleanup(t *testing.T) {
now: func() time.Time { return now }, now: func() time.Time { return now },
} }
r.OnIdle(context.Background()) r.OnIdle(t.Context())
assert.NoDirExists(t, stale) assert.NoDirExists(t, stale)
} }
@@ -293,7 +293,7 @@ func TestRunnerOnIdleSkipsWhenAlreadyCancelled(t *testing.T) {
now: func() time.Time { return now }, now: func() time.Time { return now },
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
cancel() cancel()
r.OnIdle(ctx) r.OnIdle(ctx)
@@ -346,7 +346,7 @@ func TestRunnerOnIdleRemovesOrphanNetworks(t *testing.T) {
r := &Runner{uuid: "runner-1", cfg: cfg, labels: labels.Labels{kubernetesLabel}, now: func() time.Time { return now }} r := &Runner{uuid: "runner-1", cfg: cfg, labels: labels.Labels{kubernetesLabel}, now: func() time.Time { return now }}
r.isolatedCacheContainer = func() string { return "a1b2c3d4e5f6" } r.isolatedCacheContainer = func() string { return "a1b2c3d4e5f6" }
r.OnIdle(context.Background()) r.OnIdle(t.Context())
assert.Equal(t, []string{"runner-1"}, swept) assert.Equal(t, []string{"runner-1"}, swept)
assert.Equal(t, swept, sweptVolumes) assert.Equal(t, swept, sweptVolumes)
// a network of a job starting during the pass is younger than this and so out of scope // a network of a job starting during the pass is younger than this and so out of scope
@@ -358,13 +358,13 @@ func TestRunnerOnIdleRemovesOrphanNetworks(t *testing.T) {
t.Cleanup(func() { dockerReachable = origDockerReachable }) t.Cleanup(func() { dockerReachable = origDockerReachable })
hostOnly := &Runner{uuid: "runner-2", cfg: &config.Config{Runner: cfg.Runner}, now: func() time.Time { return now }} hostOnly := &Runner{uuid: "runner-2", cfg: &config.Config{Runner: cfg.Runner}, now: func() time.Time { return now }}
hostOnly.isolatedCacheContainer = func() string { return "" } hostOnly.isolatedCacheContainer = func() string { return "" }
hostOnly.OnIdle(context.Background()) hostOnly.OnIdle(t.Context())
assert.Equal(t, []string{"runner-1"}, swept) assert.Equal(t, []string{"runner-1"}, swept)
assert.Equal(t, swept, sweptVolumes) assert.Equal(t, swept, sweptVolumes)
dockerReachable = func(context.Context) bool { return true } dockerReachable = func(context.Context) bool { return true }
now = now.Add(time.Minute) now = now.Add(time.Minute)
hostOnly.OnIdle(context.Background()) hostOnly.OnIdle(t.Context())
assert.Equal(t, []string{"runner-1", "runner-2"}, sweptVolumes) assert.Equal(t, []string{"runner-1", "runner-2"}, sweptVolumes)
assert.Equal(t, []string{"a1b2c3d4e5f6", ""}, detached) assert.Equal(t, []string{"a1b2c3d4e5f6", ""}, detached)
assert.Equal(t, []string{"runner-1"}, sweptPods) assert.Equal(t, []string{"runner-1"}, sweptPods)
+1 -1
View File
@@ -47,7 +47,7 @@ func TestRunnerCapabilitiesAndDeclare(t *testing.T) {
})).Return(connect.NewResponse(&runnerv1.DeclareResponse{}), nil) })).Return(connect.NewResponse(&runnerv1.DeclareResponse{}), nil)
r := &Runner{client: cli} r := &Runner{client: cli}
_, err := r.Declare(context.Background(), []string{"ubuntu"}) _, err := r.Declare(t.Context(), []string{"ubuntu"})
require.NoError(t, err) require.NoError(t, err)
} }
+1 -1
View File
@@ -11,7 +11,7 @@ import (
) )
func TestCheckIfDockerRunningReturnsPingError(t *testing.T) { func TestCheckIfDockerRunningReturnsPingError(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
cancel() cancel()
err := CheckIfDockerRunning(ctx, "unix:///definitely/missing/docker.sock") err := CheckIfDockerRunning(ctx, "unix:///definitely/missing/docker.sock")
+1 -1
View File
@@ -96,7 +96,7 @@ func TestRegisterRunningJobsFuncZeroCapacity(t *testing.T) {
} }
func TestStartServerCanBeCancelled(t *testing.T) { func TestStartServerCanBeCancelled(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
StartServer(ctx, "127.0.0.1:0", nil) StartServer(ctx, "127.0.0.1:0", nil)
cancel() cancel()
} }
@@ -4,7 +4,6 @@
package process package process
import ( import (
"context"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@@ -70,7 +69,7 @@ func TestKillProcessesWithCWDUnderTerminatesMatch(t *testing.T) {
cmd := startSleeperIn(t, dir) cmd := startSleeperIn(t, dir)
awaitCWD(t, cmd.Process.Pid) awaitCWD(t, cmd.Process.Pid)
killed, err := KillProcessesWithCWDUnder(context.Background(), []string{dir}) killed, err := KillProcessesWithCWDUnder(t.Context(), []string{dir})
require.NoError(t, err) require.NoError(t, err)
require.GreaterOrEqual(t, killed, 1) require.GreaterOrEqual(t, killed, 1)
@@ -85,7 +84,7 @@ func TestKillProcessesWithCWDUnderSparesUnrelated(t *testing.T) {
cmd := startSleeperIn(t, elsewhere) cmd := startSleeperIn(t, elsewhere)
awaitCWD(t, cmd.Process.Pid) awaitCWD(t, cmd.Process.Pid)
_, err := KillProcessesWithCWDUnder(context.Background(), []string{workspace}) _, err := KillProcessesWithCWDUnder(t.Context(), []string{workspace})
require.NoError(t, err) require.NoError(t, err)
require.True(t, processAlive(cmd.Process.Pid), "process outside owned dirs must be spared") require.True(t, processAlive(cmd.Process.Pid), "process outside owned dirs must be spared")
} }
+2 -3
View File
@@ -4,7 +4,6 @@
package process package process
import ( import (
"context"
"os/exec" "os/exec"
"testing" "testing"
@@ -12,7 +11,7 @@ import (
) )
func TestNewTreeKillConfiguresCommand(t *testing.T) { func TestNewTreeKillConfiguresCommand(t *testing.T) {
cmd := exec.CommandContext(context.Background(), "sleep", "1") cmd := exec.CommandContext(t.Context(), "sleep", "1")
tk := NewTreeKill(cmd) tk := NewTreeKill(cmd)
require.NotNil(t, tk) require.NotNil(t, tk)
@@ -22,7 +21,7 @@ func TestNewTreeKillConfiguresCommand(t *testing.T) {
} }
func TestTreeKillCaptureStoresKiller(t *testing.T) { func TestTreeKillCaptureStoresKiller(t *testing.T) {
cmd := exec.CommandContext(context.Background(), "sleep", "10") cmd := exec.CommandContext(t.Context(), "sleep", "10")
cmd.SysProcAttr = SysProcAttr("", false) cmd.SysProcAttr = SysProcAttr("", false)
tk := NewTreeKill(cmd) tk := NewTreeKill(cmd)
require.NoError(t, cmd.Start()) require.NoError(t, cmd.Start())
+1 -1
View File
@@ -43,7 +43,7 @@ func TestJobLog_MirrorsUploadedRows(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
cfg.Log.Job.Dir = t.TempDir() cfg.Log.Job.Dir = t.TempDir()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
t.Cleanup(cancel) t.Cleanup(cancel)
task := &runnerv1.Task{Id: 41, Context: &structpb.Struct{}, Secrets: map[string]string{"TOKEN": "s3cret-value"}} task := &runnerv1.Task{Id: 41, Context: &structpb.Struct{}, Secrets: map[string]string{"TOKEN": "s3cret-value"}}
reporter := NewReporter(ctx, cancel, client, task, cfg) reporter := NewReporter(ctx, cancel, client, task, cfg)
+22 -22
View File
@@ -244,7 +244,7 @@ func TestReporter_Handle(t *testing.T) {
t.Logf("Received UpdateTask: %s", req.Msg.String()) t.Logf("Received UpdateTask: %s", req.Msg.String())
return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{}), nil return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{}), nil
}) })
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
cfg, _ := config.LoadDefault("") cfg, _ := config.LoadDefault("")
@@ -305,7 +305,7 @@ func TestReporter_LogLevelFiltering(t *testing.T) {
return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{}), nil return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{}), nil
}) })
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
cfg, _ := config.LoadDefault("") cfg, _ := config.LoadDefault("")
@@ -374,7 +374,7 @@ func TestReporter_EphemeralRunnerDeletion(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -439,7 +439,7 @@ func TestReporter_RunDaemonClose_Race(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
cfg, _ := config.LoadDefault("") cfg, _ := config.LoadDefault("")
@@ -481,7 +481,7 @@ func TestReporter_MaxLatencyTimer(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -532,7 +532,7 @@ func TestReporter_BatchSizeFlush(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -585,7 +585,7 @@ func TestReporter_StateChangedNotLostDuringReport(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -646,7 +646,7 @@ func TestReporter_StateChangedRestoredOnError(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -691,7 +691,7 @@ func TestReporter_StateNotifyFlush(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -748,7 +748,7 @@ func TestReporter_CloseAlwaysSendsRowsWithNoMore(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -799,7 +799,7 @@ func TestReporter_StateHeartbeat(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -871,7 +871,7 @@ func TestReporter_ServerCancelStillFlushesFinal(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -940,7 +940,7 @@ func TestReporter_CloseReportsCancelledOnCanceledCtx(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
cfg, _ := config.LoadDefault("") cfg, _ := config.LoadDefault("")
@@ -999,7 +999,7 @@ func TestReporter_StopHeartbeats(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -1112,7 +1112,7 @@ func TestReporter_DebugSettingsAreNotMasked(t *testing.T) {
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
reporter := NewReporter(context.Background(), nil, nil, &runnerv1.Task{ reporter := NewReporter(t.Context(), nil, nil, &runnerv1.Task{
Context: taskCtx, Context: taskCtx,
Secrets: map[string]string{"ACTIONS_STEP_DEBUG": "true", "ACTIONS_RUNNER_DEBUG": "true", "TOKEN": "s3cr3t"}, Secrets: map[string]string{"ACTIONS_STEP_DEBUG": "true", "ACTIONS_RUNNER_DEBUG": "true", "TOKEN": "s3cr3t"},
}, &config.Config{}) }, &config.Config{})
@@ -1136,7 +1136,7 @@ func TestReporter_OutputsSentOnce(t *testing.T) {
return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{SentOutputs: slices.Collect(maps.Keys(req.Msg.Outputs))}), nil return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{SentOutputs: slices.Collect(maps.Keys(req.Msg.Outputs))}), nil
}) })
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -1210,7 +1210,7 @@ func TestReporter_AckIndexBeyondBuffer(t *testing.T) {
return connect_go.NewResponse(&runnerv1.UpdateLogResponse{AckIndex: 1000}), nil return connect_go.NewResponse(&runnerv1.UpdateLogResponse{AckIndex: 1000}), nil
}) })
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -1247,7 +1247,7 @@ func TestReporter_CloseWithStuckDaemon(t *testing.T) {
return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{}), nil return connect_go.NewResponse(&runnerv1.UpdateTaskResponse{}), nil
}).Maybe() }).Maybe()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -1294,7 +1294,7 @@ func TestReporter_ServerFailureResultIsReportedAsFailure(t *testing.T) {
}), nil }), nil
}).Maybe() }).Maybe()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -1351,7 +1351,7 @@ func TestReporter_CloseMasksLastWords(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
const idToken = "id-token-request-secret" const idToken = "id-token-request-secret"
taskCtx, err := structpb.NewStruct(map[string]any{"actions_id_token_request_token": idToken}) taskCtx, err := structpb.NewStruct(map[string]any{"actions_id_token_request_token": idToken})
@@ -1420,7 +1420,7 @@ func TestReporter_StepRangeCoversAckedRows(t *testing.T) {
}, },
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)
@@ -1466,7 +1466,7 @@ func TestReporter_StepRangeCoversAckedRows(t *testing.T) {
// A flush the server took no rows for describes nothing new, so it must not spend an // A flush the server took no rows for describes nothing new, so it must not spend an
// UpdateTask. UpdateTask is never registered on the client, so calling it fails the test. // UpdateTask. UpdateTask is never registered on the client, so calling it fails the test.
func TestReporter_FlushWithoutAckedRowsSkipsState(t *testing.T) { func TestReporter_FlushWithoutAckedRowsSkipsState(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(t.Context())
defer cancel() defer cancel()
taskCtx, err := structpb.NewStruct(map[string]any{}) taskCtx, err := structpb.NewStruct(map[string]any{})
require.NoError(t, err) require.NoError(t, err)