mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-09-18 07:32:20 +02:00
feat: manage task process lifetimes and preserve turn history
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
//go:build linux
|
||||
|
||||
package processguard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCgroupContainsSetsidAndAppliesLimits(t *testing.T) {
|
||||
opts := testOptions()
|
||||
if opts.CgroupRoot == "" {
|
||||
t.Skip("set CSAI_TEST_CGROUP_ROOT to a delegated cgroup v2 root")
|
||||
}
|
||||
opts.Mode = "required"
|
||||
opts.CPUQuotaMicros = 50000
|
||||
id := testID()
|
||||
g, err := NewWithOptions(id, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer closeTestGroup(t, g)
|
||||
file := filepath.Join(t.TempDir(), "escaped")
|
||||
cmd, err := startTestCommand(g, fmt.Sprintf("setsid sh -c 'echo $$ > %s; exec sleep 300' </dev/null >/dev/null 2>&1 &", file))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
reaped := make(chan struct{})
|
||||
go func() { _ = cmd.Wait(); close(reaped) }()
|
||||
pid := readPID(t, file)
|
||||
<-reaped // The launching shell is gone; the cgroup must still own setsid descendants.
|
||||
root := filepath.Join(opts.CgroupRoot, "task-"+id)
|
||||
for name, want := range map[string]string{"pids.max": "64", "memory.max": "268435456", "cpu.max": "50000 100000"} {
|
||||
data, err := os.ReadFile(filepath.Join(root, name))
|
||||
if err != nil || strings.TrimSpace(string(data)) != want {
|
||||
t.Fatalf("%s=%s err=%v", name, data, err)
|
||||
}
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if err = g.Close(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
<-reaped
|
||||
waitGone(t, pid)
|
||||
if _, err = os.Stat(root); !os.IsNotExist(err) {
|
||||
t.Fatalf("cgroup retained after cleanup: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCgroupStartupDelegationAndRecovery(t *testing.T) {
|
||||
opts := testOptions()
|
||||
if opts.CgroupRoot == "" {
|
||||
t.Skip("requires delegated cgroup fixture")
|
||||
}
|
||||
before, err := os.ReadFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
original := ""
|
||||
for _, line := range strings.Split(string(before), "\n") {
|
||||
if strings.HasPrefix(line, "0::") {
|
||||
original = filepath.Join("/sys/fs/cgroup", strings.TrimPrefix(line, "0::"))
|
||||
}
|
||||
}
|
||||
root := filepath.Join(opts.CgroupRoot, "startup-fixture")
|
||||
if err = os.Mkdir(root, 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = os.WriteFile(filepath.Join(root, "cgroup.procs"), []byte(fmt.Sprint(os.Getpid())), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = os.WriteFile(filepath.Join(original, "cgroup.procs"), []byte(fmt.Sprint(os.Getpid())), 0600)
|
||||
if rootLock != nil {
|
||||
_ = rootLock.Close()
|
||||
rootLock = nil
|
||||
}
|
||||
_ = removeCgroupTree(root)
|
||||
}()
|
||||
stale := filepath.Join(root, "task-"+testID())
|
||||
if err = os.Mkdir(stale, 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dir, err := os.Open(stale)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
cmd := exec.Command("sh", "-c", "exec sleep 300")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{UseCgroupFD: true, CgroupFD: int(dir.Fd()), Setsid: true}
|
||||
if err = cmd.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
reaped := make(chan struct{})
|
||||
go func() { _ = cmd.Wait(); close(reaped) }()
|
||||
opts.CgroupRoot = root
|
||||
opts.Mode = "required"
|
||||
if err = configurePlatform(&opts); err != nil {
|
||||
_ = cmd.Process.Kill()
|
||||
<-reaped
|
||||
t.Fatal(err)
|
||||
}
|
||||
<-reaped
|
||||
waitGone(t, cmd.Process.Pid)
|
||||
if _, err = os.Stat(stale); !os.IsNotExist(err) {
|
||||
t.Fatalf("stale task cgroup was not removed: %v", err)
|
||||
}
|
||||
data, err := os.ReadFile(filepath.Join(root, "cgroup.subtree_control"))
|
||||
if err != nil || !strings.Contains(string(data), "memory") {
|
||||
t.Fatalf("delegation not enabled: %s %v", data, err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user