mirror of
https://github.com/QingdaoU/Judger.git
synced 2024-12-29 00:11:41 +00:00
修复setitimer无法限制子进程时间的BUG, 增加测试17
This commit is contained in:
parent
7fa58f5d72
commit
df0cc40750
12
runner.c
12
runner.c
@ -31,7 +31,7 @@ void run(struct config *config, struct result *result) {
|
||||
int status;
|
||||
struct rusage resource_usage;
|
||||
struct timeval start, end;
|
||||
struct rlimit memory_limit;
|
||||
struct rlimit memory_limit, cpu_time_rlimit;
|
||||
int signal;
|
||||
int i;
|
||||
FILE* log_fp;
|
||||
@ -166,7 +166,7 @@ void run(struct config *config, struct result *result) {
|
||||
if (config->max_memory != MEMORY_UNLIMITED) {
|
||||
memory_limit.rlim_cur = memory_limit.rlim_max = (rlim_t) (config->max_memory) * 2;
|
||||
if (setrlimit(RLIMIT_AS, &memory_limit) == -1) {
|
||||
LOG_FATAL(log_fp, "setrlimit failed, errno: %d", errno);
|
||||
LOG_FATAL(log_fp, "setrlimit memory failed, errno: %d", errno);
|
||||
ERROR(log_fp, SETRLIMIT_FAILED);
|
||||
}
|
||||
}
|
||||
@ -181,6 +181,14 @@ void run(struct config *config, struct result *result) {
|
||||
LOG_FATAL(log_fp, "set real time timer failed");
|
||||
ERROR(log_fp, SETITIMER_FAILED);
|
||||
}
|
||||
|
||||
// child process can not inherit timeout rules from parent process defined by setitimer, so we use setrlimit to
|
||||
// control child process max running time
|
||||
cpu_time_rlimit.rlim_cur = cpu_time_rlimit.rlim_max = (config->max_cpu_time + 1000) / 1000;
|
||||
if (setrlimit(RLIMIT_CPU, &cpu_time_rlimit) == -1) {
|
||||
LOG_FATAL(log_fp, "setrlimit cpu time failed, errno: %d", errno);
|
||||
ERROR(log_fp, SETRLIMIT_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
// read stdin from in file
|
||||
|
29
tests/17/Main.c
Normal file
29
tests/17/Main.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int status;
|
||||
int pid;
|
||||
|
||||
if ((pid = fork()) < 0) {
|
||||
perror("fork error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
while (1) {};
|
||||
}
|
||||
else {
|
||||
struct rusage resource_usage;
|
||||
if (wait4(pid, &status, 0, &resource_usage) == -1) {
|
||||
perror("wait4 error!");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
1
tests/17/config
Normal file
1
tests/17/config
Normal file
@ -0,0 +1 @@
|
||||
{"language": "c", "max_cpu_time": 2000, "max_memory": 200000000, "use_sandbox": false}
|
0
tests/17/in
Normal file
0
tests/17/in
Normal file
0
tests/17/out
Normal file
0
tests/17/out
Normal file
1
tests/17/result
Normal file
1
tests/17/result
Normal file
@ -0,0 +1 @@
|
||||
{"flag": 0, "signal": 0}
|
@ -31,7 +31,7 @@ class JudgerTest(TestCase):
|
||||
continue
|
||||
print "\n\nRunning test: ", i
|
||||
test_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), str(i))
|
||||
exe_path = os.path.join("/tmp/judger_test", str(i))
|
||||
exe_path = os.path.join(self.tmp_path, str(i))
|
||||
config = json.loads(open(os.path.join(test_dir, "config")).read())
|
||||
self.assertEqual(self.compile_src(os.path.join(test_dir, "Main.c"), config.pop("language"), exe_path), 0)
|
||||
|
||||
@ -51,6 +51,7 @@ class JudgerTest(TestCase):
|
||||
self._judger_in_file_args_check()
|
||||
self._judger_args_args_check()
|
||||
self._judger_env_args_check()
|
||||
self._judger_child_process_cpu_time_check()
|
||||
self._judger_user_args_check()
|
||||
|
||||
def _judger_cpu_time_args_check(self):
|
||||
@ -129,6 +130,22 @@ class JudgerTest(TestCase):
|
||||
out_file="/dev/null", max_cpu_time=2000, max_memory=200000000,
|
||||
env=["aaa=123"], use_sandbox=True, use_nobody=True)
|
||||
|
||||
# child process can not inherit timeout rules from parent process defined by setitimer, so we use setrlimit to
|
||||
# control child process max running time
|
||||
def _judger_child_process_cpu_time_check(self):
|
||||
try:
|
||||
max_cpu_time = 2000
|
||||
result = judger.run(path=os.path.join(self.tmp_path, "17"), in_file="/dev/null",
|
||||
out_file="/dev/null", max_cpu_time=max_cpu_time, max_memory=200000000,
|
||||
env=["aaa=123"], use_sandbox=False, use_nobody=True)
|
||||
expected_cpu_time = (max_cpu_time + 1000) / 1000 * 1000
|
||||
if result["cpu_time"] > expected_cpu_time * 1.1:
|
||||
self.fail("cpu time exceeded")
|
||||
if result["real_time"] >= max_cpu_time * 3:
|
||||
self.fail("real time exceeded")
|
||||
except Exception as e:
|
||||
self.fail(e.message)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
Loading…
Reference in New Issue
Block a user