A build module runs in the directory its build was unpacked in. When the node-engine replaced that build, every command the module started inherited a deleted working directory, and the toolchain probe's failure became a final refusal of the check that asked it (three checks on ace on 2026-10-26). forgekey: ExecRunnerClean starts its command in the HOME it is given, or the temporary directory; the other runners keep the process's directory while it exists and use the temporary directory once it is gone. buildstep: a guard whose probe failed answers a Refusal with Again set; the puller declines such an ask (delivery.StepDeclined) so its asker puts it again for another node or a later pull, instead of ending it refused. A version mismatch stays a refusal.
84 lines
3.1 KiB
Go
84 lines
3.1 KiB
Go
//go:build integration
|
|
|
|
package forgekey
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func lowered(t *testing.T) {
|
|
was := CallTimeout
|
|
CallTimeout = 50 * time.Millisecond
|
|
t.Cleanup(func() { CallTimeout = was })
|
|
}
|
|
|
|
// 1497/AC1: ExecRunnerFor(0), no deadline: a command longer than the lowered CallTimeout is not cut.
|
|
func TestExecRunnerForZeroIsNotCutByCallTimeout(t *testing.T) {
|
|
lowered(t)
|
|
r := ExecRunnerFor(0)(context.Background(), nil, "sleep", "0.2")
|
|
if r.Status != 0 || r.Err != "" {
|
|
t.Errorf("ran = %+v, want status 0", r)
|
|
}
|
|
}
|
|
|
|
// 1497/AC2: ExecRunner is unchanged: cut at CallTimeout with status 124.
|
|
func TestExecRunnerIsStillCutAtCallTimeout(t *testing.T) {
|
|
lowered(t)
|
|
r := ExecRunner(context.Background(), nil, "sleep", "0.2")
|
|
if r.Status != 124 {
|
|
t.Errorf("ran = %+v, want status 124", r)
|
|
}
|
|
}
|
|
|
|
// 1497/AC3: ExecRunnerFor(0) is cut when its context is cancelled.
|
|
func TestExecRunnerForZeroIsCutByItsContext(t *testing.T) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
|
|
defer cancel()
|
|
began := time.Now()
|
|
r := ExecRunnerFor(0)(ctx, nil, "sleep", "2")
|
|
if r.Err != "ended by its step's deadline" {
|
|
t.Errorf("Err = %q, want the step's deadline named, not a bound that was never set", r.Err)
|
|
}
|
|
if r.Status == 0 || time.Since(began) > time.Second {
|
|
t.Errorf("ran = %+v after %v, want it cut", r, time.Since(began))
|
|
}
|
|
}
|
|
|
|
// 1497/AC4: ExecRunnerClean(0) runs env with only the given words: PATH and HOME, not the process's secret. And issue
|
|
// 734: run from a process whose own directory was deleted under it (a module whose build a new one replaced), a clean
|
|
// command starts in its HOME, and any other in the temporary directory, rather than failing to find where it is.
|
|
func TestExecRunnerCleanGivesTheCommandOnlyTheEnvArgument(t *testing.T) {
|
|
t.Setenv("MESH_TEST_SECRET", "x")
|
|
r := ExecRunnerClean(0)(context.Background(), []string{"PATH=" + os.Getenv("PATH"), "HOME=/h"}, "env")
|
|
if r.Status != 0 || !strings.Contains(r.Stdout, "HOME=/h") || !strings.Contains(r.Stdout, "PATH=") || strings.Contains(r.Stdout, "MESH_TEST_SECRET") {
|
|
t.Errorf("ran = %+v", r)
|
|
}
|
|
|
|
home, gone := t.TempDir(), t.TempDir()
|
|
t.Chdir(gone)
|
|
if err := os.Remove(gone); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
r = ExecRunnerClean(0)(context.Background(), []string{"PATH=" + os.Getenv("PATH"), "HOME=" + home}, "pwd")
|
|
if r.Status != 0 || strings.TrimSpace(r.Stdout) != home {
|
|
t.Errorf("a clean command run from a deleted directory = %+v, want it started in its HOME %s", r, home)
|
|
}
|
|
r = ExecRunnerFor(0)(context.Background(), nil, "pwd")
|
|
if r.Status != 0 || strings.TrimSpace(r.Stdout) != os.TempDir() {
|
|
t.Errorf("a command run from a deleted directory = %+v, want it started in %s", r, os.TempDir())
|
|
}
|
|
}
|
|
|
|
// 1497/AC5: ExecRunnerFor(0) is unchanged: the env argument is added to the process's environment.
|
|
func TestExecRunnerForAddsToTheProcessEnvironment(t *testing.T) {
|
|
t.Setenv("MESH_TEST_SECRET", "x")
|
|
r := ExecRunnerFor(0)(context.Background(), []string{"HOME=/h"}, "env")
|
|
if !strings.Contains(r.Stdout, "MESH_TEST_SECRET=x") || !strings.Contains(r.Stdout, "HOME=/h") {
|
|
t.Errorf("ran = %+v", r)
|
|
}
|
|
}
|