修复代码输出重定向错误的问题 增加了输出结果判断
lrun在运行的时候,输入输出重定向的context是当前的shell,所以不能重定向到进程的tmpfs中。考虑在docker中开辟tmpfs缓存空间。 输出结果比较是采用的md5,暂时没考虑格式错误的情况。
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
import commands
|
import commands
|
||||||
from copy_reg import pickle
|
import hashlib
|
||||||
from types import MethodType
|
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
|
|
||||||
from settings import max_running_number, lrun_gid, lrun_uid, use_tmpfs
|
from settings import max_running_number, lrun_gid, lrun_uid, judger_workspace
|
||||||
from consts import Language, Result
|
from consts import Language, Result
|
||||||
|
|
||||||
|
|
||||||
@@ -57,14 +56,15 @@ class JudgeClient(object):
|
|||||||
{
|
{
|
||||||
"1": {"input_name": "1.in",
|
"1": {"input_name": "1.in",
|
||||||
"output_name": "1.out",
|
"output_name": "1.out",
|
||||||
"output_md5": "yyy",
|
"output_md5": "b10a8db164e0754105b7a99be72e3fe5",
|
||||||
"output_size": 100},
|
"output_size": 100},
|
||||||
|
|
||||||
"2": {"input_name": "2.in",
|
"2": {"input_name": "2.in",
|
||||||
"output_name": "2.out",
|
"output_name": "2.out",
|
||||||
"output_md5": "yyy",
|
"output_md5": "3e25960a79dbc69b674cd4ec67a72c62",
|
||||||
"output_size": 100}
|
"output_size": 100}
|
||||||
}
|
},
|
||||||
|
"output_total_size": 200
|
||||||
}
|
}
|
||||||
|
|
||||||
def generate_command(self, test_case_id):
|
def generate_command(self, test_case_id):
|
||||||
@@ -80,17 +80,14 @@ class JudgeClient(object):
|
|||||||
" --network false" + \
|
" --network false" + \
|
||||||
" --uid " + str(lrun_uid) + \
|
" --uid " + str(lrun_uid) + \
|
||||||
" --gid " + str(lrun_gid)
|
" --gid " + str(lrun_gid)
|
||||||
#if use_tmpfs:
|
|
||||||
# command += (" --tmpfs /var " +
|
|
||||||
# str(int(self.test_case_info["test_cases"][str(test_case_id)]["output_size"] * 1.2)))
|
|
||||||
|
|
||||||
if self.language == Language.JAVA:
|
if self.language == Language.JAVA:
|
||||||
command += (" java " + self.exec_file_path)
|
command += (" java " + self.exec_file_path)
|
||||||
else:
|
else:
|
||||||
command += (" " + self.exec_file_path)
|
command += (" " + self.exec_file_path)
|
||||||
# fixme 输出路径
|
|
||||||
command += (" 0<" + self.test_case_dir + str(test_case_id) + ".in" +
|
command += (" 0<" + self.test_case_dir + str(test_case_id) + ".in" +
|
||||||
" 1>" + "/var/judge/" + str(test_case_id) + ".out" +
|
" 1>" + judger_workspace + str(test_case_id) + ".out" +
|
||||||
" 3>&2")
|
" 3>&2")
|
||||||
return command
|
return command
|
||||||
|
|
||||||
@@ -115,9 +112,9 @@ class JudgeClient(object):
|
|||||||
if name == "MEMORY":
|
if name == "MEMORY":
|
||||||
result[translate[name]] = int(value)
|
result[translate[name]] = int(value)
|
||||||
elif name == "CPUTIME":
|
elif name == "CPUTIME":
|
||||||
result[translate[name]] = float(value) * 1000
|
result[translate[name]] = int(float(value) * 1000)
|
||||||
elif name == "REALTIME":
|
elif name == "REALTIME":
|
||||||
result[translate[name]] = float(value) * 1000
|
result[translate[name]] = int(float(value) * 1000)
|
||||||
elif name == "EXITCODE":
|
elif name == "EXITCODE":
|
||||||
result[translate[name]] = int(value)
|
result[translate[name]] = int(value)
|
||||||
elif name == "TERMSIG":
|
elif name == "TERMSIG":
|
||||||
@@ -131,6 +128,30 @@ class JudgeClient(object):
|
|||||||
result[translate[name]] = translate[value]
|
result[translate[name]] = translate[value]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def compare_output(self, test_case_id):
|
||||||
|
test_case_md5 = self.test_case_info["test_cases"][str(test_case_id)]["output_md5"]
|
||||||
|
output_path = judger_workspace + str(test_case_id) + ".out"
|
||||||
|
|
||||||
|
try:
|
||||||
|
f = open(output_path, "rb")
|
||||||
|
except IOError:
|
||||||
|
# 文件不存在等引发的异常 返回结果错误
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 计算输出文件的md5 和之前测试用例文件的md5进行比较
|
||||||
|
md5 = hashlib.md5()
|
||||||
|
while True:
|
||||||
|
data = f.read(2 ** 8)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
md5.update(data)
|
||||||
|
|
||||||
|
# 对比文件是否一致
|
||||||
|
print "my", md5.hexdigest()
|
||||||
|
print test_case_md5
|
||||||
|
# todo 去除最后的空行
|
||||||
|
return md5.hexdigest() == test_case_md5
|
||||||
|
|
||||||
def judge_one(self, test_case_id):
|
def judge_one(self, test_case_id):
|
||||||
# 运行lrun程序 接收返回值
|
# 运行lrun程序 接收返回值
|
||||||
command = self.generate_command(test_case_id)
|
command = self.generate_command(test_case_id)
|
||||||
@@ -156,8 +177,13 @@ class JudgeClient(object):
|
|||||||
raise JudgeClientException("Error exceeded type: " + run_result["exceed"])
|
raise JudgeClientException("Error exceeded type: " + run_result["exceed"])
|
||||||
return run_result
|
return run_result
|
||||||
|
|
||||||
# 下面就是代码正常运行了
|
# 下面就是代码正常运行了 需要判断代码的输出是否正确
|
||||||
run_result["result"] = Result.ACCEPTED
|
|
||||||
|
if self.compare_output(test_case_id):
|
||||||
|
run_result["result"] = Result.ACCEPTED
|
||||||
|
else:
|
||||||
|
run_result["result"] = Result.WRONG_ANSWER
|
||||||
|
|
||||||
return run_result
|
return run_result
|
||||||
|
|
||||||
def collect_result(self, result):
|
def collect_result(self, result):
|
||||||
@@ -177,6 +203,7 @@ class JudgeClient(object):
|
|||||||
try:
|
try:
|
||||||
results.append(item.get())
|
results.append(item.get())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
print e
|
||||||
results.append({"result": Result.SYSTEM_ERROR})
|
results.append({"result": Result.SYSTEM_ERROR})
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@@ -188,11 +215,10 @@ class JudgeClient(object):
|
|||||||
return self_dict
|
return self_dict
|
||||||
|
|
||||||
|
|
||||||
# pickle(MethodType, _pickle_method, _unpickle_method)
|
|
||||||
client = JudgeClient(language=Language.C,
|
client = JudgeClient(language=Language.C,
|
||||||
exec_file_path="/var/judge/a.out",
|
exec_file_path="/var/judger/a.out",
|
||||||
max_cpu_time=1000000,
|
max_cpu_time=1000000,
|
||||||
max_real_time=200000,
|
max_real_time=200000,
|
||||||
max_memory=1,
|
max_memory=1,
|
||||||
test_case_dir="/var/test_case/1/")
|
test_case_dir="/var/test_cases/1/")
|
||||||
print client.run()
|
print client.run()
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
# 这样可以避免同时运行的程序过多导致的cpu占用太高
|
# 这样可以避免同时运行的程序过多导致的cpu占用太高
|
||||||
max_running_number = 10
|
max_running_number = 10
|
||||||
|
|
||||||
# 是否使用tmpfs来缓存程序输出。开启可以提高性能,在内存不足的情况下,可以关闭
|
|
||||||
use_tmpfs = True
|
|
||||||
|
|
||||||
# lrun运行用户的uid
|
# lrun运行用户的uid
|
||||||
lrun_uid = 1001
|
lrun_uid = 1001
|
||||||
|
|
||||||
# lrun用户组gid
|
# lrun用户组gid
|
||||||
lrun_gid = 1002
|
lrun_gid = 1002
|
||||||
|
|
||||||
|
#judger工作目录
|
||||||
|
judger_workspace = "/var/judger/"
|
||||||
|
|||||||
Reference in New Issue
Block a user