mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-05-13 19:33:23 +02:00
## Summary - clone the runner environment map for each task before injecting runtime and OIDC tokens - keep the shared base environment immutable so concurrent jobs cannot hit `concurrent map writes` - add a unit test covering task-local env cloning Fixes #958 --------- Co-authored-by: Nicolas <bircni@icloud.com> Reviewed-on: https://gitea.com/gitea/runner/pulls/959 Reviewed-by: Nicolas <bircni@icloud.com>
62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package run
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestRunnerCloneEnvsReturnsTaskLocalCopy(t *testing.T) {
|
|
r := &Runner{
|
|
envs: map[string]string{
|
|
"ACTIONS_CACHE_URL": "http://cache.example",
|
|
"ACTIONS_RUNTIME_URL": "http://runner.example",
|
|
},
|
|
}
|
|
|
|
cloned := r.cloneEnvs()
|
|
require.Equal(t, r.envs, cloned)
|
|
|
|
cloned["ACTIONS_RUNTIME_TOKEN"] = "task-token"
|
|
cloned["ACTIONS_ID_TOKEN_REQUEST_URL"] = "http://oidc.example"
|
|
|
|
assert.NotContains(t, r.envs, "ACTIONS_RUNTIME_TOKEN")
|
|
assert.NotContains(t, r.envs, "ACTIONS_ID_TOKEN_REQUEST_URL")
|
|
assert.Equal(t, "http://cache.example", r.envs["ACTIONS_CACHE_URL"])
|
|
}
|
|
|
|
// Regression test for #958: concurrent tasks writing task-specific env keys
|
|
// used to race on the shared r.envs map and crash the runner with
|
|
// "fatal error: concurrent map writes". Each task must mutate its own clone.
|
|
func TestRunnerCloneEnvsConcurrentMutation(t *testing.T) {
|
|
r := &Runner{
|
|
envs: map[string]string{
|
|
"ACTIONS_CACHE_URL": "http://cache.example",
|
|
"ACTIONS_RUNTIME_URL": "http://runner.example",
|
|
},
|
|
}
|
|
|
|
const goroutines = 16
|
|
var wg sync.WaitGroup
|
|
wg.Add(goroutines)
|
|
for range goroutines {
|
|
go func() {
|
|
defer wg.Done()
|
|
envs := r.cloneEnvs()
|
|
envs["ACTIONS_RUNTIME_TOKEN"] = "task-token"
|
|
envs["ACTIONS_ID_TOKEN_REQUEST_URL"] = "http://oidc.example"
|
|
envs["ACTIONS_ID_TOKEN_REQUEST_TOKEN"] = "oidc-token"
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
|
|
assert.NotContains(t, r.envs, "ACTIONS_RUNTIME_TOKEN")
|
|
assert.NotContains(t, r.envs, "ACTIONS_ID_TOKEN_REQUEST_URL")
|
|
assert.NotContains(t, r.envs, "ACTIONS_ID_TOKEN_REQUEST_TOKEN")
|
|
}
|