github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/mods/unix/rlimit_test.go (about) 1 //go:build !windows && !plan9 && !js 2 // +build !windows,!plan9,!js 3 4 package unix 5 6 import ( 7 "errors" 8 "testing" 9 10 "golang.org/x/sys/unix" 11 "github.com/markusbkk/elvish/pkg/eval" 12 "github.com/markusbkk/elvish/pkg/eval/errs" 13 "github.com/markusbkk/elvish/pkg/eval/evaltest" 14 "github.com/markusbkk/elvish/pkg/eval/vals" 15 "github.com/markusbkk/elvish/pkg/eval/vars" 16 ) 17 18 func TestRlimits(t *testing.T) { 19 mock(t, &getRlimit, func(res int, lim *unix.Rlimit) error { 20 switch res { 21 case unix.RLIMIT_CPU: 22 *lim = unix.Rlimit{Cur: unix.RLIM_INFINITY, Max: unix.RLIM_INFINITY} 23 case unix.RLIMIT_NOFILE: 24 *lim = unix.Rlimit{Cur: 30, Max: 40} 25 case unix.RLIMIT_STACK: 26 return errors.New("fake getrlimit error") 27 } 28 return nil 29 }) 30 31 var cpuCur, cpuMax int 32 mock(t, &setRlimit, func(res int, lim *unix.Rlimit) error { 33 switch res { 34 case unix.RLIMIT_CPU: 35 cpuCur = rlimTToInt(lim.Cur) 36 cpuMax = rlimTToInt(lim.Max) 37 case unix.RLIMIT_NOFILE: 38 return errors.New("fake setrlimit error") 39 } 40 return nil 41 }) 42 43 setup := func(ev *eval.Evaler) { 44 useUNIX(ev) 45 ev.ExtendGlobal(eval.BuildNs(). 46 AddVar("cpu-cur", vars.FromPtr(&cpuCur)). 47 AddVar("cpu-max", vars.FromPtr(&cpuMax))) 48 } 49 50 evaltest.TestWithSetup(t, setup, 51 That("put $unix:rlimits[cpu]").Puts(vals.EmptyMap), 52 That("put $unix:rlimits[nofile]").Puts(vals.MakeMap("cur", 30, "max", 40)), 53 That("has-key $unix:rlimits stack").Puts(false), 54 55 That("set unix:rlimits[cpu] = [&cur=3 &max=8]", "put $cpu-cur $cpu-max"). 56 Puts(3, 8), 57 That("set unix:rlimits[cpu] = [&cur=4]", "put $cpu-cur $cpu-max"). 58 Puts(4, -1), 59 That("set unix:rlimits[cpu] = [&]", "put $cpu-cur $cpu-max").Puts(-1, -1), 60 61 That("set unix:rlimits[nofile] = [&]"). 62 Throws(ErrorWithMessage("setrlimit nofile: fake setrlimit error")), 63 64 // Error parsing the rlimits map 65 That("set unix:rlimits = x"). 66 Throws(errs.BadValue{What: "$unix:rlimits", Valid: "map", Actual: "string"}), 67 That("set unix:rlimits = [&[]=[&]]"). 68 Throws(errs.BadValue{What: "key of $unix:rlimits", 69 Valid: "string", Actual: "list"}), 70 That("set unix:rlimits = [&bad-resource=[&]]"). 71 Throws(errs.BadValue{What: "key of $unix:rlimits", 72 Valid: "valid resource key", Actual: "bad-resource"}), 73 That("set unix:rlimits = [&]"). 74 Throws(errs.BadValue{What: "$unix:rlimits", 75 Valid: "map containing all resource keys", Actual: "[&]"}), 76 // Error parsing a value of the rlimits map 77 That("set unix:rlimits[cpu] = x"). 78 Throws(errs.BadValue{What: "rlimit value", Valid: "map", Actual: "string"}), 79 That("set unix:rlimits[cpu] = [&bad]"). 80 Throws(errs.BadValue{What: "key of rlimit value", 81 Valid: "cur or max", Actual: "bad"}), 82 That("set unix:rlimits[cpu] = [&cur=[]]"). 83 Throws(errs.BadValue{What: "cur in rlimit value", 84 Valid: rlimTValid, Actual: "[]"}), 85 That("set unix:rlimits[cpu] = [&cur=1 &max=[]]"). 86 Throws(errs.BadValue{What: "max in rlimit value", 87 Valid: rlimTValid, Actual: "[]"}), 88 ) 89 } 90 91 func rlimTToInt(r rlimT) int { 92 if r == unix.RLIM_INFINITY { 93 return -1 94 } 95 return int(r) 96 } 97 98 type rlimitFunc = func(int, *unix.Rlimit) error 99 100 func mock(t *testing.T, p *rlimitFunc, f rlimitFunc) { 101 saved := *p 102 *p = f 103 t.Cleanup(func() { *p = saved }) 104 }