rlimit_test.go 3.0 KB

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