Skip to content

Commit d4c450a

Browse files
Reapply "[lit] Implement ulimit builtin"
This reverts commit e812142. This was causing some test failures on MacOS that are now fixed in the reland. These failures were related to calling ulimit -v despite XNU not having support for that option. This patch simply disables the test on non-Linux platforms for now until we can have a Linux specific test for ulimit -v.
1 parent 1c50ee5 commit d4c450a

File tree

7 files changed

+104
-1
lines changed

7 files changed

+104
-1
lines changed

lit/TestRunner.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,12 @@ class ShellEnvironment(object):
9292
we maintain a dir stack for pushd/popd.
9393
"""
9494

95-
def __init__(self, cwd, env, umask=-1):
95+
def __init__(self, cwd, env, umask=-1, ulimit={}):
9696
self.cwd = cwd
9797
self.env = dict(env)
9898
self.umask = umask
9999
self.dirStack = []
100+
self.ulimit = ulimit
100101

101102
def change_dir(self, newdir):
102103
if os.path.isabs(newdir):
@@ -595,6 +596,27 @@ def executeBuiltinUmask(cmd, shenv):
595596
return ShellCommandResult(cmd, "", "", 0, False)
596597

597598

599+
def executeBuiltinUlimit(cmd, shenv):
600+
"""executeBuiltinUlimit - Change the current limits."""
601+
if os.name != "posix":
602+
raise InternalShellError(cmd, "'ulimit' not supported on this system")
603+
if len(cmd.args) != 3:
604+
raise InternalShellError(cmd, "'ulimit' requires two arguments")
605+
try:
606+
new_limit = int(cmd.args[2])
607+
except ValueError as err:
608+
raise InternalShellError(cmd, "Error: 'ulimit': %s" % str(err))
609+
if cmd.args[1] == "-v":
610+
shenv.ulimit["RLIMIT_AS"] = new_limit * 1024
611+
elif cmd.args[1] == "-n":
612+
shenv.ulimit["RLIMIT_NOFILE"] = new_limit
613+
else:
614+
raise InternalShellError(
615+
cmd, "'ulimit' does not support option: %s" % cmd.args[1]
616+
)
617+
return ShellCommandResult(cmd, "", "", 0, False)
618+
619+
598620
def executeBuiltinColon(cmd, cmd_shenv):
599621
"""executeBuiltinColon - Discard arguments and exit with status 0."""
600622
return ShellCommandResult(cmd, "", "", 0, False)
@@ -749,6 +771,7 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
749771
"popd": executeBuiltinPopd,
750772
"pushd": executeBuiltinPushd,
751773
"rm": executeBuiltinRm,
774+
"ulimit": executeBuiltinUlimit,
752775
"umask": executeBuiltinUmask,
753776
":": executeBuiltinColon,
754777
}
@@ -914,6 +937,19 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
914937
if kIsWindows:
915938
args = quote_windows_command(args)
916939

940+
# Handle any resource limits. We do this by launching the command with
941+
# a wrapper that sets the necessary limits. We use a wrapper rather than
942+
# setting the limits in process as we cannot reraise the limits back to
943+
# their defaults without elevated permissions.
944+
if cmd_shenv.ulimit:
945+
executable = sys.executable
946+
args.insert(0, sys.executable)
947+
args.insert(1, os.path.join(builtin_commands_dir, "_launch_with_limit.py"))
948+
for limit in cmd_shenv.ulimit:
949+
cmd_shenv.env["LIT_INTERNAL_ULIMIT_" + limit] = str(
950+
cmd_shenv.ulimit[limit]
951+
)
952+
917953
try:
918954
# TODO(boomanaiden154): We currently wrap the subprocess.Popen with
919955
# os.umask as the umask argument in subprocess.Popen is not
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import sys
2+
import subprocess
3+
import resource
4+
import os
5+
6+
ULIMIT_ENV_VAR_PREFIX = "LIT_INTERNAL_ULIMIT_"
7+
8+
9+
def main(argv):
10+
command_args = argv[1:]
11+
for env_var in os.environ:
12+
if env_var.startswith(ULIMIT_ENV_VAR_PREFIX):
13+
limit_str = env_var[len(ULIMIT_ENV_VAR_PREFIX) :]
14+
limit_value = int(os.environ[env_var])
15+
limit = (limit_value, limit_value)
16+
if limit_str == "RLIMIT_AS":
17+
resource.setrlimit(resource.RLIMIT_AS, limit)
18+
elif limit_str == "RLIMIT_NOFILE":
19+
resource.setrlimit(resource.RLIMIT_NOFILE, limit)
20+
process_output = subprocess.run(command_args)
21+
sys.exit(process_output.returncode)
22+
23+
24+
if __name__ == "__main__":
25+
main(sys.argv)

tests/Inputs/shtest-ulimit/lit.cfg

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import lit.formats
2+
3+
config.name = "shtest-ulimit"
4+
config.suffixes = [".txt"]
5+
config.test_format = lit.formats.ShTest(execute_external=False)
6+
config.test_source_root = None
7+
config.test_exec_root = None
8+
config.substitutions.append(("%{python}", '"%s"' % (sys.executable)))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import resource
2+
3+
print("RLIMIT_AS=" + str(resource.getrlimit(resource.RLIMIT_AS)[0]))
4+
print("RLIMIT_NOFILE=" + str(resource.getrlimit(resource.RLIMIT_NOFILE)[0]))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# RUN: ulimit -n
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# RUN: ulimit -v 1048576
2+
# RUN: ulimit -n 50
3+
# RUN: %{python} %S/print_limits.py
4+
# Fail the test so that we can assert on the output.
5+
# RUN: not echo return

tests/shtest-ulimit.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Check the ulimit command
2+
3+
# ulimit does not work on non-POSIX platforms.
4+
# UNSUPPORTED: system-windows
5+
6+
# TODO(boomanaiden154): The test fails on some non-Linux POSIX
7+
# platforms (like MacOS) due to the underlying system not supporting
8+
# ulimit -v. This test needs to be carved up so we keep full test
9+
# coverage on Linux and as much as possible on other platforms.
10+
# REQUIRES: system-linux
11+
12+
# RUN: not %{lit} -a -v %{inputs}/shtest-ulimit | FileCheck %s
13+
14+
# CHECK: -- Testing: 2 tests{{.*}}
15+
16+
# CHECK-LABEL: FAIL: shtest-ulimit :: ulimit-bad-arg.txt ({{[^)]*}})
17+
# CHECK: ulimit -n
18+
# CHECK: 'ulimit' requires two arguments
19+
20+
# CHECK-LABEL: FAIL: shtest-ulimit :: ulimit_okay.txt ({{[^)]*}})
21+
# CHECK: ulimit -v 1048576
22+
# CHECK: ulimit -n 50
23+
# CHECK: RLIMIT_AS=1073741824
24+
# CHECK: RLIMIT_NOFILE=50

0 commit comments

Comments
 (0)