mirror of
https://github.com/QingdaoU/JudgeServer.git
synced 2025-11-04 14:50:01 +08:00
优化代码结构
This commit is contained in:
parent
d8ae42ca07
commit
c112b71415
73
client.py
73
client.py
@ -7,80 +7,15 @@ import time
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
from utils import make_signature
|
from utils import make_signature
|
||||||
|
from languages import c_lang_config, c_lang_spj_config, cpp_lang_config, java_lang_config
|
||||||
|
|
||||||
c_lang_config = {
|
|
||||||
"name": "c",
|
|
||||||
"compile": {
|
|
||||||
"src_name": "main.c",
|
|
||||||
"exe_name": "main",
|
|
||||||
"max_cpu_time": 3000,
|
|
||||||
"max_real_time": 5000,
|
|
||||||
"max_memory": 128 * 1024 * 1024,
|
|
||||||
"compile_command": "/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c99 -static {src_path} -lm -o {exe_path}",
|
|
||||||
},
|
|
||||||
"run": {
|
|
||||||
"command": "{exe_path}",
|
|
||||||
"seccomp_rule": "c_cpp",
|
|
||||||
"max_process_number": 5
|
|
||||||
},
|
|
||||||
"spj_compile": {
|
|
||||||
"src_name": "spj-{spj_version}.c",
|
|
||||||
"exe_name": "spj-{spj_version}",
|
|
||||||
"max_cpu_time": 10000,
|
|
||||||
"max_real_time": 20000,
|
|
||||||
"max_memory": 1024 * 1024 * 1024,
|
|
||||||
"compile_command": "/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c99 {src_path} -lm -o {exe_path}",
|
|
||||||
# server should replace to real info
|
|
||||||
"version": "1",
|
|
||||||
"src": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cpp_lang_config = {
|
|
||||||
"name": "cpp",
|
|
||||||
"compile": {
|
|
||||||
"src_name": "main.cpp",
|
|
||||||
"exe_name": "main",
|
|
||||||
"max_cpu_time": 3000,
|
|
||||||
"max_real_time": 5000,
|
|
||||||
"max_memory": 128 * 1024 * 1024,
|
|
||||||
"compile_command": "/usr/bin/g++ -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c++11 {src_path} -lm -o {exe_path}",
|
|
||||||
},
|
|
||||||
"run": {
|
|
||||||
"command": "{exe_path}",
|
|
||||||
"seccomp_rule": "c_cpp",
|
|
||||||
"max_process_number": 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
java_lang_config = {
|
|
||||||
"name": "java",
|
|
||||||
"compile": {
|
|
||||||
"src_name": "Main.java",
|
|
||||||
"exe_name": "Main",
|
|
||||||
"max_cpu_time": 3000,
|
|
||||||
"max_real_time": 5000,
|
|
||||||
"max_memory": -1,
|
|
||||||
"compile_command": "/usr/bin/javac {src_path} -d {exe_dir} -encoding UTF8"
|
|
||||||
},
|
|
||||||
"run": {
|
|
||||||
"command": "/usr/bin/java -cp {exe_dir} -Xss1M -XX:MaxPermSize=16M -XX:PermSize=8M -Xms16M -Xmx{max_memory}k -Djava.security.manager -Djava.security.policy==/server/java_policy -Djava.awt.headless=true Main",
|
|
||||||
"seccomp_rule": None,
|
|
||||||
"max_process_number": -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
submission_id = str(int(time.time()))
|
submission_id = str(int(time.time()))
|
||||||
|
|
||||||
c_config = c_lang_config
|
c_config = c_lang_config
|
||||||
c_config["spj_compile"]["version"] = "1027"
|
|
||||||
c_config["spj_compile"]["src"] = "#include<stdio.h>\nint main(){//哈哈哈哈\nwhile(1);return 0;}"
|
|
||||||
|
|
||||||
token = hashlib.sha256("token").hexdigest()
|
token = hashlib.sha256("token").hexdigest()
|
||||||
|
|
||||||
|
|
||||||
c_src = r"""
|
c_src = r"""
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int main(){
|
int main(){
|
||||||
@ -113,7 +48,7 @@ public class Main{
|
|||||||
Scanner in=new Scanner(System.in);
|
Scanner in=new Scanner(System.in);
|
||||||
int a=in.nextInt();
|
int a=in.nextInt();
|
||||||
int b=in.nextInt();
|
int b=in.nextInt();
|
||||||
System.out.println((a / (b - 2)));
|
System.out.println(a + b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -126,12 +61,12 @@ def judge():
|
|||||||
src=java_src,
|
src=java_src,
|
||||||
max_cpu_time=1000, max_memory=1024 * 1024 * 1024,
|
max_cpu_time=1000, max_memory=1024 * 1024 * 1024,
|
||||||
test_case_id="d28280c6f3c5ddeadfecc3956a52da3a")
|
test_case_id="d28280c6f3c5ddeadfecc3956a52da3a")
|
||||||
r = requests.post("http://192.168.99.100:8080/judge", data=json.dumps(data))
|
r = requests.post("http://123.57.151.42:11235/judge", data=json.dumps(data))
|
||||||
print r.json()
|
print r.json()
|
||||||
|
|
||||||
|
|
||||||
def ping():
|
def ping():
|
||||||
r = requests.post("http://192.168.99.100:8080/ping", data=json.dumps({}))
|
r = requests.post("http://123.57.151.42:11235/ping", data=json.dumps({}))
|
||||||
print r.json()
|
print r.json()
|
||||||
|
|
||||||
ping()
|
ping()
|
||||||
|
|||||||
@ -4,7 +4,7 @@ judge_server:
|
|||||||
- /data/test_case:/test_case
|
- /data/test_case:/test_case
|
||||||
- /data/log:/log
|
- /data/log:/log
|
||||||
- /data/JudgeServer:/code
|
- /data/JudgeServer:/code
|
||||||
environments:
|
environment:
|
||||||
- judger_token=PLEASE_REPLACE_TO_SECRET_TOKEN
|
- judger_token=PLEASE_REPLACE_TO_SECRET_TOKEN
|
||||||
ports:
|
ports:
|
||||||
- "0.0.0.0:11235:8080"
|
- "0.0.0.0:11235:8080"
|
||||||
|
|||||||
68
languages.py
Normal file
68
languages.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
c_lang_config = {
|
||||||
|
"name": "c",
|
||||||
|
"compile": {
|
||||||
|
"src_name": "main.c",
|
||||||
|
"exe_name": "main",
|
||||||
|
"max_cpu_time": 3000,
|
||||||
|
"max_real_time": 5000,
|
||||||
|
"max_memory": 128 * 1024 * 1024,
|
||||||
|
"compile_command": "/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c99 -static {src_path} -lm -o {exe_path}",
|
||||||
|
},
|
||||||
|
"run": {
|
||||||
|
"command": "{exe_path}",
|
||||||
|
"seccomp_rule": "c_cpp",
|
||||||
|
"max_process_number": 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
c_lang_spj_config = {
|
||||||
|
"src_name": "spj-{spj_version}.c",
|
||||||
|
"exe_name": "spj-{spj_version}",
|
||||||
|
"max_cpu_time": 10000,
|
||||||
|
"max_real_time": 20000,
|
||||||
|
"max_memory": 1024 * 1024 * 1024,
|
||||||
|
"compile_command": "/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c99 {src_path} -lm -o {exe_path}",
|
||||||
|
# server should replace to real info
|
||||||
|
"version": "1",
|
||||||
|
"src": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cpp_lang_config = {
|
||||||
|
"name": "cpp",
|
||||||
|
"compile": {
|
||||||
|
"src_name": "main.cpp",
|
||||||
|
"exe_name": "main",
|
||||||
|
"max_cpu_time": 3000,
|
||||||
|
"max_real_time": 5000,
|
||||||
|
"max_memory": 128 * 1024 * 1024,
|
||||||
|
"compile_command": "/usr/bin/g++ -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c++11 {src_path} -lm -o {exe_path}",
|
||||||
|
},
|
||||||
|
"run": {
|
||||||
|
"command": "{exe_path}",
|
||||||
|
"seccomp_rule": "c_cpp",
|
||||||
|
"max_process_number": 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
java_lang_config = {
|
||||||
|
"name": "java",
|
||||||
|
"compile": {
|
||||||
|
"src_name": "Main.java",
|
||||||
|
"exe_name": "Main",
|
||||||
|
"max_cpu_time": 3000,
|
||||||
|
"max_real_time": 5000,
|
||||||
|
"max_memory": -1,
|
||||||
|
"compile_command": "/usr/bin/javac {src_path} -d {exe_dir} -encoding UTF8"
|
||||||
|
},
|
||||||
|
"run": {
|
||||||
|
"command": "/usr/bin/java -cp {exe_dir} -Xss1M -XX:MaxPermSize=16M -XX:PermSize=8M -Xms16M -Xmx{max_memory}k -Djava.security.manager -Djava.security.policy==/etc/java_policy -Djava.awt.headless=true Main",
|
||||||
|
"seccomp_rule": None,
|
||||||
|
"max_process_number": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
77
server.py
77
server.py
@ -4,19 +4,21 @@ from __future__ import unicode_literals
|
|||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import socket
|
|
||||||
import shutil
|
import shutil
|
||||||
|
import socket
|
||||||
|
|
||||||
import web
|
|
||||||
import _judger
|
import _judger
|
||||||
import psutil
|
import psutil
|
||||||
|
import web
|
||||||
|
|
||||||
from judge_client import JudgeClient
|
|
||||||
from compiler import Compiler
|
from compiler import Compiler
|
||||||
from config import JUDGER_WORKSPACE_BASE, TEST_CASE_DIR
|
from config import JUDGER_WORKSPACE_BASE, TEST_CASE_DIR
|
||||||
from exception import SignatureVerificationFailed, CompileError, SPJCompileError
|
from exception import SignatureVerificationFailed, CompileError, SPJCompileError
|
||||||
|
from judge_client import JudgeClient
|
||||||
from utils import make_signature, check_signature
|
from utils import make_signature, check_signature
|
||||||
|
|
||||||
|
DEBUG = os.environ.get("judger_debug") == "1"
|
||||||
|
|
||||||
|
|
||||||
class InitSubmissionEnv(object):
|
class InitSubmissionEnv(object):
|
||||||
def __init__(self, judger_workspace, submission_id):
|
def __init__(self, judger_workspace, submission_id):
|
||||||
@ -28,7 +30,8 @@ class InitSubmissionEnv(object):
|
|||||||
return self.path
|
return self.path
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
shutil.rmtree(self.path, ignore_errors=True)
|
if not DEBUG:
|
||||||
|
shutil.rmtree(self.path, ignore_errors=True)
|
||||||
|
|
||||||
|
|
||||||
class JudgeServer(object):
|
class JudgeServer(object):
|
||||||
@ -50,11 +53,12 @@ class JudgeServer(object):
|
|||||||
raise SignatureVerificationFailed("token not set")
|
raise SignatureVerificationFailed("token not set")
|
||||||
return hashlib.sha256(t).hexdigest()
|
return hashlib.sha256(t).hexdigest()
|
||||||
|
|
||||||
def judge(self, data, signature, timestamp):
|
def entry(self, data, signature, timestamp, callback):
|
||||||
# check_signature(token=self._token, data=data, signature=signature, timestamp=timestamp)
|
if not DEBUG:
|
||||||
|
check_signature(token=self._token, data=data, signature=signature, timestamp=timestamp)
|
||||||
ret = {"err": None, "data": None}
|
ret = {"err": None, "data": None}
|
||||||
try:
|
try:
|
||||||
ret["data"] = self._judge(**json.loads(data))
|
ret["data"] = callback(**json.loads(data))
|
||||||
except (CompileError, SPJCompileError, SignatureVerificationFailed) as e:
|
except (CompileError, SPJCompileError, SignatureVerificationFailed) as e:
|
||||||
ret["err"] = e.__class__.__name__
|
ret["err"] = e.__class__.__name__
|
||||||
ret["data"] = e.message
|
ret["data"] = e.message
|
||||||
@ -63,7 +67,7 @@ class JudgeServer(object):
|
|||||||
ret["data"] = ": ".join([e.__class__.__name__, e.message])
|
ret["data"] = ": ".join([e.__class__.__name__, e.message])
|
||||||
return make_signature(token=self._token, **ret)
|
return make_signature(token=self._token, **ret)
|
||||||
|
|
||||||
def _judge(self, language_config, submission_id, src, max_cpu_time, max_memory, test_case_id):
|
def judge(self, language_config, submission_id, src, max_cpu_time, max_memory, test_case_id):
|
||||||
# init
|
# init
|
||||||
compile_config = language_config["compile"]
|
compile_config = language_config["compile"]
|
||||||
spj_compile_config = language_config.get("spj_compile")
|
spj_compile_config = language_config.get("spj_compile")
|
||||||
@ -87,39 +91,39 @@ class JudgeServer(object):
|
|||||||
test_case_id=test_case_id,
|
test_case_id=test_case_id,
|
||||||
submission_dir=submission_dir)
|
submission_dir=submission_dir)
|
||||||
run_result = judge_client.run()
|
run_result = judge_client.run()
|
||||||
|
|
||||||
if spj_compile_config:
|
|
||||||
spj_compile_config["src_name"] = spj_compile_config["src_name"].format(spj_version=spj_compile_config["version"])
|
|
||||||
spj_compile_config["exe_name"] = spj_compile_config["exe_name"].format(spj_version=spj_compile_config["version"])
|
|
||||||
|
|
||||||
spj_src_path = os.path.join(TEST_CASE_DIR, test_case_id, spj_compile_config["src_name"])
|
|
||||||
spj_exe_path = os.path.join(TEST_CASE_DIR, test_case_id, spj_compile_config["exe_name"])
|
|
||||||
|
|
||||||
# if spj source code not found, then write it into file
|
|
||||||
if not os.path.exists(spj_src_path):
|
|
||||||
with open(spj_src_path, "w") as f:
|
|
||||||
f.write(spj_compile_config["src"].encode("utf-8"))
|
|
||||||
|
|
||||||
# if spj exe file not found, then compile it
|
|
||||||
if not os.path.exists(spj_exe_path):
|
|
||||||
try:
|
|
||||||
spj_exe_path = Compiler().compile(compile_config=spj_compile_config,
|
|
||||||
src_path=spj_src_path,
|
|
||||||
output_dir=os.path.join(TEST_CASE_DIR, test_case_id))
|
|
||||||
# turn common CompileError into SPJCompileError
|
|
||||||
except CompileError as e:
|
|
||||||
raise SPJCompileError(e.message)
|
|
||||||
return run_result
|
return run_result
|
||||||
|
|
||||||
|
def compile_spj(self, spj_compile_config, test_case_id):
|
||||||
|
spj_compile_config["src_name"] = spj_compile_config["src_name"].format(spj_version=spj_compile_config["version"])
|
||||||
|
spj_compile_config["exe_name"] = spj_compile_config["exe_name"].format(spj_version=spj_compile_config["version"])
|
||||||
|
|
||||||
|
spj_src_path = os.path.join(TEST_CASE_DIR, test_case_id, spj_compile_config["src_name"])
|
||||||
|
|
||||||
|
# if spj source code not found, then write it into file
|
||||||
|
if not os.path.exists(spj_src_path):
|
||||||
|
with open(spj_src_path, "w") as f:
|
||||||
|
f.write(spj_compile_config["src"].encode("utf-8"))
|
||||||
|
try:
|
||||||
|
Compiler().compile(compile_config=spj_compile_config,
|
||||||
|
src_path=spj_src_path,
|
||||||
|
output_dir=os.path.join(TEST_CASE_DIR, test_case_id))
|
||||||
|
# turn common CompileError into SPJCompileError
|
||||||
|
except CompileError as e:
|
||||||
|
raise SPJCompileError(e.message)
|
||||||
|
return "success"
|
||||||
|
|
||||||
def POST(self):
|
def POST(self):
|
||||||
try:
|
try:
|
||||||
data = json.loads(web.data())
|
data = json.loads(web.data())
|
||||||
print web.ctx["path"]
|
|
||||||
if web.ctx["path"] == "/judge":
|
if web.ctx["path"] == "/judge":
|
||||||
return json.dumps(self.judge(**data))
|
callback = self.judge
|
||||||
if web.ctx["path"] == "/ping":
|
elif web.ctx["path"] == "/ping":
|
||||||
return json.dumps(self.pong())
|
callback = self.pong
|
||||||
return {"err": "invalid-method", "data": None}
|
elif web.ctx["path"] == "/compile_spj":
|
||||||
|
callback = self.compile_spj
|
||||||
|
else:
|
||||||
|
return {"err": "invalid-method", "data": None}
|
||||||
|
return json.dumps(self.entry(data=data["data"], signature=data["signature"], timestamp=data["timestamp"], callback=callback))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
ret = dict()
|
ret = dict()
|
||||||
ret["err"] = "ServerError"
|
ret["err"] = "ServerError"
|
||||||
@ -129,7 +133,8 @@ class JudgeServer(object):
|
|||||||
|
|
||||||
urls = (
|
urls = (
|
||||||
"/judge", "JudgeServer",
|
"/judge", "JudgeServer",
|
||||||
"/ping", "JudgeServer"
|
"/ping", "JudgeServer",
|
||||||
|
"/compile_spj", "JudgerServer"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not os.environ.get("judger_token"):
|
if not os.environ.get("judger_token"):
|
||||||
|
|||||||
2
utils.py
2
utils.py
@ -17,7 +17,7 @@ def make_signature(**kwargs):
|
|||||||
|
|
||||||
def check_signature(token, data, signature, timestamp):
|
def check_signature(token, data, signature, timestamp):
|
||||||
ts = int(time.time())
|
ts = int(time.time())
|
||||||
if abs(timestamp - ts) > 5:
|
if abs(timestamp - ts) > 10:
|
||||||
raise SignatureVerificationFailed("Timestamp interval is too long")
|
raise SignatureVerificationFailed("Timestamp interval is too long")
|
||||||
|
|
||||||
if hashlib.sha256(data + str(timestamp) + token).hexdigest() != signature:
|
if hashlib.sha256(data + str(timestamp) + token).hexdigest() != signature:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user