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  }