mirror of
https://github.com/QingdaoU/JudgeServer.git
synced 2024-12-28 04:51:44 +00:00
dynamic input and output
This commit is contained in:
parent
f9af52145c
commit
b6fcde6f18
@ -29,13 +29,17 @@ class JudgeServerClient(object):
|
||||
def ping(self):
|
||||
return self._request(self.server_base_url + "/ping")
|
||||
|
||||
def judge(self, src, language_config, max_cpu_time, max_memory, test_case_id, spj_version=None, spj_config=None,
|
||||
def judge(self, src, language_config, max_cpu_time, max_memory, test_case_id=None, test_case=None, spj_version=None, spj_config=None,
|
||||
spj_compile_config=None, spj_src=None, output=False):
|
||||
if not (test_case or test_case_id) or (test_case and test_case_id):
|
||||
raise ValueError("invalid parameter")
|
||||
|
||||
data = {"language_config": language_config,
|
||||
"src": src,
|
||||
"max_cpu_time": max_cpu_time,
|
||||
"max_memory": max_memory,
|
||||
"test_case_id": test_case_id,
|
||||
"test_case": test_case,
|
||||
"spj_version": spj_version,
|
||||
"spj_config": spj_config,
|
||||
"spj_compile_config": spj_compile_config,
|
||||
@ -143,3 +147,8 @@ print(int(s1[0]) + int(s1[1]))"""
|
||||
print(client.judge(src=py3_src, language_config=py3_lang_config,
|
||||
max_cpu_time=1000, max_memory=128 * 1024 * 1024,
|
||||
test_case_id="normal"), "\n\n")
|
||||
|
||||
print("c_dynamic_input_judge")
|
||||
print(client.judge(src=c_src, language_config=c_lang_config,
|
||||
max_cpu_time=1000, max_memory=1024 * 1024 * 128,
|
||||
test_case=[{"input": "1 2\n", "output": "3"}, {"input": "1 4\n", "output": "3"}], output=True), "\n\n")
|
||||
|
@ -19,15 +19,14 @@ def _run(instance, test_case_file_id):
|
||||
|
||||
|
||||
class JudgeClient(object):
|
||||
def __init__(self, run_config, exe_path, max_cpu_time, max_memory, test_case_id,
|
||||
def __init__(self, run_config, exe_path, max_cpu_time, max_memory, test_case_dir,
|
||||
submission_dir, spj_version, spj_config, output=False):
|
||||
self._run_config = run_config
|
||||
self._exe_path = exe_path
|
||||
self._max_cpu_time = max_cpu_time
|
||||
self._max_memory = max_memory
|
||||
self._max_real_time = self._max_cpu_time * 3
|
||||
self._test_case_id = test_case_id
|
||||
self._test_case_dir = os.path.join(TEST_CASE_DIR, test_case_id)
|
||||
self._test_case_dir = test_case_dir
|
||||
self._submission_dir = submission_dir
|
||||
|
||||
self._pool = Pool(processes=psutil.cpu_count())
|
||||
@ -145,8 +144,8 @@ class JudgeClient(object):
|
||||
|
||||
if self._output:
|
||||
try:
|
||||
with open(user_output_file, "r", encoding="utf-8") as f:
|
||||
run_result["output"] = f.read()
|
||||
with open(user_output_file, "rb") as f:
|
||||
run_result["output"] = f.read().decode("utf-8", errors="backslashreplace")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
@ -6,7 +7,8 @@ import uuid
|
||||
from flask import Flask, request, Response
|
||||
|
||||
from compiler import Compiler
|
||||
from config import JUDGER_WORKSPACE_BASE, SPJ_SRC_DIR, SPJ_EXE_DIR, COMPILER_USER_UID, SPJ_USER_UID, RUN_USER_UID, RUN_GROUP_GID
|
||||
from config import (JUDGER_WORKSPACE_BASE, SPJ_SRC_DIR, SPJ_EXE_DIR, COMPILER_USER_UID, SPJ_USER_UID,
|
||||
RUN_USER_UID, RUN_GROUP_GID, TEST_CASE_DIR)
|
||||
from exception import TokenVerificationFailed, CompileError, SPJCompileError, JudgeClientError
|
||||
from judge_client import JudgeClient
|
||||
from utils import server_info, logger, token
|
||||
@ -17,23 +19,30 @@ app.debug = DEBUG
|
||||
|
||||
|
||||
class InitSubmissionEnv(object):
|
||||
def __init__(self, judger_workspace, submission_id):
|
||||
self.path = os.path.join(judger_workspace, submission_id)
|
||||
def __init__(self, judger_workspace, submission_id, init_test_case_dir=False):
|
||||
self.work_dir = os.path.join(judger_workspace, submission_id)
|
||||
self.init_test_case_dir = init_test_case_dir
|
||||
if init_test_case_dir:
|
||||
self.test_case_dir = os.path.join(self.work_dir, "submission_" + submission_id)
|
||||
else:
|
||||
self.test_case_dir = None
|
||||
|
||||
def __enter__(self):
|
||||
try:
|
||||
os.mkdir(self.path)
|
||||
os.chown(self.path, COMPILER_USER_UID, RUN_GROUP_GID)
|
||||
os.chmod(self.path, 0o711)
|
||||
os.mkdir(self.work_dir)
|
||||
if self.init_test_case_dir:
|
||||
os.mkdir(self.test_case_dir)
|
||||
os.chown(self.work_dir, COMPILER_USER_UID, RUN_GROUP_GID)
|
||||
os.chmod(self.work_dir, 0o711)
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
raise JudgeClientError("failed to create runtime dir")
|
||||
return self.path
|
||||
return self.work_dir, self.test_case_dir
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if not DEBUG:
|
||||
try:
|
||||
shutil.rmtree(self.path)
|
||||
shutil.rmtree(self.work_dir)
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
raise JudgeClientError("failed to clean runtime dir")
|
||||
@ -47,14 +56,18 @@ class JudgeServer:
|
||||
return data
|
||||
|
||||
@classmethod
|
||||
def judge(cls, language_config, src, max_cpu_time, max_memory, test_case_id,
|
||||
def judge(cls, language_config, src, max_cpu_time, max_memory, test_case_id=None, test_case=None,
|
||||
spj_version=None, spj_config=None, spj_compile_config=None, spj_src=None, output=False):
|
||||
if not (test_case or test_case_id) or (test_case and test_case_id):
|
||||
raise JudgeClientError("invalid parameter")
|
||||
# init
|
||||
compile_config = language_config.get("compile")
|
||||
run_config = language_config["run"]
|
||||
submission_id = uuid.uuid4().hex
|
||||
|
||||
if spj_version and spj_config:
|
||||
is_spj = spj_version and spj_config
|
||||
|
||||
if is_spj:
|
||||
spj_exe_path = os.path.join(SPJ_EXE_DIR, spj_config["exe_name"].format(spj_version=spj_version))
|
||||
# spj src has not been compiled
|
||||
if not os.path.isfile(spj_exe_path):
|
||||
@ -62,7 +75,11 @@ class JudgeServer:
|
||||
cls.compile_spj(spj_version=spj_version, src=spj_src,
|
||||
spj_compile_config=spj_compile_config)
|
||||
|
||||
with InitSubmissionEnv(JUDGER_WORKSPACE_BASE, submission_id=str(submission_id)) as submission_dir:
|
||||
init_test_case_dir = bool(test_case)
|
||||
with InitSubmissionEnv(JUDGER_WORKSPACE_BASE, submission_id=str(submission_id), init_test_case_dir=init_test_case_dir) as dirs:
|
||||
submission_dir, test_case_dir = dirs
|
||||
test_case_dir = test_case_dir or os.path.join(TEST_CASE_DIR, test_case_id)
|
||||
|
||||
if compile_config:
|
||||
src_path = os.path.join(submission_dir, compile_config["src_name"])
|
||||
|
||||
@ -88,11 +105,39 @@ class JudgeServer:
|
||||
with open(exe_path, "w", encoding="utf-8") as f:
|
||||
f.write(src)
|
||||
|
||||
if init_test_case_dir:
|
||||
info = {"test_case_number": len(test_case), "spj": is_spj, "test_cases": {}}
|
||||
# write test case
|
||||
for index, item in enumerate(test_case):
|
||||
index += 1
|
||||
item_info = {}
|
||||
|
||||
input_name = str(index) + ".in"
|
||||
item_info["input_name"] = input_name
|
||||
input_data = item["input"].encode("utf-8")
|
||||
item_info["input_size"] = len(input_data)
|
||||
|
||||
with open(os.path.join(test_case_dir, input_name), "wb") as f:
|
||||
f.write(input_data)
|
||||
if not is_spj:
|
||||
output_name = str(index) + ".out"
|
||||
item_info["output_name"] = output_name
|
||||
output_data = item["output"].encode("utf-8")
|
||||
item_info["output_md5"] = hashlib.md5(output_data).hexdigest()
|
||||
item_info["output_size"] = len(output_data)
|
||||
item_info["stripped_output_md5"] = hashlib.md5(output_data.rstrip()).hexdigest()
|
||||
|
||||
with open(os.path.join(test_case_dir, output_name), "wb") as f:
|
||||
f.write(output_data)
|
||||
info["test_cases"][index] = item_info
|
||||
with open(os.path.join(test_case_dir, "info"), "w") as f:
|
||||
json.dump(info, f)
|
||||
|
||||
judge_client = JudgeClient(run_config=language_config["run"],
|
||||
exe_path=exe_path,
|
||||
max_cpu_time=max_cpu_time,
|
||||
max_memory=max_memory,
|
||||
test_case_id=str(test_case_id),
|
||||
test_case_dir=test_case_dir,
|
||||
submission_dir=submission_dir,
|
||||
spj_version=spj_version,
|
||||
spj_config=spj_config,
|
||||
|
@ -37,8 +37,9 @@ class JudgeService(object):
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
service = JudgeService()
|
||||
service.heartbeat()
|
||||
if not os.environ.get("DISABLE_HEARTBEAT"):
|
||||
service = JudgeService()
|
||||
service.heartbeat()
|
||||
exit(0)
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
|
Loading…
Reference in New Issue
Block a user