mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2025-11-04 14:49:58 +08:00
add upload test case zip test
This commit is contained in:
parent
e6deec0834
commit
681a88ea83
@ -1,6 +1,7 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from utils.api.tests import APITestCase
|
from utils.api.tests import APITestCase
|
||||||
|
|
||||||
from .models import JudgeServer, JudgeServerToken, SMTPConfig
|
from .models import JudgeServer, JudgeServerToken, SMTPConfig
|
||||||
|
|||||||
@ -1,3 +1,9 @@
|
|||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from utils.api.tests import APITestCase
|
from utils.api.tests import APITestCase
|
||||||
|
|
||||||
from .models import ProblemTag
|
from .models import ProblemTag
|
||||||
@ -16,6 +22,8 @@ class ProblemTagListAPITest(APITestCase):
|
|||||||
class TestCaseUploadAPITest(APITestCase):
|
class TestCaseUploadAPITest(APITestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.api = TestCaseUploadAPI()
|
self.api = TestCaseUploadAPI()
|
||||||
|
self.url = self.reverse("test_case_upload_api")
|
||||||
|
self.create_super_admin()
|
||||||
|
|
||||||
def test_filter_file_name(self):
|
def test_filter_file_name(self):
|
||||||
self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in", ".DS_Store"], spj=False), ["1.in", "1.out"])
|
self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in", ".DS_Store"], spj=False), ["1.in", "1.out"])
|
||||||
@ -23,3 +31,45 @@ class TestCaseUploadAPITest(APITestCase):
|
|||||||
|
|
||||||
self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in"], spj=True), ["1.in", "2.in"])
|
self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in"], spj=True), ["1.in", "2.in"])
|
||||||
self.assertEqual(self.api.filter_name_list(["2.in", "3.in"], spj=True), [])
|
self.assertEqual(self.api.filter_name_list(["2.in", "3.in"], spj=True), [])
|
||||||
|
|
||||||
|
def make_test_case_zip(self):
|
||||||
|
base_dir = os.path.join("/tmp", "test_case")
|
||||||
|
shutil.rmtree(base_dir, ignore_errors=True)
|
||||||
|
os.mkdir(base_dir)
|
||||||
|
file_names = ["1.in", "1.out", "2.in", ".DS_Store"]
|
||||||
|
for item in file_names:
|
||||||
|
with open(os.path.join(base_dir, item), "w", encoding="utf-8") as f:
|
||||||
|
f.write(item + "\n" + item + "\r\n" + "end")
|
||||||
|
zip_file = os.path.join(base_dir, "test_case.zip")
|
||||||
|
with ZipFile(os.path.join(base_dir, "test_case.zip"), "w") as f:
|
||||||
|
for item in file_names:
|
||||||
|
f.write(os.path.join(base_dir, item), item)
|
||||||
|
return zip_file
|
||||||
|
|
||||||
|
def test_upload_spj_test_case_zip(self):
|
||||||
|
with open(self.make_test_case_zip(), "rb") as f:
|
||||||
|
resp = self.client.post(self.url,
|
||||||
|
data={"spj": "true", "file": f}, format="multipart")
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
data = resp.data["data"]
|
||||||
|
self.assertEqual(data["spj"], True)
|
||||||
|
test_case_dir = os.path.join(settings.TEST_CASE_DIR, data["id"])
|
||||||
|
self.assertTrue(os.path.exists(test_case_dir))
|
||||||
|
for item in data["info"]:
|
||||||
|
name = item["input_name"]
|
||||||
|
with open(os.path.join(test_case_dir, name), "r", encoding="utf-8") as f:
|
||||||
|
self.assertEqual(f.read(), name + "\n" + name + "\n" + "end")
|
||||||
|
|
||||||
|
def test_upload_test_case_zip(self):
|
||||||
|
with open(self.make_test_case_zip(), "rb") as f:
|
||||||
|
resp = self.client.post(self.url,
|
||||||
|
data={"spj": "false", "file": f}, format="multipart")
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
data = resp.data["data"]
|
||||||
|
self.assertEqual(data["spj"], False)
|
||||||
|
test_case_dir = os.path.join(settings.TEST_CASE_DIR, data["id"])
|
||||||
|
self.assertTrue(os.path.exists(test_case_dir))
|
||||||
|
for item in data["info"]:
|
||||||
|
name = item["input_name"]
|
||||||
|
with open(os.path.join(test_case_dir, name), "r", encoding="utf-8") as f:
|
||||||
|
self.assertEqual(f.read(), name + "\n" + name + "\n" + "end")
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
|
import hashlib
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from utils.api import CSRFExemptAPIView
|
|
||||||
from account.decorators import admin_required
|
from account.decorators import admin_required
|
||||||
|
from utils.api import CSRFExemptAPIView
|
||||||
from utils.shortcuts import rand_str
|
from utils.shortcuts import rand_str
|
||||||
|
|
||||||
from ..serializers import TestCaseUploadForm
|
from ..serializers import TestCaseUploadForm
|
||||||
|
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ class TestCaseUploadAPI(CSRFExemptAPIView):
|
|||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
try:
|
try:
|
||||||
zip_file = zipfile.ZipFile(tmp_file)
|
zip_file = zipfile.ZipFile(tmp_file)
|
||||||
except zipfile.BadZipfile:
|
except zipfile.BadZipFile:
|
||||||
return self.error("Bad zip file")
|
return self.error("Bad zip file")
|
||||||
name_list = zip_file.namelist()
|
name_list = zip_file.namelist()
|
||||||
test_case_list = self.filter_name_list(name_list, spj=spj)
|
test_case_list = self.filter_name_list(name_list, spj=spj)
|
||||||
@ -62,11 +63,42 @@ class TestCaseUploadAPI(CSRFExemptAPIView):
|
|||||||
test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id)
|
test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id)
|
||||||
os.mkdir(test_case_dir)
|
os.mkdir(test_case_dir)
|
||||||
|
|
||||||
|
size_cache = {}
|
||||||
|
md5_cache = {}
|
||||||
|
|
||||||
for item in test_case_list:
|
for item in test_case_list:
|
||||||
with open(os.path.join(test_case_dir, item), "wb") as f:
|
with open(os.path.join(test_case_dir, item), "wb") as f:
|
||||||
f.write(zip_file.read(item).replace(b"\r\n", b"\n"))
|
content = zip_file.read(item).replace(b"\r\n", b"\n")
|
||||||
|
size_cache[item] = len(content)
|
||||||
|
if item.endswith(".out"):
|
||||||
|
md5_cache[item] = hashlib.md5(content).hexdigest()
|
||||||
|
f.write(content)
|
||||||
|
test_case_info = {"spj": spj, "test_cases": {}}
|
||||||
|
|
||||||
hint = None
|
hint = None
|
||||||
diff = set(name_list).difference(set(test_case_list))
|
diff = set(name_list).difference(set(test_case_list))
|
||||||
if diff:
|
if diff:
|
||||||
hint = ", ".join(diff) + " are ignored"
|
hint = ", ".join(diff) + " are ignored"
|
||||||
return self.success({"id": test_case_id, "file_list": test_case_list, "hint": hint, "spj": spj})
|
|
||||||
|
ret = []
|
||||||
|
|
||||||
|
if spj:
|
||||||
|
for index, item in enumerate(test_case_list):
|
||||||
|
data = {"input_name": item, "input_size": size_cache[item]}
|
||||||
|
ret.append(data)
|
||||||
|
test_case_info["test_cases"][str(index + 1)] = data
|
||||||
|
else:
|
||||||
|
# ["1.in", "1.out", "2.in", "2.out"] => [("1.in", "1.out"), ("2.in", "2.out")]
|
||||||
|
test_case_list = zip(*[test_case_list[i::2] for i in range(2)])
|
||||||
|
for index, item in enumerate(test_case_list):
|
||||||
|
data = {"stripped_output_md5": md5_cache[item[1]],
|
||||||
|
"input_size": size_cache[item[0]],
|
||||||
|
"output_size": size_cache[item[1]],
|
||||||
|
"input_name": item[0],
|
||||||
|
"output_name": item[1]}
|
||||||
|
ret.append(data)
|
||||||
|
test_case_info["test_cases"][str(index + 1)] = data
|
||||||
|
|
||||||
|
with open(os.path.join(test_case_dir, "info"), "w", encoding="utf-8") as f:
|
||||||
|
f.write(json.dumps(test_case_info, indent=4))
|
||||||
|
return self.success({"id": test_case_id, "info": ret, "hint": hint, "spj": spj})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user