nitunit: use a safe_exec function with high ulimits
[nit.git] / src / testing / testing_base.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Base options for testing tools.
16 module testing_base
17
18 import modelize
19 private import parser_util
20
21 redef class ToolContext
22 # opt --full
23 var opt_full = new OptionBool("Process also imported modules", "--full")
24 # opt --output
25 var opt_output = new OptionString("Output name (default is 'nitunit.xml')", "-o", "--output")
26 # opt --dirr
27 var opt_dir = new OptionString("Working directory (default is '.nitunit')", "--dir")
28 # opt --no-act
29 var opt_noact = new OptionBool("Does not compile and run tests", "--no-act")
30 # opt --nitc
31 var opt_nitc = new OptionString("nitc compiler to use", "--nitc")
32
33 # Working directory for testing.
34 fun test_dir: String do
35 var dir = opt_dir.value
36 if dir == null then return ".nitunit"
37 return dir
38 end
39
40 # Search the `nitc` compiler to use
41 #
42 # If not `nitc` is suitable, then prints an error and quit.
43 fun find_nitc: String
44 do
45 var nitc = opt_nitc.value
46 if nitc != null then
47 if not nitc.file_exists then
48 fatal_error(null, "error: cannot find `{nitc}` given by --nitc.")
49 abort
50 end
51 return nitc
52 end
53
54 nitc = "NITC".environ
55 if nitc != "" then
56 if not nitc.file_exists then
57 fatal_error(null, "error: cannot find `{nitc}` given by NITC.")
58 abort
59 end
60 return nitc
61 end
62
63 var nit_dir = nit_dir
64 nitc = nit_dir/"bin/nitc"
65 if not nitc.file_exists then
66 fatal_error(null, "Error: cannot find nitc. Set envvar NIT_DIR or NITC or use the --nitc option.")
67 abort
68 end
69 return nitc
70 end
71
72 # Execute a system command in a more safe context than `Sys::system`.
73 fun safe_exec(command: String): Int
74 do
75 info(command, 2)
76 var real_command = """
77 bash -c "
78 ulimit -f {{{ulimit_file}}} 2> /dev/null
79 ulimit -t {{{ulimit_usertime}}} 2> /dev/null
80 {{{command}}}
81 "
82 """
83 return system(real_command)
84 end
85
86 # The maximum size (in KB) of files written by a command executed trough `safe_exec`
87 #
88 # Default: 64MB
89 var ulimit_file = 65536 is writable
90
91 # The maximum amount of cpu time (in seconds) for a command executed trough `safe_exec`
92 #
93 # Default: 10 CPU minute
94 var ulimit_usertime = 600 is writable
95 end