diff --git a/judge/bridge/judgecallback.py b/judge/bridge/judgecallback.py index 4f1bf6021c..2fc80c6f10 100644 --- a/judge/bridge/judgecallback.py +++ b/judge/bridge/judgecallback.py @@ -2,6 +2,7 @@ import logging import os import time +from operator import itemgetter from django import db from django.utils import timezone @@ -326,46 +327,50 @@ def on_batch_end(self, packet): def on_test_case(self, packet, max_feedback=SubmissionTestCase._meta.get_field('feedback').max_length): super(DjangoJudgeHandler, self).on_test_case(packet) id = packet['submission-id'] + updates = packet['cases'] + max_position = max(map(itemgetter('position'), updates)) - if not Submission.objects.filter(id=id).update(current_testcase=packet['position'] + 1): + if not Submission.objects.filter(id=id).update(current_testcase=max_position + 1): logger.warning('Unknown submission: %d', id) json_log.error(self._make_json_log(packet, action='test-case', info='unknown submission')) return - test_case = SubmissionTestCase(submission_id=id, case=packet['position']) - status = packet['status'] - if status & 4: - test_case.status = 'TLE' - elif status & 8: - test_case.status = 'MLE' - elif status & 64: - test_case.status = 'OLE' - elif status & 2: - test_case.status = 'RTE' - elif status & 16: - test_case.status = 'IR' - elif status & 1: - test_case.status = 'WA' - elif status & 32: - test_case.status = 'SC' - else: - test_case.status = 'AC' - test_case.time = packet['time'] - test_case.memory = packet['memory'] - test_case.points = packet['points'] - test_case.total = packet['total-points'] - test_case.batch = self.batch_id if self.in_batch else None - test_case.feedback = (packet.get('feedback') or '')[:max_feedback] - test_case.extended_feedback = packet.get('extended-feedback') or '' - test_case.output = packet['output'] - test_case.save() - - json_log.info(self._make_json_log( - packet, action='test-case', case=test_case.case, batch=test_case.batch, - time=test_case.time, memory=test_case.memory, feedback=test_case.feedback, - extended_feedback=test_case.extended_feedback, output=test_case.output, - points=test_case.points, total=test_case.total, status=test_case.status, - )) + bulk_test_case_updates = [] + for result in updates: + test_case = SubmissionTestCase(submission_id=id, case=result['position']) + status = result['status'] + if status & 4: + test_case.status = 'TLE' + elif status & 8: + test_case.status = 'MLE' + elif status & 64: + test_case.status = 'OLE' + elif status & 2: + test_case.status = 'RTE' + elif status & 16: + test_case.status = 'IR' + elif status & 1: + test_case.status = 'WA' + elif status & 32: + test_case.status = 'SC' + else: + test_case.status = 'AC' + test_case.time = result['time'] + test_case.memory = result['memory'] + test_case.points = result['points'] + test_case.total = result['total-points'] + test_case.batch = self.batch_id if self.in_batch else None + test_case.feedback = (result.get('feedback') or '')[:max_feedback] + test_case.extended_feedback = result.get('extended-feedback') or '' + test_case.output = result['output'] + bulk_test_case_updates.append(test_case) + + json_log.info(self._make_json_log( + packet, action='test-case', case=test_case.case, batch=test_case.batch, + time=test_case.time, memory=test_case.memory, feedback=test_case.feedback, + extended_feedback=test_case.extended_feedback, output=test_case.output, + points=test_case.points, total=test_case.total, status=test_case.status, + )) do_post = True @@ -384,16 +389,12 @@ def on_test_case(self, packet, max_feedback=SubmissionTestCase._meta.get_field(' if do_post: event.post('sub_%s' % Submission.get_id_secret(id), { 'type': 'test-case', - 'id': packet['position'], - 'status': test_case.status, - 'time': '%.3f' % round(float(packet['time']), 3), - 'memory': packet['memory'], - 'points': float(test_case.points), - 'total': float(test_case.total), - 'output': packet['output'], + 'id': max_position, }) self._post_update_submission(id, state='test-case') + SubmissionTestCase.objects.bulk_create(bulk_test_case_updates) + def on_supported_problems(self, packet): super(DjangoJudgeHandler, self).on_supported_problems(packet) self.judge.problems.set(Problem.objects.filter(code__in=list(self.problems.keys()))) diff --git a/judge/bridge/judgehandler.py b/judge/bridge/judgehandler.py index 817975da8b..2a0921839d 100644 --- a/judge/bridge/judgehandler.py +++ b/judge/bridge/judgehandler.py @@ -249,7 +249,7 @@ def on_batch_end(self, packet): logger.info('%s: Batch ended on: %s', self.name, packet['submission-id']) def on_test_case(self, packet): - logger.info('%s: Test case completed on: %s', self.name, packet['submission-id']) + logger.info('%s: %d test case(s) completed on: %s', self.name, len(packet['cases']), packet['submission-id']) def on_malformed(self, packet): logger.error('%s: Malformed packet: %s', self.name, packet)